Presentazione di Packed BERT per una velocità di formazione doppia nell'elaborazione del linguaggio naturale

Nodo di origine: 1062065

Presentazione di Packed BERT per una velocità di formazione doppia nell'elaborazione del linguaggio naturale

Dai un'occhiata a questo nuovo algoritmo di confezionamento BERT per un allenamento più efficiente.


By Dott. Mario Michael Krell, Principal Machine Learning Lead presso Graphcore & Matej Kosec, Specialista di applicazioni AI presso Graphcore


Header image
Immagine dell'autore.

 

Utilizzando un nuovo algoritmo di compressione, abbiamo accelerato l'elaborazione del linguaggio naturale di oltre 2 volte durante l'addestramento di BERT-Large. La nostra nuova tecnica di imballaggio rimuove il riempimento, consentendo un calcolo significativamente più efficiente.

Sospettiamo che ciò possa essere applicato anche alla genomica e ai modelli di ripiegamento delle proteine ​​e ad altri modelli con distribuzioni di lunghezza distorte per avere un impatto molto più ampio in diversi settori e applicazioni.

Abbiamo introdotto l'algoritmo altamente efficiente Non-Negative Least Squares Histogram-Packing di Graphcore (o NNLSHP) così come il nostro algoritmo BERT applicato a sequenze impacchettate in un nuovo documento [1].

Rifiuti computazionali nella PNL a causa del riempimento di sequenza

 
 
Abbiamo iniziato a studiare nuovi modi per ottimizzare la formazione BERT mentre lavoravamo al nostro recente invii di benchmark a MLPerf™. L'obiettivo era sviluppare ottimizzazioni utili che potessero essere facilmente adottate nelle applicazioni del mondo reale. BERT è stata una scelta naturale come uno dei modelli su cui concentrarsi per queste ottimizzazioni, poiché è ampiamente utilizzato nell'industria e da molti dei nostri clienti.

Ci ha davvero sorpreso apprendere che nella nostra applicazione di addestramento BERT-Large che utilizzava il set di dati di Wikipedia, il 50% dei token nel set di dati erano riempiti, con conseguente spreco di calcolo.

Il riempimento delle sequenze per allinearle tutte alla stessa lunghezza è un approccio comune utilizzato con le GPU, ma abbiamo pensato che valesse la pena provare un approccio diverso.

Le sequenze hanno una grande variazione di lunghezza per due motivi:

  1. I dati di Wikipedia sottostanti mostrano una grande variazione nella lunghezza del documento
  2. La stessa pre-elaborazione BERT riduce in modo casuale le dimensioni dei documenti estratti che vengono combinati per generare una sequenza di addestramento

Il riempimento della lunghezza fino alla lunghezza massima di 512 fa sì che il 50% di tutti i token siano token di riempimento. La sostituzione del 50% del riempimento con dati reali potrebbe comportare l'elaborazione del 50% in più di dati con lo stesso sforzo computazionale e quindi una velocità 2 volte superiore in condizioni ottimali.



Figura 1: Distribuzioni dei set di dati di Wikipedia. Immagine dell'autore.

 

Questo è specifico di Wikipedia? No.

Bene, allora è specifico per la lingua? No.

In effetti, distribuzioni di lunghezza asimmetriche si trovano ovunque: nel linguaggio, nella genomica e nel ripiegamento delle proteine. Le Figure 2 e 3 mostrano le distribuzioni per il dataset SQuAD 1.1 e per i dataset GLUE.



Figura 2: Istogramma della lunghezza della sequenza del set di dati di pre-addestramento BERT SQuAD 1.1 per la lunghezza massima della sequenza di 384. Immagine dell'autore.

 


Figura 3: Istogrammi della lunghezza della sequenza del set di dati GLUE per la lunghezza massima della sequenza di 128. Immagine dell'autore.

 

Come possiamo gestire le diverse lunghezze evitando lo spreco di calcolo?

