在 Amazon EKS 上部署生成式 AI 模型

6ab6169def2cf89da50d240bcb284a41.gif

导言

生成式 AI 正在改变企业的运作方式,并加快创新的步伐。总体而言,人工智能正在改变企业利用技术的方式。生成式 AI 技术包括微调和部署大型语言模型(LLM),并允许开发人员访问这些模型以执行提示和对话。负责在 Kubernetes 上制定标准的平台团队可以在 Amazon EKS 上微调和部署大语言模型。

本文将通过一个端到端的例子带您了解如何在 Amazon EKS 上构建生成式 AI 系统。Amazon EKS 是一项托管的 Kubernetes 服务,可以在亚马逊云科技上轻松实现部署、管理和扩展容器化的应用程序。

Amazon EKS 的核心优势之一是其可扩展性,数据节点的动态扩展很好满足了大语言模型对于计算资源的灵活要求。例如,Amazon EKS 集群可以扩展到支持数万个容器,这使其成为密集型人工智能工作负载的理想选择。除了可扩展性,Amazon EKS 还提供高度定制化功能,允许用户根据具体需求对配置进行调整。Amazon EKS 具有强大的内置的保障措施,可保护您的人工智能模型和数据。

生成式 AI 模型是人工智能/机器学习领域的一个重大突破,因为它具有广泛的适用性,而且非人工智能专家也能轻松使用。传统上,利用人工智能意味着为每种特定的用例创建专门的模型,每次都需要大量的计算资源和人力资源。生成式 AI 通过创建基础模型克服了这一瓶颈。对基础模型进行微调,使其适用于多种用例,从而实现重复使用,而无需重复从头开始构建模型。目前最常见的是基础模型利用 Transformer(文本生成)/ Diffusers(即图像生成)来实现这种适应性。这些模型具有广泛的用例和行业垂直领域的潜在适用性,从聊天机器人和虚拟助手到完全通过文本提示生成视频的市场营销,不一而足。

大语言模型包含数十亿参数,需要大量资源来进行高性能训练和低延迟推理。Amazon EKS 可作为一个有效的协调器,帮助实现这些生成式 AI 工作负载所需的快速扩缩容,同时提供满足企业管理和控制的工具。Amazon EKS 不仅可以简化管理,还提供各种开源工具,以应对独特的机器学习方面的挑战。Amazon EKS 可让您完全控制自己的环境,从而确保最佳成本效益。

解决方案概述

在 Amazon EKS 上部署

Stable Diffusion 模型的架构

49cdc7fd43d445220f080e55e29a6121.png

即使在 Kubernetes 环境中,也有大量可用来构建和运行模型的工具。一个新兴的工具栈是 Jupterhub,Argo Workflows,Ray 和 Kubernetes,我们称之为 JARK Stack。

89a2cf52a5930665f2d36e8594a6346c.png

JARK 架构

JupyterHub 提供了一个共享平台,用于运行在商业、教育和研究领域广受欢迎的一些 notebook 。它促进了交互式计算,用户可以在这里执行代码、可视化结果并协同工作。在生成式 AI 领域,JupyterHub 加速了实验过程,尤其是反馈环节。数据工程师也可以在这里一起为模型创建相关的提示工程。

Argo Workflows  是一个开源的容器原生的工作流引擎,用于在 Kubernetes 上协调并行作业。它提供了一个结构化和自动化的流水线,专为微调模型而定制。

这个 Argo 的工作流水线包含以下几个阶段:

  • 数据准备:组织和预处理训练数据集

  • 模型配置:定义大语言模型微调的架构和超参数

  • 微调:执行训练计划

  • 验证:衡量微调模型的性能

  • 超参数调优:优化设置,实现最佳性能

  • 模型评估:使用测试数据评估模型效率

  • 部署:托管模型,满足推理需求

Ray 是一个开源分布式计算框架,可轻松扩展应用程序并使用最先进的机器学习库。Ray 用于在多个节点上分布式训练生成模型,从而加快训练过程,并允许处理更大的数据集。

