Menyajikan Llama 3.1 405B di GKE dengan disaggregasi PD menggunakan Dynamo dan SGLang di VM A4

Tutorial ini menunjukkan cara men-deploy dan menyajikan Llama 3.1 405B (nvidia/Llama-3.1-405B-Instruct-FP8), model yang disesuaikan dengan petunjuk dan memiliki 405 miliar parameter yang dikuantisasi ke FP8, di Google Kubernetes Engine (GKE) di Google Cloud. Deployment ini menggunakan Cluster Toolkit, dua instance virtual machine (VM) A4 (a4-highgpu-8g) dengan total 16 GPU NVIDIA B200, NVIDIA Dynamo, dan framework inferensi SGLang dengan disagregasi prefill-decode (PD) host tunggal.

Dalam konfigurasi deployment yang dijelaskan dalam tutorial ini, Anda akan menggunakan Cluster Toolkit untuk menyediakan cluster GKE dalam mode Standard. Cluster ini berisi dua node a4-highgpu-8g yang terhubung melalui jaringan GPUDirect Remote Direct Memory Access (RDMA). Kemudian, Anda akan menginstal platform KAI Scheduler dan NVIDIA Dynamo dengan penjadwalan gang Grove. Terakhir, Anda men-deploy resource kustom DynamoGraphDeployment yang memisahkan prefill dan decode di dua worker delapan GPU host tunggal dengan paralelisme tensor dan cache KV FP8.

Tujuan

  • Instal Cluster Toolkit dan sediakan cluster GKE A4 dua node dalam mode Standard.
  • Instal platform KAI Scheduler dan NVIDIA Dynamo dengan penjadwalan gang Grove di cluster Anda.
  • Men-deploy server inferensi SGLang yang dipisahkan PD dengan satu worker prefill A4 host tunggal dan satu worker dekode A4 host tunggal.
  • Mengirim permintaan penyelesaian chat ke router frontend Dynamo.
  • Menjalankan workload benchmark inferensi.
  • Bersihkan resource yang di-deploy.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponenGoogle Cloudyang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga.

Sebelum memulai

Siapkan lingkungan Anda untuk tutorial:

  1. Instal dan lakukan inisialisasi Google Cloud CLI, serta instal kubectl dan Helm (versi 3.10 atau yang lebih baru). Jika Anda menggunakan Cloud Shell, alat ini sudah diinstal sebelumnya.
  2. Jika Anda menjalankan tutorial ini dari workstation Linux atau macOS, bukan Cloud Shell, instal dependensi Cluster Toolkit yang diperlukan, seperti Terraform dan Git.
  3. Aktifkan Kubernetes Engine API, Compute Engine API, Cloud Storage API, Identity and Access Management API, Cloud Resource Manager API, dan Service Usage API di project Google Cloud Anda:

    Aktifkan API

Mendapatkan token akses Hugging Face

Anda memerlukan token akses Hugging Face untuk menggunakan tutorial ini. Anda dapat mendaftar untuk mendapatkan akun gratis di Hugging Face. Setelah Anda memiliki akun, buat token akses:

  1. Di halaman Welcome to Hugging Face, klik avatar akun Anda, lalu pilih Token akses.
  2. Di halaman Token akses, klik Create new token.
  3. Pilih jenis token Read dan masukkan nama untuk token Anda.
  4. Token akses Anda akan ditampilkan. Simpan token di tempat yang aman.

Peran yang diperlukan

Untuk mendapatkan izin yang Anda perlukan untuk menyelesaikan tutorial ini, minta administrator untuk memberi Anda peran IAM berikut di project Anda:

Untuk mengetahui informasi selengkapnya tentang pemberian peran, lihat Mengelola akses ke project, folder, dan organisasi.

Anda mungkin juga bisa mendapatkan izin yang diperlukan melalui peran khusus atau peran bawaan lainnya.

Menyiapkan variabel lingkungan Anda

Ekspor variabel lingkungan yang Anda gunakan di sepanjang tutorial ini:

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

