Questo tutorial mostra come eseguire il servizio di un modello linguistico di grandi dimensioni (LLM) con GPU in Google Kubernetes Engine (GKE) utilizzando più GPU per un'inferenza efficiente e scalabile. Questo tutorial crea un cluster GKE che utilizza più GPU L4 e prepara l'infrastruttura GKE per pubblicare uno dei seguenti modelli:
Il numero di GPU varia a seconda del formato dei dati del modello. In questo tutorial, ogni modello utilizza due GPU L4. Per scoprire di più, consulta Calcolo del numero di GPU.
Prima di completare questo tutorial in GKE, ti consigliamo di scoprire di più sulle GPU in GKE.
Obiettivi
Questo tutorial è rivolto a DevOps o MLOps engineer o amministratori della piattaforma che vogliono utilizzare le funzionalità di orchestrazione di GKE per pubblicare LLM.
Questo tutorial illustra i seguenti passaggi:
- Crea un cluster e pool di nodi.
- Prepara il tuo carico di lavoro.
- Esegui il deployment del carico di lavoro.
- Interagisci con l'interfaccia LLM.
Prima di iniziare
Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:
- Attiva l'API Google Kubernetes Engine. Attiva l'API Google Kubernetes Engine
- Se vuoi utilizzare Google Cloud CLI per questa attività,
installa e poi
inizializza gcloud CLI. Se hai già installato gcloud CLI, ottieni la versione più recente eseguendo
gcloud components update
.
Per alcuni modelli sono previsti requisiti aggiuntivi. Assicurati di soddisfare i seguenti requisiti:
- Per accedere ai modelli di Hugging Face, utilizza un token HuggingFace.
- Per il modello Mixtral 8x7b, accetta le condizioni per il modello Mistral Mixtral.
- Per il modello Llama 3 70b, assicurati di disporre di una licenza attiva per i modelli Meta Llama.
prepara l'ambiente
Nella console Google Cloud, avvia un'istanza Cloud Shell:
Apri Cloud ShellImposta le variabili di ambiente predefinite:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=us-central1
Sostituisci PROJECT_ID con il tuo ID progetto Google Cloud.
Crea un cluster GKE e un pool di nodi
Puoi pubblicare LLM sulle GPU in un cluster GKE Autopilot o Standard. Ti consigliamo di utilizzare un cluster Autopilot per un'esperienza Kubernetes completamente gestita. Per scegliere la modalità operativa di GKE più adatta ai tuoi carichi di lavoro, consulta Scegliere una modalità operativa GKE.
Autopilot
In Cloud Shell, esegui questo comando:
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --region=${REGION} \ --release-channel=rapid
GKE crea un cluster Autopilot con nodi CPU e GPU come richiesto dai carichi di lavoro di cui è stato eseguito il deployment.
Configura
kubectl
per comunicare con il cluster:gcloud container clusters get-credentials l4-demo --region=${REGION}
Standard
In Cloud Shell, esegui il seguente comando per creare un cluster standard che utilizza la federazione delle identità per i carichi di lavoro per GKE:
gcloud container clusters create l4-demo --location ${REGION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=$REGION-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapid
La creazione del cluster potrebbe richiedere diversi minuti.
Esegui il comando seguente per creare un pool di nodi per il cluster:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations $REGION-a,$REGION-c --region $REGION --spot
GKE crea le seguenti risorse per l'LLM:
- Un cluster pubblico Google Kubernetes Engine (GKE) versione Standard.
- Un pool di nodi con tipo di macchina
g2-standard-24
ridotto a 0 nodi. Non ti verrà addebitato alcun importo per le GPU finché non avvii i pod che richiedono GPU. Questo pool di nodi esegue il provisioning delle VM spot, il cui prezzo è inferiore rispetto alle VM Compute Engine standard predefinite e che non offrono alcuna garanzia di disponibilità. Per utilizzare le VM on demand, puoi rimuovere il flag--spot
da questo comando e il selettore di nodicloud.google.com/gke-spot
nella configurazionetext-generation-inference.yaml
.
Configura
kubectl
per comunicare con il cluster:gcloud container clusters get-credentials l4-demo --region=${REGION}
Prepara il tuo carico di lavoro
La sezione seguente mostra come configurare il tuo carico di lavoro in base al modello che vuoi utilizzare:
Llama 3 70b
Imposta le variabili di ambiente predefinite:
export HF_TOKEN=HUGGING_FACE_TOKEN
Sostituisci
HUGGING_FACE_TOKEN
con il tuo token HuggingFace.Crea un secret di Kubernetes per il token HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crea il seguente manifest
text-generation-inference.yaml
:In questo manifest:
NUM_SHARD
deve essere2
perché il modello richiede due GPU NVIDIA L4.QUANTIZE
è impostato subitsandbytes-nf4
, il che significa che il modello viene caricato in 4 bit anziché in 32 bit. In questo modo, GKE può ridurre la quantità di memoria GPU necessaria e migliorare la velocità di inferenza. Tuttavia, l'accuratezza del modello può diminuire. Per scoprire come calcolare le GPU da richiedere, consulta Calcolo del numero di GPU.
Applica il manifest:
kubectl apply -f text-generation-inference.yaml
L'output è simile al seguente:
deployment.apps/llm created
Verifica lo stato del modello:
kubectl get deploy
L'output è simile al seguente:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
Visualizza i log del deployment in esecuzione:
kubectl logs -l app=llm
L'output è simile al seguente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
Imposta le variabili di ambiente predefinite:
export HF_TOKEN=HUGGING_FACE_TOKEN
Sostituisci
HUGGING_FACE_TOKEN
con il tuo token HuggingFace.Crea un secret di Kubernetes per il token HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crea il seguente manifest
text-generation-inference.yaml
:In questo manifest:
NUM_SHARD
deve essere2
perché il modello richiede due GPU NVIDIA L4.QUANTIZE
è impostato subitsandbytes-nf4
, il che significa che il modello viene caricato in 4 bit anziché in 32 bit. In questo modo, GKE può ridurre la quantità di memoria GPU necessaria e migliorare la velocità di inferenza. Tuttavia, la precisione del modello potrebbe diminuire. Per scoprire come calcolare il numero di GPU da richiedere, consulta Calcolo del numero di GPU.
Applica il manifest:
kubectl apply -f text-generation-inference.yaml
L'output è simile al seguente:
deployment.apps/llm created
Verifica lo stato del modello:
watch kubectl get deploy
Quando il deployment è pronto, l'output è simile al seguente. Per uscire dall'orologio, digita
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Visualizza i log del deployment in esecuzione:
kubectl logs -l app=llm
L'output è simile al seguente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
Crea il seguente manifest
text-generation-inference.yaml
:In questo manifest:
NUM_SHARD
deve essere2
perché il modello richiede due GPU NVIDIA L4.QUANTIZE
è impostato subitsandbytes-nf4
, il che significa che il modello viene caricato in 4 bit anziché in 32 bit. In questo modo, GKE può ridurre la quantità di memoria GPU necessaria e migliorare la velocità di inferenza. Tuttavia, l'accuratezza del modello può diminuire. Per scoprire come calcolare il numero di GPU da richiedere, consulta Calcolo del numero di GPU.
Applica il manifest:
kubectl apply -f text-generation-inference.yaml
L'output è simile al seguente:
deployment.apps/llm created
Verifica lo stato del modello:
watch kubectl get deploy
Quando il deployment è pronto, l'output è simile al seguente. Per uscire dall'orologio, digita
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Visualizza i log del deployment in esecuzione:
kubectl logs -l app=llm
L'output è simile al seguente:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Crea un servizio di tipo ClusterIP
Crea il seguente manifest
llm-service.yaml
:apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080
Applica il manifest:
kubectl apply -f llm-service.yaml
Esegui il deployment di un'interfaccia di chat
Utilizza Gradio per creare un'applicazione web che ti consenta di interagire con il tuo modello. Gradio è una libreria Python che ha un wrapper ChatInterface che crea interfacce utente per i chatbot.
Llama 3 70b
Crea un file denominato
gradio.yaml
:Applica il manifest:
kubectl apply -f gradio.yaml
Trova l'indirizzo IP esterno del servizio:
kubectl get svc
L'output è simile al seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia l'indirizzo IP esterno dalla colonna
EXTERNAL-IP
.Visualizza l'interfaccia del modello dal browser web utilizzando l'indirizzo IP esterno con la porta esposta:
http://EXTERNAL_IP
Mixtral 8x7b
Crea un file denominato
gradio.yaml
:Applica il manifest:
kubectl apply -f gradio.yaml
Trova l'indirizzo IP esterno del servizio:
kubectl get svc
L'output è simile al seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia l'indirizzo IP esterno dalla colonna
EXTERNAL-IP
.Visualizza l'interfaccia del modello dal browser web utilizzando l'indirizzo IP esterno con la porta esposta:
http://EXTERNAL_IP
Falcon 40b
Crea un file denominato
gradio.yaml
:Applica il manifest:
kubectl apply -f gradio.yaml
Trova l'indirizzo IP esterno del servizio:
kubectl get svc
L'output è simile al seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copia l'indirizzo IP esterno dalla colonna
EXTERNAL-IP
.Visualizza l'interfaccia del modello dal browser web utilizzando l'indirizzo IP esterno con la porta esposta:
http://EXTERNAL_IP
Calcolo del numero di GPU
Il numero di GPU dipende dal valore del flag QUANTIZE
. In questo
tutorial, QUANTIZE
è impostato su bitsandbytes-nf4
, il che significa che il modello viene caricato in 4 bit.
Un modello con 70 miliardi di parametri richiederebbe almeno 40 GB di memoria GPU, ovvero 70 miliardi di volte 4 bit (70 miliardi x 4 bit= 35 GB) e considera un overhead di 5 GB. In questo caso, una singola GPU L4 non avrebbe memoria sufficiente. Pertanto, gli esempi in questo tutorial utilizzano due GPU L4 di memoria (2 x 24 = 48 GB). Questa configurazione è sufficiente per eseguire Falcon 40b o Llama 3 70b nelle GPU L4.
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 il cluster
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse che hai creato in questa guida, elimina il cluster GKE:
gcloud container clusters delete l4-demo --region ${REGION}