Menyajikan LLM seperti DeepSeek-R1 671B atau Llama 3.1 405B di GKE


Ringkasan

Panduan ini menunjukkan cara menayangkan model bahasa besar (LLM) terbaru seperti DeepSeek-R1 671B atau Llama 3.1 405B di Google Kubernetes Engine (GKE) menggunakan unit pemrosesan grafis (GPU) di beberapa node.

Panduan ini menunjukkan cara menggunakan teknologi open source portabel—Kubernetes, vLLM, dan LeaderWorkerSet (LWS) API— untuk men-deploy dan menayangkan workload AI/ML di GKE, dengan memanfaatkan kontrol terperinci, skalabilitas, ketahanan, portabilitas, dan efektivitas biaya GKE.

Sebelum membaca halaman ini, pastikan Anda memahami hal-hal berikut:

Latar belakang

Bagian ini menjelaskan teknologi utama yang digunakan dalam panduan ini, termasuk dua LLM yang digunakan sebagai contoh dalam panduan ini—DeepSeek-R1 dan Llama 3.1 405B.

DeepSeek-R1

DeepSeek-R1, model bahasa besar dengan parameter 671 miliar dari DeepSeek, dirancang untuk inferensi logis, penalaran matematika, dan pemecahan masalah real-time dalam berbagai tugas berbasis teks. GKE menangani permintaan komputasi DeepSeek-R1, yang mendukung kemampuannya dengan resource yang skalabel, komputasi terdistribusi, dan jaringan yang efisien.

Untuk mempelajari lebih lanjut, lihat dokumentasi DeepSeek.

Llama 3.1 405B

Llama 3.1 405B adalah model bahasa besar dari Meta yang dirancang untuk berbagai tugas natural language processing, termasuk pembuatan teks, terjemahan, dan menjawab pertanyaan. GKE menawarkan infrastruktur andal yang diperlukan untuk mendukung kebutuhan pelatihan dan penayangan terdistribusi model dalam skala ini.

Untuk mempelajari lebih lanjut, lihat dokumentasi Llama.

Layanan Kubernetes terkelola GKE

Google Cloud menawarkan berbagai layanan, termasuk GKE, yang sangat cocok untuk men-deploy dan mengelola workload AI/ML. GKE adalah layanan Kubernetes terkelola yang menyederhanakan deployment, penskalaan, dan pengelolaan aplikasi dalam container. GKE menyediakan infrastruktur yang diperlukan, termasuk resource yang skalabel, komputasi terdistribusi, dan jaringan yang efisien, untuk menangani permintaan komputasi LLM.

Untuk mempelajari konsep utama Kubernetes lebih lanjut, lihat Mulai mempelajari Kubernetes. Untuk mempelajari GKE lebih lanjut dan cara GKE membantu Anda menskalakan, mengotomatiskan, dan mengelola Kubernetes, lihat ringkasan GKE.

GPU

Unit pemrosesan grafis (GPU) memungkinkan Anda mempercepat beban kerja tertentu seperti machine learning dan pemrosesan data. GKE menawarkan node yang dilengkapi dengan GPU yang canggih ini, sehingga Anda dapat mengonfigurasi cluster untuk performa yang optimal dalam tugas machine learning dan pemrosesan data. GKE menyediakan berbagai opsi jenis mesin untuk konfigurasi node, termasuk jenis mesin dengan GPU NVIDIA H100, L4, dan A100.

Untuk mempelajari lebih lanjut, lihat Tentang GPU di GKE.

LeaderWorkerSet (LWS)

LeaderWorkerSet (LWS) adalah API deployment Kubernetes yang menangani pola deployment umum beban kerja inferensi multi-node AI/ML. Penayangan multi-node memanfaatkan beberapa Pod, yang masing-masing berpotensi berjalan di node yang berbeda, untuk menangani workload inferensi terdistribusi. LWS memungkinkan perlakuan beberapa Pod sebagai grup, yang menyederhanakan pengelolaan penayangan model terdistribusi.

vLLM dan penayangan multi-host

Saat menayangkan LLM yang intensif komputasi, sebaiknya gunakan vLLM dan jalankan workload di seluruh GPU.

