Best practice per la scalabilità automatica dei carichi di lavoro di inferenza del modello linguistico di grandi dimensioni (LLM) con le TPU

Questa guida alle best practice mostra le metriche disponibili e come selezionare quelle adatte per configurare Horizontal Pod Autoscaler(HPA) per i workload di inferenza JetStream su host singolo con TPU su GKE. HPA è un modo efficiente per garantire che i server di modelli vengano scalati in modo appropriato in base al carico. La messa a punto delle impostazioni HPA è il modo principale per allineare il costo dell'hardware di cui è stato eseguito il provisioning alle richieste di traffico per raggiungere gli obiettivi di rendimento del server di inferenza.

Per esempi di come implementare queste best practice, consulta Configurare la scalabilità automatica per i workload LLM sulle TPU con GKE.

Per una panoramica consolidata di tutte le best practice di GKE, consulta Best practice per GKE.

Obiettivi

Questa guida è rivolta ai clienti di AI generativa, agli utenti GKE nuovi o esistenti, agli ingegneri ML e agli ingegneri LLMOps (DevOps) interessati a ottimizzare i workload JetStream su host singolo utilizzando le TPU con Kubernetes.

Dopo aver letto questa guida, dovresti essere in grado di:

  • Comprendi le metriche chiave di scalabilità automatica per l'inferenza JetStream su un singolo host.
  • Comprendi i compromessi di alto livello quando scegli le metriche su cui eseguire la scalabilità automatica.

Panoramica delle metriche di scalabilità automatica per l'inferenza JetStream

Ti consigliamo di utilizzare le seguenti metriche:

Metriche del server

JetStream, come molti altri server di inferenza LLM, fornisce metriche sul rendimento. GKE semplifica il monitoraggio e la scalabilità automatica di JetStream in base a queste metriche a livello di server. Per configurare la scalabilità automatica, devi prima capire in che modo la pipeline di richiesta JetStream influisce sugli indicatori chiave di prestazione. Tutte le richieste in entrata passano attraverso una coda di precompilazione, una coda di trasferimento e una coda di generazione, per poi diventare una richiesta di decodifica. JetStream accetta le richieste di decodifica su base continuativa e le elabora contemporaneamente utilizzando un numero fisso di thread di decodifica. La percentuale di motori di decodifica occupati a gestire una richiesta di decodifica in un determinato momento viene misurata come metrica jetstream_slots_used_percentage.

Per scalare JetStream su un singolo host, ciò ha due implicazioni per la latenza e il throughput:

  • Le richieste non verranno arretrate nelle code se la frequenza delle richieste in entrata è inferiore alla frequenza con cui gli slot di decodifica possono elaborare le richieste. Se JetStream non ha backlog, la velocità effettiva sarà proporzionale alla velocità delle richieste in entrata. La latenza rimarrà per lo più costante, ma aumenterà leggermente e proporzionalmente al numero di richieste di decodifica simultanee, poiché le richieste di decodifica appena accettate interromperanno la decodifica.
  • Le richieste verranno inserite in un backlog nelle code quando la frequenza delle richieste in entrata supera la frequenza con cui gli slot di decodifica possono elaborarle. Se JetStream ha un backlog, la latenza delle richieste aumenterà in modo più significativo e proporzionale al numero di richieste in backlog, mentre il throughput rimarrà costante.

Le seguenti metriche del server avranno la correlazione più forte con questi indicatori di rendimento pertinenti. Ti consigliamo di utilizzarli per la scalabilità automatica:

  • jetstream_prefill_backlog_size: il numero di richieste in attesa di elaborazione nella coda del server (arretrato). Questa metrica ha una forte correlazione con la latenza. Per saperne di più, consulta la sezione best practice correlata.
  • jetstream_slots_used_percentage: il numero di richieste sottoposte a inferenza in percentuale del numero totale di richieste che JetStream è in grado di gestire. Questa metrica ha una forte correlazione con il throughput. Per saperne di più, consulta la sezione relativa alle best practice.

Queste metriche sono spesso resilienti alle fluttuazioni del rendimento e del traffico, il che le rende un punto di partenza affidabile per la scalabilità automatica in diverse configurazioni hardware TPU.

Metriche TPU

Poiché l'erogazione di LLM è limitata dal collo di bottiglia della memoria e non dal calcolo, ti consigliamo di scalare JetStream in base alla memoria utilizzata anziché ad altre metriche TPU, in quanto riflette meglio l'utilizzo delle risorse dell'hardware. Per saperne di più, consulta la sezione best practice correlata.

Considerazioni per la scelta delle metriche di scalabilità automatica

Utilizza le seguenti considerazioni e best practice per selezionare la metrica migliore per la scalabilità automatica su GKE, in modo da soddisfare i tuoi obiettivi di rendimento del workload di inferenza.

Best practice: utilizza le dimensioni del backlog (coda) di pre-compilazione per massimizzare il throughput e ridurre al minimo i costi entro una determinata soglia di latenza target

