在 GKE 上使用 vLLM 搭配 Qwen3 執行推論作業

本教學課程會說明如何使用 vLLM 服務架構,部署及提供 Qwen3 大型語言模型 (LLM) 服務。您將在 Google Kubernetes Engine (GKE) 的單一 A4 虛擬機器 (VM) 執行個體上部署模型。

本教學課程的適用對象為機器學習 (ML) 工程師、平台管理員和操作員,以及有興趣使用 Kubernetes 容器自動化調度管理功能處理推論工作負載的資料和 AI 專家。

目標

  1. 使用 Hugging Face 存取 Qwen3。

  2. 準備環境。

  3. 在 Autopilot 模式中建立 GKE 叢集。

  4. 建立 Cloud Storage bucket。

  5. 建立 Hugging Face 憑證的 Kubernetes 密鑰。

  6. 設定 Cloud Storage 適用的 Workload Identity Federation。

  7. 在 Cloud Storage 值區中填入 Qwen3 模型。

  8. 將 vLLM 容器部署至 GKE。

  9. 使用 curl 與 Qwen3 互動。

  10. 清除所用資源。

費用

本教學課程使用 Google Cloud的計費元件,包括:

如要根據預測用量估算費用,請使用 Pricing Calculator

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用必要的 API:

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用必要的 API:

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com
  14. 將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令: roles/container.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    更改下列內容:

    • PROJECT_ID:專案 ID。
    • USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com
    • ROLE:授予使用者帳戶的 IAM 角色。
  15. 登入或建立 Hugging Face 帳戶

使用 Hugging Face 存取 Qwen3

如要使用 Hugging Face 存取 Qwen3,請按照下列步驟操作:

  1. 登入 Hugging Face
  2. 建立 Hugging Face read 存取權杖。 依序點選「你的設定檔」>「設定」>「存取權杖」>「+ 建立新權杖」
  3. 為權杖指定想要的名稱,然後選取角色。在本教學課程中,您可以選取的最低角色權限等級為「讀取」
  4. 選取「建立權杖」
  5. 將產生的權杖複製到剪貼簿並儲存。本教學課程稍後會用到這項資訊。

準備環境

如要準備環境,請設定預設環境變數:

export PROJECT_ID="YOUR_PROJECT_ID"
export RESERVATION_NAME="YOUR_RESERVATION_NAME"
export REGION="YOUR_REGION"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export GCS_BUCKET_NAME="YOUR_GCS_BUCKET"
export HUGGING_FACE_TOKEN="YOUR_HF_TOKEN"
export NETWORK="YOUR_NETWORK_NAME"
export SUBNETWORK="YOUR_SUBNETWORK_NAME"

gcloud config set project "${PROJECT_ID}"
gcloud config set billing/quota_project "${PROJECT_ID}"

更改下列內容:

  • YOUR_PROJECT_ID:您要在 Google Cloud 專案中建立 GKE 叢集,請輸入該專案的 ID。

  • YOUR_RESERVATION_NAME:您要用來建立 GKE 叢集的預留項目名稱。根據預留項目所在的專案,指定下列其中一個值:

    • 專案中已有預留項目: RESERVATION_NAME

    • 預留項目位於其他專案,且您的專案可以使用該預留項目: projects/RESERVATION_PROJECT_ID/reservations/RESERVATION_NAME

  • YOUR_REGION:要建立 GKE 叢集的區域。您只能在預訂項目所在的區域建立叢集。

  • YOUR_CLUSTER_NAME:要建立的 GKE 叢集名稱。

  • YOUR_BUCKET_NAME:要建立的區域 Cloud Storage bucket 名稱。

  • YOUR_HF_TOKEN:您在上一個章節中建立的 Hugging Face 存取權杖。

  • YOUR_NETWORK_NAME:GKE 叢集使用的網路。請指定下列其中一個值:

    • 如果您建立的是自訂網路,請指定網路名稱。

    • 否則,請指定 default

  • YOUR_SUBNETWORK_NAME:GKE 叢集使用的子網路。請指定下列其中一個值:

    • 如果您建立的是自訂子網路,請指定子網路名稱。您只能指定與預留項目位於相同區域的子網路。

    • 否則,請指定 default

在 Autopilot 模式中建立 GKE 叢集

如要在 Autopilot 模式中建立 GKE 叢集,請執行下列指令:

gcloud container clusters create-auto "$CLUSTER_NAME" \
    --project="$PROJECT_ID" \
    --region="$REGION" \
    --release-channel=rapid \
    --network="$NETWORK" \
    --subnetwork="$SUBNETWORK"
建立 GKE 叢集可能需要一段時間才能完成。如要確認 Google Cloud 已完成叢集建立作業,請前往 Google Cloud 控制台的「Kubernetes clusters」(Kubernetes 叢集) 頁面。

