Utilizza vLLM su GKE per eseguire l'inferenza con DeepSeek-V3.2-Speciale

Questo tutorial mostra come eseguire il deployment e l'erogazione di un modello linguistico DeepSeek-V3.2-Speciale utilizzando il framework vLLM. Esegui il deployment di questo modello in un cluster Autopilot di Google Kubernetes Engine (GKE) Enterprise e utilizzi una singola macchina virtuale A4 (VM) con 8 GPU B200.

Questo tutorial presuppone che tu abbia esaminato il modello linguistico DeepSeek-V3.2-Speciale e verificato che le sue funzionalità soddisfino i requisiti del tuo caso d'uso.

Questo tutorial è rivolto a machine learning (ML) engineer, amministratori e operatori di piattaforme e a specialisti di dati e AI interessati a utilizzare le funzionalità di orchestrazione dei container Kubernetes per gestire i carichi di lavoro di inferenza.

Obiettivi

  1. Accedi a DeepSeek-V3.2-Speciale utilizzando Hugging Face.

  2. Prepara l'ambiente.

  3. Creare un cluster GKE in modalità Autopilot.

  4. Crea un secret di Kubernetes per le credenziali di Hugging Face.

  5. Creare un bucket Cloud Storage.

  6. Scarica il modello nel bucket Cloud Storage.

  7. Esegui il deployment di un container vLLM nel cluster GKE.

  8. Interagisci con DeepSeek-V3.2-Speciale utilizzando curl.

  9. Eseguire la pulizia.

Costi

Questo tutorial utilizza componenti fatturabili di Google Cloud, tra cui:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi.

