vLLM in GKE verwenden, um die Inferenz mit DeepSeek-V3.1-Base auszuführen

In dieser Anleitung wird gezeigt, wie Sie ein DeepSeek-V3.1-Base-Sprachmodell mit dem vLLM-Framework bereitstellen und verfügbar machen. Sie stellen dieses Modell in einem GKE Enterprise-Autopilot-Cluster (Google Kubernetes Engine) bereit und nutzen eine einzelne virtuelle A4-Maschine (VM) mit 8 B200-GPUs.

Diese Anleitung richtet sich an ML-Entwickler (Machine Learning), Plattformadministratoren und ‑operatoren sowie an Daten- und KI-Spezialisten, die daran interessiert sind, Kubernetes-Container-Orchestrierungsfunktionen zum Verarbeiten von Inferenz-Arbeitslasten zu verwenden.

Ziele

  1. Über Hugging Face auf DeepSeek-V3.1-Base zugreifen
  2. Bereiten Sie Ihre Umgebung vor.
  3. Erstellen Sie einen GKE-Cluster im Autopilot-Modus.
  4. Erstellen Sie ein Kubernetes-Secret für Hugging Face-Anmeldedaten.
  5. Cloud Storage-Bucket erstellen
  6. Laden Sie das Modell in Ihren Cloud Storage-Bucket herunter.
  7. Stellen Sie einen vLLM-Container in Ihrem GKE-Cluster bereit.
  8. Mit DeepSeek-V3.1-Base über curl interagieren
  9. bereinigen.

Kosten

In dieser Anleitung werden kostenpflichtige Komponenten von Google Cloudverwendet, darunter:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Hinweis

  1. Installieren Sie die Google Cloud CLI.

  2. Konfigurieren Sie die gcloud CLI für die Verwendung Ihrer föderierten Identität.

    Weitere Informationen finden Sie unter Mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  3. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  4. Erstellen Sie ein Google Cloud Projekt oder wählen Sie eines aus.

    Rollen, die zum Auswählen oder Erstellen eines Projekts erforderlich sind

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Projektersteller“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Weitere Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts in Google Cloud .

  5. Prüfen Sie, ob die Abrechnung für Ihr Google Cloud Projekt aktiviert ist.

  6. Aktivieren Sie die erforderliche API:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die Berechtigung serviceusage.services.enable. Wenn Sie das Projekt erstellt haben, haben Sie diese Berechtigung wahrscheinlich bereits über die Rolle „Inhaber“ (roles/owner). Andernfalls können Sie diese Berechtigung über die Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin) erhalten. Informationen zum Zuweisen von Rollen

    gcloud services enable container.googleapis.com
  7. Weisen Sie Ihrem Nutzerkonto Rollen zu. Führen Sie den folgenden Befehl für jede der folgenden IAM-Rollen einmal aus: roles/container.admin

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

    Ersetzen Sie Folgendes:

  8. Melden Sie sich in einem Hugging Face-Konto an oder erstellen Sie ein Konto.

Über Hugging Face auf DeepSeek zugreifen

So verwenden Sie Hugging Face, um auf DeepSeek zuzugreifen:

  1. Bei Hugging Face anmelden und das Modell „DeepSeek-V3.1-Base“ ansehen
  2. Erstellen Sie ein Hugging Face-Zugriffstoken für read.
  3. Kopieren und speichern Sie den read access-Tokenwert. Sie benötigen sie später in dieser Anleitung.

Umgebung vorbereiten

Legen Sie die Standardumgebungsvariablen fest, um Ihre Umgebung vorzubereiten:

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}"

Ersetzen Sie Folgendes:

  • YOUR_PROJECT_ID: die ID des Google Cloud Projekts, in dem Sie den GKE-Cluster erstellen möchten.

  • YOUR_RESERVATION_NAME: Die URL der Reservierung, die Sie zum Erstellen Ihres GKE-Cluster verwenden möchten. Geben Sie je nach Projekt, in dem die Reservierung vorhanden ist, einen der folgenden Werte an:

    • Die Reservierung ist in Ihrem Projekt vorhanden: RESERVATION_NAME

    • Die Reservierung ist in einem anderen Projekt vorhanden und Ihr Projekt kann sie nutzen: projects/RESERVATION_PROJECT_ID/reservations/RESERVATION_NAME

  • YOUR_REGION: die Region, in der Sie Ihren GKE-Cluster erstellen möchten. Sie können den Cluster nur in der Region erstellen, in der Ihre Reservierung vorhanden ist.

  • YOUR_CLUSTER_NAME: Der Name des zu erstellenden GKE-Cluster.

  • YOUR_GCS_BUCKET: Der Name des Cloud Storage-Bucket, aus dem Sie das Modell herunterladen.

  • YOUR_HF_TOKEN: Das Hugging Face-Zugriffstoken, das Sie im vorherigen Abschnitt erstellt haben.

  • YOUR_NETWORK_NAME: Das Netzwerk, das der GKE-Cluster verwendet. Geben Sie einen der folgenden Werte an:

    • Wenn Sie ein benutzerdefiniertes Netzwerk erstellt haben, geben Sie den Namen Ihres Netzwerks an.

    • Geben Sie andernfalls default an.

  • YOUR_SUBNETWORK_NAME: Das Subnetzwerk, das vom GKE-Cluster verwendet wird. Geben Sie einen der folgenden Werte an:

    • Wenn Sie ein benutzerdefiniertes Subnetzwerk erstellt haben, geben Sie den Namen des Subnetzwerks an. Sie können nur ein Subnetzwerk angeben, das sich in derselben Region wie die Reservierung befindet.

    • Geben Sie andernfalls default an.

