Disponibilizar o Llama 3.1 405B no GKE com desagregação de DP usando o Dynamo e o SGLang em VMs A4

Neste tutorial, mostramos como implantar e disponibilizar o Llama 3.1 405B (nvidia/Llama-3.1-405B-Instruct-FP8), um modelo ajustado por instruções de 405 bilhões de parâmetros quantizado para FP8, no Google Kubernetes Engine (GKE) no Google Cloud. A implantação usa o Cluster Toolkit, duas instâncias de máquina virtual (VM) A4 (a4-highgpu-8g) com um total de 16 GPUs NVIDIA B200, NVIDIA Dynamo e o framework de exibição SGLang com desagregação de preenchimento e decodificação (DP) de host único.

Na configuração de implantação descrita neste tutorial, use o Cluster Toolkit para provisionar um cluster do GKE no modo Standard. O cluster contém dois nós a4-highgpu-8g conectados pela rede de acesso direto à memória remota (RDMA) do GPUDirect. Em seguida, instale o KAI Scheduler e a plataforma NVIDIA Dynamo com o agendamento de gangues do Grove. Por fim, implante um recurso personalizado DynamoGraphDeployment que separa a pré-preenchimento e a decodificação em dois workers de oito GPUs de host único com paralelismo de tensor e um cache de KV FP8.

Objetivos

  • Instale o Cluster Toolkit e provisione um cluster do GKE A4 de dois nós no modo Standard.
  • Instale o programador KAI e a plataforma NVIDIA Dynamo com a programação de gangues do Grove no cluster.
  • Implante um servidor de inferência SGLang desagregado por DP com um worker de pré-preenchimento A4 de host único e um worker de decodificação A4 de host único.
  • Envie uma solicitação de conclusão de chat para o roteador de front-end do Dynamo.
  • Executar uma carga de trabalho de comparativo de mercado de exibição.
  • Limpe os recursos implantados.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

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

Antes de começar

Configure o ambiente para o tutorial:

  1. Instale e inicialize a Google Cloud CLI e instale kubectl e Helm (versão 3.10 ou mais recente). Se você usa o Cloud Shell, essas ferramentas já estão pré-instaladas.
  2. Se você estiver executando este tutorial em uma estação de trabalho Linux ou macOS em vez do Cloud Shell, instale as dependências necessárias do Cluster Toolkit, como o Terraform e o Git.
  3. Ative as API Kubernetes Engine, Compute Engine, Cloud Storage, Identity and Access Management, Cloud Resource Manager e Service Usage no projeto do Google Cloud :

    Ativar APIs

Receber um token de acesso do Hugging Face

Você precisa de um token de acesso do Hugging Face para usar este tutorial. Você pode se inscrever para uma conta sem custo financeiro no Hugging Face. Depois de criar uma conta, gere um token de acesso:

  1. Na página Welcome to Hugging Face, clique no avatar da sua conta e selecione Tokens de acesso.
  2. Na página Tokens de acesso, clique em Criar novo token.
  3. Selecione o tipo de token Read e insira um nome para ele.
  4. Seu token de acesso será exibido. Salve o token em um local seguro.

Funções exigidas

Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Configurar as variáveis de ambiente

Exporte as variáveis de ambiente que você vai usar neste tutorial:

export PROJECT_ID="YOUR_PROJECT_ID"
export REGION="YOUR_REGION"
export ZONE="YOUR_ZONE"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export RESERVATION_NAME="YOUR_RESERVATION_NAME"
export GCS_BUCKET="YOUR_BUCKET_NAME"
export HF_TOKEN="YOUR_HF_TOKEN"
export CLUSTER_TOOLKIT_VERSION="v1.104.0"
export DYNAMO_RELEASE_VERSION="1.5.0"

gcloud config set project "${PROJECT_ID}"
gcloud config set billing/quota_project "${PROJECT_ID}"

Substitua:

  • YOUR_PROJECT_ID: ID do seu projeto do Google Cloud.
  • YOUR_REGION: a região em que a capacidade do A4 está localizada e em que você quer implantar o cluster, como us-central1.
  • YOUR_ZONE: a zona em que sua capacidade de A4 está localizada, como us-central1-b.
  • YOUR_CLUSTER_NAME: o nome do cluster do GKE e da implantação do Cluster Toolkit. Use um nome com até 20 caracteres para que o ID da conta de serviço do pool de nós gerado (YOUR_CLUSTER_NAME-gke-np-sa) permaneça dentro do limite de 30 caracteres do Identity and Access Management (IAM).
  • YOUR_RESERVATION_NAME: o nome da sua reserva A4.
  • YOUR_BUCKET_NAME: um nome globalmente exclusivo para o bucket do Cloud Storage que armazena o estado do Terraform para o Cluster Toolkit.
  • YOUR_HF_TOKEN: seu token de acesso do Hugging Face.

