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


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

如果您在微调 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 的 Transformers 库,您可以访问先进的预训练模型。借助 Transformer 库,您可以减少与完整模型训练相关的时间、资源和计算费用。

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

目标

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

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

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

准备工作

  • Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

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

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

  • Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role colunn to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

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

    5. 选择角色列表中,选择一个角色。
    6. 如需授予其他角色,请点击 添加其他角色,然后添加其他各个角色。
    7. 点击保存

获取对模型的访问权限

如需获取对 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 预安装有本教程所需的软件,包括 kubectlgcloud 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 REGION=REGION
    export CLUSTER_NAME=finetuning
    export HF_TOKEN=HF_TOKEN
    export HF_PROFILE=HF_PROFILE
    

    替换以下值:

    • PROJECT_ID:您的 Google Cloud 项目 ID
    • REGION:支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1
    • 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。我们建议您使用 Autopilot 集群获得全托管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式

Autopilot

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

gcloud container clusters create-auto ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${REGION} \
  --release-channel=rapid \
  --cluster-version=1.29

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

标准

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

    gcloud container clusters create ${CLUSTER_NAME} \
      --project=${PROJECT_ID} \
      --region=${REGION} \
      --workload-pool=${PROJECT_ID}.svc.id.goog \
      --release-channel=rapid \
      --num-nodes=1
    

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

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

    gcloud container node-pools create gpupool \
      --accelerator type=nvidia-l4,count=8,gpu-driver-version=latest \
      --project=${PROJECT_ID} \
      --location=${REGION} \
      --node-locations=${REGION}-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=${REGION}
    
  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 -
    

使用 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"
    
  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 微调作业

  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 模型。

  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: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20240220_0936_RC01
            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.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=1
            env:
            - 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
    
  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-finetune
    

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

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} \
  --region=${REGION}

后续步骤