Disponibilizar modelos Llama usando GPUs no GKE com vLLM

Neste tutorial, mostramos como implantar e disponibilizar o modelo de linguagem grande (LLM) Llama 4 usando GPUs no Google Kubernetes Engine (GKE) com o framework de disponibilização vLLM. Isso fornece uma base para entender e explorar a implantação prática de LLMs para inferência em um ambiente gerenciado do Kubernetes. Você implanta um contêiner pré-criado que executa vLLM no GKE. Você também configura o GKE para carregar o Llama do Hugging Face.

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 veicular cargas de trabalho de IA/ML em hardwares de GPU H200, H100, A100 e L4. Para saber mais sobre papéis comuns e tarefas de exemplo referenciados no conteúdo do Google Cloud , consulte Tarefas e funções de usuário comuns do GKE.

Se você precisa de uma plataforma de IA gerenciada unificada projetada para criar e disponibilizar modelos de ML rapidamente e de maneira econômica, recomendamos que você teste nossa solução de implantação da Vertex AI.

Antes de ler esta página, confira se você conhece os seguintes conceitos:

Contexto

Esta seção descreve as principais tecnologias usadas neste guia.

Llama

O Llama é um modelo de linguagem grande da Meta projetado para uma variedade de tarefas de processamento de linguagem natural, incluindo geração de texto, tradução e resposta a perguntas. O GKE oferece a infraestrutura necessária para atender às necessidades de treinamento e disponibilização distribuídos de modelos dessa escala. Para mais informações, consulte a documentação do Llama.

GPUs

As GPUs permitem acelerar cargas de trabalho específicas em execução nos nós, como machine learning e processamento de dados. O GKE oferece uma gama de opções de tipos de máquina para configuração de nós, incluindo tipos de máquinas com GPUs NVIDIA H200, H100, L4 e A100.

vLLM

O vLLM é um framework de exibição de LLM de código aberto altamente otimizado que pode aumentar a capacidade de exibição em GPUs, com recursos como:

  • Otimização da implementação do transformador com PagedAttention
  • Lotes contínuos para melhorar a capacidade geral de exibição
  • Paralelismo de tensor e exibição distribuída em várias GPUs

Para mais informações, consulte a documentação do vLLM.

Receber acesso ao modelo

Para acessar o modelo pelo "Rosto abraçado", você vai precisar de um token de rosto abraçado.

Siga as etapas abaixo para gerar um novo token, caso ainda não tenha um:

  1. Clique em Seu perfil > Configurações > Tokens de acesso.
  2. Selecione Novo token.
  3. Especifique um Nome de sua escolha e um Papel de pelo menos Read.
  4. Selecione Gerar um token.
  5. Copie o token gerado para a área de transferência.

Preparar o ambiente

Neste tutorial, você vai usar o Cloud Shell para gerenciar recursos hospedados no Google Cloud. O Cloud Shell vem pré-instalado com o software necessário para este tutorial, incluindo kubectl e gcloud CLI.

Para configurar o ambiente com o Cloud Shell, siga estas etapas:

  1. No console do Google Cloud , inicie uma sessão do Cloud Shell clicando em Ícone de ativação do Cloud Shell Ativar o Cloud Shell no Google Cloud console. Isso inicia uma sessão no painel inferior do console Google Cloud .

  2. Defina as variáveis de ambiente padrão:

    gcloud config set project PROJECT_ID
    gcloud config set billing/quota_project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export REGION=REGION
    export CLUSTER_NAME=CLUSTER_NAME
    export HF_TOKEN=HF_TOKEN
    

    Substitua os seguintes valores:

    • PROJECT_ID: o Google Cloud ID do projeto.
    • REGION: uma região compatível com o tipo de acelerador que você quer usar, por exemplo, us-central1 para GPU L4.
    • CLUSTER_NAME: o nome do cluster.
    • HF_TOKEN: o token do Hugging Face gerado anteriormente.

Criar e configurar recursos Google Cloud

Siga estas instruções para criar os recursos necessários.

Criar um cluster do GKE e um pool de nós

É possível disponibilizar modelos Llama 4 em GPUs em um cluster do GKE Autopilot ou Standard. Recomendamos que você use um cluster do Autopilot para ter uma experiência totalmente gerenciada do Kubernetes. Para escolher o modo de operação do GKE mais adequado para suas cargas de trabalho, consulte Escolher um modo de operação do GKE.

Piloto automático

No Cloud Shell, execute este comando:

gcloud container clusters create-auto CLUSTER_NAME \
    --project=PROJECT_ID \
    --location=CONTROL_PLANE_LOCATION \
    --release-channel=rapid