Consigliamo la scalabilità automatica delle dimensioni della coda di precompilazione quando ottimizzi il throughput e il costo e quando i target di latenza sono raggiungibili con il throughput massimo delle dimensioni del batch per dispositivo del server di modelli.

La dimensione della coda di precompilazione è direttamente correlata alla latenza delle richieste. Le richieste in entrata vengono accodate nella coda di precompilazione dei server di modelli prima di essere elaborate e questo tempo di coda si aggiunge alla latenza complessiva. Le dimensioni della coda sono un indicatore sensibile dei picchi di carico, poiché l'aumento del carico riempie rapidamente la coda.

La scalabilità automatica in base alle dimensioni della coda di precompilazione riduce al minimo il tempo di attesa nella coda facendo lo scale up in caso di carico e facendo lo scale down quando la coda è vuota. Questo approccio è relativamente facile da implementare perché le dimensioni della coda sono indipendenti dalle dimensioni della richiesta, dal modello o dall'hardware.

Se vuoi massimizzare il throughput di ogni replica del server di modelli, valuta la possibilità di concentrarti sulle dimensioni della coda di precompilazione. La dimensione della coda di precompilazione monitora le richieste in attesa, non quelle in elaborazione. JetStream utilizza il batch continuo, che massimizza le richieste in parallelo e mantiene la coda bassa quando è disponibile spazio batch. La coda cresce notevolmente quando lo spazio del batch è limitato, quindi utilizza il punto di crescita come indicatore per avviare lo scale up. Combinando la scalabilità automatica delle dimensioni della coda con la velocità effettiva ottimizzata dei batch, puoi massimizzare la velocità effettiva delle richieste.

Determinare il valore di soglia ottimale per la dimensione della coda per HPA

Per scegliere la soglia corretta per le dimensioni della coda, inizia con un valore compreso tra 3 e 5 e aumentalo gradualmente fino a quando le richieste non raggiungono la latenza preferita. Utilizza lo strumento locust-load-inference per i test. Per soglie inferiori a 10, ottimizza le impostazioni di scale up dell'HPA per gestire i picchi di traffico.

Puoi anche creare una dashboard personalizzata di Cloud Monitoring per visualizzare il comportamento della metrica.

Limitazioni

Tieni presente la tolleranza HPA, che per impostazione predefinita prevede un intervallo di inattività di 0,1 intorno al valore target per ridurre l'oscillazione.

La dimensione della coda di precompilazione non controlla direttamente le richieste in parallelo, pertanto la sua soglia non può garantire una latenza inferiore a quella consentita dalle dimensioni del batch per dispositivo. Come soluzione alternativa, puoi ridurre manualmente la dimensione del batch per dispositivo o scalare automaticamente in base alla dimensione del batch.

Best practice: utilizza la percentuale slots_used per raggiungere soglie di latenza target inferiori rispetto alle dimensioni della coda

Ti consigliamo di scegliere la scalabilità automatica basata su slots_used se hai carichi di lavoro sensibili alla latenza in cui la scalabilità basata sulla coda non è abbastanza veloce per soddisfare i tuoi requisiti.

La scalabilità automatica in base a slots_used garantisce che il throughput dei tuoi workload aumenti per massimizzare il numero di richieste elaborate in parallelo contemporaneamente e diminuisca quando il numero di richieste elaborate in parallelo è inferiore. Ciò ha due implicazioni per la latenza. Innanzitutto, poiché la scalabilità automatica basata su slots_used viene eseguita per garantire uno slot per ogni richiesta in entrata, la vicinanza della soglia a 1 corrisponde alla probabilità che una richiesta trascorra del tempo in coda e di conseguenza abbia una latenza maggiore. In secondo luogo, batch di dimensioni maggiori aumentano il throughput, ma anche la latenza a causa della fase di precompilazione di alcune richieste che interrompono la fase di decodifica di altre nei server di modelli di batch continuo. Puoi monitorare i pattern delle dimensioni dei batch e utilizzare la scalabilità automatica per ridurre al minimo le richieste in parallelo durante i picchi di carico.

Se le dimensioni della coda soddisfano già i tuoi target di latenza, dai la priorità alla scalabilità automatica. In questo modo, massimizzi sia il throughput sia l'efficienza in termini di costi. Tuttavia, slots_used è utile per i carichi di lavoro sensibili alla latenza.

Ti consigliamo inoltre di impostare le dimensioni del batch per dispositivo su un valore appropriato prima di esplorare la scalabilità automatica basata su slots_used. Se vuoi, puoi anche abbinare questa opzione alla scalabilità automatica basata su coda.

Determinare il valore di soglia percentuale ottimale di slots_used per HPA

