在 GKE 上使用 vLLM 运行 DeepSeek-V3.2-Speciale 的推理

本教程介绍如何使用 vLLM 框架部署和提供 DeepSeek-V3.2-Speciale 语言模型。您可以在 Google Kubernetes Engine (GKE) Enterprise 版 Autopilot 集群上部署此模型,并使用具有 8 个 B200 GPU 的单个 A4 虚拟机 (VM)。

本教程假设您已查看 DeepSeek-V3.2-Speciale 语言模型,并确认其功能符合您的使用场景要求。

本教程适用于机器学习 (ML) 工程师、平台管理员和运维人员,以及对使用 Kubernetes 容器编排功能处理推理工作负载感兴趣的数据和 AI 专家。

目标

  1. 使用 Hugging Face 访问 DeepSeek-V3.2-Speciale。

  2. 准备环境。

  3. 在 Autopilot 模式下创建 GKE 集群。

  4. 为 Hugging Face 凭据创建 Kubernetes Secret。

  5. 创建 Cloud Storage 存储桶。

  6. 将模型下载到您的 Cloud Storage 存储桶。

  7. 将 vLLM 容器部署到 GKE 集群。

  8. 使用 curl 与 DeepSeek-V3.2-Speciale 互动。

  9. 清理。

费用

本教程使用 Google Cloud的收费组件,包括:

如需根据您的预计使用量来估算费用,请使用价格计算器。

准备工作

  1. 安装 Google Cloud CLI。

  2. 配置 gcloud CLI 以使用您的联合身份。

    如需了解详情,请参阅使用联合身份登录 gcloud CLI。

  3. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  4. 创建或选择 Google Cloud 项目。

    选择或创建项目所需的角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要拥有 Project Creator 角色 (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 项目名称。

  5. 验证是否已为您的 Google Cloud 项目启用结算功能。

  6. 启用所需的 API(如果尚未启用):

    启用 API 所需的角色

    如需启用 API,您需要拥有 serviceusage.services.enable 权限。如果您创建了项目,则可能已经通过 Owner 角色 (roles/owner) 获得了此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色。

    gcloud services enable container.googleapis.com
  7. 向您的用户账号授予角色。对以下每个 IAM 角色运行以下命令一次: roles/container.admin

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

    替换以下内容:

    • PROJECT_ID:您的项目 ID。
    • USER_IDENTIFIER:您的用户 账号。如需查看示例,请参阅 在 IAM 政策中表示员工池用户。
    • ROLE:您向用户账号授予的 IAM 角色。
  8. 登录或创建 Hugging Face 账号。

使用 Hugging Face 访问 DeepSeek-V3.2-Speciale

如需使用 Hugging Face 访问 DeepSeek-V3.2-Speciale 模型,请按以下步骤操作:

  1. 登录 Hugging Face。
  2. 创建 Hugging Face read 访问令牌。
  3. 复制并保存 read 访问令牌值。您将在本教程的后面部分使用该地址。

准备环境

如需准备环境,请设置默认环境变量:

export PROJECT_ID="YOUR_PROJECT_ID"
export RESERVATION_URL="YOUR_RESERVATION_NAME"
export REGION="YOUR_REGION"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export GCS_BUCKET="YOUR_GCS_BUCKET"
export HUGGING_FACE_TOKEN="YOUR_HF_TOKEN"
export NETWORK="YOUR_NETWORK_NAME"
export SUBNETWORK="YOUR_SUBNETWORK_NAME"
export PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)")

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

替换以下内容:

  • YOUR_PROJECT_ID:您要在其中创建 GKE 集群的 Google Cloud 项目的 ID。

  • YOUR_RESERVATION_NAME:您要用于创建 GKE 集群的预留的名称。根据预留所在的项目,指定以下某个值:

    • 预留存在于您的项目中:YOUR_RESERVATION_NAME

    • 预留存在于其他项目中,并且您的项目可以使用该预留:projects/RESERVATION_PROJECT_ID/reservations/YOUR_RESERVATION_NAME

  • YOUR_REGION:您要在其中创建 GKE 集群的区域。您只能在预留所在的区域中创建集群。

  • YOUR_CLUSTER_NAME:要创建的 GKE 集群的名称。

  • YOUR_GCS_BUCKET:您下载模型的 Cloud Storage 存储桶的名称。

  • 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 集群。

为 Hugging Face 凭据创建 Kubernetes Secret

如需为 Hugging Face 凭据创建 Kubernetes Secret,请按以下步骤操作:

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

    gcloud container clusters get-credentials "$CLUSTER_NAME" \
        --location="$REGION"
  2. 创建一个 Kubernetes Secret 来存储您的 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 存储桶

