7.0. LoRA Improvements in fine-tuning

Βελτιώσεις LoRA

Η χρήση του LoRA μειώνει πολύ τους υπολογισμούς που απαιτούνται για να προσαρμόσετε ήδη εκπαιδευμένα μοντέλα.

Το LoRA καθιστά δυνατή την αποτελεσματική προσαρμογή μεγάλων μοντέλων αλλάζοντας μόνο ένα μικρό μέρος του μοντέλου. Μειώνει τον αριθμό των παραμέτρων που χρειάζεται να εκπαιδεύσετε, εξοικονομώντας μνήμη και υπολογιστικούς πόρους. Αυτό συμβαίνει επειδή:

  1. Μειώνει τον Αριθμό των Εκπαιδεύσιμων Παραμέτρων: Αντί να ενημερώνετε ολόκληρη τη μήτρα βαρών στο μοντέλο, το LoRA χωρίζει τη μήτρα βαρών σε δύο μικρότερες μήτρες (που ονομάζονται A και B). Αυτό καθιστά την εκπαίδευση ταχύτερη και απαιτεί λιγότερη μνήμη επειδή λιγότερες παράμετροι χρειάζεται να ενημερωθούν.

  2. Αυτό συμβαίνει επειδή αντί να υπολογίζει την πλήρη ενημέρωση βαρών ενός επιπέδου (μήτρα), την προσεγγίζει ως το γινόμενο 2 μικρότερων μητρών μειώνοντας την ενημέρωση για υπολογισμό:\

2. **Διατηρεί τους Αρχικούς Βάρη του Μοντέλου Αμετάβλητους**: Το LoRA σας επιτρέπει να διατηρείτε τους αρχικούς βάρους του μοντέλου ίδιους και να ενημερώνετε μόνο τις **νέες μικρές μήτρες** (A και B). Αυτό είναι χρήσιμο γιατί σημαίνει ότι η αρχική γνώση του μοντέλου διατηρείται, και εσείς προσαρμόζετε μόνο ό,τι είναι απαραίτητο. 3. **Αποτελεσματική Προσαρμογή για Συγκεκριμένες Εργασίες**: Όταν θέλετε να προσαρμόσετε το μοντέλο σε μια **νέα εργασία**, μπορείτε απλά να εκπαιδεύσετε τις **μικρές μήτρες LoRA** (A και B) αφήνοντας το υπόλοιπο του μοντέλου όπως είναι. Αυτό είναι **πολύ πιο αποτελεσματικό** από το να εκπαιδεύσετε ξανά ολόκληρο το μοντέλο. 4. **Αποτελεσματικότητα Αποθήκευσης**: Μετά την προσαρμογή, αντί να αποθηκεύετε ένα **εντελώς νέο μοντέλο** για κάθε εργασία, χρειάζεται μόνο να αποθηκεύσετε τις **μήτρες LoRA**, οι οποίες είναι πολύ μικρές σε σύγκριση με το ολόκληρο μοντέλο. Αυτό διευκολύνει την προσαρμογή του μοντέλου σε πολλές εργασίες χωρίς να χρησιμοποιείτε υπερβολικό χώρο αποθήκευσης.

Για να υλοποιήσετε τα LoraLayers αντί για τα γραμμικά κατά τη διάρκεια μιας προσαρμογής, προτείνεται αυτός ο κώδικας εδώ https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01_main-chapter-code/appendix-E.ipynb:

import math

# Create the LoRA layer with the 2 matrices and the alpha
class LoRALayer(torch.nn.Module):
def __init__(self, in_dim, out_dim, rank, alpha):
super().__init__()
self.A = torch.nn.Parameter(torch.empty(in_dim, rank))
torch.nn.init.kaiming_uniform_(self.A, a=math.sqrt(5))  # similar to standard weight initialization
self.B = torch.nn.Parameter(torch.zeros(rank, out_dim))
self.alpha = alpha

def forward(self, x):
x = self.alpha * (x @ self.A @ self.B)
return x

# Combine it with the linear layer
class LinearWithLoRA(torch.nn.Module):
def __init__(self, linear, rank, alpha):
super().__init__()
self.linear = linear
self.lora = LoRALayer(
linear.in_features, linear.out_features, rank, alpha
)

def forward(self, x):
return self.linear(x) + self.lora(x)

# Replace linear layers with LoRA ones
def replace_linear_with_lora(model, rank, alpha):
for name, module in model.named_children():
if isinstance(module, torch.nn.Linear):
# Replace the Linear layer with LinearWithLoRA
setattr(model, name, LinearWithLoRA(module, rank, alpha))
else:
# Recursively apply the same function to child modules
replace_linear_with_lora(module, rank, alpha)

Αναφορές

Last updated