Tecniche avanzate per migliorare il throughput LLM

Pubblicato: 2024-04-02
Mostra il sommario
Sfide nel raggiungimento di un throughput più elevato per i LLM
Requisito di memoria
Autoregressività e operazione legata alla memoria
Soluzioni innovative per superare le sfide della produttività
Dosaggio continuo
Attenzione paginata
Attenzione lampo
Caratteristiche principali di Flash Attenzione:
Caso di studio: ottimizzazione dell'inferenza con la decodifica speculativa
Conclusione

Nel frenetico mondo della tecnologia, i Large Language Model (LLM) sono diventati attori chiave nel modo in cui interagiamo con le informazioni digitali. Questi potenti strumenti possono scrivere articoli, rispondere a domande e persino tenere conversazioni, ma non sono privi di sfide. Poiché pretendiamo di più da questi modelli, ci imbattiamo in ostacoli, soprattutto quando si tratta di farli funzionare in modo più rapido ed efficiente. Questo blog parla di affrontare questi ostacoli a testa alta.

Stiamo approfondendo alcune strategie intelligenti progettate per aumentare la velocità con cui operano questi modelli, senza perdere la qualità del loro risultato. Immagina di provare a migliorare la velocità di un'auto da corsa assicurandoti allo stesso tempo che possa ancora percorrere curve strette in modo impeccabile: questo è ciò a cui miriamo con modelli linguistici di grandi dimensioni. Esamineremo metodi come il Continuous Batching, che aiuta a elaborare le informazioni in modo più fluido, e approcci innovativi come Paged e Flash Attention, che rendono gli LLM più attenti e veloci nel ragionamento digitale.

Quindi, se sei curioso di spingerti oltre i limiti di ciò che possono fare questi giganti dell'intelligenza artificiale, sei nel posto giusto. Esploriamo insieme come queste tecniche avanzate stanno plasmando il futuro dei LLM, rendendoli più veloci e migliori che mai.

Sfide nel raggiungimento di un throughput più elevato per i LLM

Il raggiungimento di un throughput più elevato nei Large Language Models (LLM) deve affrontare diverse sfide significative, ognuna delle quali costituisce un ostacolo alla velocità e all’efficienza con cui questi modelli possono funzionare. Uno degli ostacoli principali è l’enorme fabbisogno di memoria necessario per elaborare e archiviare le grandi quantità di dati con cui lavorano questi modelli. Man mano che gli LLM crescono in complessità e dimensioni, la domanda di risorse computazionali si intensifica, rendendo difficile mantenere, per non parlare di migliorare, le velocità di elaborazione.

Un'altra sfida importante è la natura autoregressiva degli LLM, soprattutto nei modelli utilizzati per generare testo. Ciò significa che l’output di ogni passaggio dipende da quelli precedenti, creando un requisito di elaborazione sequenziale che limita intrinsecamente la velocità con cui le attività possono essere eseguite. Questa dipendenza sequenziale spesso si traduce in un collo di bottiglia, poiché ogni passaggio deve attendere il completamento del passaggio precedente prima di poter procedere, ostacolando gli sforzi volti a ottenere un throughput più elevato.

Inoltre, l’equilibrio tra precisione e velocità è delicato. Migliorare la produttività senza compromettere la qualità dell’output è una passeggiata sul filo del rasoio, che richiede soluzioni innovative in grado di destreggiarsi nel complesso panorama dell’efficienza computazionale e dell’efficacia dei modelli.

Queste sfide costituiscono lo sfondo su cui vengono compiuti i progressi nell'ottimizzazione LLM, ampliando i confini di ciò che è possibile nel campo dell'elaborazione del linguaggio naturale e oltre.

Requisito di memoria

La fase di decodifica genera un singolo token in ogni fase temporale, ma ogni token dipende dai tensori chiave e valore di tutti i token precedenti (inclusi i tensori KV dei token di input calcolati al momento della precompilazione e qualsiasi nuovo tensore KV calcolato fino alla fase temporale corrente) .

Pertanto, per ridurre al minimo i calcoli ridondanti ogni volta ed evitare di ricalcolare tutti questi tensori per tutti i token ad ogni passo temporale, è possibile memorizzarli nella memoria della GPU. Ad ogni iterazione, quando vengono calcolati nuovi elementi, questi vengono semplicemente aggiunti alla cache in esecuzione per essere utilizzati nell'iterazione successiva. Questo è essenzialmente noto come cache KV.