Gli approcci attuali richiedono kernel computazionali diversi per lunghezze diverse o che l'ingegnere rimuova a livello di codice il riempimento e quindi lo aggiunga ripetutamente per ogni blocco di attenzione e calcolo della perdita. Salvare il calcolo facendo saltare in aria il codice e renderlo più complesso non era allettante, quindi abbiamo cercato qualcosa di meglio. Non possiamo semplicemente mettere insieme più sequenze in un pacchetto con una lunghezza massima ed elaborarle tutte insieme? Si scopre che possiamo!

Questo approccio richiede tre ingredienti chiave:

  1. Un algoritmo efficiente per decidere quali campioni mettere insieme per avere il minor riempimento possibile
  2. Adeguamento del modello BERT per elaborare i pacchetti anziché le sequenze
  3. E regolando gli iperparametri

Imballaggio

 
 
All'inizio, sembrava improbabile che si potesse imballare un set di dati di grandi dimensioni come Wikipedia in modo molto efficiente. Questo problema è comunemente noto come bin-packing. Anche quando l'imballaggio è limitato a tre sequenze o meno, il problema risultante sarebbe ancora fortemente NP-completo, privo di una soluzione algoritmica efficiente. Gli algoritmi di impacchettamento euristico esistenti non erano promettenti perché avevano una complessità almeno pari a O(n registro(n)), dove n è il numero di sequenze (~16M per Wikipedia). Eravamo interessati ad approcci che si adattassero bene a milioni di sequenze.

Due trucchi ci hanno aiutato a ridurre drasticamente la complessità:

  1. Limitare il numero di sequenze in un pacchetto a tre (per il nostro primo approccio di soluzione)
  2. Operando esclusivamente sull'istogramma della lunghezza della sequenza con un bin per ogni lunghezza che si verifica

La nostra lunghezza massima della sequenza era 512. Quindi, il passaggio all'istogramma ha ridotto la dimensione e la complessità da 16 milioni di sequenze a 512 conteggi di lunghezza. Consentire un massimo di tre sequenze in un pacchetto ha ridotto il numero di combinazioni di lunghezza consentite a 22K. Ciò includeva già il trucco per richiedere che le sequenze fossero ordinate per lunghezza nel pacchetto. Allora perché non provare 4 sequenze? Ciò ha aumentato il numero di combinazioni da 22K a 940K, che era troppo per il nostro primo approccio di modellazione. Inoltre, la profondità 3 ha già raggiunto un'efficienza di confezionamento notevolmente elevata.

Inizialmente, pensavamo che l'utilizzo di più di tre sequenze in un pacchetto avrebbe aumentato il sovraccarico di calcolo e avrebbe avuto un impatto sul comportamento di convergenza durante l'allenamento. Tuttavia, per supportare applicazioni come l'inferenza, che richiedono un impacchettamento in tempo reale ancora più rapido, abbiamo sviluppato l'algoritmo altamente efficiente Non-Negative Least Squares Histogram-Packing (NNLSHP).

Imballaggio dell'istogramma dei minimi quadrati non negativo (NNLSHP)

 
 
L'imballaggio dei contenitori è spesso formulato come un problema di ottimizzazione matematica. Tuttavia, con 16 milioni di sequenze (o più) questo non è pratico. Le variabili del problema da sole supererebbero la memoria della maggior parte delle macchine. Il programma matematico per un approccio basato sugli istogrammi è abbastanza accurato. Per semplicità, abbiamo deciso per un approccio ai minimi quadrati (Ascia = b) con vettore istogramma b. Lo abbiamo esteso richiedendo il vettore della strategia x essere non negativo e aggiungere pesi per consentire un riempimento minore.

La parte difficile è stata la matrice della strategia. Ogni colonna ha una somma massima di tre e codifica quali sequenze vengono impacchettate insieme per corrispondere esattamente alla lunghezza totale desiderata; 512 nel nostro caso. Le righe codificano ciascuna delle potenziali combinazioni per raggiungere una lunghezza pari alla lunghezza totale. Il vettore della strategia x è quello che stavamo cercando, che descrive la frequenza con cui scegliamo una delle 20 combinazioni. È interessante notare che alla fine sono state selezionate solo circa 600 combinazioni. Per ottenere una soluzione esatta, la strategia conta x dovrebbero essere numeri interi positivi, ma ci siamo resi conto che una soluzione arrotondata approssimata con solo non negativo x era sufficiente. Per una soluzione approssimativa, è possibile utilizzare un semplice risolutore pronto all'uso per ottenere un risultato entro 30 secondi.