Prima di iniziare

  1. Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Installa Google Cloud CLI.

  3. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  4. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  5. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere ruoli.
    • Crea un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  6. Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .

  7. Abilita l'API richiesta, se non è già abilitata:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre dell'autorizzazione serviceusage.services.enable. Se hai creato il progetto, probabilmente disponi già di questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore utilizzo servizi (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.

    gcloud services enable container.googleapis.com
  8. Installa Google Cloud CLI.

  9. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  10. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  11. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere ruoli.
    • Crea un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  12. Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .

  13. Abilita l'API richiesta, se non è già abilitata:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre dell'autorizzazione serviceusage.services.enable. Se hai creato il progetto, probabilmente disponi già di questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore utilizzo servizi (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.

    gcloud services enable container.googleapis.com
  14. Concedi ruoli al tuo account utente. Esegui il seguente comando una volta per ciascuno dei seguenti ruoli IAM: roles/container.admin

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

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo ID progetto.
    • USER_IDENTIFIER: l'identificatore del tuo account utente . Ad esempio: myemail@example.com.
    • ROLE: il ruolo IAM che concedi al tuo account utente.
  15. Accedi o crea un account Hugging Face.

Accedere a DeepSeek-V3.2-Speciale utilizzando Hugging Face

Per utilizzare Hugging Face per accedere al modello DeepSeek-V3.2-Speciale, segui questi passaggi:

  1. Accedi a Hugging Face.
  2. Crea un token di accesso read di Hugging Face.
  3. Copia e salva il valore del token di accesso read. Lo utilizzerai più avanti in questo tutorial.

prepara l'ambiente

Per preparare l'ambiente, imposta le variabili di ambiente predefinite:

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

Sostituisci quanto segue:

  • YOUR_PROJECT_ID: l'ID del progetto Google Cloud in cui vuoi creare il cluster GKE.

  • YOUR_RESERVATION_NAME: il nome della prenotazione che vuoi utilizzare per creare il cluster GKE. In base al progetto in cui esiste la prenotazione, specifica uno dei seguenti valori:

    • La prenotazione esiste nel tuo progetto: YOUR_RESERVATION_NAME

    • La prenotazione esiste in un progetto diverso e il tuo progetto può utilizzarla: projects/RESERVATION_PROJECT_ID/reservations/YOUR_RESERVATION_NAME

  • YOUR_REGION: la regione in cui vuoi creare il cluster GKE. Puoi creare il cluster solo nella regione in cui esiste la prenotazione.

  • YOUR_CLUSTER_NAME: il nome del cluster GKE da creare.

  • YOUR_GCS_BUCKET: il nome del bucket Cloud Storage da cui scaricare il modello.

  • YOUR_HF_TOKEN: il token di accesso a Hugging Face che hai creato nella sezione precedente.

  • YOUR_NETWORK_NAME: la rete utilizzata dal cluster GKE. Specifica uno dei seguenti valori:

    • Se hai creato una rete personalizzata, specifica il nome della rete.

    • In caso contrario, specifica default.

  • YOUR_SUBNETWORK_NAME: la subnet utilizzata dal cluster GKE. Specifica uno dei seguenti valori:

    • Se hai creato una subnet personalizzata, specifica il nome della subnet. Puoi specificare solo una subnet che si trova nella stessa regione della prenotazione.

    • In caso contrario, specifica default.

Crea un cluster GKE in modalità Autopilot

Per creare un cluster GKE in modalità Autopilot, esegui questo comando:

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

La creazione del cluster GKE potrebbe richiedere un po' di tempo. Per verificare che Google Cloud abbia terminato la creazione del cluster, vai a Cluster Kubernetes nella console Google Cloud .

Crea un secret Kubernetes per le credenziali di Hugging Face

Per creare un secret Kubernetes per le credenziali di Hugging Face:

  1. Configura kubectl per comunicare con il cluster GKE:

    gcloud container clusters get-credentials "$CLUSTER_NAME" \
        --location="$REGION"
  2. Crea un secret Kubernetes per archiviare il token Hugging Face:

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

Crea un bucket Cloud Storage

Se vuoi utilizzare un bucket Cloud Storage esistente, puoi saltare questo passaggio. Tuttavia, devi assicurarti che il bucket si trovi nella stessa regione del cluster e che il account di servizio disponga delle autorizzazioni write richieste.

Se vuoi utilizzare un nuovo bucket per archiviare il modello, esegui questo comando:

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

Concedi le autorizzazioni write sul bucket Cloud Storage al account di servizio predefinito:

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"

Scarica il modello nel bucket Cloud Storage

  1. Crea un file 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. Applica il manifest deepseek-download-job.yaml per inizializzare il job di download:

    envsubst '$GCS_BUCKET' < deepseek-download-job.yaml | kubectl apply -f -
  3. Per visualizzare lo stato di completamento, esegui questo comando:

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

    Il flag --timeout specifica per quanto tempo il comando monitora il job prima del timeout.

    La risorsa del job scarica i pesi del modello DeepSeek-V3.2-Speciale da Hugging Face nel bucket Storage Google Cloud utilizzando il volume SSD. Il completamento del download richiede circa 40 minuti. Al termine del download, passa alla sezione successiva per avviare il deployment del modello.

  4. Per eliminare il job, esegui questo comando:

    kubectl delete job deepseek-download-job

Esegui il deployment di un container vLLM nel cluster GKE

Dopo aver scaricato il modello nel bucket Cloud Storage, esegui il deployment di un container vLLM nel cluster GKE completando i seguenti passaggi:

  1. Crea un file vllm-deepseek3-2.yaml con il deployment vLLM che hai scelto:

    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. Applica il file vllm-deepseek3-2.yaml al tuo cluster GKE:

    envsubst < vllm-deepseek3-2.yaml | kubectl apply -f -
  3. Per visualizzare lo stato di completamento, esegui questo comando:

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

    Il flag --timeout consente al comando di monitorare il deployment per il periodo di tempo specificato.

Interagisci con DeepSeek-V3.2-Speciale utilizzando curl

Per verificare il modello DeepSeek-V3.2-Speciale che hai eseguito il deployment:

  1. Configura il port forwarding a DeepSeek-V3.2-Speciale:

    kubectl port-forward service/deepseek-service 8000:8000
  2. Apri una nuova finestra del terminale. Puoi quindi chattare con il modello utilizzando 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. L'output visualizzato è simile al seguente:

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

Osserva le prestazioni del modello

Per osservare le prestazioni del modello, puoi utilizzare l'integrazione della dashboard vLLM in Cloud Monitoring. Utilizza questa dashboard per visualizzare metriche di rendimento critiche come velocità effettiva dei token, latenza delle richieste e tassi di errore.

Per informazioni sull'utilizzo di Google Cloud Managed Service per Prometheus per raccogliere metriche dal tuo modello, consulta le indicazioni sull'osservabilità di vLLM nella documentazione di Monitoring.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Per evitare che al tuo account di fatturazione Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina le risorse

Al termine del tutorial, elimina le risorse che non ti servono più:

  1. Per eliminare il deployment e il servizio definiti nel file vllm-deepseek3-2.yaml e il secret Kubernetes dal cluster GKE, esegui questo comando:

    envsubst < vllm-deepseek3-2.yaml | kubectl delete -f -
    kubectl delete secret hf-secret
  2. Per eliminare il bucket Cloud Storage, esegui questo comando:

    gcloud storage rm --recursive gs://"$GCS_BUCKET"
  3. Per eliminare il cluster GKE:

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

Elimina il progetto

Elimina un progetto Google Cloud :

gcloud projects delete PROJECT_ID

Passaggi successivi