Ciò riduce notevolmente il calcolo necessario, ma introduce un requisito di memoria insieme a requisiti di memoria già più elevati per modelli linguistici di grandi dimensioni che rendono difficile l'esecuzione su GPU commerciali. Con l'aumento delle dimensioni dei parametri del modello (da 7B a 33B) e la maggiore precisione (da fp16 a fp32) aumentano anche i requisiti di memoria. Vediamo un esempio per la capacità di memoria richiesta,

Come sappiamo, i due principali occupanti della memoria sono

  1. Pesi del modello in memoria, questo viene fornito con n. di parametri come 7B e tipo di dati di ciascun parametro, ad esempio 7B in fp16 (2 byte) ~= 14 GB in memoria
  2. Cache KV: la cache utilizzata per il valore chiave della fase di auto-attenzione per evitare calcoli ridondanti.

Dimensione della cache KV per token in byte = 2 * (num_layers) * (hidden_size) * Precision_in_bytes

Il primo fattore 2 tiene conto delle matrici K e V. Questi hidden_size e dim_head possono essere ottenuti dalla scheda del modello o dal file di configurazione.

La formula sopra è per token, quindi per una sequenza di input sarà seq_len * size_of_kv_per_token. Quindi la formula sopra si trasformerà in,

Dimensione totale della cache KV in byte = (sequence_length) * 2 * (num_layers) * (hidden_size) * Precision_in_bytes

Ad esempio, con LLAMA 2 in fp16, la dimensione sarà (4096) * 2 * (32) * (4096) * 2, ovvero ~2 GB.

Quanto sopra è per un singolo input, con più input cresce rapidamente, questa allocazione e gestione della memoria in volo diventa quindi un passaggio cruciale per ottenere prestazioni ottimali, altrimenti si traducono in problemi di memoria esaurita e frammentazione.

A volte, il requisito di memoria è superiore alla capacità della nostra GPU, in questi casi dobbiamo esaminare il parallelismo del modello, il parallelismo del tensore che non è trattato qui ma puoi esplorare in quella direzione.

Autoregressività e operazione legata alla memoria

Come possiamo vedere, la parte di generazione dell’output dei modelli linguistici di grandi dimensioni è di natura autoregressiva. L'indica che ogni nuovo token da generare dipende da tutti i token precedenti e dai loro stati intermedi. Poiché nella fase di output non tutti i token sono disponibili per eseguire ulteriori calcoli e ha solo un vettore (per il token successivo) e il blocco della fase precedente, questa diventa come un'operazione matrice-vettore che sottoutilizza la capacità di calcolo della GPU quando rispetto alla fase di preriempimento. La velocità con cui i dati (pesi, chiavi, valori, attivazioni) vengono trasferiti alla GPU dalla memoria domina la latenza, non la velocità effettiva dei calcoli. In altre parole, questa è un'operazione legata alla memoria .

Soluzioni innovative per superare le sfide della produttività

Dosaggio continuo

Il passaggio molto semplice per ridurre la natura legata alla memoria della fase di decodifica è raggruppare l'input ed eseguire calcoli per più input contemporaneamente. Ma un semplice batch costante ha comportato scarse prestazioni a causa della natura delle diverse lunghezze di sequenza generate e in questo caso la latenza di un batch dipende dalla sequenza più lunga generata in un batch e anche dalla crescente richiesta di memoria poiché vengono utilizzati più input ora elaborato immediatamente.

Pertanto, il semplice dosaggio statico è inefficace e si arriva al dosaggio continuo. La sua essenza risiede nell'aggregazione dinamica dei lotti di richieste in entrata, nell'adattamento alle fluttuazioni dei tassi di arrivo e nello sfruttamento delle opportunità di elaborazione parallela quando possibile. Ciò ottimizza anche l'utilizzo della memoria raggruppando sequenze di lunghezze simili in ciascun batch, riducendo al minimo la quantità di riempimento necessaria per sequenze più brevi ed evitando di sprecare risorse di calcolo per un riempimento eccessivo.