vLLM adalah framework penayangan LLM open source yang dioptimalkan secara maksimal dan dapat meningkatkan throughput penayangan di GPU, dengan fitur seperti berikut:

  • Penerapan transformer yang dioptimalkan dengan PagedAttention
  • Pengelompokan berkelanjutan untuk meningkatkan throughput penayangan secara keseluruhan
  • Penyertaan terdistribusi di beberapa GPU

Dengan LLM yang sangat intensif komputasinya dan tidak dapat muat dalam satu node GPU, Anda dapat menggunakan beberapa node GPU untuk menayangkan model. vLLM mendukung workload yang berjalan di seluruh GPU dengan dua strategi:

  • Paralelisme tensor membagi perkalian matriks di lapisan transformer di beberapa GPU. Namun, strategi ini memerlukan jaringan yang cepat karena komunikasi yang diperlukan antar-GPU, sehingga kurang cocok untuk menjalankan workload di seluruh node.

  • Paralelisme pipeline membagi model menurut lapisan, atau secara vertikal. Strategi ini tidak memerlukan komunikasi yang konstan antar-GPU, sehingga menjadi opsi yang lebih baik saat menjalankan model di seluruh node.

Anda dapat menggunakan kedua strategi tersebut dalam penayangan multi-node. Misalnya, saat menggunakan dua node dengan masing-masing delapan GPU H100, Anda dapat menggunakan kedua strategi tersebut:

  • Paralelisme pipeline dua arah untuk membuat shard model di kedua node
  • Paralelisme tensor delapan arah untuk membuat shard model di delapan GPU di setiap node

Untuk mempelajari lebih lanjut, lihat dokumentasi vLLM.

Tujuan

  1. Siapkan lingkungan Anda dengan cluster GKE dalam mode Autopilot atau Standard.
  2. Deploy vLLM di beberapa node di cluster Anda.
  3. Gunakan vLLM untuk menayangkan model melalui curl.

Sebelum memulai

  • Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

  • Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin, roles/iam.securityAdmin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Buka IAM
    2. Pilih project.
    3. Klik Berikan akses.
    4. Di kolom New principals, masukkan ID pengguna Anda. Ini biasanya adalah alamat email untuk Akun Google.

    5. Di daftar Pilih peran, pilih peran.
    6. Untuk memberikan peran tambahan, klik Tambahkan peran lain, lalu tambahkan setiap peran tambahan.
    7. Klik Simpan.
  • Buat akun Hugging Face, jika Anda belum memilikinya.
  • Pastikan project Anda memiliki kuota yang memadai untuk GPU H100. Untuk mempelajari lebih lanjut, lihat Tentang GPU dan Kuota alokasi.

Mendapatkan akses ke model

Anda dapat menggunakan model Llama 3.1 405B atau DeepSeek-R1.

DeepSeek-R1

Membuat token akses

Jika Anda belum memilikinya, buat token Hugging Face baru:

  1. Klik Profil Anda > Setelan > Token Akses.
  2. Pilih New Token.
  3. Tentukan Nama pilihan Anda dan Peran minimal Read.
  4. Pilih Buat token.

Llama 3.1 405B

Membuat token akses

Jika Anda belum memilikinya, buat token Hugging Face baru:

  1. Klik Profil Anda > Setelan > Token Akses.
  2. Pilih New Token.
  3. Tentukan Nama pilihan Anda dan Peran minimal Read.
  4. Pilih Buat token.

Menyiapkan lingkungan

Dalam tutorial ini, Anda akan menggunakan Cloud Shell untuk mengelola resource yang dihosting diGoogle Cloud. Cloud Shell telah diinstal dengan software yang akan Anda perlukan untuk tutorial ini, termasuk kubectl dan gcloud CLI.

Untuk menyiapkan lingkungan Anda dengan Cloud Shell, ikuti langkah-langkah berikut:

  1. Di konsol Google Cloud, luncurkan sesi Cloud Shell dengan mengklik Ikon aktivasi Cloud Shell Aktifkan Cloud Shell di konsol Google Cloud. Tindakan ini akan meluncurkan sesi di panel bawah Konsol Google Cloud.

  2. Tetapkan variabel lingkungan default:

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export CLUSTER_NAME=CLUSTER_NAME
    export ZONE=ZONE
    export HF_TOKEN=HUGGING_FACE_TOKEN
    export IMAGE_NAME=REGION_NAME-docker.pkg.dev/PROJECT_ID/vllm-multihost/vllm-multihost:latest
    

    Ganti nilai berikut:

    • PROJECT_ID: Google Cloud project ID Anda.
    • CLUSTER_NAME: nama cluster GKE Anda.
    • ZONE: zona yang mendukung GPU NVIDIA H100 Tensor Core.
    • IMAGE_NAME: image vLLM yang menyertakan skrip Ray.