GKE-Cluster im Autopilot-Modus erstellen

Führen Sie den folgenden Befehl aus, um einen GKE-Cluster im Autopilot-Modus zu erstellen:

gcloud container clusters create-auto $CLUSTER_NAME \
    --project=$PROJECT_ID \
    --region=$REGION \
    --release-channel=rapid \
    --network=$NETWORK \
    --subnetwork=$SUBNETWORK

Das Erstellen des GKE-Cluster kann einige Zeit dauern. Rufen Sie in der Google Cloud Console die Seite Kubernetes-Cluster auf, um zu prüfen, ob Google Cloud den Cluster erstellt hat.

Kubernetes-Secret für Hugging Face-Anmeldedaten erstellen

So erstellen Sie ein Kubernetes-Secret für Hugging Face-Anmeldedaten:

  1. Konfigurieren Sie kubectl für die Kommunikation mit Ihrem GKE-Cluster:

    gcloud container clusters get-credentials $CLUSTER_NAME \
        --location=$REGION
  2. Erstellen Sie ein Kubernetes-Secret zum Speichern Ihres Hugging Face-Tokens:

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

Cloud Storage-Bucket erstellen

Wenn Sie einen neuen Bucket zum Speichern des Modells verwenden möchten, führen Sie Folgendes aus:

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

Gewähren Sie dem Standarddienstkonto die Berechtigungen write für den Cloud Storage-Bucket:

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"

Wenn Sie einen vorhandenen Cloud Storage-Bucket verwenden möchten, können Sie diesen Schritt überspringen. Sie müssen jedoch darauf achten, dass sich Ihr Bucket in derselben Region wie Ihr Cluster befindet und dass das Dienstkonto die erforderlichen write-Berechtigungen dafür hat.

Modell in Ihren Cloud Storage-Bucket herunterladen

  1. deepseek-download-job.yaml-Datei erstellen:

    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. Wenden Sie das deepseek-download-job.yaml-Manifest an, um den Downloadjob zu initialisieren:

    envsubst '$GCS_BUCKET' < deepseek-download-job.yaml | kubectl apply -f -
  3. Führen Sie den folgenden Befehl aus, um den Abschlussstatus aufzurufen:

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

    Das Flag --timeout gibt an, wie lange der Befehl den Job überwacht, bevor eine Zeitüberschreitung auftritt.

    Die Jobressource lädt die DeepSeek-V3.1-Base-Modellgewichte von Hugging Face mithilfe des SSD-Volumes in Ihren Google Cloud Storage-Bucket herunter. Der Download dauert etwa 40 Minuten. Fahren Sie nach Abschluss des Downloads mit dem nächsten Abschnitt fort, um die Modellbereitstellung zu starten.

  4. Führen Sie den folgenden Befehl aus, um den Job zu löschen:

    kubectl delete job deepseek-download-job

vLLM-Container in Ihrem GKE-Cluster bereitstellen

Nachdem Sie das Modell in Ihren Cloud Storage-Bucket heruntergeladen haben, stellen Sie einen vLLM-Container in Ihrem GKE-Cluster bereit. Führen Sie dazu die folgenden Schritte aus:

  1. Erstellen Sie eine vllm-deepseek3-1-base.yaml-Datei mit der von Ihnen ausgewählten vLLM-Bereitstellung:

    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. Wenden Sie die Datei vllm-deepseek3-1-base.yaml auf Ihren GKE-Cluster an:

    envsubst < vllm-deepseek3-1-base.yaml | kubectl apply -f -
  3. Führen Sie den folgenden Befehl aus, um den Abschlussstatus aufzurufen:

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

    Mit dem Flag --timeout kann der Befehl die Bereitstellung für den angegebenen Zeitraum überwachen.

Mithilfe von curl mit DeepSeek-V3.1-Base interagieren

So prüfen Sie das bereitgestellte DeepSeek-V3.1-Base-Modell:

  1. Richten Sie die Portweiterleitung zu DeepSeek-V3.1-Base ein:

    kubectl port-forward service/deepseek-service 8000:8000
  2. Öffnen Sie ein neues Terminalfenster. Anschließend können Sie mit Ihrem Modell chatten, indem Siecurl verwenden:

    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. Die Ausgabe sieht in etwa so aus:

    {
      "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
    }
    

Leistung des Modells beobachten

Wenn Sie die Leistung Ihres Modells beobachten möchten, können Sie die vLLM-Dashboard-Integration in Cloud Monitoring verwenden. In diesem Dashboard können Sie wichtige Leistungsmesswerte für Ihr Modell wie Token-Durchsatz, Netzwerklatenz und Fehlerraten einsehen. Weitere Informationen finden Sie unter vLLM in der Dokumentation zu Monitoring.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Ressourcen löschen

Löschen Sie nach Abschluss der Anleitung die Ressourcen, die Sie nicht mehr benötigen:

  1. Führen Sie den folgenden Befehl aus, um das in der Datei vllm-deepseek3-1-base.yaml definierte Deployment und den Dienst sowie das Kubernetes-Secret aus dem GKE-Cluster zu löschen:

    envsubst < vllm-deepseek3-1-base.yaml | kubectl delete -f -
    kubectl delete secret hf-secret
  2. Führen Sie den folgenden Befehl aus, um Ihren Cloud Storage-Bucket zu löschen:

    gcloud storage rm --recursive gs://$GCS_BUCKET
  3. So löschen Sie Ihren GKE-Cluster:

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

Projekt löschen

Google Cloud -Projekt löschen:

gcloud projects delete PROJECT_ID

Nächste Schritte