Ganti kode berikut:

  • YOUR_PROJECT_ID: ID project Google Cloud Anda.
  • YOUR_REGION: region tempat kapasitas A4 Anda berada dan tempat Anda ingin men-deploy cluster, seperti us-central1.
  • YOUR_ZONE: zona tempat kapasitas A4 Anda berada, seperti us-central1-b.
  • YOUR_CLUSTER_NAME: nama untuk cluster GKE dan deployment Cluster Toolkit Anda. Gunakan nama yang terdiri dari 20 karakter atau kurang agar ID akun layanan node pool yang dihasilkan (YOUR_CLUSTER_NAME-gke-np-sa) tetap berada dalam batas 30 karakter Identity and Access Management (IAM).
  • YOUR_RESERVATION_NAME: nama pemesanan A4 Anda.
  • YOUR_BUCKET_NAME: nama unik global untuk bucket Cloud Storage yang menyimpan status Terraform untuk Cluster Toolkit.
  • YOUR_HF_TOKEN: token akses Hugging Face Anda.

Membuat cluster GKE

Download Cluster Toolkit dan sediakan cluster GKE dalam mode Standard dengan dua node a4-highgpu-8g, jaringan GPUDirect RDMA, dan dukungan DRA:

  1. Login ke Google Cloud CLI dan buat Kredensial Default Aplikasi untuk Terraform:

    gcloud auth login
    gcloud auth application-default login
  2. Download dan ekstrak paket Cluster Toolkit bawaan untuk versi yang ditentukan dalam 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

    Jika Anda menjalankan perintah ini di macOS atau di workstation arm64, tetapkan OS="mac" atau ARCH="arm64" agar sesuai dengan platform Anda.

  3. Untuk menyimpan status Terraform untuk deployment Cluster Toolkit Anda, buat bucket Cloud Storage dengan pembuatan versi objek diaktifkan:

    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. Buat file konfigurasi deployment cluster-toolkit/examples/gke-a4/gke-a4-deployment.yaml untuk dua node 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

    Secara default, file deployment dikonfigurasi untuk menggunakan pemesanan tertentu. Jika Anda tidak memiliki pemesanan khusus, sebelum men-deploy cluster, Anda dapat memperbarui cluster-toolkit/examples/gke-a4/gke-a4-deployment.yaml untuk menggunakan opsi konsumsi alternatif, seperti Spot VM atau Flex-start VM. Untuk petunjuk konfigurasi, lihat Opsi pemakaian GKE.

  5. Ubah ke direktori cluster-toolkit, deploy cluster GKE menggunakan perintah gcluster deploy, lalu kembali ke direktori kerja Anda:

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

    Pembuatan cluster memerlukan waktu sekitar 20 hingga 30 menit. Jika Anda menjalankan ./gcluster deploy tanpa flag --auto-approve, untuk menerapkan perubahan yang diusulkan, masukkan a saat diminta.

  6. Konfigurasi kredensial kubectl untuk berkomunikasi dengan cluster Anda:

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

Menginstal KAI Scheduler dan NVIDIA Dynamo

Siapkan cluster Anda dengan membuat Secret Hugging Face dan menginstal KAI Scheduler dan platform NVIDIA Dynamo dengan penjadwalan gang Grove:

  1. Buat Secret Kubernetes bernama hf-secret untuk menyimpan token akses Hugging Face Anda:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token="${HF_TOKEN}" \
        --dry-run=client -o yaml | kubectl apply -f -
  2. Download diagram Helm platform NVIDIA Dynamo (v1.5.0), instal KAI Scheduler, dan instal platform Dynamo dengan Grove diaktifkan:

    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

Men-deploy server SGLang yang dipisahkan dengan satu host

