7.0. LoRA Improvements in fine-tuning

LoRA İyileştirmeleri

LoRA'nın kullanımı, zaten eğitilmiş modelleri ince ayar yapmak için gereken hesaplamayı büyük ölçüde azaltır.

LoRA, modelin küçük bir kısmını değiştirerek büyük modelleri verimli bir şekilde ince ayar yapmayı mümkün kılar. Eğitilmesi gereken parametre sayısını azaltarak bellek ve hesaplama kaynakları tasarrufu sağlar. Bunun nedeni:

  1. Eğitilebilir Parametre Sayısını Azaltır: Modeldeki tüm ağırlık matrisini güncellemek yerine, LoRA ağırlık matrisini iki daha küçük matrise (A ve B olarak adlandırılır) bölerek çalışır. Bu, eğitimi daha hızlı hale getirir ve daha az bellek gerektirir çünkü daha az parametre güncellenmesi gerekir.

  2. Bunun nedeni, bir katmanın (matrisin) tam ağırlık güncellemesini hesaplamak yerine, bunu 2 daha küçük matrisin çarpımı olarak yaklaşık olarak hesaplamasıdır, bu da güncellemeyi hesaplamayı azaltır:\

2. **Orijinal Model Ağırlıklarını Değiştirmeden Tutma**: LoRA, orijinal model ağırlıklarını aynı tutmanıza ve yalnızca **yeni küçük matrisleri** (A ve B) güncellemenize olanak tanır. Bu, modelin orijinal bilgisinin korunması anlamına geldiği için faydalıdır ve yalnızca gerekli olanı ayarlarsınız. 3. **Verimli Görev-Özel İnce Ayar**: Modeli **yeni bir göreve** uyarlamak istediğinizde, modelin geri kalanını olduğu gibi bırakırken yalnızca **küçük LoRA matrislerini** (A ve B) eğitebilirsiniz. Bu, tüm modeli yeniden eğitmekten **çok daha verimlidir**. 4. **Depolama Verimliliği**: İnce ayar yaptıktan sonra, her görev için **tamamen yeni bir modeli** kaydetmek yerine, yalnızca **LoRA matrislerini** saklamanız gerekir; bu matrisler, tüm modele kıyasla çok küçüktür. Bu, modeli çok fazla depolama alanı kullanmadan birçok göreve uyarlamayı kolaylaştırır.

LoRA katmanlarını ince ayar sırasında Lineer olanlar yerine uygulamak için, burada önerilen kod 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)

Referanslar

Last updated