Criar o cluster do GKE

Faça o download do Cluster Toolkit e provisione um cluster do GKE no modo Standard com dois nós a4-highgpu-8g, rede GPUDirect RDMA e suporte a DRA:

  1. Faça login na Google Cloud CLI e gere o Application Default Credentials para o Terraform:

    gcloud auth login
    gcloud auth application-default login
  2. Faça o download e extraia o pacote pré-criado do Cluster Toolkit para a versão especificada em CLUSTER_TOOLKIT_VERSION (v1.104.0):

    TAG="${CLUSTER_TOOLKIT_VERSION:-v1.104.0}"
    OS="linux"
    ARCH="amd64"
    mkdir -p cluster-toolkit && curl -L "https://github.com/GoogleCloudPlatform/cluster-toolkit/releases/download/${TAG}/gcluster_bundle_${OS}_${ARCH}.tgz" | tar -xz -C cluster-toolkit

    Se você executar esse comando no macOS ou em uma estação de trabalho arm64, defina OS="mac" ou ARCH="arm64" para corresponder à sua plataforma.

  3. Para armazenar o estado do Terraform para a implantação do Cluster Toolkit, crie um bucket do Cloud Storage com o controle de versões de objeto ativado:

    gcloud storage buckets create "gs://${GCS_BUCKET}" \
        --default-storage-class=STANDARD \
        --project="${PROJECT_ID}" \
        --location="${REGION}" \
        --uniform-bucket-level-access
    gcloud storage buckets update "gs://${GCS_BUCKET}" --versioning
  4. Crie o arquivo de configuração de implantação cluster-toolkit/examples/gke-a4/gke-a4-deployment.yaml para dois nós a4-highgpu-8g:

    cat <<EOF > cluster-toolkit/examples/gke-a4/gke-a4-deployment.yaml
    terraform_backend_defaults:
      type: gcs
      configuration:
        bucket: ${GCS_BUCKET}
    
    vars:
      project_id: ${PROJECT_ID}
      deployment_name: ${CLUSTER_NAME}
      region: ${REGION}
      zone: ${ZONE}
      static_node_count: 2
      authorized_cidr: 0.0.0.0/0
      reservation_affinity:
        consume_reservation_type: SPECIFIC_RESERVATION
        specific_reservations:
        - name: ${RESERVATION_NAME}
    EOF

    Por padrão, o arquivo de implantação é configurado para consumir uma reserva específica. Se você não tiver uma reserva específica, antes de implantar o cluster, atualize cluster-toolkit/examples/gke-a4/gke-a4-deployment.yaml para usar uma opção de consumo alternativa, como VMs spot ou VMs flex-start. Para instruções de configuração, consulte Opções de consumo do GKE.

  5. Mude para o diretório cluster-toolkit, implante o cluster do GKE usando o comando gcluster deploy e volte para o diretório de trabalho:

    cd cluster-toolkit
    ./gcluster deploy \
        -d examples/gke-a4/gke-a4-deployment.yaml \
        examples/gke-a4/gke-a4.yaml \
        --auto-approve -w
    cd ..

    A criação do cluster leva aproximadamente de 20 a 30 minutos. Se você executar ./gcluster deploy sem a flag --auto-approve, para aplicar as mudanças propostas, insira a quando solicitado.

  6. Configure as credenciais de kubectl para se comunicar com o cluster:

    gcloud container clusters get-credentials "${CLUSTER_NAME}" \
        --location="${REGION}" \
        --project="${PROJECT_ID}"

Instalar o KAI Scheduler e o NVIDIA Dynamo