Ray Serve 是一个功能强大的模型服务库,用于创建在线推理应用编程接口(API)。值得注意的是,它与 PyTorch,Keras 和 Tensorflow 等主要框架兼容。它针对大语言模型服务进行了优化,具有流式响应、动态请求批处理和多节点/多 GPU(图形处理单元)支持等功能。除模型服务外,Ray Serve 还可以将多个模型和业务规则整合到一个服务中。Ray Serve 基于 Ray 构建,旨在实现跨机器的可扩展性,并提供资源节约型调度。关于和 JupyterHub 的关系,虽然两者之间的联系看起来不大,但这两种工具都可以成为更大的机器学习生态的一部分,JupyterHub 可以促进交互式计算,而 Ray Serve 则可以处理模型部署和服务。

Kubernetes 是一个功能强大的容器编排平台,可自动部署、扩展和管理容器化应用程序。Kubernetes 为在容器中运行和扩展生成式 AI 模型提供了基础架构,从而确保了高可用性、容错性和极高的资源利用率。

解决方案架构

49c2cbac01a6b2c86899fb4e00131c8c.png

演练

关于如何在 Amazon EKS 上

微调和部署模型的分步指南

具体例子

正如我们前面提到的,大多数下游用例都需要根据业务需求为特定任务微调大语言模型。这通常只需要一个实例相对较少的小型数据集,而且在大多数情况下只需一个 GPU 即可完成。在本文中,我们将以 Dreambooth 为例,展示如何调整类似 Stable Diffusion 这种文生图的模型来为一个主题(例如,狗)在不同的场景生成不同的背景图像。Dreambooth 相关的论文描述了一种将唯一标识符与主题(如[v]狗的照片)绑定的方法,以便根据输入提示(如[v]狗在月球上的照片)在逼真的图像中合成所述主题的照片。

  • Dreambooth 相关的论文

    https://arxiv.org/abs/2208.12242

Dreambooth 相关的商业应用可能包括如下几个:

  1. 根据文字描述为社交媒体平台、电子商务网站和其他在线平台生成图片。

  2. 为用户创建个性化头像。

  3. 为网店生成产品图像。

  4. 制作营销材料和生成使用视觉教具的教学内容。

在本文的剩余部分,我们将我们的示例模型和推理服务称为 dogbooth。为了在 Amazon EKS 上微调 dogbooth ,我们使用了几种开源技术来支持实现。除了 JARK Stack,我们还利用了 Hugging Face 的两个库,它们为我们提供了个性化 Stable Diffusion 模型的工具:Accelerate 和 Diffusers。

Accelerate 是一个开源库,专门用于简化和优化深度学习模型的训练和微调过程。就我们的目的而言,它提供了一个上层应用程序接口(API),让我们可以轻松地尝试不同的超参数和训练配置,而无需每次重写训练循环,并有效利用可用的硬件资源。

Diffusers 是最先进的预训练 diffusion 模型库,用于生成图像、音频甚至 3D分子结构。他们以脚本集的形式提供了易于使用的训练示例,演示了如何在各种个性化任务中有效地使用 Diffusers,如 Unconditional Training、Text-to-Image Training、Dreambooth、ControlNet、Custom Diffusion 等。

在 Amazon EKS 上部署 Stable Diffusion 

模型的步骤

先决条件

  1. Amazon Command Line Interface (Amazon CLI) v2 – the CLI for Amazon services

    https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

  2. kubectl – the Kubernetes CLI

    https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

  3. Terraform 1.5 – an infrastructure as code tool

    https://developer.hashicorp.com/terraform/downloads

  4. Hugging Face Tokenwith write scope

    https://huggingface.co/docs/hub/security-tokens

  5. jq – a lightweight and flexible command line JSON processor

    https://jqlang.github.io/jq/

第一步:下载代码

git clone https://github.com/awslabs/data-on-eks.git

第二步:部署 Amazon EKS

