• Data di pubblicazione
    18 Febbraio 2025
  • Condividi

In questo post del blog, parlerò dei dettagli e dei principi del metodo LoRA (Low-Rank Adaptation Of Large Language Models), analizzando nel contempo l'articolo . L'obiettivo principale dell'articolo è quello di presentare una nuova struttura che riduca il costo del fine-tuning di un modello, aumentandone al contempo le prestazioni. Le operazioni di fine-tuning rivestono da tempo un ruolo importante negli studi di elaborazione del linguaggio naturale. Supponiamo di avere un modello addestrato e di voler ampliarne le conoscenze. È possibile farlo tramite il fine-tuning, senza dover addestrare il modello da zero.

Supponiamo che un modello abbia n parametri dopo l'addestramento e che tu debba ottimizzarlo. Se utilizzi un metodo di ottimizzazione completa, tutti i parametri del modello verranno aggiornati. Quando consideriamo modelli che hanno miliardi di parametri, l'aggiornamento di tutti i parametri creerà problemi di tempo e di archiviazione. Nel documento, i risultati di prestazioni migliori o alla pari sono enfatizzati per i modelli RoBERTa, DeBERTa, GPT-2 e GPT-3 utilizzando il metodo LoRA.

Nel documento si menziona che il metodo LoRA è ispirato agli studi di Li et. al (2018a) e Aghajanyan et al. (2020). Questi studi sottolineano che il successo dei modelli sovraparametrizzati si basa in realtà su una bassa dimensione intrinseca. Questo è diventato il punto che ha plasmato l'ipotesi del metodo LoRA.

Il metodo LoRA è uno studio basato interamente sulla fattorizzazione dei ranghi. In questo metodo, due matrici sequenziali vengono aggiunte parallelamente ad alcuni strati densi nelle reti neurali come mostrato nella Figura 1. Queste matrici sequenziali sono formate da una data configurazione di rango. La figura sottostante mostra come appare uno strato denso dopo aver aggiunto le matrici di rango sequenziali. Le variabili di input vengono inviate sia attraverso la matrice di peso di pre-addestramento originale sia attraverso la prima matrice delle matrici sequenziali. Quindi, i valori di output vengono calcolati sommando gli output di queste due matrici parallele.

 

Ekran Resmi 2024-12-26 15.25.36.png
Fonte: https://arxiv.org/abs/2106.09685

Il metodo LoRA

Le reti neurali hanno molti strati densi che eseguono moltiplicazioni di matrici. Le matrici dei pesi in questi strati sono in realtà matrici a rango pieno (tutte le righe e le colonne sono indipendenti). Tuttavia, Aghajanyan et al. hanno menzionato nel loro articolo che i modelli linguistici pre-addestrati hanno una bassa "dimensione intrinseca". Questo ha plasmato l'ipotesi LoRA in questo contesto. Pertanto, l'ipotesi LoRA è diventata che i modelli potrebbero apprendere con modifiche a bassa dimensionalità nella matrice dei pesi durante l'adattamento a un compito specifico.

Gli aggiornamenti di questa matrice sono stati effettuati tramite matrici 

Ekran_Resmi_2024_12_26_15_32_57_6efdebb733.png

separati da basso rango. Qui, B è una matrice dxr, A è una matrice rxk, mentre r (rango) è molto più piccolo di d e k. Durante la messa a punto fine, gli aggiornamenti del gradiente a Wo vengono impediti. Entrambe le matrici Wo e ∆W vengono moltiplicate per gli stessi valori di input e i risultati vengono sommati e si forma l'output h= w0 + ∆Wx = w0 +BAx.

All'inizio dell'addestramento, hanno utilizzato l'inizializzazione gaussiana casuale per i valori della matrice A e l'inizializzazione a zero completo per i valori della matrice B. In altre parole, BA è uguale a zero all'inizio.

Applicazione LoRA nell'architettura del trasformatore

Ci sono 4 matrici di peso Wq, Wk, Wv, Wo nel modulo self-attention e 2 matrici di peso nel modulo MLP nell'architettura del trasformatore. Durante l'adattamento LoRA, hanno congelato i pesi nel modulo MLP e applicato il metodo ai pesi dell'attenzione per mantenere semplice l'addestramento.