Figura 4: Esempio di una matrice di strategia per la lunghezza della sequenza 8 e la profondità dell'imballaggio 3. Le righe rappresentano le sequenze di lunghezza 1–8 che vengono impacchettate insieme e le colonne rappresentano tutte le possibili combinazioni di lunghezza in un pacchetto senza un ordinamento particolare. Immagine dell'autore.

 

Alla fine, abbiamo dovuto correggere alcuni campioni a cui non era stata assegnata una strategia ma erano minimi. Abbiamo anche sviluppato un risolutore di varianti che impone che ogni sequenza venga impacchettata, potenzialmente con riempimento, e abbia una ponderazione dipendente dal riempimento. Ci è voluto molto più tempo e la soluzione non era molto migliore.

Imballaggio dell'istogramma del pacchetto più corto-primo

 
 
NNLSHP ci ha fornito un approccio di imballaggio sufficiente. Tuttavia, ci chiedevamo se potessimo teoricamente ottenere un approccio online più veloce e rimuovere il limite di mettere insieme solo 3 sequenze.

Pertanto, abbiamo preso ispirazione dagli algoritmi di impacchettamento esistenti, ma ci siamo comunque concentrati sugli istogrammi.

Ci sono quattro ingredienti per il nostro primo algoritmo, Shortest-pack-first histogram-packing (SPFHP):

  1. Opera sui conteggi dell'istogramma dalle sequenze più lunghe a quelle più brevi
  2. Se la lunghezza della sequenza corrente non rientra in nessun pacchetto, avviare un nuovo set di pacchetti
  3. Se ci sono più accoppiamenti, prendi il pacchetto in cui la somma della lunghezza della sequenza è più breve e modifica i conteggi rispettivamente
  4. Controlla di nuovo gli accoppiamenti dei conteggi rimanenti

Questo approccio è stato il più semplice da implementare e ha richiesto solo 0.02 secondi.

Una variante consisteva nel prendere la somma più grande della lunghezza della sequenza invece dei conteggi più brevi e suddivisi per ottenere accoppiamenti più perfetti. Nel complesso, questo non ha cambiato molto l'efficienza, ma ha aumentato molto la complessità del codice.



Come funziona la compressione dell'istogramma del pacchetto più corto. Animazione dell'autore.

 

Wikipedia, SQuAD 1.1, risultati dell'imballaggio GLUE

 
 
Le tabelle 1, 2 e 3 mostrano i risultati di impacchettamento dei nostri due algoritmi proposti. Profondità dell'imballaggio descrive il numero massimo di sequenze impaccate. La profondità di imballaggio 1 è l'implementazione BERT di base. La profondità di confezionamento massima che si verifica, se non viene impostato alcun limite, viene indicata con un "max" aggiuntivo. Il numero di confezioni descrive la lunghezza del nuovo dataset compresso. EFFICIENZA è la percentuale di token reali nel set di dati compresso. Il fattore di imballaggio descrive l'accelerazione potenziale risultante rispetto alla profondità di confezionamento 1.

Abbiamo avuto quattro osservazioni principali:

  1. Più una distribuzione è asimmetrica, maggiori sono i vantaggi dell'imballaggio.
  2. Tutti i set di dati traggono vantaggio dall'imballaggio. Alcuni anche di più di un fattore 2.
  3. SPFHP diventa più efficiente quando la profondità di confezionamento non è limitata.
  4. Per un numero massimo di 3 sequenze impaccate, più complesso è NNLSHP, più efficiente è (99.75 contro 89.44).