进入第一步下载的代码目录,到 ai-ml/jark-stack 目录下并执行 install.sh 脚本。这个脚本会执行 Terraform 命令来创建基础设施。值得注意的是资源默认会被部署到 us-west-2 region,可以通过更新文件 variables.tf 里面的值来指定其他的 Amazon Region。整个部署过程大概需要耗时 30 分钟。

cd data-on-eks/ai-ml/jark-stack/terraform
export TF_VAR_huggingface_token=hf_XXXXXXXXXX./install.sh  Initializing ...
Initializing the backend...
Initializing modules...Initializing provider plugins...
Terraform has been successfully initialized!
...
SUCCESS: Terraform apply of all modules completed successfully

部署的主要资源清单如下:

  • VPC (subnets, route tables, NAT gateway)

  • Amazon EKS cluster

  • Core-Managed Node Group

  • GPU-Managed Node Group

  • A kubernetes secret for Hugging Face token

  • Add-ons

Add-ons

让我们来看一下部署了哪些 add-ons。

aws eks update-kubeconfig --name jark-stack --region us-west-2kubectl get deployments -ANAMESPACE              NAME                                                 READY   UP-TO-DATE   AVAILABLE   AGE
ingress-nginx          ingress-nginx-controller                             1/1     1            1           36h
jupyterhub             hub                                                  1/1     1            1           36h
jupyterhub             proxy                                                1/1     1            1           36h
kube-system            aws-load-balancer-controller                         2/2     2            2           36h
kube-system            coredns                                              2/2     2            2           2d5h
kube-system            ebs-csi-controller                                   2/2     2            2           2d5h
kuberay-operator       kuberay-operator                                     1/1     1            1           36h
nvidia-device-plugin   nvidia-device-plugin-node-feature-discovery-master   1/1     1            1           36h

Amazon EBS CSI Driver

这个 Driver 允许 Amazon EKS 管理 Amazon EBS 持久卷的生命周期。默认的 StorageClass 是 gp3 。

Amazon Load Balancer Controller

这个 controller 为 Amazon EKS 管理 Amazon ELB。您需要一个网络负载均衡器来访问我们的 Jupyter notebook,最终还需要另一个网络负载均衡器来为我们的自托管推理服务提供入口,这将在本文的后面部分讨论。

NVIDIA Device Plugin

NVIDIA Device Plugin 是一个 Kubernetes DaemonSet,它是 Kubernetes 集群和其底层 GPU 之间的桥梁,允许我们在集群上运行支持 GPU 的容器。

JupyterHub

Terraform 脚本安装了 JupyterHub。在本例中,我们将 values.yaml 传递给了 Helm Chart,这个 values.yaml 定义了 JupyterHub 使用负载均衡器对外提供服务、对 GPU 资源的要求、基于 Amazon EBS 的存储卷用于持久化。请注意,我们展示了 Notebook 基于用户名和密码的基本用户身份验证,仅供演示之用。对于实际场景的设置,请考虑使用 identity provider。

...
proxy:service:annotations:service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ipservice.beta.kubernetes.io/aws-load-balancer-scheme: internet-facingservice.beta.kubernetes.io/aws-load-balancer-type: externalservice.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: 'true'service.beta.kubernetes.io/aws-load-balancer-ip-address-type: ipv4
singleuser:image:name: public.ecr.aws/h3o5n2r0/gpu-jupytertag: v1.5_cuda-11.6_ubuntu-20.04_python-onlypullPolicy: Always
..extraResource:limits:nvidia.com/gpu: "1"extraEnv:HUGGING_FACE_HUB_TOKEN:valueFrom:secretKeyRef:name: hf-tokenkey: tokenstorage:capacity: 100Gi
...- name: notebookconfigMap:name: notebook
...

Ingress-Nginx

Ingress-Nginx 允许我们使用一些路径重写的规则,在同一个负载均衡器上同时暴露 Ray dashboard 和推理入口。还允许我们运行多个 Ray 服务入口,并使用基于路径的路由方式来实现同一个负载均衡器提供不同版本的模型服务。

Kuberay-Operator