Per scegliere la soglia della dimensione batch corretta, aumenta sperimentalmente il carico sul server e osserva dove raggiunge il picco. Ti consigliamo inoltre di utilizzare lo strumento locust-load-inference per i test. Una volta identificata una dimensione batch ottimale per dispositivo in cui l'utilizzo della memoria è massimizzato, puoi configurare la percentuale target di slots_used. Imposta il valore target iniziale leggermente inferiore a 1 e diminuiscilo finché non ottieni la latenza preferita.

Puoi anche creare una dashboard personalizzata di Cloud Monitoring per visualizzare il comportamento della metrica.

Limitazioni

Tieni presente la tolleranza HPA, che è un intervallo di inattività predefinito di 0,1 intorno al valore target per smorzare l'oscillazione.

La scalabilità automatica in base alla percentuale di slots_used, sebbene utile per il controllo della latenza, presenta delle limitazioni. Le dimensioni variabili delle richieste e i vincoli hardware rendono difficile trovare la soglia percentuale di slots_used corretta. Se una regola di scalabilità tenta di mantenere la percentuale media di slots_used al di sotto del 100%, significa che la regola di scalabilità tenta di mantenere un numero diverso da zero di slot disponibili. Questi slot disponibili corrispondono alla velocità effettiva disponibile non utilizzata, il che non è l'ideale se vuoi sfruttare al meglio le TPU disponibili.

Best practice: utilizza la memoria ad alta larghezza di banda (HBM) della TPU per massimizzare l'utilizzo dell'hardware

L'utilizzo della memoria ad alta larghezza di banda (HBM) della TPU ha la corrispondenza più diretta con l'utilizzo dell'hardware, anche rispetto alle metriche di sistema, poiché non tengono conto delle dimensioni delle richieste. Sebbene lo scaling in base alle dimensioni della coda massimizzi meglio l'utilizzo dell'hardware, lo fa a scapito della latenza. Se preferisci utilizzare le metriche di sistema anziché quelle del server, ti consigliamo l'utilizzo di HBM come migliore alternativa per la scalabilità automatica con slots_used, poiché entrambi corrispondono alla velocità effettiva. Per saperne di più sulla memoria della TPU, consulta Come funziona una TPU.

L'aumento della dimensione del batch oltre il punto ottimale migliora il throughput, ma aumenta anche il rischio di errori out of memory (OOM). Ti consigliamo vivamente di scalare in base alla metrica HBM per bilanciare throughput e stabilità. Ti consigliamo di non scalare contemporaneamente con le dimensioni della coda di precompilazione e l'utilizzo di HBM, poiché all'aumentare del carico, l'utilizzo di HBM aumenterà e attiverà prima lo scaling.

Determinare il valore soglia ottimale di utilizzo della HBM della TPU per HPA

Prima di scegliere la soglia di utilizzo della memoria, ti consigliamo di impostare la dimensione del batch per dispositivo su un valore che massimizzi la memoria utilizzata quando si opera con il carico massimo previsto. Tieni presente che questo valore dovrà essere determinato in modo sperimentale e dipenderà in larga misura dall'HBM totale, nonché dalle lunghezze previste di prompt e risposte. Ti consigliamo di utilizzare lo strumento locust-load-inference per i tuoi esperimenti e test.

Analogamente alla dimensione del batch per dispositivo, imposta la soglia per massimizzare l'utilizzo della memoria della TPU riducendo al minimo il rischio di comportamento OOM.

Puoi anche creare una dashboard personalizzata di Cloud Monitoring per visualizzare il comportamento della metrica.

Limitazioni

Esistono due avvertenze che riducono la forza con cui la latenza e il throughput corrispondono all'utilizzo di HBM, ovvero la volatilità dell'utilizzo di HBM e la frequenza di campionamento inferiore delle metriche TPU in generale. Inoltre, anche se esiste ancora una corrispondenza tra l'utilizzo di HBM e la latenza, gli aumenti dell'utilizzo di HBM influiscono sulla latenza molto meno degli aumenti del numero di richieste in coda.

Best practice: ottimizza la configurazione dell'HPA

Ti consigliamo di impostare queste opzioni di configurazione dell'HPA:

  • Finestra di stabilizzazione: utilizza questa opzione di configurazione HPA per evitare rapidi cambiamenti nel conteggio delle repliche a causa di metriche fluttuanti. I valori predefiniti sono 5 minuti per lo scale down (per evitare uno scale down prematuro) e 0 per lo scale up (per garantire la reattività). Modifica il valore in base alla volatilità dei carichi di lavoro e alla reattività che preferisci.
  • Policy di scalabilità: utilizza questa opzione di configurazione HPA per ottimizzare il comportamento di scalabilità orizzontale e riduzione della scalabilità. Puoi impostare il limite della policy "Pod" per specificare il numero assoluto di repliche modificate per unità di tempo e il limite della policy "Percentuale" per specificare la variazione percentuale.

Per scoprire di più su queste opzioni, consulta la sezione Scalabilità automatica orizzontale dei pod nella documentazione di Kubernetes open source.

Passaggi successivi