如果您想使用现有的 Cloud Storage 存储桶,可以跳过此步骤。不过,您必须确保存储桶与集群位于同一区域,并且服务账号具有所需的 write 权限。

如果您想使用新存储桶来存储模型,请运行以下命令:

gcloud storage buckets create gs://"$GCS_BUCKET" --location="$REGION" --uniform-bucket-level-access

向默认服务账号授予对 Cloud Storage 存储桶的 write 权限:

gcloud storage buckets add-iam-policy-binding gs://"$GCS_BUCKET" \
    --member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/default/sa/default" \
    --role="roles/storage.objectAdmin"

将模型下载到您的 Cloud Storage 存储桶

  1. 创建 deepseek-download-job.yaml 文件:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: deepseek-download-job
      namespace: default
    spec:
      template:
        metadata:
          labels:
            app: deepseek-oss-downloader
        spec:
          restartPolicy: OnFailure
          containers:
          - name: downloader
            image: google/cloud-sdk:slim
            resources:
              requests:
                cpu: "8"
                memory: "32Gi"
              limits:
                cpu: "8"
                memory: "32Gi"
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_token
            - name: HF_XET_HIGH_PERFORMANCE
              value: "0"
            - name: PIP_BREAK_SYSTEM_PACKAGES
              value: "1"
            command: ["/bin/sh", "-c"]
            args:
            - |
              set -e
              echo "Installing Hugging Face Hub CLI..."
              pip install -U "huggingface_hub[cli]"
    
              LOCAL_DIR="/mnt/model-download/deepseek-v3-2"
              mkdir -p "$LOCAL_DIR"
    
              echo "Downloading model from HF to local SSD using parallel workers..."
              hf download deepseek-ai/DeepSeek-V3.2-Speciale \
                --token "$HUGGING_FACE_HUB_TOKEN" \
                --local-dir "$LOCAL_DIR" \
                --max-workers 8
    
              DOWNLOAD_STATUS=$?
    
              if [ $DOWNLOAD_STATUS -ne 0 ]; then
                echo "ERROR: Model download failed with exit code $DOWNLOAD_STATUS"
                exit $DOWNLOAD_STATUS
              fi
    
              echo "Download to SSD complete. Syncing to GCS..."
              gcloud storage rsync "$LOCAL_DIR" "gs://$GCS_BUCKET/deepseek-v3-2" --recursive
    
              echo "Process successfully completed!"
            volumeMounts:
            - mountPath: /mnt/model-download
              name: download-storage
          volumes:
          - name: download-storage
            ephemeral:
              volumeClaimTemplate:
                spec:
                  accessModes: [ "ReadWriteOnce" ]
                  storageClassName: premium-rwo
                  resources:
                    requests:
                      storage: 800Gi
  2. 应用 deepseek-download-job.yaml 清单以初始化下载作业:

    envsubst '$GCS_BUCKET' < deepseek-download-job.yaml | kubectl apply -f -
  3. 如需查看完成状态,请运行以下命令:

    kubectl wait \
        --for=condition=Complete \
        --timeout=7200s job/deepseek-download-job

    --timeout 标志用于指定命令在超时之前监控作业的时间。

    作业资源使用 SSD 卷将 DeepSeek-V3.2-Speciale 模型权重从 Hugging Face 下载到您的 Google Cloud 存储桶。下载大约需要 40 分钟才能完成。下载完成后,请继续下一部分以启动模型部署。

  4. 如需删除作业,请运行以下命令:

    kubectl delete job deepseek-download-job

将 vLLM 容器部署到 GKE 集群

