在 GKE 上使用多個 GPU 微調 Gemma 開放模型


本教學課程說明如何使用 Hugging FaceTransformers 程式庫,在 Google Kubernetes Engine (GKE) 上,透過繪圖處理單元 (GPU) 微調 Gemma 大型語言模型 (LLM) 系列的開放模型。微調是監督式學習程序,可透過新資料集更新預先訓練模型的參數,提升模型執行特定工作的能力。在本教學課程中,您會從 Hugging Face 下載 20 億參數的預先訓練 Gemma 系列模型,並在 GKE AutopilotStandard 叢集上微調模型。

如果您需要代管型 Kubernetes 的精細控制、擴充性、復原能力、可攜性和成本效益,以便微調 LLM,這份指南是很好的入門資源。

最佳做法

如果您需要統合式管理 AI 平台,以經濟實惠的方式快速建構及提供機器學習模型,請試用 Vertex AI 解決方案。

背景

在 GKE 上使用 GPU 和 Transformers 程式庫提供 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 Transformers

您可以使用 Hugging Face 的 Transformers 程式庫,存取最先進的預先訓練模型。Transformers 程式庫可協助您減少完整模型訓練所需的時間、資源和運算成本。

在本教學課程中,您將使用 Hugging Face API 和工具下載及微調這些預先訓練模型。

目標

本指南適用於 GKE 新手或現有使用者、機器學習工程師、MLOps (開發運作) 工程師,或是有意使用 Kubernetes 容器自動化調度管理功能,在 H100、A100 和 L4 GPU 硬體上微調 LLM 的平台管理員。

完成本指南後,您應該就能執行下列步驟:

  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

  • Verify 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

  • Verify 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 column 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. 在「New principals」(新增主體) 欄位中,輸入您的使用者 ID。 這通常是 Google 帳戶的電子郵件地址。

    5. 在「Select a role」(選取角色) 清單中,選取角色。
    6. 如要授予其他角色,請按一下 「新增其他角色」,然後新增每個其他角色。
    7. 按一下 [Save]
    8. 取得模型存取權

      如要存取 Gemma 模型並部署至 GKE,請先簽署授權同意聲明,然後產生 Hugging Face 存取權杖。

      您必須簽署同意聲明協議,才能使用 Gemma。請按照下列步驟操作:

      1. 前往 Kaggle.com 的模型同意聲明頁面
      2. 使用 Hugging Face 帳戶驗證同意聲明。
      3. 接受模型條款。

      產生存取權杖

      如要透過 Hugging Face 存取模型,必須提供 Hugging Face 權杖

      如要產生新權杖 (如果沒有),請按照下列步驟操作:

      1. 依序點選「Your Profile」(你的個人資料) >「Settings」(設定) >「Access Tokens」(存取權杖)
      2. 選取「New Token」
      3. 指定所選名稱和至少 Write 的角色。
      4. 選取「產生權杖」
      5. 將產生的權杖複製到剪貼簿。

      準備環境

      在本教學課程中,您將使用 Cloud Shell 管理託管於Google Cloud的資源。Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectl gcloud CLI

      如要使用 Cloud Shell 設定環境,請按照下列步驟操作:

      1. 在 Google Cloud 控制台中,按一下Cloud Shell 啟用圖示Google Cloud 控制台中的「啟用 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=1.29
      

      替換下列值:

      • PROJECT_ID:您的 Google Cloud 專案 ID
      • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 區域。提供支援您要使用加速器類型的區域,例如 L4 GPU 的 us-central1
      • CLUSTER_NAME:叢集名稱。

      GKE 會根據部署的工作負載要求,建立含 CPU 和 GPU 節點的 Autopilot 叢集。

      標準

      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 密鑰

      在 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 Transformers 程式碼,微調現有的預先訓練 Gemma 模型。

      1. 建立 Artifact Registry Docker 存放區:

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

        PROJECT_ID 替換為專案 ID。 Google Cloud

      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,並確保這些 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. 執行下列指令來監控 Job:

        watch kubectl get pods
        
      4. 執行下列指令,檢查工作記錄:

        kubectl logs job.batch/finetune-job -f
        

        Job 資源會下載模型資料,然後在所有八個 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. 查看執行中 Deployment 的記錄:

        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:叢集名稱。

      後續步驟