Prepare o cluster criando um Secret do Hugging Face e instalando o programador do KAI e a plataforma NVIDIA Dynamo com a programação de gangues do Grove:

  1. Crie um Secret do Kubernetes chamado hf-secret para armazenar o token de acesso do Hugging Face:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token="${HF_TOKEN}" \
        --dry-run=client -o yaml | kubectl apply -f -
  2. Faça o download do gráfico do Helm da plataforma NVIDIA Dynamo (v1.5.0), instale o programador KAI e instale a plataforma Dynamo com o Grove ativado:

    RELEASE_VERSION="${DYNAMO_RELEASE_VERSION:-1.5.0}"
    helm fetch "https://helm.ngc.nvidia.com/nvidia/ai-dynamo/charts/dynamo-platform-${RELEASE_VERSION}.tgz"
    tar -zxf "dynamo-platform-${RELEASE_VERSION}.tgz"
    
    helm upgrade --install kai-scheduler ./dynamo-platform/charts/kai-scheduler \
        --set scheduler.args.default-staleness-grace-period="-1s" \
        --set topologyMigration.enabled=false
    
    kubectl wait --for=condition=Available deployment/kai-operator --timeout=120s
    until kubectl get deployment/queue-controller >/dev/null 2>&1; do sleep 2; done
    kubectl wait --for=condition=Available deployment/queue-controller --timeout=120s
    
    helm upgrade --install dynamo-platform ./dynamo-platform \
        --set global.grove.install=true \
        --set global.grove.enabled=true \
        --set global.kai-scheduler.enabled=true

Implantar o servidor SGLang desagregado de host único

O manifesto da carga de trabalho (llama3.1-405b-singlehost-a4.yaml) define um ResourceClaimTemplate do Kubernetes (all-mrdma), que aloca os dispositivos RDMA de várias NICs do nó (mrdma.google.com) por meio de DRA, e um DynamoGraphDeployment do NVIDIA Dynamo (llama3-405b-a4-disagg) com a programação de gangues do Grove ativada. A implantação consiste no seguinte:

  • Front-end (Frontend): executa uma réplica de roteador que aceita solicitações de clientes, descobre workers de preenchimento prévio e decodificação registrados e coordena o roteamento de solicitações desagregadas.
  • Worker de preenchimento prévio (Prefill): executa um worker de host único em um nó a4-highgpu-8g com oito GPUs NVIDIA B200. Na inicialização, o pod usa o ambiente NCCL/gIB, faz o download do checkpoint nvidia/Llama-3.1-405B-Instruct-FP8 do Hugging Face Hub para o SSD NVMe local do nó e inicia python3 -m dynamo.sglang em --disaggregation-mode prefill com as seguintes flags:
    • --tensor-parallel-size 8
    • --kv-cache-dtype fp8_e4m3
    • --context-length 16384
    • --mem-fraction-static 0.85
  • Worker de decodificação (Decode): executa um worker de host único no segundo nó a4-highgpu-8g com oito GPUs NVIDIA B200. Na inicialização, o pod armazena em cache os pesos do modelo no SSD NVMe local do nó e inicia python3 -m dynamo.sglang em --disaggregation-mode decode com as seguintes flags:
    • --tensor-parallel-size 8
    • --kv-cache-dtype fp8_e4m3
    • --context-length 16384
    • --mem-fraction-static 0.85