建立 Cloud Storage bucket

如要建立 Regional Cloud Storage bucket 來儲存模型,請執行下列指令:

gcloud storage buckets create gs://$GCS_BUCKET_NAME \
    --project=$PROJECT_ID \
    --location=$REGION

建立 Hugging Face 憑證的 Kubernetes 密鑰

如要為 Hugging Face 憑證建立 Kubernetes Secret,請按照下列步驟操作:

  1. 設定 kubectl,與 GKE 叢集通訊:

    gcloud container clusters get-credentials "$CLUSTER_NAME" \
        --location="$REGION" \
        --project="$PROJECT_ID"
  2. 建立 Kubernetes 密鑰,儲存您的 Hugging Face 權杖:

    kubectl create secret generic hf-secret \
        --from-literal=hf_token="${HUGGING_FACE_TOKEN}" \
        --dry-run=client -o yaml | kubectl apply -f -

設定 Cloud Storage 適用的 Workload Identity 聯盟

如要允許 GKE 安全存取 Cloud Storage 值區,請設定 GKE Workload Identity Federation:

gcloud iam service-accounts create qwen-gcs-sa \
    --project=$PROJECT_ID

gcloud storage buckets add-iam-policy-binding gs://$GCS_BUCKET_NAME \
    --member="serviceAccount:qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/storage.objectAdmin"

kubectl create serviceaccount qwen-ksa \
    --namespace=default

gcloud iam service-accounts add-iam-policy-binding qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com \
    --project=$PROJECT_ID \
    --role=roles/iam.workloadIdentityUser \
    --member="serviceAccount:$PROJECT_ID.svc.id.goog[default/qwen-ksa]"

kubectl annotate serviceaccount qwen-ksa \
    --namespace=default \
    iam.gke.io/gcp-service-account="qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com"

在 Cloud Storage bucket 中填入 Qwen3 模型權重

如要使用 Qwen3 模型權重填入 Cloud Storage bucket,請執行 Kubernetes Job,並使用 Cloud Storage FUSE CSI 驅動程式將 bucket 掛接為磁碟區。如果 bucket 中沒有模型,這項工作會從 Hugging Face 下載模型。

  1. 建立名為 qwen3-model-loader.yaml 的檔案,並加入以下內容:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: qwen3-model-loader
    spec:
      template:
        metadata:
          annotations:
            gke-gcsfuse/volumes: "true"
            gke-gcsfuse/cpu-limit: "0"
            gke-gcsfuse/memory-limit: "0"
            gke-gcsfuse/ephemeral-storage-limit: "0"
        spec:
          serviceAccountName: qwen-ksa
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: python:3.11-slim
            resources:
              requests:
                cpu: "4"
                memory: "16Gi"
                ephemeral-storage: "100Gi"
              limits:
                cpu: "4"
                memory: "16Gi"
                ephemeral-storage: "100Gi"
            command: ["/bin/sh", "-c"]
            args:
            - |
              pip install huggingface_hub
              python3 -c '
              import os
              from huggingface_hub import snapshot_download
              model_id = "Qwen/Qwen3-235B-A22B-Instruct-2507"
              local_dir = "/data/Qwen/Qwen3-235B-A22B-Instruct-2507"
              config_path = os.path.join(local_dir, "config.json")
              if os.path.exists(config_path):
                  print(f"Model already exists at {local_dir}. Skipping download.")
              else:
                  print(f"Downloading model {model_id} to {local_dir}...")
                  snapshot_download(
                      repo_id=model_id,
                      local_dir=local_dir,
                      local_dir_use_symlinks=False,
                      token=os.environ.get("HUGGING_FACE_HUB_TOKEN")
                  )
                  print("Download completed successfully!")
              '
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            volumeMounts:
            - name: gcs-fuse-volume
              mountPath: /data
          volumes:
          - name: gcs-fuse-volume
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: $GCS_BUCKET_NAME
                mountOptions: "implicit-dirs"
  2. 套用 qwen3-model-loader.yaml 資訊清單,初始化下載工作:

    envsubst < qwen3-model-loader.yaml | kubectl apply -f -
  3. 如要確認工作是否正在執行,請串流下載工作記錄:

    kubectl logs -f job/qwen3-model-loader -c downloader
    
  4. 等待模型下載工作完成:

    kubectl wait \
        --for=condition=Complete \
        --timeout=1800s job/qwen3-model-loader
  5. 如要刪除作業,請執行下列指令:

    kubectl delete job qwen3-model-loader --ignore-not-found

將 vLLM 容器部署至 GKE 叢集

