Menyajikan LLM (Llama3.1 405B) menggunakan beberapa node GPU


Ringkasan

Tutorial ini menunjukkan cara menayangkan Llama 3.1 405b menggunakan Unit Pemrosesan Grafis (GPU) di beberapa node di Google Kubernetes Engine (GKE), menggunakan framework penayangan vLLM dan API LeaderWorkerSet (LWS).

Dokumen ini adalah titik awal yang baik jika Anda memerlukan kontrol terperinci, skalabilitas, ketahanan, portabilitas, dan efektivitas biaya Kubernetes terkelola saat men-deploy dan menayangkan beban kerja AI/ML.

LeaderWorkerSet (LWS)

LWS adalah API deployment Kubernetes yang menangani pola deployment umum dari workload inferensi multi-node AI/ML. LWS memungkinkan perlakuan beberapa Pod sebagai grup.

Penyertaan Multi-Host dengan vLLM

Saat men-deploy model bahasa yang sangat besar yang tidak dapat muat dalam satu node GPU, gunakan beberapa node GPU untuk menayangkan model. vLLM mendukung paralelisme tensor dan paralelisme pipeline untuk menjalankan beban kerja di seluruh GPU.

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 8 GPU H100, Anda dapat menggunakan paralelisme pipeline dua arah untuk membuat shard model di kedua node, dan paralelisme tensor delapan arah untuk membuat shard model di delapan GPU di setiap node.

Tujuan

  1. Siapkan cluster GKE Standard.
  2. Deploy vLLM di beberapa node di cluster Anda.
  3. Gunakan vLLM untuk menayangkan model Llama3 405b 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

    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 colunn 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. Untuk mempelajari lebih lanjut, lihat Tentang GPU dan Kuota alokasi.

Mendapatkan akses ke model

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 di Google 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=IMAGE_NAME
    

    Ganti nilai berikut:

    • PROJECT_ID: project ID Google Cloud Anda.
    • CLUSTER_NAME: nama cluster GKE Anda.
    • ZONE: Zona yang mendukung H100.
    • IMAGE_NAME: Image vLLM yang menyertakan skrip ray. Kami menyediakan us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20240821_1034_RC00 untuk Anda, atau Anda dapat membuat sendiri.

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}

Standard

  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
    

Konfigurasi kubectl untuk berkomunikasi dengan cluster Anda:

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

Membuat Secret Kubernetes untuk kredensial Hugging Face

Buat Secret Kubernetes yang berisi token Hugging Face:

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

(Opsional) Membuat image multi-node vLLM Anda sendiri

Untuk memiliki kontrol lebih besar atas konten image Docker dan menyertakan dependensi tertentu bersama skrip Anda, pilih opsi ini. Untuk menjalankan vLLM di beberapa node, Anda dapat menggunakan Ray untuk komunikasi lintas node. Anda dapat melihat Dockerfile, yang berisi skrip bash untuk menyiapkan Ray dengan vLLM di repositori LeaderWorkerSet.

Buat container

  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 . -t vllm-multihost
    

Mengirim image ke Artifact Registry

Untuk memastikan deployment Kubernetes Anda dapat mengakses image, simpan image di Artifact Registry dalam project Google Cloud 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:

VERSION=v0.4.0
kubectl apply --server-side -f https://github.com/kubernetes-sigs/lws/releases/download/$VERSION/manifests.yaml

Validasi bahwa pengontrol LeaderWorkerSet berjalan di namespace lws-system:

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. 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
                  - "/workspace/vllm/examples/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
                  - "/workspace/vllm/examples/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
    
  3. Melihat log dari server model yang berjalan

    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

Jalankan perintah berikut untuk menyiapkan penerusan port ke model

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

Berinteraksi dengan model menggunakan curl

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

(Opsional) Mempercepat waktu pemuatan model dengan Hyperdisk ML

vLLM dapat memerlukan waktu hingga 90 menit untuk mendownload, memuat, dan melakukan pemanasan Llama 3.1-405B di setiap replika baru. Anda dapat mengurangi waktu ini menjadi 20 menit dengan mendownload model langsung ke Hyperdisk ML dan memasangnya ke setiap pod.

Anda dapat mengikuti tutorial Mempercepat pemuatan data AI/ML dengan Hyperdisk ML menggunakan file YAML 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:

    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-bookworm
            command:
            - bash
            - -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
    

Men-deploy Server Model vLLM

Setelah menyelesaikan langkah-langkah tersebut, Anda dapat men-deploy deployment server GPU multi-node vLLM yang menggunakan volume Hyperdisk ML.



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
              - "/workspace/vllm/examples/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
              - "/workspace/vllm/examples/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 dibuat dalam panduan ini, jalankan perintah berikut:

gcloud container clusters delete CLUSTER_NAME \
  --location=ZONE

Langkah selanjutnya