Membuat cluster GKE

Anda dapat menayangkan model menggunakan vLLM di beberapa node GPU dalam cluster GKE Autopilot atau Standard. Sebaiknya gunakan cluster Autopilot untuk pengalaman Kubernetes yang dikelola sepenuhnya. Untuk memilih mode operasi GKE yang paling sesuai untuk workload Anda, lihat Memilih mode operasi GKE.

Autopilot

Jalankan perintah berikut di Cloud Shell:

  gcloud container clusters create-auto ${CLUSTER_NAME} \
    --project=${PROJECT_ID} \
    --region=${REGION} \
    --cluster-version=${CLUSTER_VERSION}

Standar

  1. Buat cluster GKE Standard dengan dua node CPU:

    gcloud container clusters create CLUSTER_NAME \
        --project=PROJECT_ID \
        --num-nodes=2 \
        --location=ZONE \
        --machine-type=e2-standard-16
    
  2. Buat node pool A3 dengan dua node, masing-masing dengan delapan H100:

    gcloud container node-pools create gpu-nodepool \
        --location=ZONE \
        --num-nodes=2 \
        --machine-type=a3-highgpu-8g \
        --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \
        --placement-type=COMPACT \
        --cluster=CLUSTER_NAME
    

Mengonfigurasi kubectl untuk berkomunikasi dengan cluster Anda

Konfigurasi kubectl untuk berkomunikasi dengan cluster Anda dengan perintah berikut:

gcloud container clusters get-credentials CLUSTER_NAME --location=ZONE

Membuat Secret Kubernetes untuk kredensial Hugging Face

Buat Secret Kubernetes yang berisi token Hugging Face menggunakan perintah berikut:

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

Membuat image multi-node vLLM Anda sendiri

Untuk memfasilitasi komunikasi lintas node untuk vLLM, Anda dapat menggunakan Ray. Repositori LeaderWorkerSet menyediakan Dockerfile, yang menyertakan skrip bash untuk mengonfigurasi Ray dengan vLLM.

Untuk membuat image multi-node vLLM Anda sendiri, Anda perlu meng-clone repositori LeaderWorkerSet, mem-build image Docker menggunakan Dockerfile yang disediakan (yang mengonfigurasi Ray untuk komunikasi lintas node), lalu mengirim image tersebut ke Artifact Registry untuk deployment di GKE.

Buat container

Untuk mem-build penampung, ikuti langkah-langkah berikut:

  1. Buat clone repositori LeaderWorkerSet:

    git clone https://github.com/kubernetes-sigs/lws.git
    
  2. Membangun image

    cd lws/docs/examples/vllm/build/ && docker build -f Dockerfile.GPU . -t vllm-multihost
    

Mengirim image ke Artifact Registry

Untuk memastikan deployment Kubernetes Anda dapat mengakses image, simpan di Artifact Registry dalam Google Cloud project Anda.

gcloud artifacts repositories create vllm-multihost --repository-format=docker --location=REGION_NAME && \
gcloud auth configure-docker REGION_NAME-docker.pkg.dev && \
docker image tag vllm-multihost REGION_NAME-docker.pkg.dev/PROJECT_ID/vllm-multihost/vllm-multihost:latest && \
docker push REGION_NAME-docker.pkg.dev/PROJECT_ID/vllm-multihost/vllm-multihost:latest

Menginstal LeaderWorkerSet

Untuk menginstal LWS, jalankan perintah berikut:

kubectl apply --server-side -f https://github.com/kubernetes-sigs/lws/releases/latest/download/manifests.yaml

Validasi bahwa pengontrol LeaderWorkerSet berjalan di namespace lws-system, menggunakan perintah berikut:

kubectl get pod -n lws-system

Outputnya mirip dengan hal berikut ini:

NAME                                      READY   STATUS    RESTARTS   AGE
lws-controller-manager-5c4ff67cbd-9jsfc   2/2     Running   0          6d23h

Men-deploy Server Model vLLM

