Come la ricerca di Amazon M5 ha permesso di risparmiare il 30% dei costi per la formazione LLM utilizzando AWS Trainium.

Come la ricerca di Amazon M5 ha permesso di risparmiare il 30% dei costi per la formazione LLM utilizzando AWS Trainium una soluzione innovativa per la formazione a costo ridotto.

Da decenni, Amazon ha inaugurato e innovato nell’apprendimento automatico (ML), offrendo esperienze piacevoli ai suoi clienti. Fin dai primi giorni, Amazon ha utilizzato ML per vari casi d’uso come le raccomandazioni dei libri, la ricerca e la rilevazione delle frodi. Come il resto dell’industria, i progressi dell’hardware accelerato hanno permesso alle squadre di Amazon di perseguire architetture di modelli utilizzando reti neurali e deep learning (DL).

Il programma M5 all’interno di Amazon Search gestisce la strategia di apprendimento basato sulla scoperta per Amazon e sviluppa modelli su larga scala che coinvolgono multilingue, multi-località, multi-entità, multi-task e multimodali come testo, immagine e video. Il programma M5 ha fornito embedding universali e modelli di base su larga scala a centinaia di squadre di ML in tutta Amazon mantenendo rigorosi controlli per l’ottimizzazione dei costi. Per raggiungere questo obiettivo, il team M5 valuta regolarmente nuove tecniche per ridurre i costi.

Come molte organizzazioni di ML, gli acceleratori sono ampiamente utilizzati per accelerare l’addestramento e l’inferenza del DL. Quando AWS ha lanciato gli acceleratori appositamente progettati con il primo rilascio di AWS Inferentia nel 2020, il team M5 ha iniziato rapidamente a utilizzarli per distribuire in modo più efficiente carichi di lavoro di produzione, risparmiando sia costi che riducendo la latenza. Lo scorso anno, AWS ha lanciato i suoi acceleratori AWS Trainium, che ottimizzano le prestazioni per costo per lo sviluppo e la costruzione di modelli DL di prossima generazione. In questo post, discutiamo di come M5 è stato in grado di ridurre i costi di addestramento dei loro modelli del 30% e condividiamo alcune delle migliori pratiche che abbiamo imparato lungo il percorso.

Istanze Trainium

Con i progressi degli acceleratori appositamente progettati, Amazon fornisce anche acceleratori convincenti sotto forma di AWS Inferentia e Trainium. Come i loro nomi indicano, questi chip sono ottimizzati per soddisfare le esigenze dei carichi di lavoro di inferenza e di addestramento, rispettivamente. Per l’addestramento su larga scala dei modelli di base che raggiungono miliardi di parametri di dimensioni, le istanze Trainium Trn1 e Trn1n sono scelte ideali per le loro caratteristiche. Le istanze Trn1 sono alimentate dallo stato dell’arte NeuronCore-v2, e dispongono di un’ampia quantità di calcolo e memoria accelerati. Le istanze Trn1n possono anche essere scelte per una maggiore larghezza di banda di rete (1.600 Gbit/s) e sono quindi ideali per addestramenti performanti con l’ottimizzazione dei costi in mente.

Per utilizzare gli acceleratori, è necessario uno strato software di supporto. Con i chip Trn e Inf, l’AWS Neuron SDK sblocca gli acceleratori appositamente progettati di Amazon con l’aiuto di PyTorch XLA. PyTorch XLA converte la modalità impaziente di PyTorch in una modalità pigra basata su grafo. Questi grafi vengono quindi utilizzati e compilati per essere utilizzati con l’acceleratore. PyTorch Neuron (parte dell’AWS Neuron SDK) consente agli utenti di PyTorch di addestrare i propri modelli su Trainium NeuronCores con poche righe di codice.

Modello e carico di lavoro

Il team M5 addestra e distribuisce modelli fondamentali e rappresentazioni universali per assistere diverse squadre di Amazon nell’offrire soddisfazione ai clienti di Amazon.com. Uno di questi modelli è un modello di codificatore di testo seguito da un perceptron multi-strato (MLP) con interazioni tra le caratteristiche esplicite o implicite definite dall’architettura della rete neurale con centinaia di milioni di parametri addestrabili. Questo modello viene addestrato su miliardi di token e viene utilizzato per generare milioni di embedding in un’infrastruttura di inferenza batch offline. Questi embedding sono input per un servizio di primo livello di Amazon rivolto ai clienti.

Per il flusso di produzione, viene utilizzato AWS Batch con strategie di coda condivisa, utilizzando un cluster trn1.32xlarge multi-nodo abilitato per EFA come calcolo per l’addestramento del modello. Funzionalmente, il flusso di produzione esegue l’addestramento incrementale del modello, la valutazione del modello addestrato e l’inferenza batch offline sul modello addestrato, il tutto utilizzando PyTorch come libreria DL sottostante.