Tabella 1: Risultati chiave delle prestazioni degli algoritmi di impacchettamento proposti (SPFHP e NNLSHP) su Wikipedia. Immagine dell'autore.

 


Tabella 2: Risultati delle prestazioni degli algoritmi di confezionamento proposti per il pre-allenamento SQUAAD 1.1 BERT. Immagine dell'autore.

 


Tabella 3: Risultati delle prestazioni degli algoritmi di impacchettamento proposti per il set di dati GLUE. Vengono visualizzati solo la linea di base e i risultati di impaccamento SPFHP senza limitare la profondità di impaccamento. Immagine dell'autore.

 

Adeguamento elaborazione BERT

 
 
Qualcosa di interessante nell'architettura BERT è che la maggior parte dell'elaborazione avviene a livello di token, il che significa che non interferisce con il nostro confezionamento. Ci sono solo quattro componenti che necessitano di un aggiustamento: la maschera di attenzione, la perdita di MLM, la perdita di NSP e l'accuratezza.

La chiave per tutti e quattro gli approcci per gestire numeri diversi di sequenze era la vettorizzazione e l'utilizzo di un numero massimo di sequenze che possono essere concatenate. Per attenzione, avevamo già una maschera per affrontare l'imbottitura. Estendere questo a più sequenze è stato semplice, come si può vedere nel seguente pseudocodice TensorFlow. Il concetto è che ci siamo assicurati che l'attenzione sia limitata alle sequenze separate e non possa estendersi oltre.

Esempio di codice maschera di attenzione.


 


Figura 5: Esempio di maschera zero-uno

 

Per il calcolo delle perdite, in linea di principio spacchettamo le sequenze e calcoliamo le perdite separate, ottenendo eventualmente la media delle perdite sulle sequenze (invece dei pacchi).

Per la perdita MLM, il codice è simile a:

Esempio di codice per il calcolo delle perdite.


 

Per la perdita di NSP e l'accuratezza, il principio è lo stesso. Nei nostri esempi pubblici, puoi trovare il rispettivo codice con il nostro interno Quadro PopART.

Stima delle spese generali e dell'accelerazione di Wikipedia

 
 
Con la nostra modifica di BERT, abbiamo avuto due domande:

  1. Quanto sovraccarico porta con sé?
  2. Quanto dipende l'overhead dal numero massimo di sequenze che vengono messe insieme in un pacchetto?

Poiché la preparazione dei dati in BERT può essere ingombrante, abbiamo utilizzato una scorciatoia e compilato il codice per diverse profondità di confezionamento e confrontato i rispettivi cicli (misurati). I risultati sono visualizzati nella Tabella 4. Con alto, indichiamo la diminuzione percentuale della velocità effettiva dovuta alle modifiche al modello per abilitare l'imballaggio (come lo schema di mascheramento per l'attenzione e il calcolo della perdita modificato). Il accelerazione realizzata è la combinazione dell'accelerazione dovuta all'imballaggio (il fattore di imballaggio) e la diminuzione del throughput dovuta al alto.



Tabella 4: Confronto dell'accelerazione stimata degli algoritmi di impacchettamento proposti (SPFHP e NNLSHP) su Wikipedia. Immagine dell'autore.

 

Grazie alla tecnica di vettorizzazione, l'overhead è sorprendentemente piccolo e non vi è alcuno svantaggio nell'impacchettare insieme molte sequenze.

Regolazioni iperparametriche

 
 
Con l'imballaggio, stiamo raddoppiando le dimensioni effettive del lotto (in media). Ciò significa che dobbiamo regolare gli iperparametri di addestramento. Un semplice trucco consiste nel dimezzare il conteggio dell'accumulo del gradiente per mantenere la stessa dimensione media del batch effettiva di prima dell'allenamento. Utilizzando un'impostazione di benchmark con punti di controllo pre-addestrati, possiamo vedere che le curve di precisione corrispondono perfettamente.



Figura 6: confronto delle curve di apprendimento per l'elaborazione compressa e decompressa con dimensione del lotto ridotta per l'approccio imballato. Immagini per autore.

 