Implante e monitore o servidor de inferência desagregado:

  1. Faça o download do manifesto de carga de trabalho llama3.1-405b-singlehost-a4.yaml:

    curl -O https://raw.githubusercontent.com/GoogleCloudSamples/AIHypercomputerSamples/refs/heads/main/gpu/inference/llama3-405b/llama3.1-405b-singlehost-a4.yaml

    Como alternativa, crie um arquivo chamado llama3.1-405b-singlehost-a4.yaml com o seguinte conteúdo:

    # ==============================================================================
    # Single-Host Disaggregated Serving of Llama 3.1 405B FP8 on GKE
    # using NVIDIA Dynamo Platform (v1.5.0) and SGLang on GPU A4 (2 x a4-highgpu-8g)
    # Topology: 1-node Prefill (8 x B200, TP=8) + 1-node Decode (8 x B200, TP=8)
    # ==============================================================================
    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: all-mrdma
    spec:
      spec:
        devices:
          requests:
            - name: req-mrdma
              exactly:
                deviceClassName: mrdma.google.com
                allocationMode: All
    ---
    apiVersion: nvidia.com/v1alpha1
    kind: DynamoGraphDeployment
    metadata:
      name: llama3-405b-a4-disagg
      annotations:
        nvidia.com/enable-grove: "true"
    spec:
      backendFramework: sglang
      services:
        # --------------------------------------------------------------------------
        # FRONTEND: Dynamo OpenAI-Compatible Router (`python3 -m dynamo.frontend`)
        # --------------------------------------------------------------------------
        Frontend:
          componentType: frontend
          replicas: 1
          resources:
            requests:
              cpu: "8"
              memory: "32Gi"
            limits:
              cpu: "8"
              memory: "32Gi"
          extraPodSpec:
            tolerations:
              - key: "nvidia.com/gpu"
                operator: "Exists"
                effect: "NoSchedule"
            mainContainer:
              image: nvcr.io/nvidia/ai-dynamo/sglang-runtime:1.5.0
              command: ["/bin/bash", "-c"]
              args:
                - |
                  set -ex
                  exec python3 -m dynamo.frontend --http-port 8000
    
        # --------------------------------------------------------------------------
        # PREFILL WORKER: 1 x GPU A4 (`a4-highgpu-8g`, 8 x B200 GPUs, TP=8)
        # --------------------------------------------------------------------------
        Prefill:
          componentType: worker
          subComponentType: prefill
          replicas: 1
          livenessProbe:
            httpGet:
              path: /live
              port: system
            initialDelaySeconds: 600
            periodSeconds: 60
            timeoutSeconds: 30
            failureThreshold: 60
          readinessProbe:
            httpGet:
              path: /health
              port: system
            initialDelaySeconds: 120
            periodSeconds: 30
            timeoutSeconds: 30
            failureThreshold: 60
          sharedMemory:
            size: 128Gi
          resources:
            requests:
              gpu: "8"
              cpu: "128"
              memory: "1500Gi"
            limits:
              gpu: "8"
              cpu: "128"
              memory: "2000Gi"
          envs:
            - name: MODEL_PATH
              value: "nvidia/Llama-3.1-405B-Instruct-FP8"
            - name: HF_HOME
              value: "/data"
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
                  optional: true
            - name: DYN_SYSTEM_ENABLED
              value: "true"
            - name: DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS
              value: "[\"generate\"]"
            - name: DYN_SYSTEM_PORT
              value: "9090"
            - name: LD_LIBRARY_PATH
              value: "/usr/local/gib/lib64:/usr/local/nvidia/lib64"
            - name: GLOO_SOCKET_IFNAME
              value: "eth0"
            - name: WITH_NVIDIA_PEERMEM
              value: "0"
            # Xet CAS downloads returned unretried 429s; plain HTTP downloads back off on 429.
            - name: HF_HUB_DISABLE_XET
              value: "1"
          extraPodSpec:
            resourceClaims:
              - name: rdma
                resourceClaimTemplateName: all-mrdma
            nodeSelector:
              cloud.google.com/gke-accelerator: nvidia-b200
              cloud.google.com/gke-gpu: "true"
              kubernetes.io/arch: amd64
            tolerations:
              - key: "nvidia.com/gpu"
                operator: "Exists"
                effect: "NoSchedule"
              - key: "kubernetes.io/arch"
                operator: "Equal"
                value: "amd64"
                effect: "NoSchedule"
            mainContainer:
              image: nvcr.io/nvidia/ai-dynamo/sglang-runtime:1.5.0
              resources:
                claims:
                  - name: rdma
              startupProbe:
                httpGet:
                  path: /live
                  port: system
                initialDelaySeconds: 120
                periodSeconds: 30
                timeoutSeconds: 10
                failureThreshold: 120
              command: ["/bin/bash", "-c"]
              args:
                - |
                  set -ex
                  if [ -f /usr/local/gib/scripts/set_nccl_env.sh ]; then
                    . /usr/local/gib/scripts/set_nccl_env.sh
                  fi
    
                  # Pre-download with huggingface_hub, which backs off on HTTP 429s. Dynamo's built-in
                  # downloader (ModelExpress) aborts on the first 429 and skips fetching if weights are cached.
                  echo "=== [Dynamo Prefill Worker] Ensuring weights are cached in ${HF_HOME:-/data} ==="
                  python3 -c "import os; from huggingface_hub import snapshot_download; snapshot_download(os.environ['MODEL_PATH'], max_workers=16)"
                  # --host 0.0.0.0 is required so MooncakeKVBootstrapServer binds to 0.0.0.0:30001 instead of 127.0.0.1:30001.
                  echo "=== [Dynamo Prefill Worker] Launching dynamo.sglang ==="
                  exec python3 -m dynamo.sglang \
                    --model-path "${MODEL_PATH}" \
                    --host 0.0.0.0 \
                    --disaggregation-mode prefill \
                    --disaggregation-bootstrap-port 30001 \
                    --tensor-parallel-size 8 \
                    --kv-cache-dtype fp8_e4m3 \
                    --context-length 16384 \
                    --mem-fraction-static 0.85 \
                    --enable-metrics
              volumeMounts:
                - name: library-dir-host
                  mountPath: /usr/local/nvidia
                - name: gib
                  mountPath: /usr/local/gib
                - name: data-volume
                  mountPath: /data
            volumes:
              - name: library-dir-host
                hostPath:
                  path: /home/kubernetes/bin/nvidia
              - name: gib
                hostPath:
                  path: /home/kubernetes/bin/gib
              - name: data-volume
                emptyDir: {}
    
        # --------------------------------------------------------------------------
        # DECODE WORKER: 1 x GPU A4 (`a4-highgpu-8g`, 8 x B200 GPUs, TP=8)
        # --------------------------------------------------------------------------
        Decode:
          componentType: worker
          subComponentType: decode
          replicas: 1
          livenessProbe:
            httpGet:
              path: /live
              port: system
            initialDelaySeconds: 600
            periodSeconds: 60
            timeoutSeconds: 30
            failureThreshold: 60
          readinessProbe:
            httpGet:
              path: /health
              port: system
            initialDelaySeconds: 120
            periodSeconds: 30
            timeoutSeconds: 30
            failureThreshold: 60
          sharedMemory:
            size: 128Gi
          resources:
            requests:
              gpu: "8"
              cpu: "128"
              memory: "1500Gi"
            limits:
              gpu: "8"
              cpu: "128"
              memory: "2000Gi"
          envs:
            - name: MODEL_PATH
              value: "nvidia/Llama-3.1-405B-Instruct-FP8"
            - name: HF_HOME
              value: "/data"
            - name: HF_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
                  optional: true
            - name: DYN_SYSTEM_ENABLED
              value: "true"
            - name: DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS
              value: "[\"generate\"]"
            - name: DYN_SYSTEM_PORT
              value: "9090"
            - name: LD_LIBRARY_PATH
              value: "/usr/local/gib/lib64:/usr/local/nvidia/lib64"
            - name: GLOO_SOCKET_IFNAME
              value: "eth0"
            - name: WITH_NVIDIA_PEERMEM
              value: "0"
            # Xet CAS downloads returned unretried 429s; plain HTTP downloads back off on 429.
            - name: HF_HUB_DISABLE_XET
              value: "1"
          extraPodSpec:
            resourceClaims:
              - name: rdma
                resourceClaimTemplateName: all-mrdma
            nodeSelector:
              cloud.google.com/gke-accelerator: nvidia-b200
              cloud.google.com/gke-gpu: "true"
              kubernetes.io/arch: amd64
            tolerations:
              - key: "nvidia.com/gpu"
                operator: "Exists"
                effect: "NoSchedule"
              - key: "kubernetes.io/arch"
                operator: "Equal"
                value: "amd64"
                effect: "NoSchedule"
            mainContainer:
              image: nvcr.io/nvidia/ai-dynamo/sglang-runtime:1.5.0
              resources:
                claims:
                  - name: rdma
              startupProbe:
                httpGet:
                  path: /live
                  port: system
                initialDelaySeconds: 120
                periodSeconds: 30
                timeoutSeconds: 10
                failureThreshold: 120
              command: ["/bin/bash", "-c"]
              args:
                - |
                  set -ex
                  if [ -f /usr/local/gib/scripts/set_nccl_env.sh ]; then
                    . /usr/local/gib/scripts/set_nccl_env.sh
                  fi
    
                  # Pre-download with huggingface_hub, which backs off on HTTP 429s. Dynamo's built-in
                  # downloader (ModelExpress) aborts on the first 429 and skips fetching if weights are cached.
                  echo "=== [Dynamo Decode Worker] Ensuring weights are cached in ${HF_HOME:-/data} ==="
                  python3 -c "import os; from huggingface_hub import snapshot_download; snapshot_download(os.environ['MODEL_PATH'], max_workers=16)"
                  echo "=== [Dynamo Decode Worker] Launching dynamo.sglang ==="
                  exec python3 -m dynamo.sglang \
                    --model-path "${MODEL_PATH}" \
                    --host 0.0.0.0 \
                    --disaggregation-mode decode \
                    --disaggregation-bootstrap-port 30001 \
                    --tensor-parallel-size 8 \
                    --kv-cache-dtype fp8_e4m3 \
                    --context-length 16384 \
                    --mem-fraction-static 0.85 \
                    --enable-metrics
              volumeMounts:
                - name: library-dir-host
                  mountPath: /usr/local/nvidia
                - name: gib
                  mountPath: /usr/local/gib
                - name: data-volume
                  mountPath: /data
            volumes:
              - name: library-dir-host
                hostPath:
                  path: /home/kubernetes/bin/nvidia
              - name: gib
                hostPath:
                  path: /home/kubernetes/bin/gib
              - name: data-volume
                emptyDir: {}
  2. Aplique o manifesto da carga de trabalho ao cluster:

    kubectl apply -f llama3.1-405b-singlehost-a4.yaml
  3. Para monitorar o download de pesos e a inicialização do servidor, liste os pods no cluster e transmita os registros dos pods de preenchimento prévio e decodificação:

    kubectl get pods
    POD_NAME="YOUR_POD_NAME"
    kubectl logs -f "${POD_NAME}"

    Substitua YOUR_POD_NAME pelo nome do pod de pré-preenchimento ou de decodificação da saída kubectl get pods.

    Na primeira execução, leva de 10 a 20 minutos para baixar os pesos do modelo 405B FP8 e inicializar os servidores SGLang. Antes de enviar solicitações, aguarde até que os pods de front-end, preenchimento prévio e decodificação mostrem 1/1 na coluna READY de kubectl get pods:

    NAME                                        READY   STATUS    RESTARTS   AGE
    llama3-405b-a4-disagg-0-decode-tgl7q        1/1     Running   0          15m
    llama3-405b-a4-disagg-0-frontend-wrxq5      1/1     Running   0          15m
    llama3-405b-a4-disagg-0-prefill-67h5s       1/1     Running   0          15m
    

