Pubblica un LLM (Llama3.1 405B) utilizzando più nodi GPU


Panoramica

Questo tutorial mostra come eseguire il servizio Llama 3.1 405b utilizzando GPU su più nodi su Google Kubernetes Engine (GKE), utilizzando il framework di servizio vLLM e l'API LeaderWorkerSet (LWS).

Questo documento è un buon punto di partenza se hai bisogno di controlli granulari, scalabilità, resilienza, portabilità e convenienza di Kubernetes gestito il deployment e la gestione dei carichi di lavoro di AI/ML.

LeaderWorkerSet (LWS)

LWS è un'API di deployment di Kubernetes che si rivolge pattern di deployment comuni dei carichi di lavoro di inferenza multinodo AI/ML. LWS consente di trattare più pod come un gruppo.

Pubblicazione multi-host con vLLM

Quando esegui il deployment di modelli linguistici di dimensioni eccezionalmente grandi che non possono essere inseriti in un singolo nodo GPU, utilizza più nodi GPU per fornire il modello. vLLM supporta sia il parallelismo tensore che il parallelismo della pipeline per eseguire carichi di lavoro su GPU.

Il parallelismo dei Tensor suddivide le moltiplicazioni della matrice nel livello del trasformatore su più GPU. Tuttavia, questa strategia richiede una rete veloce per via della comunicazione necessaria tra le GPU, rendendolo meno adatto all'esecuzione di carichi di lavoro tra nodi.

Il parallismo della pipeline suddivide il modello per livello o in verticale. Questa strategia non richiede comunicazione costante tra GPU, il che la rende un'opzione migliore quando si eseguono modelli su più nodi.

Puoi utilizzare entrambe le strategie nella pubblicazione con più nodi. Ad esempio, se utilizzi due nodi con otto GPU H100 ciascuno, puoi utilizzare il parallelismo della pipeline bidirezionale per suddividere il modello nei due nodi e il parallelismo tensoriale a otto vie per suddividere il modello nelle otto GPU di ciascun nodo.

Obiettivi

  1. Prepara un cluster GKE Standard.
  2. Esegui il deployment di vLLM su più nodi del cluster.
  3. Utilizza vLLM per pubblicare il modello Llama3 405b tramite curl.

Prima di iniziare

  • 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.

      Vai a IAM
    2. Seleziona il progetto.
    3. Fai clic su Concedi l'accesso.
    4. Nel campo Nuove entità, inserisci il tuo identificatore utente. In genere si tratta dell'indirizzo email di un Account Google.

    5. Nell'elenco Seleziona un ruolo, seleziona un ruolo.
    6. Per concedere altri ruoli, fai clic su Aggiungi un altro ruolo e aggiungi ogni altro ruolo.
    7. Fai clic su Salva.

Ottieni l'accesso al modello

Genera un token di accesso

Se non ne hai già uno, genera un nuovo token Hugging Face:

  1. Fai clic su Il tuo profilo > Impostazioni > Token di accesso.
  2. Seleziona New Token (Nuovo token).
  3. Specifica un nome a tua scelta e un ruolo di almeno Read.
  4. Seleziona Genera un token.

prepara l'ambiente

In questo tutorial utilizzerai Cloud Shell per gestire le risorse ospitate in Google Cloud. Cloud Shell include il software di cui avrai bisogno per questo tutorial, tra cui kubectl e gcloud CLI.

Per configurare l'ambiente con Cloud Shell, segui questi passaggi:

  1. Nella console Google Cloud, avvia una sessione di Cloud Shell facendo clic su Icona di attivazione di Cloud Shell Attiva Cloud Shell nella console Google Cloud. Viene avviata una sessione nel riquadro inferiore della console Google Cloud.

  2. Imposta le variabili di ambiente predefinite:

    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
    

    Sostituisci i seguenti valori:

    • PROJECT_ID: il tuo ID progetto Google Cloud.
    • CLUSTER_NAME: il nome del tuo cluster GKE.
    • ZONE: una zona che supporta le schede H100.

Crea un cluster GKE

Crea un cluster GKE Standard con due nodi CPU:

gcloud container clusters create CLUSTER_NAME \
    --project=PROJECT_ID \
    --num-nodes=2 \
    --location=ZONE \
    --machine-type=e2-standard-16

Crea pool di nodi GPU

Crea un pool di nodi A3 con due nodi, con otto H100 ciascuno:

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

Configura kubectl per comunicare con il tuo cluster:

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

Crea un secret di Kubernetes per le credenziali di Hugging Face

Crea un secret di Kubernetes contenente il token di Hugging Face:

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

Installa LeaderWorkerSet

Per installare LWS, esegui questo comando:

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

Verifica che il controller LeaderWorkerSet sia in esecuzione nello spazio dei nomi lws-system:

kubectl get pod -n lws-system

L'output è simile al seguente:

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

Esegui il deployment del server del modello vLLM

Per eseguire il deployment del server modello vLLM, segui questi passaggi:

  1. Controlla il file manifest 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: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20240821_1034_RC00
                env:
                  - name: RAY_CLUSTER_SIZE
                    valueFrom:
                      fieldRef:
                        fieldPath: metadata.annotations['leaderworkerset.sigs.k8s.io/size']
                  - 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=$RAY_CLUSTER_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: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20240821_1034_RC00
                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. Applica il manifest eseguendo il seguente comando:

    kubectl apply -f vllm-llama3-405b-A3.yaml
    
  3. Visualizza i log dal server del modello in esecuzione

    kubectl logs vllm-0 -c vllm-leader
    

    L'output dovrebbe essere simile al seguente:

    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)
    

Pubblica il modello

Esegui il comando seguente per configurare il port forwarding al modello

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

Interagire con il modello utilizzando curl

In un nuovo terminale, invia una richiesta al 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
}'

L'output dovrebbe essere simile al seguente:

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

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Elimina le risorse di cui è stato eseguito il deployment

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse che hai creato in questa guida, esegui il seguente comando:

gcloud container clusters delete CLUSTER_NAME \
  --location=ZONE

Passaggi successivi