7.0. LoRA poboljšanja u finom podešavanju

Reading time: 2 minutes

LoRA poboljšanja

tip

Korišćenje LoRA značajno smanjuje računarske resurse potrebne za fino podešavanje već obučenih modela.

LoRA omogućava efikasno fino podešavanje velikih modela menjajući samo mali deo modela. Smanjuje broj parametara koje treba obučavati, čime se štedi memorija i računarski resursi. To je zato što:

  1. Smanjuje broj obučivih parametara: Umesto da ažurira celu težinsku matricu u modelu, LoRA delimi težinsku matricu na dve manje matrice (nazvane A i B). To čini obuku bržom i zahteva manje memorije jer je potrebno ažurirati manje parametara.

  2. To je zato što umesto da izračunava potpuno ažuriranje težine sloja (matrice), aproksimira ga kao proizvod 2 manje matrice, smanjujući ažuriranje za izračunavanje:\

  1. Održava originalne težine modela nepromenjenim: LoRA vam omogućava da zadržite originalne težine modela iste, i samo ažurirate nove male matrice (A i B). To je korisno jer znači da se originalno znanje modela čuva, a vi samo prilagođavate ono što je neophodno.
  2. Efikasno fino podešavanje specifično za zadatak: Kada želite da prilagodite model za novi zadatak, možete samo obučavati male LoRA matrice (A i B) dok ostavljate ostatak modela nepromenjenim. To je mnogo efikasnije od ponovnog obučavanja celog modela.
  3. Efikasnost skladištenja: Nakon finog podešavanja, umesto da čuvate novi model za svaki zadatak, potrebno je da sačuvate samo LoRA matrice, koje su veoma male u poređenju sa celim modelom. To olakšava prilagođavanje modela mnogim zadacima bez prekomernog korišćenja skladišta.

Da biste implementirali LoraLayers umesto Linear slojeva tokom finog podešavanja, ovde je predložen ovaj kod https://github.com/rasbt/LLMs-from-scratch/blob/main/appendix-E/01_main-chapter-code/appendix-E.ipynb:

python
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)

Reference