Untuk men-deploy server model vLLM, ikuti langkah-langkah berikut:

  1. Terapkan manifes, bergantung pada LLM yang ingin Anda deploy.

    DeepSeek-R1

    1. Periksa manifes vllm-deepseek-r1-A3.yaml.

      
      apiVersion: leaderworkerset.x-k8s.io/v1
      kind: LeaderWorkerSet
      metadata:
        name: vllm
      spec:
        replicas: 1
        leaderWorkerTemplate:
          size: 2
          restartPolicy: RecreateGroupOnPodRestart
          leaderTemplate:
            metadata:
              labels:
                role: leader
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-leader
                  image: IMAGE_NAME
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  command:
                    - sh
                    - -c
                    - "/vllm-workspace/ray_init.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE); 
                      python3 -m vllm.entrypoints.openai.api_server --port 8080 --model deepseek-ai/DeepSeek-R1 --tensor-parallel-size 8 --pipeline-parallel-size 2 --trust-remote-code --max-model-len 4096"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  ports:
                    - containerPort: 8080
                  readinessProbe:
                    tcpSocket:
                      port: 8080
                    initialDelaySeconds: 15
                    periodSeconds: 10
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
          workerTemplate:
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-worker
                  image: IMAGE_NAME
                  command:
                    - sh
                    - -c
                    - "/vllm-workspace/ray_init.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  env:
                    - 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
                  sizeLimit: 15Gi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: vllm-leader
      spec:
        ports:
          - name: http
            port: 8080
            protocol: TCP
            targetPort: 8080
        selector:
          leaderworkerset.sigs.k8s.io/name: vllm
          role: leader
        type: ClusterIP
      
    2. Terapkan manifes dengan menjalankan perintah berikut:

      kubectl apply -f vllm-deepseek-r1-A3.yaml
      

    Llama 3.1 405B

    1. Periksa manifes vllm-llama3-405b-A3.yaml.

      
      apiVersion: leaderworkerset.x-k8s.io/v1
      kind: LeaderWorkerSet
      metadata:
        name: vllm
      spec:
        replicas: 1
        leaderWorkerTemplate:
          size: 2
          restartPolicy: RecreateGroupOnPodRestart
          leaderTemplate:
            metadata:
              labels:
                role: leader
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-leader
                  image: IMAGE_NAME
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  command:
                    - sh
                    - -c
                    - "/vllm-workspace/ray_init.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE); 
                      python3 -m vllm.entrypoints.openai.api_server --port 8080 --model meta-llama/Meta-Llama-3.1-405B-Instruct --tensor-parallel-size 8 --pipeline-parallel-size 2"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  ports:
                    - containerPort: 8080
                  readinessProbe:
                    tcpSocket:
                      port: 8080
                    initialDelaySeconds: 15
                    periodSeconds: 10
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
          workerTemplate:
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-worker
                  image: IMAGE_NAME
                  command:
                    - sh
                    - -c
                    - "/vllm-workspace/ray_init.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  env:
                    - 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
                  sizeLimit: 15Gi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: vllm-leader
      spec:
        ports:
          - name: http
            port: 8080
            protocol: TCP
            targetPort: 8080
        selector:
          leaderworkerset.sigs.k8s.io/name: vllm
          role: leader
        type: ClusterIP
      
    2. Terapkan manifes dengan menjalankan perintah berikut:

      kubectl apply -f vllm-llama3-405b-A3.yaml
      
  2. Lihat log dari server model yang sedang berjalan dengan perintah berikut:

    kubectl logs vllm-0 -c vllm-leader
    

    Output-nya akan terlihat seperti berikut:

    INFO 08-09 21:01:34 api_server.py:297] Route: /detokenize, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/models, Methods: GET
    INFO 08-09 21:01:34 api_server.py:297] Route: /version, Methods: GET
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/chat/completions, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/completions, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/embeddings, Methods: POST
    INFO:     Started server process [7428]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
    

Menayangkan model

Siapkan penerusan port ke model dengan menjalankan perintah berikut:

kubectl port-forward svc/vllm-leader 8080:8080

Berinteraksi dengan model menggunakan curl

Untuk berinteraksi dengan model menggunakan curl, ikuti petunjuk berikut:

DeepSeek-R1

Di terminal baru, kirim permintaan ke server:

curl http://localhost:8080/v1/completions \
-H "Content-Type: application/json" \
-d '{
    "model": "deepseek-ai/DeepSeek-R1",
    "prompt": "I have four boxes. I put the red box on the bottom and put the blue box on top. Then I put the yellow box on top the blue. Then I take the blue box out and put it on top. And finally I put the green box on the top. Give me the final order of the boxes from bottom to top. Show your reasoning but be brief",
    "max_tokens": 1024,
    "temperature": 0
}'

Outputnya akan mirip dengan berikut ini:

{
"id": "cmpl-f2222b5589d947419f59f6e9fe24c5bd",
"object": "text_completion",
"created": 1738269669,
"model": "deepseek-ai/DeepSeek-R1",
"choices": [
  {
    "index": 0,
    "text": ".\n\nOkay, let's see. The user has four boxes and is moving them around. Let me try to visualize each step. \n\nFirst, the red box is placed on the bottom. So the stack starts with red. Then the blue box is put on top of red. Now the order is red (bottom), blue. Next, the yellow box is added on top of blue. So now it's red, blue, yellow. \n\nThen the user takes the blue box out. Wait, blue is in the middle. If they remove blue, the stack would be red and yellow. But where do they put the blue box? The instruction says to put it on top. So after removing blue, the stack is red, yellow. Then blue is placed on top, making it red, yellow, blue. \n\nFinally, the green box is added on the top. So the final order should be red (bottom), yellow, blue, green. Let me double-check each step to make sure I didn't mix up any steps. Starting with red, then blue, then yellow. Remove blue from the middle, so yellow is now on top of red. Then place blue on top of that, so red, yellow, blue. Then green on top. Yes, that seems right. The key step is removing the blue box from the middle, which leaves yellow on red, then blue goes back on top, followed by green. So the final order from bottom to top is red, yellow, blue, green.\n\n**Final Answer**\nThe final order from bottom to top is \\boxed{red}, \\boxed{yellow}, \\boxed{blue}, \\boxed{green}.\n</think>\n\n1. Start with the red box at the bottom.\n2. Place the blue box on top of the red box. Order: red (bottom), blue.\n3. Place the yellow box on top of the blue box. Order: red, blue, yellow.\n4. Remove the blue box (from the middle) and place it on top. Order: red, yellow, blue.\n5. Place the green box on top. Final order: red, yellow, blue, green.\n\n\\boxed{red}, \\boxed{yellow}, \\boxed{blue}, \\boxed{green}",
    "logprobs": null,
    "finish_reason": "stop",
    "stop_reason": null,
    "prompt_logprobs": null
  }
],
"usage": {
  "prompt_tokens": 76,
  "total_tokens": 544,
  "completion_tokens": 468,
  "prompt_tokens_details": null
}
}

Llama 3.1 405B

Di terminal baru, kirim permintaan ke server:

curl http://localhost:8080/v1/completions \
-H "Content-Type: application/json" \
-d '{
    "model": "meta-llama/Meta-Llama-3.1-405B-Instruct",
    "prompt": "San Francisco is a",
    "max_tokens": 7,
    "temperature": 0
}'

Outputnya akan mirip dengan berikut ini:

{"id":"cmpl-0a2310f30ac3454aa7f2c5bb6a292e6c",
"object":"text_completion","created":1723238375,"model":"meta-llama/Meta-Llama-3.1-405B-Instruct","choices":[{"index":0,"text":" top destination for foodies, with","logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":5,"total_tokens":12,"completion_tokens":7}}

Menyiapkan autoscaler kustom

Di bagian ini, Anda akan menyiapkan penskalaan otomatis Pod horizontal untuk menggunakan metrik Prometheus kustom. Anda menggunakan metrik Google Cloud Managed Service for Prometheus dari server vLLM.

Untuk mempelajari lebih lanjut, lihat Google Cloud Managed Service for Prometheus. Fitur ini akan diaktifkan secara default di cluster GKE.

  1. Siapkan Adaptor Stackdriver Metrik Kustom di cluster Anda:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    
  2. Tambahkan peran Monitoring Viewer ke akun layanan yang digunakan Adaptor Stackdriver Metrik Kustom:

    gcloud projects add-iam-policy-binding projects/PROJECT_ID \
        --role roles/monitoring.viewer \
        --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    
  3. Simpan manifes berikut sebagai vllm_pod_monitor.yaml:

    
    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
     name: vllm-pod-monitoring
    spec:
     selector:
       matchLabels:
        leaderworkerset.sigs.k8s.io/name: vllm
        role: leader
     endpoints:
     - path: /metrics
       port: 8080
       interval: 15s
    
  4. Terapkan manifes ke cluster:

    kubectl apply -f vllm_pod_monitor.yaml
    

Membuat beban di endpoint vLLM

Buat beban di server vLLM untuk menguji cara GKE melakukan penskalaan otomatis dengan metrik vLLM kustom.

  1. Siapkan penerusan port ke model:

    kubectl port-forward svc/vllm-leader 8080:8080
    
  2. Jalankan skrip bash (load.sh) untuk mengirim N jumlah permintaan paralel ke endpoint vLLM:

    #!/bin/bash
    N=PARALLEL_PROCESSES
    export vllm_service=$(kubectl get service vllm-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    for i in $(seq 1 $N); do
      while true; do
        curl http://$vllm_service:8000/v1/completions -H "Content-Type: application/json" -d '{"model": "meta-llama/Meta-Llama-3.1-70B", "prompt": "Write a story about san francisco", "max_tokens": 100, "temperature": 0}'
      done &  # Run in the background
    done
    wait
    

    Ganti PARALLEL_PROCESSES dengan jumlah proses paralel yang ingin Anda jalankan.

  3. Jalankan skrip bash:

    nohup ./load.sh &
    

Memastikan bahwa Google Cloud Managed Service for Prometheus menyerap metrik

Setelah Google Cloud Managed Service for Prometheus mengambil metrik dan Anda menambahkan beban ke endpoint vLLM, Anda dapat melihat metrik di Cloud Monitoring.

  1. Di Konsol Google Cloud, buka halaman Metrics Explorer.

    Buka Metrics Explorer

  2. Klik < > PromQL.

  3. Masukkan kueri berikut untuk mengamati metrik traffic:

    vllm:gpu_cache_usage_perc{cluster='CLUSTER_NAME'}
    

Gambar berikut adalah contoh grafik setelah eksekusi skrip pemuatan. Grafik ini menunjukkan bahwa Google Cloud Managed Service for Prometheus menyerap metrik traffic sebagai respons terhadap beban yang ditambahkan ke endpoint vLLM:

Metrik traffic yang diambil untuk server vLLM

Men-deploy konfigurasi Horizontal Pod Autoscaler

Saat Anda memutuskan metrik mana yang akan diskalakan secara otomatis, sebaiknya gunakan metrik berikut untuk vLLM:

  • num_requests_waiting: metrik ini terkait dengan jumlah permintaan yang menunggu di antrean server model. Jumlah ini mulai meningkat secara signifikan saat cache kv penuh.

  • gpu_cache_usage_perc: metrik ini berkaitan dengan penggunaan cache KV, yang secara langsung berkorelasi dengan jumlah permintaan yang diproses untuk siklus inferensi tertentu di server model.

Sebaiknya gunakan num_requests_waiting saat Anda mengoptimalkan throughput dan biaya, dan saat target latensi dapat dicapai dengan throughput maksimum server model Anda.

Sebaiknya gunakan gpu_cache_usage_perc jika Anda memiliki workload yang sensitif terhadap latensi, dengan penskalaan berbasis antrean yang tidak cukup cepat untuk memenuhi persyaratan Anda.

Untuk penjelasan lebih lanjut, lihat Praktik terbaik untuk menskalakan otomatis workload inferensi model bahasa besar (LLM) dengan GPU.

Saat memilih target averageValue untuk konfigurasi HPA, Anda perlu menentukan metrik mana yang akan diskalakan secara otomatis secara eksperimental. Untuk mendapatkan ide tambahan tentang cara mengoptimalkan eksperimen, lihat postingan blog Hemat GPU: Penskalaan otomatis yang lebih cerdas untuk workload inferensi GKE Anda. Pembuat profil yang digunakan dalam postingan blog ini juga berfungsi untuk vLLM.

Untuk men-deploy konfigurasi Horizontal Pod Autoscaler menggunakan num_requests_waiting, ikuti langkah-langkah berikut:

  1. Simpan manifes berikut sebagai vllm-hpa.yaml:

    
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: lws-hpa
    spec:
      minReplicas: 1
      maxReplicas: 2
      metrics:
      - type: Pods
        pods:
          metric:
            name: prometheus.googleapis.com|vllm:num_requests_waiting|gauge
          target:
            type: AverageValue
            averageValue: 5
      scaleTargetRef:
        apiVersion: leaderworkerset.x-k8s.io/v1
        kind: LeaderWorkerSet
        name: vllm
    

    Metrik vLLM di Google Cloud Managed Service for Prometheus mengikuti format vllm:metric_name.

    Praktik terbaik:

    Gunakan num_requests_waiting untuk menskalakan throughput. Gunakan gpu_cache_usage_perc untuk kasus penggunaan GPU yang sensitif terhadap latensi.

  2. Deploy konfigurasi Horizontal Pod Autoscaler:

    kubectl apply -f vllm-hpa.yaml
    

    GKE menjadwalkan Pod lain untuk di-deploy, yang memicu autoscaler kumpulan node untuk menambahkan node kedua sebelum men-deploy replika vLLM kedua.

  3. Lihat progres penskalaan otomatis Pod:

    kubectl get hpa --watch
    

    Outputnya mirip dengan hal berikut ini:

    NAME      REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    lws-hpa   LeaderWorkerSet/vllm   0/1       1         2         1          6d1h
    lws-hpa   LeaderWorkerSet/vllm   1/1       1         2         1          6d1h
    lws-hpa   LeaderWorkerSet/vllm   0/1       1         2         1          6d1h
    lws-hpa   LeaderWorkerSet/vllm   4/1       1         2         1          6d1h
    lws-hpa   LeaderWorkerSet/vllm   0/1       1         2         2          6d1h
    

Mempercepat waktu pemuatan model dengan Hyperdisk ML

Dengan jenis LLM ini, vLLM dapat memerlukan waktu yang cukup lama untuk mendownload, memuat, dan melakukan pemanasan pada setiap replika baru. Misalnya, proses tersebut dapat memerlukan waktu sekitar 90 menit dengan Llama 3.1 405B. Anda dapat mengurangi waktu ini (menjadi 20 menit dengan Llama 3.1 405B) dengan mendownload model langsung ke volume ML Hyperdisk dan memasang volume tersebut ke setiap Pod. Untuk menyelesaikan operasi ini, tutorial ini menggunakan volume ML Hyperdisk dan Tugas Kubernetes. Pengontrol Tugas di Kubernetes membuat satu atau beberapa Pod dan memastikan bahwa Pod tersebut berhasil menjalankan tugas tertentu.

Untuk mempercepat waktu pemuatan model, lakukan langkah-langkah berikut:

  1. Simpan contoh manifes berikut sebagai producer-pvc.yaml:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: producer-pvc
    spec:
      storageClassName: hyperdisk-ml
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 800Gi
    
  2. Simpan contoh manifes berikut sebagai producer-job.yaml:

    DeepSeek-R1

    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: producer-job
    spec:
      template:  # Template for the Pods the Job will create
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - "ZONE"
          containers:
          - name: copy
            resources:
              requests:
                cpu: "32"
              limits:
                cpu: "32"
            image: python:3.11-alpine
            command:
            - sh
            - -c
            - "pip install 'huggingface_hub==0.24.6' && \
              huggingface-cli download deepseek-ai/DeepSeek-R1 --local-dir-use-symlinks=False --local-dir=/data/DeepSeek-R1 --include *.safetensors *.json *.py"
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
              - mountPath: "/data"
                name: volume
          restartPolicy: Never
          volumes:
            - name: volume
              persistentVolumeClaim:
                claimName: producer-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 4        # Max retries on failure
    
    

    Llama 3.1 405B

    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: producer-job
    spec:
      template:  # Template for the Pods the Job will create
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - "ZONE"
          containers:
          - name: copy
            resources:
              requests:
                cpu: "32"
              limits:
                cpu: "32"
            image: python:3.11-alpine
            command:
            - sh
            - -c
            - "pip install 'huggingface_hub==0.24.6' && \
              huggingface-cli download meta-llama/Meta-Llama-3.1-405B-Instruct --local-dir-use-symlinks=False --local-dir=/data/Meta-Llama-3.1-405B-Instruct --include *.safetensors *.json"
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
              - mountPath: "/data"
                name: volume
          restartPolicy: Never
          volumes:
            - name: volume
              persistentVolumeClaim:
                claimName: producer-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 4        # Max retries on failure
    
    
  3. Ikuti petunjuk di Mempercepat pemuatan data AI/ML dengan Hyperdisk ML, menggunakan dua file yang Anda buat di langkah sebelumnya.

    Setelah langkah ini, Anda telah membuat dan mengisi volume ML Hyperdisk dengan data model.

  4. Deploy deployment server GPU multi-node vLLM, yang akan menggunakan volume Hyperdisk ML yang baru dibuat untuk data model.

    DeepSeek-R1

    
    
    apiVersion: leaderworkerset.x-k8s.io/v1
    kind: LeaderWorkerSet
    metadata:
      name: vllm
    spec:
      replicas: 1
      leaderWorkerTemplate:
        size: 2
        restartPolicy: RecreateGroupOnPodRestart
        leaderTemplate:
          metadata:
            labels:
              role: leader
          spec:
            containers:
              - name: vllm-leader
                image: IMAGE_NAME
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-secret
                        key: hf_api_token
                command:
                  - sh
                  - -c
                  - "/vllm-workspace/ray_init.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE); 
                    python3 -m vllm.entrypoints.openai.api_server --port 8080 --model /models/DeepSeek-R1 --tensor-parallel-size 8 --pipeline-parallel-size 2 --trust-remote-code --max-model-len 4096"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                ports:
                  - containerPort: 8080
                readinessProbe:
                  tcpSocket:
                    port: 8080
                  initialDelaySeconds: 15
                  periodSeconds: 10
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
                  - mountPath: /models
                    name: deepseek-r1
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
            - name: deepseek-r1
              persistentVolumeClaim:
                claimName: hdml-static-pvc
        workerTemplate:
          spec:
            containers:
              - name: vllm-worker
                image: IMAGE_NAME
                command:
                  - sh
                  - -c
                  - "/vllm-workspace/ray_init.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-secret
                        key: hf_api_token
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
                  - mountPath: /models
                    name: deepseek-r1
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
            - name: deepseek-r1
              persistentVolumeClaim:
                claimName: hdml-static-pvc
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vllm-leader
    spec:
      ports:
        - name: http
          port: 8080
          protocol: TCP
          targetPort: 8080
      selector:
        leaderworkerset.sigs.k8s.io/name: vllm
        role: leader
      type: ClusterIP
    

    Llama 3.1 405B

    
    
    apiVersion: leaderworkerset.x-k8s.io/v1
    kind: LeaderWorkerSet
    metadata:
      name: vllm
    spec:
      replicas: 1
      leaderWorkerTemplate:
        size: 2
        restartPolicy: RecreateGroupOnPodRestart
        leaderTemplate:
          metadata:
            labels:
              role: leader
          spec:
            containers:
              - name: vllm-leader
                image: IMAGE_NAME
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-secret
                        key: hf_api_token
                command:
                  - sh
                  - -c
                  - "/vllm-workspace/ray_init.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE); 
                    python3 -m vllm.entrypoints.openai.api_server --port 8080 --model /models/Meta-Llama-3.1-405B-Instruct --tensor-parallel-size 8 --pipeline-parallel-size 2"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                ports:
                  - containerPort: 8080
                readinessProbe:
                  tcpSocket:
                    port: 8080
                  initialDelaySeconds: 15
                  periodSeconds: 10
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
                  - mountPath: /models
                    name: llama3-405b
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
            - name: llama3-405b
              persistentVolumeClaim:
                claimName: hdml-static-pvc
        workerTemplate:
          spec:
            containers:
              - name: vllm-worker
                image: IMAGE_NAME
                command:
                  - sh
                  - -c
                  - "/vllm-workspace/ray_init.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                env:
                  - name: HUGGING_FACE_HUB_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-secret
                        key: hf_api_token
                volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
                  - mountPath: /models
                    name: llama3-405b
            volumes:
            - name: dshm
              emptyDir:
                medium: Memory
            - name: llama3-405b
              persistentVolumeClaim:
                claimName: hdml-static-pvc
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vllm-leader
    spec:
      ports:
        - name: http
          port: 8080
          protocol: TCP
          targetPort: 8080
      selector:
        leaderworkerset.sigs.k8s.io/name: vllm
        role: leader
      type: ClusterIP
    

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus resource yang di-deploy

Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang Anda buat dalam panduan ini, jalankan perintah berikut:

ps -ef | grep load.sh | awk '{print $2}' | xargs -n1 kill -9
gcloud container clusters delete CLUSTER_NAME \
  --location=ZONE

Langkah berikutnya