Enviar solicitações de inferência

Envie uma solicitação de preenchimento de chat para o serviço Llama 3.1 405B implantado:

  1. Encaminhe a porta local 8000 para o serviço llama3-405b-a4-disagg-frontend:

    kubectl port-forward svc/llama3-405b-a4-disagg-frontend 8000:8000

    Deixe o encaminhamento de portas em execução nesta sessão do terminal ou execute o comando em segundo plano.

  2. Em uma segunda sessão de terminal, envie uma solicitação de conclusão de chat para o endpoint /v1/chat/completions:

    curl http://127.0.0.1:8000/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "nvidia/Llama-3.1-405B-Instruct-FP8",
        "messages": [{"role": "user", "content": "Explain KV-cache disaggregation in one sentence."}],
        "max_tokens": 64
      }' | jq .

Executar uma carga de trabalho de comparativo de mercado

Faça um comparativo do servidor Llama 3.1 405B implantado no pod de front-end do Dynamo usando sglang.bench_serving. Configure o comparativo de mercado para 1.024 tokens de entrada, 1.024 tokens de saída (1k/1k), 2.048 comandos e uma simultaneidade máxima de 512:

ROUTER_POD=$(kubectl get pod -l 'nvidia.com/dynamo-component-type=frontend' -o jsonpath='{.items[0].metadata.name}')

