Usar o vLLM no GKE para executar inferências com o DeepSeek-V3.2-Speciale

Neste tutorial, mostramos como implantar e disponibilizar um modelo de linguagem DeepSeek-V3.2-Speciale usando o framework vLLM. Você implanta esse modelo em um cluster do Autopilot da edição Enterprise do Google Kubernetes Engine (GKE) e consome uma única máquina virtual A4 (VM) com 8 GPUs B200.

Este tutorial pressupõe que você já analisou o modelo de linguagem DeepSeek-V3.2-Speciale e verificou se os recursos dele atendem aos requisitos do seu caso de uso.

Este tutorial é destinado a engenheiros de machine learning (ML), administradores e operadores de plataforma e especialistas em dados e IA interessados em usar os recursos de orquestração de contêineres do Kubernetes para processar cargas de trabalho de inferência.

Objetivos

  1. Acesse o DeepSeek-V3.2-Speciale usando o Hugging Face.

  2. Prepare seu ambiente.

  3. Criar um cluster do GKE no modo Autopilot.

  4. Crie um secret do Kubernetes para as credenciais do Hugging Face.

  5. Criar um bucket do Cloud Storage.

  6. Faça o download do modelo para o bucket do Cloud Storage.

  7. Implante um contêiner vLLM no cluster do GKE.

  8. Interaja com o DeepSeek-V3.2-Speciale usando curl.

  9. Fazer a limpeza.

Custos

Neste tutorial, usamos componentes faturáveis do Google Cloud, incluindo:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.

Antes de começar

  1. Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloudagora, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho.
  2. Instale a CLI do Google Cloud.

  3. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.

  4. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  5. Crie ou selecione um Google Cloud projeto.

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.
    • Crie um projeto do Google Cloud :

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud .

  6. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  7. Ative a API necessária, se ela ainda não estiver ativada:

    Funções necessárias para ativar APIs

    Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de Proprietário (roles/owner). Caso contrário, é possível receber essa permissão pelo papel de Administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    gcloud services enable container.googleapis.com
  8. Instale a CLI do Google Cloud.

  9. Ao usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.

  10. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  11. Crie ou selecione um Google Cloud projeto.

    Funções necessárias para selecionar ou criar um projeto

    • Selecionar um projeto: não é necessário um papel específico do IAM para selecionar um projeto. Você pode escolher qualquer projeto em que tenha recebido um papel.
    • Criar um projeto: para criar um projeto, é necessário ter o papel de Criador de projetos (roles/resourcemanager.projectCreator), que contém a permissão resourcemanager.projects.create. Saiba como conceder papéis.
    • Crie um projeto do Google Cloud :

      gcloud projects create PROJECT_ID

      Substitua PROJECT_ID por um nome para o projeto do Google Cloud que você está criando.

    • Selecione o projeto Google Cloud que você criou:

      gcloud config set project PROJECT_ID

      Substitua PROJECT_ID pelo nome do projeto do Google Cloud .

  12. Verifique se o faturamento está ativado para o projeto do Google Cloud .

  13. Ative a API necessária, se ela ainda não estiver ativada:

    Funções necessárias para ativar APIs

    Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de Proprietário (roles/owner). Caso contrário, é possível receber essa permissão pelo papel de Administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    gcloud services enable container.googleapis.com
  14. Conceda papéis à sua conta de usuário. Execute uma vez o seguinte comando para cada um dos seguintes papéis do IAM: roles/container.admin

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

    Substitua:

    • PROJECT_ID: o ID do projeto.
    • USER_IDENTIFIER: o identificador da sua conta de usuário . Por exemplo, myemail@example.com.
    • ROLE: o papel do IAM que você concede à sua conta de usuário.
  15. Faça login ou crie uma conta do Hugging Face.

Acessar o DeepSeek-V3.2-Speciale usando o Hugging Face

Para usar o Hugging Face e acessar o modelo DeepSeek-V3.2-Speciale, siga estas etapas:

  1. Faça login no Hugging Face.
  2. Crie um token de acesso read do Hugging Face.
  3. Copie e salve o valor do token de acesso read. Você vai usar esse valor mais tarde neste tutorial.

Preparar o ambiente

Para preparar seu ambiente, defina as variáveis de ambiente padrão:

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

Substitua:

  • YOUR_PROJECT_ID: o ID do Google Cloud projeto em que você quer criar o cluster do GKE.

  • YOUR_RESERVATION_NAME: o nome da reserva que você quer usar para criar o cluster do GKE. Com base no projeto em que a reserva existe, especifique um dos seguintes valores:

    • A reserva existe no seu projeto: YOUR_RESERVATION_NAME

    • A reserva existe em um projeto diferente, e seu projeto pode usar a reserva: projects/RESERVATION_PROJECT_ID/reservations/YOUR_RESERVATION_NAME

  • YOUR_REGION: a região em que você quer criar o cluster do GKE. Só é possível criar o cluster na região em que a reserva está.

  • YOUR_CLUSTER_NAME: o nome do cluster do GKE a ser criado.

  • YOUR_GCS_BUCKET: o nome do bucket do Cloud Storage em que você baixa o modelo.

  • YOUR_HF_TOKEN: o token de acesso do Hugging Face que você criou na seção anterior.

  • YOUR_NETWORK_NAME: a rede usada pelo cluster do GKE. Especifique um dos seguintes valores:

    • Se você criou uma rede personalizada, especifique o nome dela.

    • Caso contrário, especifique default.

  • YOUR_SUBNETWORK_NAME: a sub-rede que o cluster do GKE usa. Especifique um dos seguintes valores:

    • Se você criou uma sub-rede personalizada, especifique o nome dela. Só é possível especificar uma sub-rede que esteja na mesma região da reserva.

    • Caso contrário, especifique default.