La precisione corrisponde: la perdita di allenamento MLM può essere leggermente diversa all'inizio, ma recupera rapidamente. Questa differenza iniziale potrebbe derivare da lievi aggiustamenti degli strati di attenzione che potrebbero essere stati sbilanciati verso brevi sequenze nell'allenamento precedente.

Per evitare un rallentamento, a volte è utile mantenere la stessa dimensione del batch originale e regolare gli iperparametri in base alla dimensione del batch effettiva aumentata (raddoppiata). I principali iperparametri da considerare sono i parametri beta e le velocità di apprendimento. Un approccio comune consiste nel raddoppiare la dimensione del batch, che nel nostro caso ha ridotto le prestazioni. Osservando le statistiche dell'ottimizzatore LAMB, potremmo dimostrare che aumentare il parametro beta alla potenza del fattore di impacchettamento corrisponde all'allenamento di più batch consecutivamente per mantenere lo slancio e la velocità comparabili.



Figura 7: confronto delle curve di apprendimento per l'elaborazione compressa e decompressa con euristico applicato. Immagini per autore.

 

I nostri esperimenti hanno dimostrato che portare beta al potere di due è una buona euristica. In questo scenario, non ci si aspetta che le curve corrispondano perché l'aumento della dimensione del lotto di solito riduce la velocità di convergenza nel senso di campioni/epoche finché non viene raggiunta una precisione target.

Ora la domanda è se, nello scenario pratico, otteniamo davvero l'accelerazione prevista?



Figura 8: Confronto delle curve di apprendimento per l'elaborazione compressa e decompressa nel file configurazione ottimizzata. Immagini per autore.

 

Sì, lo facciamo! Abbiamo guadagnato un'ulteriore velocità perché abbiamo compresso il trasferimento dei dati.

Conclusione

 
 
Mettere insieme le frasi può salvare lo sforzo di calcolo e l'ambiente. Questa tecnica può essere implementata in qualsiasi framework inclusi PyTorch e TensorFlow. Abbiamo ottenuto un netto aumento della velocità di 2 volte e, lungo il percorso, abbiamo esteso lo stato dell'arte negli algoritmi di impacchettamento.

Altre applicazioni di cui siamo curiosi sono la genomica e il ripiegamento delle proteine ​​in cui è possibile osservare distribuzioni di dati simili. I trasformatori di visione potrebbero anche essere un'area interessante per applicare immagini impacchettate di dimensioni diverse. Quali applicazioni pensi che funzionerebbero bene? Ci piacerebbe avere tue notizie!

Leggi il documento

Accedi al codice su GitHub

Grazie

 
 
Grazie ai nostri colleghi del team di ingegneria delle applicazioni di Graphcore, Sheng Fu e Mrinal Iyer, per i loro contributi a questo lavoro e grazie a Douglas Orr del team di ricerca di Graphcore per il suo prezioso feedback.

Riferimenti

 
 
[1] M. Kosec, S. Fu, MM Krell, Imballaggio: verso l'accelerazione BERT 2x NLP (2021), arXiv

 
Dott. Mario Michael Krell è un Principal Machine Learning Lead presso Graphcore. Mario ha ricercato e sviluppato algoritmi di apprendimento automatico per oltre 12 anni, creando software per settori diversi come robotica, automobilistico, telecomunicazioni e assistenza sanitaria. In Graphcore, ha contribuito al nostro impressionante Invii MLPerf e ha una passione per accelerare nuovi modelli non standard come il calcolo bayesiano approssimativo per l'analisi statistica dei dati COVID-19.

Matej Kosec è uno specialista di applicazioni AI presso Graphcore a Palo Alto. In precedenza ha lavorato come scienziato di intelligenza artificiale sulla guida autonoma presso il NIO di San Jose e ha conseguito un master in aeronautica e astronautica presso la Stanford University.

Originale. Ripubblicato con il permesso.

Correlato:

Fonte: https://www.kdnuggets.com/2021/08/packed-bert-training-speed-up-natural-language-processing.html

Timestamp:

Di più da KDnuggets