Substitua os seguintes valores:

  • PROJECT_ID: o Google Cloud ID do projeto.
  • CONTROL_PLANE_LOCATION: a região do Compute Engine do plano de controle do cluster. Forneça uma região que ofereça suporte ao tipo de acelerador que você quer usar, por exemplo, us-central1 para GPU L4.
  • CLUSTER_NAME: o nome do cluster.

O GKE cria um cluster do Autopilot com nós de CPU e GPU conforme solicitado pelas cargas de trabalho implantadas.

Padrão

  1. No Cloud Shell, execute o seguinte comando para criar um cluster Standard:

    gcloud container clusters create CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --workload-pool=PROJECT_ID.svc.id.goog \
        --release-channel=rapid \
        --num-nodes=1
    

    Substitua os seguintes valores:

    • PROJECT_ID: o Google Cloud ID do projeto.
    • CONTROL_PLANE_LOCATION: a região do Compute Engine do plano de controle do cluster. Forneça uma região que ofereça suporte ao tipo de acelerador que você quer usar, por exemplo, us-central1 para GPU H100.
    • CLUSTER_NAME: o nome do cluster.

    A criação do cluster pode levar vários minutos.

  2. Para criar um pool de nós para o cluster com o tamanho de disco adequado, execute o seguinte comando:

    gcloud container node-pools create gpupool \
        --accelerator type=nvidia-h100-80gb,count=1,gpu-driver-version=latest \
        --project=PROJECT_ID \
        --location=REGION \
        --node-locations=REGION-a \
        --cluster=CLUSTER_NAME \
        --machine-type=a3-highgpu-8g \
        --disk-type=pd-ssd \
        --num-nodes=1 \
        --disk-size=256
    

    O GKE cria um único pool de nós com oito GPUs H100 de 80 GB.

Criar um secret do Kubernetes para as credenciais do Hugging Face

No Cloud Shell, faça o seguinte:

  1. Configure kubectl para que ele possa se comunicar com o cluster:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=REGION
    

    Substitua os seguintes valores:

    • REGION: uma região compatível com o tipo de acelerador que você quer usar, por exemplo, us-central1 para GPU L4.
    • CLUSTER_NAME: o nome do cluster.
  2. Crie um secret do Kubernetes que contenha o token do Hugging Face:

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

    Substitua HF_TOKEN pelo token do Hugging Face que você gerou anteriormente.

Implantar vLLM

Nesta seção, você implanta o contêiner vLLM para veicular os modelos Llama 4 que quer usar:

  • Llama 4 Maverick 17B-128E
  • Llama 4 Scout 17B-16E

Para implantar o modelo, este tutorial usa implantações do Kubernetes. Uma implantação é um objeto da API Kubernetes que permite executar várias réplicas de pods distribuídos entre os nós de um cluster.

Llama 4 Maverick 17B-128e

Para implantar o modelo Llama 4 Maverick 17B-128E, siga estas instruções:

  1. Crie o seguinte manifesto vllm-llama4-maverick-17b-128e.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llama-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llama-server
      template:
        metadata:
          labels:
            app: llama-server
            ai.gke.io/model: Llama-4-Maverick-17B-128E
            ai.gke.io/inference-server: vllm
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: 157
                memory: 2067Gi
                ephemeral-storage: 850Gi
                nvidia.com/gpu : 8
              limits:
                cpu: 157
                memory: 2067Gi
                ephemeral-storage: 850Gi
                nvidia.com/gpu : 8
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=7080
            - --swap-space=16
            - --max-model-len=131072
            - --gpu-memory-utilization=0.95
            - --disable-log-stats
            - --dtype=auto
            - --kv-cache-dtype=auto
            - --max-num-seqs=64
            - --model=meta-llama/Llama-4-Maverick-17B-128E
            - --tensor-parallel-size=8
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
            - name: MODEL_ID
              value: 'meta-llama/Llama-4-Maverick-17B-128E'
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-h200-141gb
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llama-service
    spec:
      selector:
        app: llama-server
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 7080
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: hf-secret
    type: Opaque
    stringData:
      hf_api_token: {{HF_TOKEN}}
  2. Aplique o manifesto:

    kubectl apply -f vllm-llama4-maverick-17b-128e.yaml
    

    No nosso exemplo, limitamos a janela de contexto em 128 K usando a opção --max-model-len=131072 do vLLM.

Llama 4 Maverick 17B-128e-it