Obiettivi

Deliziare i nostri clienti è un principio fondamentale. Dato il carattere di relazione con il cliente del processo, è fondamentale rispettare tutti gli accordi di livello di servizio (SLA) senza regressioni. Abbiamo identificato due criteri fondamentali per adattare il nostro attuale processo di produzione GPU e passare a Trainium:

  • Qualità del modello – La qualità dei nostri modelli influisce direttamente sull’esperienza del cliente. Richiediamo che la differenza di qualità del modello tra GPU e Trainium sia inferiore al 0,1%.
  • Capacità di formazione – Alleniamo iterativamente i nostri modelli periodicamente per offrire un’esperienza sempre fresca ai nostri clienti. Richiediamo che la convergenza del modello venga raggiunta entro un periodo di tempo predefinito (ad esempio 1 settimana) per soddisfare i nostri SLA di produzione.

Nelle sezioni seguenti, condividiamo il nostro percorso di lavoro a ritroso da questi criteri e le nostre esperienze per supportare i carichi di lavoro di produzione della scala di Amazon.

Script di formazione

Prima di iniziare la formazione del modello, è necessario apportare modifiche allo script di formazione per renderlo conforme a XLA. Date le dimensioni del modello, utilizziamo il parallelismo di dati distribuito (DDP) per addestrare il modello. DDP ci consente di aumentare la velocità di formazione del modello aumentando il numero di macchine utilizzate per eseguire la formazione del modello, senza apportare modifiche al codice. Abbiamo seguito le istruzioni fornite nel tutorial di formazione MLP Neuron PyTorch per aggiungere costrutti specifici di XLA ai nostri script di formazione. Queste modifiche al codice sono facili da implementare. Di seguito sono riportati alcuni importanti apprendimenti tecnici derivanti dall’esercizio che hanno notevolmente migliorato la velocità di formazione del nostro modello:

  • Posizionamento di xm.mark_step()xm.mark_step() compila ed esegue i grafi di calcolo raccolti in modo pigro. Invocare mark_step troppe volte porterà a un numero maggiore di grafi piccoli, mentre invocarlo troppo poche volte porterà a pochi, ma grandi grafi. A seconda della tua applicazione, la velocità di formazione del tuo modello e l’implementazione varieranno in base al posizionamento di xm.mark_step(). La nostra implementazione inserisce un xm.mark_step() dopo un passaggio in avanti e indietro e uno dopo il passaggio dell’ottimizzatore.
  • Wrap del caricatore dei dati con caricatore di dispositivi XLA con multiprocessing – Questo è un passaggio critico che può essere facilmente trascurato. Il caricatore di dispositivi multiprocessing torch_xla.distributed.parallel_loader.MpDeviceLoader carica i dati di addestramento su ciascun dispositivo XLA con opzioni per il precaricamento e l’overlap del caricamento dei dati con l’esecuzione del dispositivo per migliorare la velocità. Il caricatore di dispositivi invoca anche xm.mark_step() ed è quindi in grado di creare grafici per il caricamento dei dati dal dispositivo all’host.

Compilazione per Trainium

Tradizionalmente, il ciclo di sviluppo del modello con GPU prevede apportare modifiche al modello o allo script di addestramento e avviarlo direttamente sul dispositivo GPU. I acceleratori come Trainium che utilizzano XLA richiedono un passaggio aggiuntivo prima che la formazione del modello possa essere eseguita sull’acceleratore. I grafi di calcolo XLA possono essere eseguiti solo dopo essere stati compilati. In generale, ci sono due modi per eseguire questa compilazione: Ahead of Time (AOT), in cui si tracciano e compilano prima tutti i grafici e quindi si eseguono, o Just In Time (JIT), in cui i grafici vengono tracciati, compilati ed eseguiti man mano che vengono incontrati. Lo SDK Neuron fornisce entrambe queste funzionalità di serie. Tipicamente, viene eseguita prima la compilazione AOT. I grafici vengono quindi eseguiti dopo questa compilazione. Se vengono incontrati nuovi grafici, il runtime Neuron invoca una compilazione JIT prima di eseguirli. Per eseguire la compilazione AOT, lo SDK Neuron fornisce neuron_parallel_compile, un’utilità di compilazione che estrae grafici da una esecuzione di prova dello script di addestramento e esegue una compilazione parallela AOT.

Un aspetto importante della compilazione AOT è assicurarsi che non vengano creati nuovi grafi di calcolo nel corso dell’addestramento. Una fonte di nuovi grafi di calcolo (e quindi ricompilazioni) sono le forme dinamiche dei batch di addestramento durante l’addestramento del modello. Abbiamo scoperto che l’utilizzo di forme statiche e batch di dimensioni fisse elimina le compilazioni durante l’addestramento e migliora notevolmente la velocità di addestramento senza alcun effetto sulla precisione del modello. Applicando tali vincoli all’addestramento, abbiamo osservato che sono necessari solo 4-5 passi di addestramento del modello, un passo di convalida del modello e il salvataggio del modello una volta per tracciare tutti i grafici durante la compilazione AOT. È importante notare che lo SDK Neuron è in continua evoluzione e in futuro supporterà anche forme dinamiche.