KubeRay Operator 使在 Kubernetes 上部署和管理 Ray 集群变得简单便捷。Ray 集群被定义为 custom resource,由高容错性的 Ray Controller 管理。KubeRay Operator 可自动执行 Ray 集群生命周期管理、自动扩展和其他关键功能。 稍后,我们将介绍如何使用集群上的 RayService 自定义资源定义为 dogbooth 创建推理服务。

第三步:微调 Stable Diffusion 模型

现在,您可以开始尝试使用我们的模型,并准备一个 Jupyter Notebook,帮助我们根据您的需求进行个性化设置。

下面首先获取负载均衡器的域名。

kubectl get svc proxy-public -n jupyterhub --output jsonpath='{.status.loadBalancer.ingress[0].hostname}'

使用浏览器打开上述域名,并使用在 jupyterhub-values.yaml 文件配置的用户名密码登陆。如下图。

209f3945afa4fe0f27acc1eda84a0bfe.png

这会触发在 g5 节点上创建了一个 Jupyter-user1 的 Pod。执行 kubectl get pods -n jupyterhub 即可看到类似下图的结果。

df9fa4a9ed1f0d19d272e56da19e5c90.png

当这个 Pod 正常运行之后,您的浏览器就会自动跳转到 notebook console。点击打开 dogbooth 目录里面的 Python noteboot。如下图所示。

824aaaad9c26cf2971d36771c8bf564e.png

打开之后,您就可以逐步执行这个 jupyter notebook 定义的内容了。如下图所示,第一步执行了 nvidia-smi 命令去确认当前的 Notebook 实例是运行在 GPU 节点上的并且可以见到 GPU 芯片的详细信息。

bd96343d5de25e219ca9cec37de16348.png

接下来的四步就是配置开发环境,包括从 GitHub 下载 diffusers 库和安装 Python 依赖。另外,为了实现 memory efficient attention,还需要安装 xFormers。

28919213db55698493ac2aaf19c825e4.png

接下来就是安装 bitsandbytes,它可以允许我们使用 8-bit 的优化器进一步减少内存的需求。

a4e26091d859d98448b8c82d9c8ac200.png

成功安装 bitsandbytes 之后,下一步就是要配置 dreambooth 训练脚本所需要的环境。这包括安装一些额外的依赖包,配置默认加速设置,登录 HuggingFace 并下载示例数据集。

ecde0be6db421ec284d5f1db3d37bb13.png

现在,您可以为输入模型的位置、数据集目录和微调后模型的输出目录设置环境变量,然后开始微调模型。HuggingFace accelerate 会完成所有繁重的工作,帮助我们对模型进行实验。以下示例中使用的超参数经过优化,可在 1 个配备 24 GB 内存的英伟达 A10G GPU 上成功运行训练。

8e960c184e4619bc09f600981839b871.png

完成这项工作大约需要 1.5 个小时。您可以通过更改一些超参数(如 -max_train_steps=400 )来减少训练时间,但这是以牺牲模型的性能和准确性为代价的。

训练脚本完成后,您就可以验证模型是否已创建,并运行样本推理以检查其性能如何。

15f67aa4e77b492b11111cebff6c5dc2.png

打开 dog-bucket.png,这张图片在/home/jovyan/diffusers/examples/deambooth 目录下。

9f280fb05ef900e4b8ffb4ff54e99db6.png

由于 HuggingFace accelerate 也会将模型上传到 HuggingFace,因此您甚至可以在其托管推理 API 上测试推理样本。您可以在这里找到您的模型 https://huggingface.co/spaces//dogbooth  或者在您指定的模型输出目录中。

7abdd2869579dbc4a6b084d8401dfcc0.png

