Kubernetes 基础设施,用于 HF 模型并与 Cluster.dev 进行聊天

本文的目标是向用户展示如何将 HuggingFace Hub 中的任何 LLM 模型与 Chat 一起启动到 AWS 云账户的 Kubernetes 上,并使其达到生产就绪状态。
HuggingFace TGI 和 Chat-UI
Hugging Face 除了模型、数据集和 Python 库之外,还提供了用于本地推理的 Docker 容器。目前有两个项目:
- 文本生成推理 (Text Generation Inference)。一个可以提供模型服务的 Docker 容器。
- Chat-UI。一个用于与模型聊天的 Docker 镜像(类似于 ChatGPT 的界面)。
如果您只需要在本地部署和测试,这已经足够了。但是,当您想快速将其部署到 Kubernetes 时,可能会遇到一些麻烦和大量的配置工作。
因此,我们决定简化用户的这一过程,让那些希望在自己的云账户中启动 LLM 模型而无需处理复杂的 Infrastructure Development 和管理的用户能够轻松实现。
Kubernetes、Helm、Terraform 和 Cluster.dev
大多数数据科学家使用 Python 作为测试、微调和提供模型的接口。然而,在生产环境中,DevOps 团队需要将其纳入基础设施代码。此外,使用 Kubernetes,GPU 节点的成本将比 SageMaker 至少降低 20%,并且您可以更灵活地进行扩展。大多数生产基础设施都是使用 Terraform 预置的,并且使用 Helm 将软件部署到 Kubernetes。
Cluster.dev(一个开源框架)专门设计用于通过最少命令和文档部署完整基础设施和软件的任务。您可以将其视为 InstallShield(下一步->下一步->安装),但用于 Terraform 和 Helm,以便将任何软件安装到您的云账户中。更多详细信息请参阅 docs.cluster.dev。
EKS 快速入门
为了展示工作流程,我们将使用 Amazon AWS 云和托管的 EKS。但这可以适用于任何其他云和 Kubernetes 版本。
先决条件
- AWS 云账户凭证。
- AWS 配额已针对 g5 或其他所需类型的 GPU 实例请求更改。
- Cluster.dev 和 Terraform 已安装。
- 从 Hub 选择一个带有 .safetensors 权重的 HuggingFace 模型。或者,您可以将模型上传到 S3 存储桶;请参阅 bootstrap.ipynb 中的示例。
- Route53 DNS 区域(可选)。
创建一个 S3 存储桶用于存储状态文件
aws s3 mb s3://cdev-states
克隆包含示例的存储库
git clone https://github.com/shalb/cdev-examples/
cd cdev-examples/aws/eks-model/cluster.dev/
编辑配置文件
project.yaml
- 主要的项目配置,用于设置当前项目的通用全局变量,例如组织、区域、状态桶名称等。它还可以用于设置全局环境变量。
backend.yaml
- 配置 Cluster.dev 状态(包括 Terraform 状态)的后端,并使用 project.yaml
中的变量。
stack-eks.yaml
- 描述 AWS 基础设施配置,包括 VPC、域名和 EKS (Kubernetes) 设置。请参阅 堆栈文档。
这里的核心配置是关于您的 GPU 节点。定义它们的 capacity_type(ON_DEMAND,SPOT)、实例类型和自动伸缩(最小/最大/期望)设置。如果需要,还可以配置磁盘大小和节点标签。接下来最重要的配置是
cluster_name: k8s-model # change this to your cluster name
domain: cluster.dev # if you leave this domain it would be auto-delegated with the zone *.cluster_name.cluster.dev
eks_managed_node_groups:
gpu-nodes:
name: ondemand-gpu-nodes
capacity_type: ON_DEMAND
block_device_mappings:
xvda:
device_name: "/dev/xvda"
ebs:
volume_size: 120
volume_type: "gp3"
delete_on_termination: true
instance_types:
- "g5.xlarge"
labels:
gpu-type: "a10g"
max_size: 1
desired_size: 1
min_size: 0
您可以通过向此 YAML 文件添加类似的代码块来创建任何额外的节点组。所有可用设置的完整列表可在相关 Terraform 模块中找到。
stack-model.yaml
- 描述 HF 模型堆栈。它引用 model-template
文件夹中的模型堆栈模板,并且还安装所需的 Nvidia 驱动程序。
模型堆栈主要使用我们准备并持续开发的 huggingface-model Helm chart 中的值。图表中所有可用选项的列表可在默认的 values.yaml 中查看。以下是您需要更改的主要内容
chart:
model:
organization: "HuggingFaceH4"
name: "zephyr-7b-beta"
init:
s3:
enabled: false # if set to false the model would be cloned directly from HF git space
bucketURL: s3://k8s-model-zephyr/llm/deployment/zephyr-7b-beta # see ../bootstrap.ipynb on how to upload model
huggingface:
args:
- "--max-total-tokens"
- "4048"
#- --quantize
#- "awq"
replicaCount: 1
persistence:
accessModes:
- ReadWriteOnce
storageClassName: gp2
storage: 100Gi
resources:
requests:
cpu: "2"
memory: "8Gi"
limits:
nvidia.com/gpu: 1
chat:
enabled: true
部署堆栈
完成配置后,只需运行一个命令即可部署所有内容
cdev apply
在后台,它将创建以下资源集
Plan results:
+----------------------------+
| WILL BE DEPLOYED |
+----------------------------+
| cluster.route53 |
| cluster.vpc |
| cluster.eks |
| cluster.eks-addons |
| cluster.kubeconfig |
| cluster.outputs |
| model.nvidia-device-plugin |
| model.model |
| model.outputs |
+----------------------------+
整个过程大约需要 30 分钟,您可以滚动此 Asciinema 来了解大概情况
基础设施操作
那么,让我们设想一下我们可以在堆栈之上执行的一些任务。
与 Kubernetes 交互
堆栈部署后,您将获得 kubeconfig
文件,该文件可用于授权访问集群并检查工作负载、日志等。
# First we need to export KUBECONFIG to use kubectl
export KUBECONFIG=`pwd`/kubeconfig
# Then we can examine workloads deployed in the `default` namespace, since we have defined it in the stack-model.yaml
kubectl get pod
# To get logs from model startup, check if the model is loaded without errors
kubectl logs -f <output model pod name from kubectl get pod>
# To list services (should be model, chat and mongo if chat is enabled)
kubectl get svc
# Then you can port-forward the service to your host
kubectl port-forward svc/<model-output from above> 8080:8080
# Now you can chat with your model
curl 127.0.0.1:8080/generate \
-X POST \
-d '{"inputs":"Continue funny story: John decide to stick finger into outlet","parameters":{"max_new_tokens":1000}}' \
-H 'Content-Type: application/json'
更改节点大小和类型
假设我们有一个大型模型,需要用一些非常大的实例来提供服务。但我们希望使用更便宜的 Spot 实例。所以我们需要更改节点组的类型
gpu-nodes:
name: spot-gpu-nodes
capacity_type: SPOT
block_device_mappings:
xvda:
device_name: "/dev/xvda"
ebs:
volume_size: 120
volume_type: "gp3"
delete_on_termination: true
instance_types:
- "g5.12xlarge"
labels:
gpu-type: "a10g"
max_size: 1
desired_size: 1
min_size: 0
然后通过运行 cdev apply
应用更改。
请注意,Spot 实例在该区域并非始终可用。如果 Spot 请求无法满足,您可以在 AWS 控制台中的 EC2 -> 自动扩缩组 -> eks-spot-gpu-nodes -> 活动 下进行检查。如果失败,请尝试更改为 ON_DEMAND
或修改清单中的 instance_types 并重新运行 cdev apply
。
更改模型
如果您需要更改模型,只需编辑其名称和组织。然后运行 cdev apply
来应用更改。
model:
organization: "WizardLM"
name: "WizardCoder-15B-V1.0"
启用 Chat-UI
要启用 Chat-UI,只需设置 chart.chat.enable:true
。您将获得一个可以进行端口转发并从浏览器使用的服务。如果您需要将聊天暴露给外部用户,请添加入口配置,如示例所示
chat:
enabled: true
modelConfig:
extraEnvVars:
- name: PUBLIC_ORIGIN
value: "https://:8080"
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: chat.k8s-model.cluster.dev
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- chat.k8s-model.cluster.dev
secretName: huggingface-model-chat
请注意,如果您正在使用带有项目前缀(请确保其唯一)的 cluster.dev
域,则 DNS 区域将自动配置。域的 https 证书将自动生成,要检查进度,请使用:kubectl describe certificaterequests.cert-manager.io
如果您希望为模型暴露 API,可以在相应的模型部分设置 Ingress。
监控和指标
您可以在 bootstrap.ipynb 中找到设置 prometheus 和 grafana 进行监控的说明。我们计划发布一个新的堆栈模板,通过一个选项即可启用监控。
在这段 Loom 视频中,您可以看到 Grafana 的配置
问题、帮助和功能请求
请随意使用 GitHub 存储库 讨论区。
结论
运行 HF 模型的方法有很多种。本文的重点是指导已经熟悉 Kubernetes 并有兴趣在不到一小时内为自己的组织使用基础设施即代码 (IaC) 方法部署自己的 ChatGPT 类模型的用户!