使用 GKE 上的多个 GPU 微调 Gemma 开放模型

本教程介绍了如何通过来自 Hugging Face 的 Transformer 库,使用 Google Kubernetes Engine (GKE) 上的图形处理器 (GPU) 来微调 Gemma 大语言模型 (LLM) 系列的开放模型。微调是一种监督式学习过程,它通过使用新数据集更新预训练模型的参数来提高模型执行特定任务的能力。在本教程中,您将从 Hugging Face 下载 2B 参数预训练 Gemma 系列模型,并在 GKE Autopilot 或 Standard 集群上微调这些模型。

如果您在微调 LLM 时需要利用托管式 Kubernetes 提供的精细控制、可伸缩性、弹性、可移植性和成本效益,则本指南是一个很好的起点。

最佳实践:

如果您需要统一的托管式 AI 平台来经济高效地快速构建和应用机器学习模型,请试用我们的 Vertex AI 解决方案。

背景

您可以通过 transformer 库使用 GKE 中的 GPU 应用 Gemma,从而实现一个可用于生产用途的强大推理服务解决方案,具备托管式 Kubernetes 的所有优势,包括高效的可伸缩性和更高的可用性。本部分介绍本指南中使用的关键技术。

Gemma

Gemma 是一组公开提供的轻量级生成式人工智能 (AI) 模型(根据开放许可发布)。这些 AI 模型可以在应用、硬件、移动设备或托管服务中运行。

在本指南中,我们将介绍适用于文本生成的 Gemma。您也可以针对执行特定任务对这些模型进行调优。

您在本文档中使用的数据集是 b-mc2/sql-create-context。

如需了解详情,请参阅 Gemma 文档。

GPU

利用 GPU,您可以加速在节点上运行的特定工作负载(例如机器学习和数据处理)。GKE 提供了一系列机器类型选项以用于节点配置,包括配备 NVIDIA H100、L4 和 A100 GPU 的机器类型。

使用 GKE 中的 GPU 之前,请考虑完成以下学习路线:

  1. 了解当前 GPU 版本可用性
  2. 了解 GKE 中的 GPU

Hugging Face Transformer

借助来自 Hugging Face 的 Transformer 库,您可以访问先进的预训练模型。借助 Transformer 库,您可以减少与完整模型训练相关的时间、资源和计算费用。

在本教程中,您将使用 Hugging Face API 和工具来下载并微调这些预训练模型。

目标

本指南适用于对通过 Kubernetes 容器编排功能在 H100、A100 和 L4 GPU 硬件上微调 LLM 感兴趣的新 GKE 用户或现有 GKE 用户、机器学习工程师、MLOps (DevOps) 工程师或平台管理员。

阅读完本指南后,您应该能够执行以下步骤:

  1. 使用处于 Autopilot 模式的 GKE 集群准备环境。
  2. 创建微调容器。
  3. 使用 GPU 微调 Gemma 2B 模型,并将该模型上传到 Hugging Face。

准备工作

  • 登录您的 Google Cloud 账号。如果您是新手 Google Cloud, 请创建一个账号来评估我们的产品在 实际场景中的表现。新客户还可获享 $300 赠金,用于 运行、测试和部署工作负载。
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  • 确保您在项目中拥有以下一个或多个角色: roles/container.admin、roles/iam.serviceAccountAdmin、roles/cloudbuild.builds.editor

    检查角色

    1. 在 Google Cloud 控制台中,前往 IAM 页面。

      转到 IAM
    2. 选择项目。
    3. 在主账号 列中,找到标识您或您所属群组的所有行。如需了解您属于哪些群组,请与您的 管理员联系。

    4. 对于指定或包含您的所有行,请检查角色 列以查看 角色列表是否包含所需的角色。

    授予角色

    1. 在 Google Cloud 控制台中,前往 IAM 页面。

      转到 IAM
    2. 选择项目。
    3. 点击 授予访问权限。
    4. 在新的主账号 字段中,输入您的用户标识符。 这通常是 Google 账号的电子邮件地址。

    5. 点击选择角色,然后搜索相应角色。
    6. 如需授予其他角色,请点击 添加其他角色 ,然后添加其他各个角色。
    7. 点击 Save (保存)。
  • 如果您还没有 Hugging Face 账号,请创建一个。
  • 确保您的项目具有足够的 L4 GPU 配额。如需了解详情,请参阅 GPU 简介和分配配额。

获取对模型的访问权限

如需获取对 Gemma 模型的访问权限以便部署到 GKE,您必须先签署许可同意协议,然后生成 Huggging Face 访问令牌。

您必须签署同意协议才能使用 Gemma。请按照以下说明操作:

  1. 访问 Kaggle.com 上的模型同意页面。
  2. 使用您的 Hugging Face 账号验证同意情况。
  3. 接受模型条款。

生成一个访问令牌

如需通过 Hugging Face 访问模型,您需要 Hugging Face 令牌。