Para implantar o modelo ajustado por instruções Llama 4 Maverick 17B-128e, siga estas instruções:

  1. Crie o seguinte manifesto vllm-llama4-maverick-17b-128e-instruct.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llama-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llama-server
      template:
        metadata:
          labels:
            app: llama-server
            ai.gke.io/model: Llama-4-Maverick-17B-128E-Instruct
            ai.gke.io/inference-server: vllm
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: 157
                memory: 2067Gi
                ephemeral-storage: 850Gi
                nvidia.com/gpu : 8
              limits:
                cpu: 157
                memory: 2067Gi
                ephemeral-storage: 850Gi
                nvidia.com/gpu : 8
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=7080
            - --swap-space=16
            - --max-model-len=131072
            - --gpu-memory-utilization=0.95
            - --disable-log-stats
            - --dtype=auto
            - --kv-cache-dtype=auto
            - --max-num-seqs=64
            - --model=meta-llama/Llama-4-Maverick-17B-128E-Instruct
            - --tensor-parallel-size=8
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
            - name: MODEL_ID
              value: 'meta-llama/Llama-4-Maverick-17B-128E-Instruct'
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-h200-141gb
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llama-service
    spec:
      selector:
        app: llama-server
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 7080
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: hf-secret
    type: Opaque
    stringData:
      hf_api_token: {{HF_TOKEN}}
  2. Aplique o manifesto:

    kubectl apply -f vllm-llama4-maverick-17b-128e-instruct.yaml
    

    No nosso exemplo, limitamos a janela de contexto em 128 K usando a opção --max-model-len=131072 do vLLM.

Llama 4 Maverick 17B-128e-it-fp8

Para implantar o modelo Llama 4 Maverick 17B-128e-Instruct-FP8, siga estas instruções:

  1. Crie o seguinte manifesto vllm-llama4-maverick-17b-128e-instruct-fp8.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llama-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llama-server
      template:
        metadata:
          labels:
            app: llama-server
            ai.gke.io/model: Llama-4-Maverick-17B-128E-Instruct-FP8
            ai.gke.io/inference-server: vllm
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
              limits:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=7080
            - --swap-space=16
            - --max-model-len=524288
            - --gpu-memory-utilization=0.90
            - --disable-log-stats
            - --model=meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8
            - --tensor-parallel-size=8
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
            - name: MODEL_ID
              value: 'meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8'
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-h100-80gb
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llama-service
    spec:
      selector:
        app: llama-server
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 7080
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: hf-secret
    type: Opaque
    stringData:
      hf_api_token: {{HF_TOKEN}}
  2. Aplique o manifesto:

    kubectl apply -f vllm-llama4-maverick-17b-128e-instruct-fp8.yaml
    

    No nosso exemplo, limitamos a janela de contexto em 512 K usando a opção --max-model-len=524288 vLLM.

Llama 4 Scout 17B-16e

Para implantar o modelo Llama 4 Scout 17B-16E, siga estas instruções:

  1. Crie o seguinte manifesto vllm-llama4-scout-17b-16e.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llama-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llama-server
      template:
        metadata:
          labels:
            app: llama-server
            ai.gke.io/model: Llama-4-Scout-17B-16E
            ai.gke.io/inference-server: vllm
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
              limits:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=7080
            - --swap-space=16
            - --max-model-len=262144
            - --limit_mm_per_prompt
            - '{"image": 5}'
            - --disable-log-stats
            - --model=meta-llama/Llama-4-Scout-17B-16E
            - --tensor-parallel-size=8
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64        
            - name: MODEL_ID
              value: 'meta-llama/Llama-4-Scout-17B-16E'
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-h100-80gb
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llama-service
    spec:
      selector:
        app: llama-server
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 7080
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: hf-secret
    type: Opaque
    stringData:
      hf_api_token: {{HF_TOKEN}}
  2. Aplique o manifesto:

    kubectl apply -f vllm-llama4-scout-17b-16e.yaml
    

    No nosso exemplo, limitamos a janela de contexto em 256 K usando a opção --max-model-len=262144 vLLM.

Llama 4 Scout 17B-16e-it

