Google Kubernetes Engine (GKE) fornisce un controllo granulare per l'inferenza del modello linguistico di grandi dimensioni (LLM) con prestazioni e costi ottimali. Questa guida descrive le best practice per ottimizzare l'inferenza e l'erogazione di LLM aperti con GPU su GKE utilizzando i framework di erogazione vLLM e Text Generation Inference (TGI).
Per un elenco di controllo riepilogativo di tutte le best practice, consulta il Riepilogo dell'elenco di controllo.
Obiettivi
Questa guida è destinata ai clienti dell'AI generativa, agli utenti GKE nuovi o esistenti, agli ingegneri ML e agli ingegneri LLMOps (DevOps) interessati a ottimizzare i propri workload LLM utilizzando le GPU con Kubernetes.
Al termine di questa guida, sarai in grado di:
- Scegli tecniche di ottimizzazione LLM post-addestramento, tra cui quantizzazione, parallelismo dei tensori e ottimizzazione della memoria.
- Valuta i compromessi di alto livello quando prendi in considerazione queste tecniche di ottimizzazione.
- Esegui il deployment di modelli LLM aperti in GKE utilizzando framework di gestione come vLLM o TGI con le impostazioni di ottimizzazione abilitate.
Panoramica delle tecniche di ottimizzazione del servizio LLM
A differenza dei workload non AI, i workload LLM in genere mostrano una latenza maggiore e un throughput inferiore a causa della loro dipendenza dalle operazioni di moltiplicazione delle matrici. Per migliorare le prestazioni di inferenza degli LLM, puoi utilizzare acceleratori hardware specializzati (ad esempio GPU e TPU) e framework di serving ottimizzati.
Puoi applicare una o più delle seguenti best practice per ridurre la latenza del carico di lavoro LLM migliorando al contempo il throughput e l'efficienza dei costi:
Gli esempi in questa guida utilizzano il modello LLM Gemma 7B insieme ai framework di pubblicazione vLLM o TGI per applicare queste best practice. Tuttavia, i concetti e le funzionalità descritti sono applicabili alla maggior parte dei modelli LLM open source più popolari.
Prima di iniziare
Prima di provare gli esempi in questa guida, completa le seguenti attività preliminari:
Segui le istruzioni riportate in queste guide per accedere al modello Gemma, preparare l'ambiente e creare e configurare Google Cloud le risorse:
- Gestisci i modelli open Gemma utilizzando le GPU su GKE con vLLM
- Gestire i modelli open Gemma utilizzando le GPU su GKE con Hugging Face TGI
Assicurati di salvare il token di accesso a Hugging Face nel secret Kubernetes.
Clona il repository di esempi https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/ nel tuo ambiente di sviluppo locale.
Cambia la directory di lavoro in
/kubernetes-engine-samples/ai-ml/llm-serving-gemma/
.
Best practice: quantizzazione
La quantizzazione è una tecnica analoga alla compressione delle immagini con perdita di dati che riduce le dimensioni del modello rappresentando i pesi in formati a precisione inferiore (8 bit o 4 bit), riducendo così i requisiti di memoria. Tuttavia, come la compressione delle immagini, la quantizzazione comporta un compromesso: la riduzione delle dimensioni del modello può comportare una minore precisione.
Esistono vari metodi di quantizzazione, ognuno con vantaggi e svantaggi unici. Alcuni, come AWQ e GPTQ, richiedono la pre-quantizzazione e sono disponibili su piattaforme come Hugging Face o Kaggle. Ad esempio, se applichi GPTQ al modello Llama-2 13B e AWQ al modello Gemma 7B, puoi gestire i modelli su una singola GPU L4 anziché su due GPU L4 senza quantizzazione.
Puoi anche eseguire la quantizzazione utilizzando strumenti come AutoAWQ
e AutoGPTQ. Questi metodi possono migliorare
la latenza e il throughput. Al contrario, le tecniche che utilizzano EETQ e la libreria
bitsandbytes
per la quantizzazione non richiedono modelli prequantizzati, quindi possono essere una scelta adatta quando le versioni prequantizzate non sono disponibili.
La tecnica di quantizzazione migliore da utilizzare dipende dai tuoi obiettivi specifici e dalla compatibilità della tecnica con il framework di pubblicazione che vuoi utilizzare. Per saperne di più, consulta la guida alla quantizzazione di Hugging Face.
Seleziona una di queste schede per vedere un esempio di applicazione della quantizzazione utilizzando i framework TGI o vLLM:
TGI
GKE supporta queste opzioni di quantizzazione con TGI:
awq
gptq
eetq
bitsandbytes
bitsandbytes-nf4
bitsandbytes-fp4
I metodi di quantizzazione AWQ e GPTQ richiedono modelli pre-quantizzati, mentre EETQ
e la quantizzazione bitsandbytes
possono essere applicati a qualsiasi modello. Per saperne di più
su queste opzioni, consulta questo articolo di Hugging Face.
Per utilizzare la quantizzazione, imposta il parametro
-–quantize
all'avvio del server del modello.
Lo snippet seguente mostra come ottimizzare Gemma 7B con la quantizzazione bitsandbytes
utilizzando TGI su GKE.
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f tgi/tgi-7b-bitsandbytes.yaml
vLLM
GKE supporta le seguenti opzioni di quantizzazione con vLLM:
gptq
- con quantizzazione a 4 bit (non supportata per Gemma, ma disponibile per altri modelli)awq
squeezellm
- Quantizzazioni della cache KV utilizzando i formati FP8 (8 bit in virgola mobile) E5M2 ed E4M3.
Per utilizzare la quantizzazione del modello con vLLM, i modelli devono essere pre-quantizzati.
Quando avvii il runtime, imposta il parametro –quantization
.
Il seguente snippet mostra come ottimizzare il modello Gemma 7B
con la quantizzazione awq
utilizzando vLLM su GKE:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f vllm/vllm-7b-awq.yaml
Migliora la latenza utilizzando la quantizzazione della cache KV
Puoi utilizzare la quantizzazione della cache KV FP8 E5M2 per ridurre significativamente l'utilizzo di memoria della cache KV e migliorare la latenza, soprattutto per batch di grandi dimensioni. Tuttavia, ciò riduce l'accuratezza dell'inferenza.
Per attivare la quantizzazione della cache KV FP8 E5M2, imposta il parametro --kv-cache-dtype fp8_e5m2
:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f vllm/vllm-7b-kvcache.yaml
Best practice: parallelismo dei tensori
Il parallelismo tensoriale è una tecnica che distribuisce il carico di calcolo su più GPU, essenziale quando esegui modelli di grandi dimensioni che superano la capacità di memoria di una singola GPU. Questo approccio può essere più conveniente in quanto ti consente di utilizzare più GPU economiche anziché una singola costosa. Può anche migliorare la velocità effettiva dell'inferenza del modello. Il parallelismo dei tensori sfrutta il fatto che le operazioni sui tensori possono essere eseguite in modo indipendente su blocchi di dati più piccoli.
Per saperne di più su questa tecnica, consulta la guida al parallelismo tensoriale di Hugging Face.
Seleziona una di queste schede per visualizzare un esempio di applicazione del parallelismo dei tensori utilizzando i framework TGI o vLLM:
TGI
Con TGI, il runtime di gestione utilizzerà tutte le GPU disponibili per il pod per impostazione predefinita. Puoi impostare il numero di GPU da utilizzare specificando il parametro
--num-shard
con il numero di GPU come valore.
Consulta la documentazione di Hugging Face per l'elenco dei modelli supportati per il parallelismo dei tensori.
Il seguente snippet mostra come ottimizzare il modello Gemma 7B ottimizzato per le istruzioni utilizzando il parallelismo dei tensori e due GPU L4:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f tgi/tgi-7b-it-tensorparallelism.yaml
Nei cluster GKE Autopilot, l'esecuzione di questo comando crea un pod con requisiti minimi di risorse di 21 vCPU e 78 GiB di memoria.
vLLM
vLLM supporta l'inferenza parallela tensoriale distribuita. vLLM abilita la funzionalità per impostazione predefinita se è disponibile più di una GPU.
Il seguente snippet mostra come ottimizzare il modello Gemma 7B ottimizzato per le istruzioni utilizzando il parallelismo dei tensori e due GPU L4:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f vllm/vllm-7b-it-tensorparallelism.yaml
Nei cluster GKE Autopilot, l'esecuzione di questo comando crea un pod con requisiti minimi di risorse di 21 vCPU e 78 GiB di memoria.
Best practice: ottimizzazione della memoria del modello
L'ottimizzazione dell'utilizzo della memoria dei modelli LLM è fondamentale per un'inferenza efficiente. Questa sezione introduce strategie di ottimizzazione del livello di attenzione, come l'attenzione paginata e l'attenzione flash. Queste strategie migliorano l'efficienza della memoria, consentendo sequenze di input più lunghe e riducendo il tempo di inattività della GPU. Questa sezione descrive anche come regolare le dimensioni dell'input e dell'output del modello per adattarle ai vincoli di memoria e ottimizzare per framework di pubblicazione specifici.
Ottimizzazione del livello di attenzione
I livelli di self-attention consentono ai modelli di comprendere il contesto nelle attività di elaborazione del linguaggio, poiché i significati delle parole possono cambiare a seconda del contesto. Tuttavia, questi livelli memorizzano pesi, chiavi (K) e valori (V) dei token di input nella vRAM della GPU. Pertanto, man mano che la sequenza di input si allunga, si verifica una crescita quadratica delle dimensioni e del tempo di calcolo.
L'utilizzo della memorizzazione nella cache KV è particolarmente utile quando si ha a che fare con sequenze di input lunghe, in cui l'overhead dell'auto-attenzione può diventare significativo. Questo approccio di ottimizzazione riduce l'elaborazione computazionale a una complessità lineare.
Le tecniche specifiche per ottimizzare i meccanismi di attenzione negli LLM includono:
- Attenzione paginata: l'attenzione paginata migliora la gestione della memoria per modelli di grandi dimensioni e sequenze di input lunghe utilizzando tecniche di paginazione, simili alla memoria virtuale del sistema operativo. Ciò riduce efficacemente la frammentazione e la duplicazione nella cache KV, consentendo sequenze di input più lunghe senza esaurire la memoria della GPU.
- Flash Attention: Flash Attention riduce i colli di bottiglia della memoria GPU riducendo al minimo i trasferimenti di dati tra la RAM della GPU e la cache L1 durante la generazione di token. In questo modo si elimina il tempo di inattività dei core di calcolo, migliorando notevolmente le prestazioni di inferenza e addestramento per le GPU.
Ottimizzazione delle dimensioni di input e output del modello
I requisiti di memoria dipendono dalle dimensioni dell'input e dell'output. Output più lunghi e più contesto richiedono più risorse, mentre output più brevi e meno contesto possono ridurre i costi utilizzando una GPU più piccola ed economica.
Seleziona una di queste schede per visualizzare un esempio di ottimizzazione dei requisiti di memoria di input e output del modello nei framework TGI o vLLM:
TGI
Il runtime di servizio TGI verifica i requisiti di memoria durante l'avvio e non si avvia se l'impronta di memoria massima possibile del modello non rientra nella memoria GPU disponibile. Questo controllo elimina gli arresti anomali per esaurimento della memoria (OOM) sui workload che richiedono molta memoria.
GKE supporta i seguenti parametri TGI per ottimizzare i requisiti di memoria del modello:
Il seguente snippet mostra come gestire un modello Gemma 7B
ottimizzato per le istruzioni con una singola GPU L4, con impostazioni dei parametri
--max-total-tokens=3072, --max-batch-prefill-tokens=512,
--max-input-length=512
:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f tgi/tgi-7b-token.yaml
vLLM
In vLLM, configura la lunghezza del contesto del modello, che influisce direttamente
sulle dimensioni della cache KV e sui requisiti di RAM della GPU. Lunghezze del contesto più brevi consentono
l'utilizzo di GPU più economiche. Il valore predefinito è il numero massimo
di token accettati dal modello. Limita la lunghezza massima del contesto con
--max-model-len MAX_MODEL_LEN
, se necessario.
Ad esempio, il modello Gemma 7B ottimizzato per le istruzioni, con una
lunghezza del contesto predefinita di 8192, supera la capacità di memoria di una singola
GPU NVIDIA L4. Per il deployment su un L4, limita la lunghezza combinata di prompt e
output impostando --max-model-len
su un valore inferiore a 640. Questo aggiustamento
consente di eseguire il modello su una singola GPU L4 nonostante la sua grande lunghezza
del contesto predefinita.
Per eseguire il deployment con il limite di token modificato, utilizza lo snippet seguente:
Per applicare questa configurazione, utilizza il comando seguente:
kubectl apply -f vllm/vllm-7b-token.yaml
Elenco di controllo di riepilogo
Obiettivo di ottimizzazione | Esercitati |
---|---|
Latenza |
|
Velocità effettiva |
|
Efficienza in termini di costi |
|
Passaggi successivi
- Per una guida end-to-end che illustra la configurazione dei container, consulta Gestisci un LLM con più GPU su GKE.
- Se hai bisogno di una soluzione di serving LLM gestita dal cloud, esegui il deployment del modello tramite Vertex AI Model Garden.