Inoltre, i grafici compilati vengono memorizzati nella Cache Persistente di Neuron su disco o in un bucket di Amazon Simple Storage Service (Amazon S3). Questo è particolarmente utile per i carichi di lavoro di produzione in cui l’architettura del modello e la configurazione di addestramento non cambiano. Pertanto, l’onere della compilazione viene sostenuto solo una volta. Utilizzare la cache è semplice come impostare un flag dell’ambiente:

export NEURON_COMPILE_CACHE_URL="s3://BUCKET/KEY"

Il compilatore di Neuron fornisce anche tre opzioni di ottimizzazione a livello di compilatore (O1, O2, O3) per bilanciare il tempo di compilazione e la velocità di esecuzione del modello. O1 abilita le ottimizzazioni di base sul grafo di calcolo e minimizza il tempo di compilazione, O3 fornisce una velocità di esecuzione del modello migliore a scapito di un tempo di compilazione più lungo, mentre O2 (opzione predefinita) è un equilibrio tra i due. Per il nostro caso d’uso, abbiamo utilizzato l’ottimizzazione O1 e abbiamo osservato una riduzione dell’86% del tempo di compilazione senza alcuna modifica alle metriche di precisione del modello, mentre abbiamo osservato una riduzione del 5-7% del throughput rispetto all’ottimizzazione predefinita (O2). A seconda del caso d’uso, è possibile scegliere diversi livelli di ottimizzazione.

Per riassumere, abbiamo utilizzato i seguenti flag per la compilazione:

NEURON_CC_FLAGS="--target trn1 --auto-cast all --auto-cast-type bf16 --model-type transformer --optlevel O1"

Compatibilità dei checkpoint

Quando la compilazione viene completata con successo, possiamo procedere all’addestramento dei nostri modelli su Trainium. Come accennato in precedenza, addestriamo incrementalmente i nostri modelli, il che significa che carichiamo un checkpoint di modello precedentemente addestrato e continuiamo l’addestramento con nuovi dati. PyTorch e PyTorch XLA consentono una transizione senza soluzione di continuità tra gli acceleratori grazie all’interoperabilità dei checkpoint. Avendo la flessibilità di passare da GPU a Trainium, siamo riusciti a caricare senza problemi il modello GPU precedente e addestrare sulle macchine Trainium. Questo è stato fondamentale per garantire che potessimo inizializzare il nostro modello con il miglior modello precedentemente addestrato senza interruzioni nella produzione o perdita di accuratezza del modello.

Poiché il modello GPU è stato salvato utilizzando le utility di salvataggio del modello standard di PyTorch, abbiamo potuto utilizzare l’utilità di caricamento del checkpoint di PyTorch per caricare il modello GPU su dispositivi Trainium.

Ad esempio, su GPU/CPU, è possibile salvare il modello con il seguente codice:

torch.save(model.state_dict(), PATH)

Poi, è possibile caricare il modello su Trainium:

import torch_xla.core.xla_model as xm
xla_device = xm.xla_device()
model = MyModel(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.to(xla_device)

In modo simile, è possibile salvare il modello su Trainium con il seguente codice:

import torch_xla.core.xla_model as xm
# sposta automaticamente i dati su CPU per il dispositivo principale
xm.save(model.state_dict(), PATH) 

E caricare il modello su GPU/CPU:

model = MyModel(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.to(device) # può essere qualsiasi dispositivo

In effetti, poiché utilizziamo DDP per l’addestramento del modello, il caricamento del modello è indipendente dal numero di macchine utilizzate per addestrare il checkpoint precedente. Ciò ci consente di scalare orizzontalmente la flotta Trn1 senza modifiche al codice o effetti negativi sull’addestramento del modello. Questi checkpoint basati su PyTorch possono essere utilizzati direttamente o anche torch-scripted per casi di utilizzo di inferenza su AWS Inferentia2 o altri acceleratori.

Stabilità operativa

Non si può sottolineare abbastanza che l’esecuzione di carichi di lavoro in produzione richiede il rispetto di più SLA. Nel nostro caso d’uso, oltre alla qualità del modello e alle SLA della velocità di addestramento, è essenziale che il flusso di lavoro di produzione sia operativamente stabile, ovvero con tempi di inattività e interruzioni minimi durante l’addestramento del modello, la valutazione e l’inferenza.

Come nel flusso di lavoro basato su GPU esistente, abbiamo aggiunto numerosi meccanismi per rendere il flusso di lavoro operativamente stabile. Prima di avviare l’addestramento del modello, eseguiamo più test di sanità per valutare lo stato delle macchine. Questi test includono generalmente semplici operazioni sui tensori per verificare lo stato dei dispositivi di accelerazione. Abbiamo osservato che per il training distribuito è importante eseguire test per verificare la comunicazione collettiva tra le istanze. Abbiamo utilizzato il set di test NCCOM dall’SDK di Neuron per raggiungere questo obiettivo, eseguendo una varietà di operazioni come all-gather, all-reduce e reduce-scatter.

Anche dopo aver seguito i suggerimenti che abbiamo menzionato, abbiamo osservato che problemi temporanei sono inevitabili in qualsiasi pipeline, indipendentemente dall’acceleratore sottostante. Per aumentare la resilienza in qualsiasi pipeline di addestramento, consigliamo di inserire meccanismi di ripetizione per risolvere questi problemi potenziali. Utilizziamo i riprova automatica di AWS Batch per riprovare i lavori che incontrano un fallimento temporaneo durante l’addestramento del modello. Questi riavvii possono essere costosi se si verifica un fallimento verso la fine dell’addestramento. Per contrastare questo problema, abbiamo adattato i nostri script di addestramento per caricare un checkpoint di modello precedentemente addestrato e continuare l’addestramento da quel punto. Con questa funzionalità, siamo in grado di riavviare aggressivamente i lavori di addestramento falliti con un minimo sovraccarico.

Con questi meccanismi di resilienza in atto, siamo riusciti a ottenere tassi di successo del 98,5% per i nostri carichi di lavoro su Trn1, paragonabili ai tassi di successo della nostra pipeline GPU esistente.

Risultati

Per convalidare l’accuratezza dei nostri modelli, abbiamo avviato due modelli dallo stesso checkpoint di GPU e ne abbiamo addestrato uno su Trainium e l’altro su una GPU comparabile. Entrambi i modelli sono stati addestrati con gli stessi iperparametri di addestramento. Il set di dati utilizzato per il calcolo delle metriche è un set di dati separato, e valutiamo l’accuratezza del modello su questo set di dati ogni N passi globali. L’asse X rappresenta il passaggio globale e l’asse Y rappresenta l’accuratezza del modello. Abbiamo osservato una differenza inferiore al 0,1% nell’accuratezza del modello in ciascun punto nel grafico seguente.

Inoltre, per valutare l’efficacia in rapporto al costo dell’addestramento del modello, preferiamo confrontare il tempo di clock impiegato per raggiungere la convergenza del modello. Riteniamo che ciò fornisca una visione più pratica dei risparmi di costo rispetto a misure come il costo per token, i FLOPS/dollaro raggiunti e altri fattori. Considerando il tempo di addestramento di trn1.32xl e le istanze comparabili di Amazon Elastic Compute Cloud (Amazon EC2), abbiamo osservato che Trainium offre un costo inferiore fino al 30% per la convergenza del modello.

Conclusioni

Ci sono molti fattori da considerare quando si valutano diversi acceleratori per i carichi di lavoro DL. Alcuni dei più importanti sono la qualità del modello, la velocità di elaborazione, il costo e la disponibilità. È fondamentale assicurarsi che la qualità del modello e la velocità di elaborazione non vengano sacrificate in base all’acceleratore scelto.

Grazie alla nostra partnership e collaborazione con il team di Annapurna Neuron, il team di Amazon Search M5 è stato in grado di risparmiare fino al 30% dei costi passando a Trainium. Il team è in grado di utilizzare Trainium e raggiungere la parità di qualità del modello e velocità di elaborazione con gli acceleratori comparabili presenti sul mercato. L’interoperabilità del checkpoint e i minimi cambiamenti nel codice con il supporto per XLA hanno permesso a M5 di scegliere tra più acceleratori per i loro carichi di lavoro. Ciò ha consentito al team di M5 di sfruttare la potenza di calcolo elevata di Trainium e creare soluzioni agnostiche per l’acceleratore per soddisfare i clienti di Amazon.com. Dal punto di vista operativo, Trainium è stato dimostrato capace di supportare servizi di livello 1 su scala Amazon. Il team di M5 continua a spostare più carichi di lavoro su Trainium per offrire i migliori modelli ad Amazon ai costi più bassi.

In sintesi, il team di M5 è stato in grado di eseguire l’addestramento ML a costo efficace e di qualità di produzione aggiungendo Trainium alla flotta di acceleratori. Ti incoraggiamo a dare un’occhiata a Trainium e ad altre dispositivi Neuron come AWS Inferentia per raccogliere i benefici del silicio Amazon appositamente progettato per i carichi di lavoro di ML. Inizia facilmente con uno dei molti tutorial che presentano modelli diversi, come Llama 2, disponibile su Trainium.