Vantaggi   

  • Le maggiori comodità fornite da LoRA sono l'utilizzo di memoria e storage. Ad esempio, nell'articolo, si menziona che per un modello di trasformatore di grandi dimensioni addestrato con Adam, l'utilizzo di VRAM è ridotto fino a 2/3 se << r d. Questo perché gli stati dell'ottimizzatore non vengono mantenuti per i parametri congelati.
  • Per il modello GPT-3 175B, il consumo di VRAM è sceso da 1.2 TB a 350 GB.
  • Nello scenario in cui r=4 e sono stati modificati solo i pesi delle matrici di valore e query, la dimensione del checkpoint è stata ridotta da 350 GB a 35 MB. Ciò ha consentito di eseguire l'addestramento con meno GPU.
  • Inoltre, poiché non vi è alcun aggiornamento del gradiente nella maggior parte dei parametri, è stata ottenuta un'accelerazione del 25% durante l'addestramento del GPT-3 175B con LoRA rispetto al processo di messa a punto completa.

L'articolo menziona anche che se il processo di messa a punto fosse necessario per un linguaggio diverso, si dovrebbe utilizzare l'intero modello invece di LoRA.

Conoscenza aggiuntiva

Che cosa è un grado?

Il rango di una matrice indica il numero totale di colonne o righe linearmente indipendenti. Supponiamo di avere una matrice con n colonne, in cui tutte le colonne sono indipendenti l'una dall'altra: in questo caso, il rango di colonna di questa matrice è n. Analogamente, se tutte le righe di una matrice con n righe sono indipendenti l'una dall'altra, il rango di riga della matrice è n.

Il rango di riga e il rango di colonna di una matrice devono essere uguali. Come esempio, possiamo guardare la matrice qui sotto.

Matrice A = [[1,2,5], [ 2, 4, 10] ]

Se osserviamo attentamente la matrice, possiamo vedere che la seconda riga è il doppio della prima riga. Allo stesso modo, la seconda e la terza colonna della matrice sono rispettivamente 2 e 1 volte la prima colonna. In altre parole, mentre ci sono due vettori sulla stessa riga su base di riga nella matrice e tre vettori diversi su un'altra riga su base di colonna, c'è solo un vettore univoco su ogni riga e base di colonna. Ciò significa che il rango della matrice è 2.

Per trovare il rango, convertiamo la matrice nella sua forma a gradini e poi calcoliamo il numero di righe che contengono almeno un valore diverso da zero.

Che cosa è una matrice di basso rango

Nelle matrici, il rango può essere uguale o inferiore al numero di colonne o righe. Le matrici che hanno righe o colonne linearmente indipendenti più piccole del numero corrente di righe o colonne sono chiamate matrici di basso rango. Le matrici in cui tutte le righe o colonne sono indipendenti sono chiamate matrici di rango completo.

Che cosa è una fattorizzazione/decomposizione di rango

Possiamo riscrivere una matrice di rango r come B=LR^T decomponendola in due matrici, L e R. Qui, L è una matrice di dimensioni mxr, mentre R^T è una matrice di dimensioni rxn. Questo processo è noto come decomposizione di rango.

L'importanza della fattorizzazione di rango:

L'importanza del processo di fattorizzazione per rango risiede nella possibilità di suddividere una matrice in due matrici più piccole, L e R, occupando meno spazio. Ciò significa che è possibile memorizzare B memorizzando i suoi fattori L e R. Questo riduce i requisiti di memoria di B da mn a (m+n)r elementi. Un ulteriore aspetto da sottolineare è che, dopo aver scomposto una matrice in queste due matrici più piccole, è possibile eseguire molti calcoli sulla matrice stessa senza doverla ricostruire. Per questo motivo, quando si ha a che fare con matrici a basso rango, la fattorizzazione per rango è sempre considerata un primo passo fondamentale. Dopo la fattorizzazione, i calcoli possono essere eseguiti molto più velocemente e con un minore utilizzo di memoria.

Inoltre

Per informazioni più dettagliate sulle matrici a basso rango, è possibile consultare il blog di Ethan R. Epperly e l'articolo su LoRA . Inoltre, è possibile esaminare in dettaglio le applicazioni basate su codice di LoRA nel repository GitHub microsoft/LoRA .

Gizem ABALI, MSc. / Responsabile del team