如要使用 Kubernetes Deployments 部署 vLLM 容器來提供 Qwen3 模型,請按照下列步驟操作:

  1. 建立 qwen3-235b-deploy.yaml 檔案,並選擇 vLLM 部署作業:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-qwen3-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: qwen3-server
      template:
        metadata:
          labels:
            app: qwen3-server
            ai.gke.io/model: Qwen3-235B-A22B-Instruct-2507
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          serviceAccountName: qwen-ksa
          containers:
          - name: qwen-inference-server
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250801_0916_RC01
            resources:
              requests:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "500Gi"
                nvidia.com/gpu: "8"
              limits:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "500Gi"
                nvidia.com/gpu: "8"
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --load-format=runai_streamer
            - --model-loader-extra-config={"distributed":true}
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=8192
            - --max-num-seqs=4
            - --dtype=bfloat16
            env:
            - name: MODEL_ID
              value: "gs://$GCS_BUCKET_NAME/Qwen/Qwen3-235B-A22B-Instruct-2507"
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            livenessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 200
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 200
              periodSeconds: 5
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-b200
            cloud.google.com/reservation-name: $RESERVATION_NAME
            cloud.google.com/reservation-affinity: "specific"
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: qwen3-service
    spec:
      selector:
        app: qwen3-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: vllm-qwen3-monitoring
    spec:
      selector:
        matchLabels:
          app: qwen3-server
      endpoints:
      - port: 8000
        path: /metrics
        interval: 30s
  2. qwen3-235b-deploy.yaml 檔案套用至 GKE 叢集:

    envsubst < qwen3-235b-deploy.yaml | kubectl apply -f -
    由於容器使用 Run:ai Model Streamer 直接從 Cloud Storage 串流模型權重,因此啟動時間大幅縮短。

  3. 如要查看完成狀態,請執行下列指令:

    kubectl wait \
        --for=condition=Available \
        --timeout=1800s deployment/vllm-qwen3-deployment
    --timeout=600s 標記可讓指令監控部署作業最多 10 分鐘。

使用 curl 與 Qwen3 互動

如要驗證您部署的 Qwen3 模型,請按照下列步驟操作:

  1. 設定通訊埠轉送至 Qwen3:

    kubectl port-forward service/qwen3-service 8000:8000
  2. 開啟新的終端機視窗。然後,您可以使用 curl 與模型對話:

    curl http://127.0.0.1:8000/v1/chat/completions \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{
      "model": "Qwen/Qwen3-235B-A22B-Instruct-2507",
      "messages": [
        {
          "role": "user",
          "content": "Describe a GPU in one short sentence?"
        }
      ],
      "stream": false
    }' | jq .
  3. 輸出結果會與下列內容相似:

    {
      "id": "chatcmpl-a926ddf7ef2745ca832bda096e867764",
      "object": "chat.completion",
      "created": 1755023619,
      "model": "Qwen/Qwen3-235B-A22B-Instruct-2507",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "A GPU is a specialized electronic circuit designed to rapidly process and render graphics and perform parallel computations.",
            "refusal": null,
            "annotations": null,
            "audio": null,
            "function_call": null,
            "tool_calls": [],
            "reasoning_content": null
          },
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": null
        }
      ],
      "service_tier": null,
      "system_fingerprint": null,
      "usage": {
        "prompt_tokens": 16,
        "total_tokens": 36,
        "completion_tokens": 20,
        "prompt_tokens_details": null
      },
      "prompt_logprobs": null,
      "kv_transfer_params": null
    }
    

觀察模型效能

如要觀察模型效能,可以使用 Cloud Monitoring 中的 vLLM 資訊主頁整合功能。這個資訊主頁可協助您查看模型的關鍵成效指標,例如權杖處理量、網路延遲和錯誤率。詳情請參閱 Monitoring 說明文件中的「vLLM」。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 帳戶收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

如要避免系統向您的 Cloud Billing 帳戶收取本教學課程所用資源的費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除資源

如要刪除教學課程資源,請執行下列指令:

envsubst < qwen3-235b-deploy.yaml | kubectl delete -f -
envsubst < qwen3-model-loader.yaml | kubectl delete -f -
kubectl delete secret hf-secret
kubectl delete serviceaccount qwen-ksa

gcloud iam service-accounts delete qwen-gcs-sa@$PROJECT_ID.iam.gserviceaccount.com \
    --project=$PROJECT_ID --quiet

gcloud storage rm --recursive gs://$GCS_BUCKET_NAME

刪除 GKE 叢集

如要刪除 GKE 叢集,請執行下列指令:

gcloud container clusters delete "$CLUSTER_NAME" \
    --region="$REGION" \
    --project="$PROJECT_ID" \
    --quiet

刪除專案

刪除 Google Cloud 專案:

gcloud projects delete PROJECT_ID

後續步驟