GKE で vLLM を使用して DeepSeek-V3.1-Base で推論を実行する

このチュートリアルでは、vLLM フレームワークを使用して DeepSeek-V3.1-Base 言語モデルをデプロイしてサービングする方法について説明します。このモデルを Google Kubernetes Engine(GKE)Enterprise エディションの Autopilot クラスタにデプロイし、8 個の B200 GPU を搭載した単一の A4 仮想マシン(VM)を使用します。

このチュートリアルは、Kubernetes コンテナ オーケストレーション機能を使用して推論ワークロードを処理することに関心のある ML エンジニア、プラットフォーム管理者、オペレーター、データおよび AI のスペシャリストを対象としています。

目標

  1. Hugging Face を使用して DeepSeek-V3.1-Base にアクセスします。
  2. 環境を準備します。
  3. Autopilot モードで GKE クラスタを作成する。
  4. Hugging Face の認証情報用の Kubernetes Secret を作成します。
  5. Cloud Storage バケットを作成する。
  6. モデルを Cloud Storage バケットにダウンロードします。
  7. vLLM コンテナを GKE クラスタにデプロイする。
  8. curl を使用して DeepSeek-V3.1-Base を操作します。
  9. クリーンアップする。

費用

このチュートリアルでは、以下を含む、 Google Cloudの課金対象となるコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。

始める前に

  1. Google Cloud CLI をインストールします。

  2. フェデレーション ID(連携 ID)を使用するように gcloud CLI を構成します。

    詳細については、連携 ID を使用して gcloud CLI にログインするをご覧ください。

  3. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  4. Google Cloud プロジェクトを作成または選択します

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
    • 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 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を介してこの権限がすでに付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を介してこの権限を取得できます。ロールを付与する方法をご覧ください。

    gcloud services enable container.googleapis.com
  7. ユーザー アカウントにロールを付与します。次の IAM ロールごとに次のコマンドを 1 回実行します。 roles/container.admin

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

    次のように置き換えます。

  8. Hugging Face アカウントにログインするか、アカウントを作成します

Hugging Face を使用して DeepSeek にアクセスする

Hugging Face を使用して DeepSeek にアクセスする手順は次のとおりです。

  1. Hugging Face にログインして、DeepSeek-V3.1-Base モデルを確認します
  2. Hugging Face read アクセス トークンを作成します
  3. read access トークンの値をコピーして保存します。これは、このチュートリアルの後半で使用します。

環境を準備する

環境を準備するには、デフォルトの環境変数を設定します。

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 クラスタの作成に使用する予約の URL。予約が存在するプロジェクトに基づいて、次のいずれかの値を指定します。

    • 予約がプロジェクトに存在する場合: RESERVATION_NAME

    • 予約が別のプロジェクトにあり、プロジェクトで予約を使用できる場合: projects/RESERVATION_PROJECT_ID/reservations/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. GKE クラスタと通信するように kubectl を構成します。

    gcloud container clusters get-credentials $CLUSTER_NAME \
        --location=$REGION
  2. Hugging Face トークンを保存する Kubernetes Secret を作成します。

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

Cloud Storage バケットを作成する

新しいバケットを使用してモデルを保存する場合は、次のコマンドを実行します。

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 バケットを使用する場合は、この手順をスキップできます。ただし、バケットがクラスタと同じリージョンにあり、サービス アカウントにバケットに対する必要な write 権限が付与されていることを確認する必要があります。

モデルを 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-1"
              mkdir -p "$LOCAL_DIR"
    
              echo "Downloading model from HF to local SSD using parallel workers..."
              hf download deepseek-ai/DeepSeek-V3.1-Base \
                --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-1" --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 ボリュームを使用して、Hugging Face から Google Cloud Storage バケットに DeepSeek-V3.1-Base モデルの重みをダウンロードします。ダウンロードには約 40 分かかります。ダウンロードが完了したら、次のセクションに進んでモデルのデプロイを開始します。

  4. ジョブを削除するには、次のコマンドを実行します。

    kubectl delete job deepseek-download-job

vLLM コンテナを GKE クラスタにデプロイする

モデルを Cloud Storage バケットにダウンロードしたら、次の手順に沿って vLLM コンテナを GKE クラスタにデプロイします。

  1. 選択した vLLM デプロイを含む vllm-deepseek3-1-base.yaml ファイルを作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: deepseek3-1-deploy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: deepseek
      template:
        metadata:
          labels:
            app: deepseek
            ai.gke.io/model: deepseek-v3-1-base
            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:20250819_0916_RC01
            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-1
            - --tensor-parallel-size=8
            - --host=0.0.0.0
            - --port=8000
            - --max-model-len=8192
            - --max-num-seqs=4
            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-1-base.yaml ファイルは GKE クラスタに適用します。

    envsubst < vllm-deepseek3-1-base.yaml | kubectl apply -f -
  3. 完了ステータスを確認するには、次のコマンドを実行します。

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

    --timeout フラグを使用すると、コマンドは指定された期間、デプロイをモニタリングできます。

curl を使用して DeepSeek-V3.1-Base を操作する

デプロイした DeepSeek-V3.1-Base モデルを確認するには、次の操作を行います。

  1. DeepSeek-V3.1-Base へのポート転送を設定します。

    kubectl port-forward service/deepseek-service 8000:8000
  2. 新しいターミナル ウィンドウを開きます。curl を使用してモデルとチャットできます。

    curl http://127.0.0.1:8000/v1/chat/completions \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{
      "model": "deepseek-ai/DeepSeek-V3.1-Base",
      "messages": [
        {
          "role": "user",
          "content": "Describe how generative AI works in one short and easy to understand sentence"
        }
      ],
    "stream":false
    }' | jq .
  3. 表示される出力は次のようになります。

    {
      "id": "chatcmpl-1a47172070544a5d83199ed5548befca",
      "object": "chat.completion",
      "created": 1755891024,
      "model": "deepseek-ai/DeepSeek-V3.1-Base",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "\nGenerative AI uses patterns from existing data to create new, similar content, like text, images, or music.\n",
            "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": 17,
        "total_tokens": 42,
        "completion_tokens": 25,
        "prompt_tokens_details": null
      },
      "prompt_logprobs": null,
      "kv_transfer_params": null
    }
    

モデルのパフォーマンスをモニタリングする

モデルのパフォーマンスをモニタリングする場合は、Cloud Monitoring で vLLM ダッシュボードの統合を使用できます。このダッシュボードでは、トークンのスループット、ネットワーク レイテンシ、エラー率など、モデルの重要なパフォーマンス指標を確認できます。詳細については、Monitoring のドキュメントの vLLM をご覧ください。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

リソースの削除

チュートリアルが完了したら、不要になったリソースを削除します。

  1. vllm-deepseek3-1-base.yaml ファイルで定義されたデプロイとサービス、および Kubernetes シークレットを GKE クラスタから削除するには、次のコマンドを実行します。

    envsubst < vllm-deepseek3-1-base.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

次のステップ