如果模型过拟合或者欠拟合,请参考 HuggingFace 对 dreambooth 的深入分析(https://huggingface.co/blog/dreambooth),以帮助您调整超参数,提高模型性能。这些建议超出了本文的讨论范围。

第四步:提供大语言模型服务

现在您已经拥有了一个微调过的模型,可以使用这个模型在 Amazon EKS 上创建推理节点了。

您可以使用 RayService 自定义资源定义(CRD)来部署一个带有 RayServe 应用程序的 Ray 集群,该应用程序会调用您之前通过 accelerate 训练脚本微调并推送到 HuggingFace 的模型。

定义 RayService 入口

RayServe 的 Python 应用程序被打包成一个容器镜像,在部署的时候可以被拉取到 RayCluster 中。Ray 的文档提供了使用 Ray Serve 和 FastAPI 创建推理应用程序的示例代码。我们对提供的 Python 代码进行了调整,通过向 RayService 配置传递环境变量 MODEL_ID,将推送到 HuggingFace 的自定义 dogbooth 模型的 model_id 作为该环境变量的值传递进去,如以下步骤所示。同时可以在 src/service/dogbooth.py 查看相关的 Python 代码。想要查看 RayCluster 的 head 和 worker 节点的容器镜像的 Dockerfile, 可以在这里 src/service/Dockerfile 找到。


探索更高级的 RayService 的配置将作为练习留给读者。

定义 RayService

现在可以部署 RayService 了。我们在目录 data-on-eks/ai-ml/jark-stack/terraform/src/service 提供了 RayService 的 Kubernetes 定义文件 ray-service.yaml。这个文件主要包含了如下定义:

  1. 创建名为 dogbooth 的命名空间,用以部署 RayCluster。

  2. 创建一个 ingress, 以便通过 ingress-nginx 将 RayService 入口暴露给亚马逊云科技网络负载均衡器,并为界面和推理服务提供基于路径的路由。

  3. 编辑 env_vars 下的 MODEL_ID,将模型库更改为微调后的模型库。

---
apiVersion: v1
kind: Namespace
metadata:name: dogbooth
---
apiVersion: ray.io/v1alpha1
kind: RayService
metadata:name: dogboothnamespace: dogbooth
spec:
...serveConfig:importPath: dogbooth:entrypointruntimeEnv: |env_vars: {"MODEL_ID": "askulkarni2/dogbooth"}rayClusterConfig:rayVersion: '2.6.0'headGroupSpec:
...template:spec:containers:- name: ray-headimage: $SERVICE_REPO:0.0.1-gpuresources:limits:cpu: 2memory: 16Ginvidia.com/gpu: 1
...workerGroupSpecs:- replicas: 1
...template:spec:containers:- name: ray-workerimage: $SERVICE_REPO:0.0.1-gpu
...resources:limits:cpu: "2"memory: "16Gi"nvidia.com/gpu: 1
...
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: dogboothnamespace: dogboothannotations:nginx.ingress.kubernetes.io/rewrite-target: "/\$1"
spec:ingressClassName: nginxrules:- http:paths:- path: /dogbooth/(.*)pathType: ImplementationSpecificbackend:service:name: dogbooth-head-svcport:number: 8265- path: /dogbooth/serve/(.*)pathType: ImplementationSpecificbackend:service:name: dogbooth-head-svcport:number: 8000

执行命令 kubectl apply -f src/service/ray-service.yaml 在 dogbooth 命名空间中创建 RayService。

一旦执行,RayCluster 的 head 和 worker 节点就会被调度到 GPU 节点上,同时推理入口会被创建并通过负载均衡器向我们提供服务。因为基于 GPU 的 rayproject/ray-ml:2.6.0-gpu 基础镜像比较大,整个部署过程会持续大概 8 分钟左右。

执行 kubectl get pods -n dogbooth –watch 命令观察并等待 Pods 正常运行。之后就可以执行命令 kubectl get ingress dogbooth -n dogbooth --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' 获取负载均衡器的域名来访问 Ray 的控制台。在浏览器中打开获取到的连接(类似 http://k8s-ingressn-ingressn-xxx.elb.us-east-1.amazonaws.com/dogbooth/) ,您可以见到如下图所示的界面。

954de2f21950bce1666ac80044656ab5.png

最后,通过以下提示验证我们的 dogbooth 模型部署,例如:

http://k8s-ingressn-ingressn-xxx.elb.us-east-1.amazonaws.com/dogbooth/serve/imagine?prompt=a photo of [v]dog on the beach

但 Argo Workflows 在哪里?

很高兴您能这么问,我们并没有忘记 Argo Workflows。我们前面讨论的步骤非常适合在问题形成和用例分析的早期阶段进行实验。一旦您找到了符合特定目标的模型,并希望将其部署到生产环境中,这时候协调数据科学家,开发者,运营团队和领域专家的就是 MLOps 了。这种协作可确保模型的开发、部署和管理符合业务目标,并满足运营要求。这就是工作流引擎发挥作用的地方。业界比较流行的工作流引擎有 Kubeflow Pipeline(基于 Argo Workflows),Apache Airflow,Amazon Step Functions 等等。我们在这篇文章(https://aws.amazon.com/blogs/containers/dynamic-spark-scaling-on-amazon-eks-with-argo-workflows-and-events/)中介绍了类似的方法,使用 Argo Events 和 Argo Workflows 作为 Kubernetes 原生的 Workflow 引擎来编排使用 Spark 进行的数据处理作业。进一步延展,我们可以开始思考怎么利用类似方法为生成式 AI 项目构建一个 MLOps 平台。我们将在接下来的文章和 re:Invent 研讨会中更深入地探讨这个系列的话题。

清理资源

要清理在本文中创建的相关资源,执行以下命令即可。

./cleanup.sh

这个脚本会删除 RayService 和执行 terraform destroy 命令删除所有基础设施。

总结

在这篇文章中,我们向您介绍了生成式 AI 模型的出现、它们的优势、关键用例以及创建高适用性输出所需的资源密集性质。我们还谈到了 Amazon EKS 对于实现这些用例所具备的关键优势。Amazon EKS 通过它内置的可扩展性、弹性和跨环境的可重复部署,使客户能够拥有更多的控制权、更大的灵活性以及更高的成本效益。然后,我们还向您介绍了利用 JARK Stack 在 Amazon EKS 上部署生成式 AI 模型的步骤。

亚马逊云科技通过 DataonEKS 项目向您提供了加速采纳机器学习的能力。DataonEKS 是亚马逊云科技的一个开源项目,为在 Amazon EKS 上部署数据工作负载提供最佳实践、基准报告、基础设施即代码(Terraform)模板、部署示例和参考架构。

此外,亚马逊云科技还提供 Amazon Bedrock 和 Amazon Sagemaker 等全托管的机器学习解决方案,可用于轻松部署现成的基础模型,或创建和运行自己的模型。

生成式 AI 处于非常早期的阶段,几乎每天都在快速发展和持续创新。亚马逊云科技很高兴能成为您的合作伙伴,利用我们在市场上最全面、最完整的机器学习功能支持您任何的生成式 AI 需求。我们期待与您在生成式 AI 和机器学习之旅以及未来的道路上合作!

  • 原文链接:https://aws.amazon.com/blogs/containers/deploy-generative-ai-models-on-amazon-eks/

本篇作者

ceeb1b5f4897f4bd6f9efad99cdfbde1.jpeg

Sanjeev Ganjihal

亚马逊云科技高级解决方案架构师。Sanjeev 专注于服务网格、GitOps、IAC、自动扩展和成本优化。他帮助客户在亚马逊云科技上运行、构建和扩展容器化工作负载。

3a61c19690d84c8c1b882303cf6b3e0d.jpeg

Apoorva Kulkarni

亚马逊云科技高级解决方案架构师。Apoorva 帮助客户在亚马逊云科技的容器服务上构建现代应用程序平台。

d0d3998b9a5a648b1cbd443fb1b34a38.jpeg

Rama Prasanna Ponnuswami

亚马逊云科技 WorldWide Goto-Market Specialist,专注于 EKS/EKS-A 领域。Rama 与世界各地的客户合作,指导他们使用亚马逊云科技提供的各种容器解决方案,加速他们的云/容器现代化之旅。

417ee4d4568e11931b9b7d163e9790d6.jpeg

Roland Barcia

亚马逊云科技解决方案架构师总监。Roland 花了 25 年的时间帮助客户构建和现代化系统,并领导着一支专注于 Kubernetes、应用程序现代化、微服务、无服务器、集成和平台工程的全球团队。

校译作者

729b1b61f554df8b814a0c9913b76fe1.png

梁宇

亚马逊云科技专业服务团队 DevOps 顾问,主要负责 DevOps 技术实施。尤为热衷云原生服务及其相关技术。在工作之余,他喜欢运动,以及和家人一起旅游。

b5e71bb441f6e7cc66e96aa207e508bc.gif

星标不迷路,开发更极速!

关注后记得星标「亚马逊云开发者」

94680a64dbbc1ac2c57a8043e6bbd9c3.gif

听说,点完下面4个按钮

就不会碰到bug了!

748ead87eae6525bd76e02928abb086b.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【String、StringBuffer和StringBuilder的区别及使用场景】

String、StringBuffer和StringBuilder的区别及使用场景 1. String类是不可变的,一旦创建,就不能修改。每次对String进行操作(如拼接、替换等),实际上是创建了一个新的String对象。由于String的不可变性,频繁…

使用 Python 的 Matplotlib 库来绘制简单的爱心图案

import matplotlib.pyplot as plt import numpy as npt np.linspace(0, 2*np.pi, 100) x 16 * np.sin(t)**3 y 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)plt.plot(x, y, r) plt.axis(equal) plt.fill(x, y, r) plt.show()这段代码首先导入了 Matpl…

【java中如何避免死锁及其分析和解决多线程环境下的死锁问题】

java中如何避免死锁及其分析和解决多线程环境下的死锁问题 死锁是在多线程环境中经常遇到的一种问题,可以通过以下方法来避免和解决死锁问题:死锁是多线程环境下常见的问题,它发生在两个或多个线程等待对方释放资源的情况下。为了避免死锁&am…

uniapp H5 touchstart touchend 切换背景会失效,或者没用

uniapp H5 touchstart touchend 切换背景会失效&#xff0c;或者没用 直接上代码 &#xff08;使用 class 以及 hover-class来设置样式&#xff09; class 设置默认的背景图或者样式 hover-class 来设置按下的背景图 或者样式 抬起 按下 <view class"mp_zoom_siz…

NRF24L01无线 2.4G射频模块(学习笔记)

一、市场上的NRF24L01模块有三种 二、模块的引脚接口 标准的4线SPI接口 三、寄存器操作命令以及寄存器地址 四、两个NRF24L01模块能够成功通信需要满足的条件 五、两个NRF24L01模块通信连接示意图

git远程仓库基本操作

目录 gitremote &#xff08;查看远程仓库&#xff09; git remote add [仓库名] [url] git clone [url]&#xff08;克隆远程仓库到本地&#xff09; git push [名][分支名]&#xff08;提交到远程仓库&#xff09;​编辑 git pull [名][分支名]从远程仓库拉取​编辑 注意操作…

人工智能是哪个专业

人工智能是一个以计算机科学为基础&#xff0c;由计算机、心理学、哲学等多学科交叉融合的交叉学科、新兴学科。其研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学&#xff0c;企图了解智能的实质&#xff0c;并生产出一种新的能以人类…

【个人博客搭建】Hexo安装部署

目录 一、本地构建Hexo (一) 安装前提 1. Node.js 2. Git 3. Hexo (二) 初始化Hexo 1. 初始化博客目录 2. 配置网站基本信息 (三) 主题配置 1. 选择主题 2. 下载主题 (四) 本地启动Hexo 1. 生成静态文件 2. 启动服务 二、部署 (一) 部署到Github Pages 1. 新建…

开源博客项目Blog .NET Core源码学习(8:EasyCaching使用浅析)

开源博客项目Blog使用EasyCaching模块实现缓存功能&#xff0c;主要是在App.Framwork项目中引用了多类包&#xff0c;包括内存缓存&#xff08;EasyCaching.InMemory&#xff09;、Redis缓存&#xff08;EasyCaching.CSRedis&#xff09;&#xff0c;同时支持多种序列化方式&am…

机器学习复习(4)——CNN算法

目录 数据增强方法 CNN图像分类数据集构建 导入数据集 定义trainer 超参数设置 数据增强 构建CNN网络 开始训练 模型测试 数据增强方法 # 一般情况下&#xff0c;我们不会在验证集和测试集上做数据扩增 # 我们只需要将图片裁剪成同样的大小并装换成Tensor就行 test_t…

【国产MCU】-CH32V307-GPIO控制:输入与输出

GPIO控制:输入与输出 文章目录 GPIO控制:输入与输出1、GPIO简单介绍2、驱动API介绍3、GPIO配置代码实现3.1 GPIO配置为输出3.2 GPIO配置为输入CH32V307的GPIO口可以配置成多种输入或输出模式,内置可关闭的上拉或下拉电阻,可以配置成推挽或开漏功能。GPIO口还可以复用成其他…

一文掌握SpringBoot注解之@Component 知识文集(8)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型23-pytorch搭建生成对抗网络(GAN):手写数字生成的项目应用。生成对抗网络&#xff08;GAN&#xff09;是一种强大的生成模型&#xff0c;在手写数字生成方面具有广泛的应用前景。通过生成…

类和对象 第六部分 继承 第一部分:继承的语法

一.继承的概念 继承是面向对象的三大特性之一 有些类与类之间存在特殊的关系&#xff0c;例如下图&#xff1a; 我们可以发现&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性&#xff0c;这个时候&#xff0c;我们可以讨论利用继承的技术&#xff0c;…

【前端素材】bootstrap3 实现地产置业公司source网页设计

一、需求分析 地产置业公司的网页通常是该公司的官方网站&#xff0c;旨在向访问者提供相关信息和服务。这些网页通常具有以下功能&#xff1a; 公司介绍&#xff1a;网页通常包含有关公司背景、历史、核心价值观和使命等方面的信息。此部分帮助访问者了解公司的身份和目标。 …

LabVIEW船舶自动识别系统

在现代航海领域&#xff0c;安全高效的船舶自动识别系统对于保障航行安全和提高船舶管理效率非常重要。介绍了利用LabVIEW软件开发的一个船舶自动识别系统&#xff0c;该系统通过先进的数据采集和信号处理技术&#xff0c;显著提升了传统自动识别系统的性能。 这个船舶自动识别…

代理IP在游戏中的作用有哪些?

游戏代理IP的作用是什么&#xff1f;IP代理软件相当于连接客户端和虚拟服务器的软件“中转站”&#xff0c;在我们向远程服务器提出需求后&#xff0c;代理服务器首先获得用户的请求&#xff0c;然后将服务请求转移到远程服务器&#xff0c;然后将远程服务器反馈的结果转移到客…

【lesson1】高并发内存池项目介绍

文章目录 这个项目做的是什么&#xff1f;这个项目的要求的知识储备和难度&#xff1f;什么是内存池池化技术内存池内存池主要解决的问题malloc 这个项目做的是什么&#xff1f; 当前项目是实现一个高并发的内存池&#xff0c;他的原型是google的一个开源项目tcmalloc&#xf…

江西省考报名照不能成功上传的原因

江西省考报名照需要根据以下要求生成&#xff1a; 1、近期6个月&#xff0c;免冠证件照 2、照片背景白背景 3、照片文件jpg格式&#xff0c;20-100kb 4、照片像素大小&#xff0c;295x413像素 5、照片必须使用审核工具审核后才能上传

【Java】内存溢出和内存泄露的区别

目录 概念 内存溢出分类 内存泄漏分类 发生场景以及解决方法 内存溢出 内存泄漏 解决方法 这道题是面试常考的&#xff0c;一定要区分好区别&#xff0c;我之前就是直接认为内存溢出就是内存泄漏了 概念 内存溢出&#xff1a;是指程序在申请内存时&#xff0c;没有足够…