Manifes workload (llama3.1-405b-singlehost-a4.yaml) menentukan ResourceClaimTemplate Kubernetes (all-mrdma), yang mengalokasikan perangkat RDMA multi-NIC node (mrdma.google.com) melalui DRA, dan DynamoGraphDeployment NVIDIA Dynamo (llama3-405b-a4-disagg) dengan penjadwalan gang Grove diaktifkan. Deployment terdiri dari hal berikut:

  • Frontend (Frontend): menjalankan satu replika router yang menerima permintaan klien, menemukan worker prefill dan dekode yang terdaftar, serta mengoordinasikan pemilihan rute permintaan yang dipisahkan.
  • Worker prefill (Prefill): menjalankan worker host tunggal pada satu node a4-highgpu-8g dengan delapan GPU NVIDIA B200. Saat memulai, Pod mengambil lingkungan NCCL/gIB, mendownload checkpoint nvidia/Llama-3.1-405B-Instruct-FP8 dari Hugging Face Hub ke SSD NVMe Lokal node, dan meluncurkan python3 -m dynamo.sglang di --disaggregation-mode prefill dengan flag berikut:
    • --tensor-parallel-size 8
    • --kv-cache-dtype fp8_e4m3
    • --context-length 16384
    • --mem-fraction-static 0.85
  • Decode worker (Decode): menjalankan worker host tunggal pada node a4-highgpu-8g kedua dengan delapan GPU NVIDIA B200. Saat startup, Pod meng-cache bobot model di SSD NVMe Lokal node dan meluncurkan python3 -m dynamo.sglang di --disaggregation-mode decode dengan flag berikut:
    • --tensor-parallel-size 8
    • --kv-cache-dtype fp8_e4m3
    • --context-length 16384
    • --mem-fraction-static 0.85

Deploy dan pantau server inferensi yang dipisahkan:

  1. Download manifes workload 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

    Atau, buat file bernama llama3.1-405b-singlehost-a4.yaml dengan konten berikut:

    # ==============================================================================
    # 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. Terapkan manifes workload ke cluster Anda:

    kubectl apply -f llama3.1-405b-singlehost-a4.yaml
  3. Untuk memantau download bobot dan inisialisasi server, buat daftar Pod di cluster Anda, dan streaming log Pod prefill dan decode:

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

    Ganti YOUR_POD_NAME dengan nama Pod prefill atau Pod dekode dari output kubectl get pods.

    Pada operasi pertama, perlu waktu sekitar 10 hingga 20 menit untuk mendownload bobot model 405B FP8 dan menginisialisasi server SGLang. Sebelum Anda mengirim permintaan apa pun, tunggu hingga Pod frontend, prefill, dan decode menampilkan 1/1 di kolom READY dari 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
    

Mengirim permintaan inferensi

Kirim permintaan penyelesaian chat ke layanan Llama 3.1 405B yang di-deploy:

  1. Teruskan port lokal 8000 ke layanan llama3-405b-a4-disagg-frontend:

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

    Biarkan penerusan port berjalan di sesi terminal ini, atau jalankan perintah di latar belakang.

  2. Di sesi terminal kedua, kirim permintaan penyelesaian chat ke 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 .

Menjalankan workload benchmark

Lakukan tolok ukur server Llama 3.1 405B yang di-deploy dari Pod frontend Dynamo menggunakan sglang.bench_serving. Konfigurasikan benchmark untuk 1.024 token input, 1.024 token output (1k/1k), 2.048 perintah, dan konkurensi maksimum 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

Setelah benchmark selesai, cari output yang berisi metrik seperti berikut:

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

Pembersihan

Agar tidak menimbulkan biaya berkelanjutan tambahan pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus workload Kubernetes, cluster GKE, dan bucket Cloud Storage Anda:

  1. Hapus resource DynamoGraphDeployment dan ResourceClaimTemplate:

    kubectl delete -f llama3.1-405b-singlehost-a4.yaml --ignore-not-found || true
  2. Uninstal rilis Helm platform NVIDIA Dynamo dan KAI Scheduler:

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

    kubectl delete secret hf-secret --ignore-not-found || true
  4. Dari direktori cluster-toolkit, hancurkan cluster GKE dan infrastruktur terkaitnya menggunakan perintah gcluster destroy:

    cd cluster-toolkit
    ./gcluster destroy "${CLUSTER_NAME}" --auto-approve || true
    cd ..
  5. Untuk menghapus bucket Cloud Storage yang menyimpan status Terraform, gunakan perintah gcloud storage rm:

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

Langkah berikutnya