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

社区文章 发布于 2023 年 12 月 18 日

HuggingFace Cluster.dev

本文的目标是向用户展示如何将 HuggingFace Hub 中的任何 LLM 模型与 Chat 一起启动到 AWS 云账户的 Kubernetes 上,并使其达到生产就绪状态。

HuggingFace TGI 和 Chat-UI

Hugging Face 除了模型、数据集和 Python 库之外,还提供了用于本地推理的 Docker 容器。目前有两个项目:

如果您只需要在本地部署和测试,这已经足够了。但是,当您想快速将其部署到 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.devTerraform 已安装。
  • 从 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 来了解大概情况

asciicast

基础设施操作

那么,让我们设想一下我们可以在堆栈之上执行的一些任务。

与 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 的配置

Grafana GPU config

问题、帮助和功能请求

请随意使用 GitHub 存储库 讨论区

结论

运行 HF 模型的方法有很多种。本文的重点是指导已经熟悉 Kubernetes 并有兴趣在不到一小时内为自己的组织使用基础设施即代码 (IaC) 方法部署自己的 ChatGPT 类模型的用户!

社区

注册登录 以评论