Para implantar o modelo ajustado por instruções Llama 4 Scout 17B-16e Instruct, siga estas instruções:

  1. Crie o seguinte manifesto vllm-llama4-scout-17b-16e-instruct.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: llama-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llama-server
      template:
        metadata:
          labels:
            app: llama-server
            ai.gke.io/model: Llama-4-Scout-17B-16E-Instruct
            ai.gke.io/inference-server: vllm
        spec:
          containers:
          - name: inference-server
            image: docker.io/vllm/vllm-openai:v0.10.0
            resources:
              requests:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
              limits:
                cpu: 146
                memory: 1311Gi
                ephemeral-storage: 600Gi
                nvidia.com/gpu : 8
            command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
            args:
            - --host=0.0.0.0
            - --port=7080
            - --swap-space=16
            - --max-model-len=1310720
            - --limit_mm_per_prompt
            - '{"image": 5}'
            - --disable-log-stats
            - --model=meta-llama/Llama-4-Scout-17B-16E-Instruct
            - --tensor-parallel-size=8
            env:
            - name: LD_LIBRARY_PATH
              value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
            - name: MODEL_ID
              value: 'meta-llama/Llama-4-Scout-17B-16E-Instruct'
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
              medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-h100-80gb
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llama-service
    spec:
      selector:
        app: llama-server
      type: ClusterIP
      ports:
      - protocol: TCP
        port: 8000
        targetPort: 7080
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: hf-secret
    type: Opaque
    stringData:
      hf_api_token: {{HF_TOKEN}}
  2. Aplique o manifesto:

    kubectl apply -f vllm-llama4-scout-17b-16e-instruct.yaml
    

    No nosso exemplo, limitamos a janela de contexto em 1.280 K usando a opção --max-model-len=1310720 do vLLM.

Aguarde até que a implantação esteja disponível:

kubectl wait --for=condition=Available --timeout=1800s deployment/llama-deployment

Confira os registros da implantação em execução:

kubectl logs -f -l app=llama-server

O recurso de implantação faz o download dos dados do modelo. O processo pode levar alguns minutos. O resultado será assim:

INFO:     Started server process [145]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
...
INFO 04-07 13:36:29 [async_llm.py:228] Added request chatcmpl-4149ea4cf35e48559f9f819dcdbbb23e.
INFO:     127.0.0.1:44018 - "POST /v1/chat/completions HTTP/1.1" 200 OK

Verifique se o download do modelo foi concluído antes de prosseguir para a próxima seção.

Disponibilizar o modelo

Nesta seção, você vai interagir com o modelo.

Configurar o encaminhamento de portas

Para configurar o encaminhamento de portas para o modelo, execute o seguinte comando:

kubectl port-forward service/llama-service 8080:8000

O resultado será assim:

Forwarding from 127.0.0.1:8080 -> 7080

Interagir com o modelo usando curl

Nesta seção, mostramos como realizar um teste preliminar básico para verificar o modelo Llama ajustado por instruções implantado. Para outros modelos, substitua meta-llama/Llama-4-Scout-17B-16E pelo nome do modelo respectivo.

Este exemplo mostra como testar o modelo Llama 4 Scout 17B-16E com entrada somente de texto.

Em uma nova sessão do terminal, use curl para conversar com seu modelo:

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-4-Scout-17B-16E",
    "messages": [{"role": "user", "content": "San Francisco is a"}],
    "max_tokens": 7,
    "temperature": 0
  }'

O resultado será assim:

"message":{"role":"assistant","reasoning_content":null,"content":"San Francisco is a city","tool_calls":[]}

Resolver problemas

  • Se você receber a mensagem Empty reply from server, é possível que o contêiner não tenha concluído o download dos dados do modelo. Verifique os registros do pod novamente para ver a mensagem Connected, que indica que o modelo está pronto para ser disponibilizado.
  • Se você vir a mensagem Connection refused, verifique se o encaminhamento de portas está ativo.

Observar o desempenho do modelo

Para conferir os painéis das métricas de observabilidade de um modelo, siga estas etapas:

  1. No console do Google Cloud , acesse a página Modelos implantados.

    Acessar "Modelos implantados"

  2. Para ver detalhes sobre a implantação específica, incluindo métricas, registros e painéis, clique no nome do modelo na lista.

  3. Na página de detalhes do modelo, clique na guia Observabilidade para conferir os seguintes painéis. Se solicitado, clique em Ativar para ativar a coleta de métricas do cluster.

    • O painel Uso da infraestrutura mostra métricas de utilização.
    • O painel DCGM mostra as métricas do DCGM.
    • Se você estiver usando o vLLM, o painel Performance do modelo vai estar disponível e mostrará métricas de desempenho do modelo vLLM.

Também é possível conferir as métricas na integração do painel do vLLM no Cloud Monitoring. Essas métricas são agregadas para todas as implantações de vLLM sem filtros predefinidos.

Para usar o painel no Cloud Monitoring, ative o Google Cloud Managed Service para Prometheus, que coleta as métricas do vLLM no cluster do GKE. O vLLM expõe métricas no formato do Prometheus por padrão. Não é necessário instalar um exportador adicional. Para informações sobre como usar o Google Cloud Managed Service para Prometheus para coletar métricas do seu modelo, consulte as orientações de capacidade de observação do vLLM na documentação do Cloud Monitoring.