将模型下载到 Cloud Storage 存储桶后,请完成以下步骤,将 vLLM 容器部署到 GKE 集群:

  1. 创建一个 vllm-deepseek3-2.yaml 文件,其中包含您选择的 vLLM 部署:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deepseek3-2-deploy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: deepseek
      template:
        metadata:
          labels:
            app: deepseek
            ai.gke.io/model: deepseek-v3-2
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          containers:
          - name: vllm-inference
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:model-garden.pytorch-vllm-serve-release_20251126.00_p0
            resources:
              requests:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "1Ti"
                nvidia.com/gpu: "8"
              limits:
                cpu: "10"
                memory: "1000Gi"
                ephemeral-storage: "1Ti"
                nvidia.com/gpu: "8"
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --model=/mnt/gcs/deepseek-v3-2
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=131072
            - --max-num-seqs=16
            - --enable-chunked-prefill
            - --gpu-memory-utilization=0.90
            - --enforce-eager
            - --trust-remote-code
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /mnt/gcs
              name: gcs-bucket-volume
              readOnly: true
            livenessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 1800
              periodSeconds: 10
            readinessProbe:
              httpGet:
                path: /health
                port: 8000
              initialDelaySeconds: 1800
              periodSeconds: 5
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          - name: gcs-bucket-volume
            csi:
              driver: gcsfuse.csi.storage.gke.io
              volumeAttributes:
                bucketName: $GCS_BUCKET
                mountOptions: "implicit-dirs,file-cache:max-size-mb:-1,file-cache:enable-parallel-downloads:true,file-cache:max-parallel-downloads:32,file-cache:parallel-downloads-per-file:8,file-cache:download-chunk-size-mb:16"
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-b200
            cloud.google.com/reservation-name: $RESERVATION_URL
            cloud.google.com/reservation-affinity: "specific"
            cloud.google.com/gke-gpu-driver-version: latest
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: deepseek-service
    spec:
      selector:
        app: deepseek
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    ---
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: deepseek-monitoring
    spec:
      selector:
        matchLabels:
          app: deepseek
      endpoints:
      - port: 8000
        path: /metrics
        interval: 30s
  2. 将 vllm-deepseek3-2.yaml 文件应用于您的 GKE 集群:

    envsubst < vllm-deepseek3-2.yaml | kubectl apply -f -
  3. 如需查看完成状态,请运行以下命令:

    kubectl wait \
      --for=condition=Available \
      --timeout=7200s deployment/deepseek3-2-deploy

    --timeout 标志允许命令在指定的时间段内监控部署。

使用 curl 与 DeepSeek-V3.2-Speciale 互动

如需验证您部署的 DeepSeek-V3.2-Speciale 模型,请执行以下操作:

  1. 设置到 DeepSeek-V3.2-Special 的端口转发:

    kubectl port-forward service/deepseek-service 8000:8000
  2. 打开一个新终端窗口。然后,您可以使用 curl 与模型聊天:

    time curl http://127.0.0.1:8000/v1/completions \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{
         "model": "deepseek-ai/DeepSeek-V3.2-Speciale",
         "prompt": "<|im_start|>user\nExplain the ReAct (Reasoning + Acting) pattern in Agentic AI. Provide a concise Python pseudocode example showing the loop. Keep the explanation under 300 words.<|im_end|>\n<|im_start|>assistant\n",
         "max_tokens": 1024,
         "temperature": 0.7,
         "stream": false,
         "stop": ["<|im_end|>"]
       }' | jq .
  3. 您看到的输出类似于以下内容:

    {
      "id": "cmpl-be345f0499e949ed8500e533be2cfe3f",
      "object": "text_completion",
      "created": 1764803171,
      "model": "deepseek-ai/DeepSeek-V3.2-Speciale",
      "choices": [
        {
          "index": 0,
          "text": "The ReAct pattern integrates reasoning (thoughts) and actions (tool calls) within an agentic loop... [TRUNCATED FOR BREVITY] ...ReAct improves transparency and reliability by explicit reasoning steps.",
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": "<|im_end|>",
          "token_ids": null,
          "prompt_logprobs": null,
          "prompt_token_ids": null
        }
      ],
      "service_tier": null,
      "system_fingerprint": null,
      "usage": {
        "prompt_tokens": 57,
        "total_tokens": 317,
        "completion_tokens": 260,
        "prompt_tokens_details": null
      },
      "kv_transfer_params": null
    }
    

观察模型性能

如需观察模型性能,您可以使用 Cloud Monitoring 中的 vLLM 信息中心集成。在此信息中心内,您可以查看各种关键性能指标,例如令牌吞吐量、请求延迟时间和错误率。

如需了解如何使用 Google Cloud Managed Service for Prometheus 从模型收集指标,请参阅 Monitoring 文档中的 vLLM 可观测性指南。

清理

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

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

删除资源

完成本教程后,请删除不再需要的资源:

  1. 如需删除 vllm-deepseek3-2.yaml 文件中定义的部署和服务以及 GKE 集群中的 Kubernetes Secret,请运行以下命令:

    envsubst < vllm-deepseek3-2.yaml | kubectl delete -f -
    kubectl delete secret hf-secret
  2. 如需删除 Cloud Storage 存储桶,请运行以下命令:

    gcloud storage rm --recursive gs://"$GCS_BUCKET"
  3. 如需删除 GKE 集群,请执行以下操作:

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

删除项目

删除 Google Cloud 项目:

gcloud projects delete PROJECT_ID

后续步骤