Regola in modo adattivo la dimensione del batch in base a fattori quali la capacità di memoria corrente, le risorse di calcolo e la lunghezza della sequenza di input. Ciò garantisce che il modello funzioni in modo ottimale in condizioni variabili senza superare i limiti di memoria. Questo aiuta con l'attenzione sulla pagina (spiegato di seguito) aiuta a ridurre la latenza e ad aumentare la velocità effettiva.

Ulteriori informazioni: In che modo l'invio in batch continuo consente un throughput 23 volte superiore nell'inferenza LLM riducendo al contempo la latenza p50

Attenzione paginata

Poiché eseguiamo il batching per migliorare il throughput, ciò comporta anche un aumento dei requisiti di memoria cache KV, poiché ora stiamo elaborando più input contemporaneamente. Queste sequenze possono superare la capacità di memoria delle risorse computazionali disponibili, rendendo poco pratico elaborarle nella loro interezza.

Si osserva inoltre che l'allocazione ingenua della memoria della cache KV determina una notevole frammentazione della memoria, proprio come osserviamo nei sistemi informatici a causa dell'allocazione non uniforme della memoria. vLLM ha introdotto Paged Attention, una tecnica di gestione della memoria ispirata ai concetti di paging e memoria virtuale del sistema operativo per gestire in modo efficiente il crescente fabbisogno di cache KV.

L'attenzione paginata risolve i vincoli di memoria dividendo il meccanismo di attenzione in pagine o segmenti più piccoli, ciascuno dei quali copre un sottoinsieme della sequenza di input. Invece di calcolare i punteggi di attenzione per l’intera sequenza di input in una volta, il modello si concentra su una pagina alla volta, elaborandola in sequenza.

Durante l'inferenza o l'addestramento, il modello esegue l'iterazione di ciascuna pagina della sequenza di input, calcolando i punteggi di attenzione e generando l'output di conseguenza. Una volta elaborata una pagina, i suoi risultati vengono archiviati e il modello passa alla pagina successiva.

Dividendo il meccanismo di attenzione in pagine, Paged Attention consente al modello linguistico Large di gestire sequenze di input di lunghezza arbitraria senza superare i vincoli di memoria. Riduce efficacemente l'ingombro di memoria richiesto per l'elaborazione di lunghe sequenze, rendendo possibile lavorare con documenti e batch di grandi dimensioni.

Ulteriori informazioni: Servizio LLM veloce con vLLM e PagedAttention

Attenzione lampo

Poiché il meccanismo di attenzione è cruciale per i modelli di trasformazione su cui si basano i modelli linguistici di grandi dimensioni, aiuta il modello a concentrarsi su parti rilevanti del testo di input quando si effettuano previsioni. Tuttavia, man mano che i modelli basati su trasformatori diventano più grandi e complessi, il meccanismo di auto-attenzione diventa sempre più lento e fa un uso intensivo di memoria, portando a un problema di collo di bottiglia della memoria, come menzionato in precedenza. Flash Attention è un'altra tecnica di ottimizzazione che mira a mitigare questo problema ottimizzando le operazioni di attenzione, consentendo training e inferenza più rapidi.

Caratteristiche principali di Flash Attenzione:

Kernel Fusion: è importante non solo massimizzare l'utilizzo del calcolo della GPU, ma anche farlo nel modo più efficiente possibile. Flash Attention combina più passaggi di calcolo in un'unica operazione, riducendo la necessità di trasferimenti di dati ripetitivi. Questo approccio semplificato semplifica il processo di implementazione e migliora l’efficienza computazionale.

Affiancamento: Flash Attention divide i dati caricati in blocchi più piccoli, favorendo l'elaborazione parallela. Questa strategia ottimizza l'utilizzo della memoria, consentendo soluzioni scalabili per modelli con dimensioni di input maggiori.