如果您还没有令牌,请按照以下步骤生成新令牌:

  1. 点击您的个人资料 > 设置 > 访问令牌。
  2. 选择新建令牌 (New Token)。
  3. 指定您选择的名称和一个至少为 Write 的角色。
  4. 选择生成令牌。
  5. 将生成的令牌复制到剪贴板。

准备环境

在本教程中,您将使用 Cloud Shell 来管理Google Cloud上托管的资源。Cloud Shell 预安装有本教程所需的软件,包括 kubectl 和 gcloud CLI。

如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,点击 Google Cloud 控制台中的 Cloud Shell 激活图标 激活 Cloud Shell 以启动 Cloud Shell 会话。此操作会在 Google Cloud 控制台的底部窗格中启动会话。

  2. 设置默认环境变量:

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION
    export CLUSTER_NAME=CLUSTER_NAME
    export HF_TOKEN=HF_TOKEN
    export HF_PROFILE=HF_PROFILE
    

    替换以下值:

    • PROJECT_ID:您的 Google Cloud项目 ID。
    • CONTROL_PLANE_LOCATION:集群控制平面的 Compute Engine 区域。提供支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1。
    • CLUSTER_NAME:您的集群的名称。
    • HF_TOKEN:您之前生成的 Hugging Face 令牌。
    • HF_PROFILE:您之前创建的 Hugging Face 个人资料 ID。
  3. 从 GitHub 克隆示例代码库:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/ai-ml/llm-finetuning-gemma
    

创建和配置 Google Cloud 资源

请按照以下说明创建所需的资源。

创建 GKE 集群和节点池

您可以在 GKE Autopilot 或 Standard 集群中的 GPU 上应用 Gemma。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式。

最佳实践:

使用 Autopilot 可获得全托管式 Kubernetes 体验。

Autopilot

在 Cloud Shell 中,运行以下命令:

gcloud container clusters create-auto CLUSTER_NAME \
    --project=PROJECT_ID \
    --location=CONTROL_PLANE_LOCATION \
    --release-channel=rapid \
    --cluster-version=CLUSTER_VERSION

替换以下值:

  • PROJECT_ID:您的 Google Cloud项目 ID。
  • CONTROL_PLANE_LOCATION:集群控制平面的 Compute Engine 区域。提供支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1。
  • CLUSTER_NAME:您的集群的名称。
  • CLUSTER_VERSION:GKE 版本,必须支持快速发布渠道。如需了解详情,请参阅 检查可用版本和默认版本。

GKE 会根据所部署的工作负载的请求,创建具有所需 CPU 和 GPU 节点的 Autopilot 集群。

Standard

  1. 在 Cloud Shell 中,运行以下命令以创建 Standard 集群:

    gcloud container clusters create CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --workload-pool=PROJECT_ID.svc.id.goog \
        --release-channel=rapid \
        --num-nodes=1
    

    替换以下值:

    • PROJECT_ID:您的 Google Cloud项目 ID。
    • CONTROL_PLANE_LOCATION:集群控制平面的 Compute Engine 区域。提供支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1。
    • CLUSTER_NAME:您的集群的名称。

    集群创建可能需要几分钟的时间。

  2. 运行以下命令来为集群创建节点池:

    gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=8,gpu-driver-version=latest \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --node-locations=CONTROL_PLANE_LOCATION-a \
        --cluster=CLUSTER_NAME \
        --machine-type=g2-standard-96 \
        --num-nodes=1
    

    GKE 会创建一个节点池,其中每个节点有两个 L4 GPU。

为 Hugging Face 凭证创建 Kubernetes Secret

在 Cloud Shell 中,执行以下操作:

  1. 配置 kubectl 以与您的集群通信:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    替换以下值:

    • CONTROL_PLANE_LOCATION:集群控制平面的 Compute Engine 区域。
    • CLUSTER_NAME:您的集群的名称。
  2. 创建包含 Hugging Face 令牌的 Kubernetes Secret:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token=$HF_TOKEN \
        --dry-run=client -o yaml | kubectl apply -f -
    

    将 $HF_TOKEN 替换为您之前生成的 Hugging Face 令牌,或者使用您设置的环境变量。

使用 Docker 和 Cloud Build 创建微调容器

此容器使用 PyTorch 和 Hugging Face Transformer 代码来微调现有的预训练 Gemma 模型。

  1. 创建 Artifact Registry Docker 仓库:

    gcloud artifacts repositories create gemma \
        --project=PROJECT_ID \
        --repository-format=docker \
        --location=us \
        --description="Gemma Repo"
    

    将 PROJECT_ID 替换为您的 Google Cloud项目 ID。

  2. 构建并推送映像:

    gcloud builds submit .
    
  3. 导出 IMAGE_URL 以供稍后在本教程中使用。

    export IMAGE_URL=us-docker.pkg.dev/PROJECT_ID/gemma/finetune-gemma-gpu:1.0.0
    

在 GKE 上运行微调作业