Criar um cluster do GKE no modo Autopilot

Para criar um cluster do GKE no modo Autopilot, execute o seguinte comando:

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

A criação do cluster do GKE pode levar algum tempo. Para verificar se o Google Cloud concluiu a criação do cluster, acesse Clusters do Kubernetes no console Google Cloud .

Criar um secret do Kubernetes para as credenciais do Hugging Face

Para criar um secret do Kubernetes para as credenciais do Hugging Face, siga estas etapas:

  1. Configure kubectl para se comunicar com o cluster do GKE:

    gcloud container clusters get-credentials "$CLUSTER_NAME" \
        --location="$REGION"
  2. Crie um secret do Kubernetes para armazenar seu token do Hugging Face:

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

Criar um bucket do Cloud Storage

Se você quiser usar um bucket do Cloud Storage, pule esta etapa. No entanto, verifique se o bucket está na mesma região do cluster e se a conta de serviço tem as permissões write necessárias para ele.

Se você quiser usar um novo bucket para armazenar o modelo, execute o seguinte:

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

Conceda permissões de write no bucket do Cloud Storage à conta de serviço padrão:

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"

Baixar o modelo para o bucket do Cloud Storage

  1. Crie um arquivo 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. Aplique o manifesto deepseek-download-job.yaml para inicializar o job de download:

    envsubst '$GCS_BUCKET' < deepseek-download-job.yaml | kubectl apply -f -
  3. Para conferir o status da conclusão, execute o seguinte comando:

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

    A flag --timeout especifica por quanto tempo o comando monitora o job antes de atingir o tempo limite.

    O recurso de job faz o download dos pesos do modelo DeepSeek-V3.2-Speciale do Hugging Face para seu bucket do Google Cloud Storage usando o volume SSD. O download leva cerca de 40 minutos para ser concluído. Depois que o download terminar, siga para a próxima seção para iniciar a implantação do modelo.

  4. Para excluir o job, execute o seguinte comando:

    kubectl delete job deepseek-download-job

Implantar um contêiner vLLM no cluster do GKE

Depois de baixar o modelo para o bucket do Cloud Storage, implante um contêiner vLLM no cluster do GKE seguindo estas etapas:

  1. Crie um arquivo vllm-deepseek3-2.yaml com a implantação do vLLM escolhida:

    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. Aplique o arquivo vllm-deepseek3-2.yaml ao cluster do GKE:

    envsubst < vllm-deepseek3-2.yaml | kubectl apply -f -
  3. Para conferir o status da conclusão, execute o seguinte comando:

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

    A flag --timeout permite que o comando monitore a implantação durante o período especificado.

Interagir com o DeepSeek-V3.2-Speciale usando curl

Para verificar o modelo DeepSeek-V3.2-Speciale implantado, faça o seguinte:

  1. Configure o encaminhamento de portas para o DeepSeek-V3.2-Speciale:

    kubectl port-forward service/deepseek-service 8000:8000
  2. Abra uma nova janela do terminal. Em seguida, converse com o modelo usando 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. A saída será semelhante a esta:

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

Observar a performance do modelo

Para observar o desempenho do modelo, use a integração do painel do vLLM no Cloud Monitoring. Use esse painel para conferir métricas de desempenho críticas, como capacidade de processamento de tokens, latência de solicitação e taxas de erro.

Para informações sobre como usar o Google Cloud Managed Service para Prometheus e coletar métricas do seu modelo, consulte as orientações de capacidade de observação do vLLM na documentação do Monitoring.

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Para evitar cobranças na sua conta do Cloud Billing pelos recursos usados neste tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Excluir os recursos

Depois de concluir o tutorial, exclua os recursos que não são mais necessários:

  1. Para excluir a implantação e o serviço definidos no arquivo vllm-deepseek3-2.yaml e o secret do Kubernetes do cluster do GKE, execute o seguinte comando:

    envsubst < vllm-deepseek3-2.yaml | kubectl delete -f -
    kubectl delete secret hf-secret
  2. Para excluir o bucket do Cloud Storage, execute o seguinte comando:

    gcloud storage rm --recursive gs://"$GCS_BUCKET"
  3. Para excluir o cluster do GKE, faça o seguinte:

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

Excluir o projeto

Excluir um projeto do Google Cloud :

gcloud projects delete PROJECT_ID

A seguir