(Kernel CUDA fuso che illustra come l'affiancamento e la fusione riducono il tempo richiesto per il calcolo, fonte immagine: FlashAttention: attenzione esatta veloce ed efficiente in termini di memoria con consapevolezza IO)

Ottimizzazione della memoria: Flash Attention carica i parametri solo per gli ultimi token, riutilizzando le attivazioni dei token calcolati di recente. Questo approccio a finestra scorrevole riduce il numero di richieste I/O per caricare i pesi e massimizza il throughput della memoria flash.

Trasferimenti di dati ridotti: Flash Attention riduce al minimo i trasferimenti di dati avanti e indietro tra tipi di memoria, come memoria a larghezza di banda elevata (HBM) e SRAM (memoria ad accesso casuale statico). Caricando tutti i dati (query, chiavi e valori) una sola volta, si riduce il sovraccarico dei trasferimenti di dati ripetitivi.

Caso di studio: ottimizzazione dell'inferenza con la decodifica speculativa

Un altro metodo utilizzato per accelerare la generazione del testo nel modello linguistico autoregressivo è la decodifica speculativa. L'obiettivo principale della decodifica speculativa è velocizzare la generazione del testo preservando la qualità del testo generato a un livello paragonabile a quello della distribuzione target.

La decodifica speculativa introduce un modello piccolo/bozza che prevede i token successivi nella sequenza, che vengono poi accettati/rifiutati dal modello principale in base a criteri predefiniti. L'integrazione di un modello di bozza più piccolo con il modello di destinazione aumenta significativamente la velocità di generazione del testo, ciò è dovuto alla natura dei requisiti di memoria. Poiché la bozza del modello è piccola, richiede meno n. di pesi di neuroni da caricare e il n. Anche il tempo di calcolo è ora inferiore rispetto al modello principale, ciò riduce la latenza e accelera il processo di generazione dell'output. Il modello principale valuta quindi i risultati generati e garantisce che si adattino alla distribuzione target del prossimo probabile token.

In sostanza, la decodifica speculativa semplifica il processo di generazione del testo sfruttando un modello di bozza più piccolo e più veloce per prevedere i token successivi, accelerando così la velocità complessiva della generazione del testo mantenendo la qualità del contenuto generato vicino alla distribuzione target.

È molto importante che i token generati dai modelli più piccoli non vengano sempre costantemente rifiutati, questo caso porta ad un calo delle prestazioni invece che ad un miglioramento. Attraverso gli esperimenti e la natura dei casi d'uso possiamo selezionare un modello più piccolo/introdurre la decodifica speculativa nel processo di inferenza.

Conclusione

Il viaggio attraverso le tecniche avanzate per migliorare la produttività del Large Language Model (LLM) illumina un percorso da seguire nel regno dell'elaborazione del linguaggio naturale, mostrando non solo le sfide ma le soluzioni innovative che possono affrontarle direttamente. Queste tecniche, dal Continuous Batching al Paged e Flash Attention, e l'intrigante approccio della Speculative Decoding, sono molto più che semplici miglioramenti incrementali. Rappresentano significativi passi avanti nella nostra capacità di rendere modelli linguistici di grandi dimensioni più veloci, più efficienti e, in definitiva, più accessibili per un’ampia gamma di applicazioni.

L’importanza di questi progressi non può essere sopravvalutata. Nell'ottimizzare il throughput LLM e nel migliorare le prestazioni, non stiamo solo ottimizzando i motori di questi potenti modelli; stiamo ridefinendo ciò che è possibile in termini di velocità ed efficienza di elaborazione. Ciò, a sua volta, apre nuovi orizzonti per l’applicazione di un modello linguistico di grandi dimensioni, dai servizi di traduzione linguistica in tempo reale che possono operare alla velocità della conversazione, a strumenti di analisi avanzati in grado di elaborare vasti set di dati con una velocità senza precedenti.

Inoltre, queste tecniche sottolineano l’importanza di un approccio equilibrato all’ottimizzazione di modelli linguistici di grandi dimensioni, che consideri attentamente l’interazione tra velocità, precisione e risorse computazionali. Man mano che ampliamo i confini delle capacità LLM, mantenere questo equilibrio sarà fondamentale per garantire che questi modelli possano continuare a fungere da strumenti versatili e affidabili in una miriade di settori.

Le tecniche avanzate per migliorare la produttività di modelli linguistici di grandi dimensioni sono molto più che semplici risultati tecnici; sono pietre miliari nella continua evoluzione dell’intelligenza artificiale. Promettono di rendere i LLM più adattabili, più efficienti e più potenti, aprendo la strada a innovazioni future che continueranno a trasformare il nostro panorama digitale.

Scopri di più sull'architettura GPU per l'ottimizzazione dell'inferenza di modelli linguistici di grandi dimensioni nel nostro recente post sul blog