在本部分中,您将部署 Gemma 微调作业。Kubernetes 中的 Job 控制器会创建一个或多个 Pod,并帮助确保它们成功执行特定任务。

  1. 打开 finetune.yaml 文件。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: finetune-job
      namespace: default
    spec:
      backoffLimit: 2
      template:
        metadata:
          annotations:
            kubectl.kubernetes.io/default-container: finetuner
        spec:
          terminationGracePeriodSeconds: 600
          containers:
          - name: finetuner
            image: $IMAGE_URL
            resources:
              limits:
                nvidia.com/gpu: "8"
            env:
            - name: MODEL_NAME
              value: "google/gemma-2b"
            - name: NEW_MODEL
              value: "gemma-2b-sql-finetuned"
            - name: LORA_R
              value: "8"
            - name: LORA_ALPHA
              value: "16"
            - name: TRAIN_BATCH_SIZE
              value: "1"
            - name: EVAL_BATCH_SIZE
              value: "2"
            - name: GRADIENT_ACCUMULATION_STEPS
              value: "2"
            - name: DATASET_LIMIT
              value: "1000"
            - name: MAX_SEQ_LENGTH
              value: "512"
            - name: LOGGING_STEPS
              value: "5"
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
          restartPolicy: OnFailure
  2. 应用清单以创建微调作业:

    envsubst < finetune.yaml | kubectl apply -f -
    

    此指令会将 IMAGE_URL 替换为清单中的变量。

  3. 通过运行以下命令来监控作业:

    watch kubectl get pods
    
  4. 通过运行以下命令来检查作业的日志:

    kubectl logs job.batch/finetune-job -f
    

    作业资源会下载模型数据,然后在所有 8 个 GPU 上对模型进行微调。此过程最多可能需要 20 分钟才能完成。

  5. 作业完成后,请访问您的 Hugging Face 账号。您的 Hugging Face 个人资料中会显示一个名为 HF_PROFILE/gemma-2b-sql-finetuned 的新模型。

在 GKE 上应用经过微调的模型

在本部分中,您将部署 vLLM 容器以应用 Gemma 模型。 本教程使用 Kubernetes Deployment 来部署 vLLM 容器。Deployment 是一个 Kubernetes API 对象,可让您运行在集群节点中分布的多个 Pod 副本。

  1. 创建以下 serve-gemma.yaml 清单:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-2b
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: "2"
                memory: "7Gi"
                ephemeral-storage: "10Gi"
                nvidia.com/gpu: 1
              limits:
                cpu: "2"
                memory: "7Gi"
                ephemeral-storage: "10Gi"
                nvidia.com/gpu: 1
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=1
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
            - name: MODEL_ID
              value: google/gemma-2b
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
  2. 为新的 MODEL_ID 创建环境变量:

    export MODEL_ID=HF_PROFILE/gemma-2b-sql-finetuned
    

    将 HF_PROFILE 替换为您之前创建的 Hugging Face 个人资料 ID。

  3. 替换清单中的 MODEL_ID:

    sed -i "s|google/gemma-2b|$MODEL_ID|g" serve-gemma.yaml
    
  4. 应用清单:

    kubectl apply -f serve-gemma.yaml
    

    集群中的 Pod 会从 Hugging Face 下载模型权重并启动服务引擎。

  5. 等待部署成为可用状态:

    kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
    
  6. 查看正在运行的部署的日志:

    kubectl logs -f -l app=gemma-server
    

部署资源会下载模型数据。此过程可能需要几分钟的时间。输出类似于以下内容:

INFO 01-26 19:02:54 model_runner.py:689] Graph capturing finished in 4 secs.
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

确保模型已完全下载,然后再继续下一部分。

应用模型

在本部分中,您将与模型互动。

设置端口转发

部署模型后,运行以下命令以设置到模型的端口转发:

kubectl port-forward service/llm-service 8000:8000

输出类似于以下内容:

Forwarding from 127.0.0.1:8000 -> 8000

使用 curl 与模型互动

在新的终端会话中,使用 curl 与模型聊天:

以下示例命令适用于 TGI:

USER_PROMPT="Question: What is the total number of attendees with age over 30 at kubecon eu? Context: CREATE TABLE attendees (name VARCHAR, age INTEGER, kubecon VARCHAR)"

curl -X POST http://localhost:8000/generate \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
    "prompt": "${USER_PROMPT}",
    "temperature": 0.1,
    "top_p": 1.0,
    "max_tokens": 24
}
EOF

以下输出显示了模型响应的示例:

{"generated_text":" Answer: SELECT COUNT(age) FROM attendees WHERE age > 30 AND kubecon = 'eu'\n"}

根据您的查询,您可能需要更改 max_token 以获得更好的结果。您还可以使用指令调优模型,以获得更出色的聊天体验。

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除已部署的资源

为避免因您在本指南中创建的资源导致您的 Google Cloud 账号产生费用,请运行以下命令:

gcloud container clusters delete CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION

替换以下值:

  • CONTROL_PLANE_LOCATION:集群控制平面的 Compute Engine 区域。提供支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1。
  • CLUSTER_NAME:您的集群的名称。

后续步骤