kubectl exec "${ROUTER_POD}" -- python3 -m sglang.bench_serving \
  --backend sglang-oai-chat \
  --base-url http://localhost:8000 \
  --model nvidia/Llama-3.1-405B-Instruct-FP8 \
  --dataset-name random \
  --random-input-len 1024 \
  --random-output-len 1024 \
  --random-range-ratio 1.0 \
  --num-prompts 2048 \
  --max-concurrency 512 \
  --warmup-requests 10 | tee benchmark.log

Depois que o comparativo de mercado for concluído, procure uma saída que contenha métricas como as seguintes:

  • Output token throughput
  • Total token throughput
  • TTFT
  • TPOT

Limpar

Para evitar cobranças contínuas adicionais na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua as cargas de trabalho do Kubernetes, o cluster do GKE e o bucket do Cloud Storage:

  1. Exclua os recursos DynamoGraphDeployment e ResourceClaimTemplate:

    kubectl delete -f llama3.1-405b-singlehost-a4.yaml --ignore-not-found || true
  2. Desinstale as versões do Helm da plataforma NVIDIA Dynamo e do KAI Scheduler:

    helm uninstall dynamo-platform kai-scheduler || true
  3. Exclua o Secret do Kubernetes do Hugging Face:

    kubectl delete secret hf-secret --ignore-not-found || true
  4. No diretório cluster-toolkit, destrua o cluster do GKE e a infraestrutura associada usando o comando gcluster destroy:

    cd cluster-toolkit
    ./gcluster destroy "${CLUSTER_NAME}" --auto-approve || true
    cd ..
  5. Para excluir o bucket do Cloud Storage que armazena o estado do Terraform, use o comando gcloud storage rm:

    gcloud storage rm --recursive "gs://${GCS_BUCKET}"

A seguir