7.0. LoRA Improvements in fine-tuning

LoRA-Verbesserungen

Die Verwendung von LoRA reduziert erheblich die Berechnungen, die erforderlich sind, um bereits trainierte Modelle fein abzustimmen.

LoRA ermöglicht es, große Modelle effizient fein abzustimmen, indem nur ein kleiner Teil des Modells geändert wird. Es reduziert die Anzahl der Parameter, die Sie trainieren müssen, und spart Speicher und Rechenressourcen. Das liegt daran:

  1. Reduziert die Anzahl der trainierbaren Parameter: Anstatt die gesamte Gewichtsmatrix im Modell zu aktualisieren, teilt LoRA die Gewichtsmatrix in zwei kleinere Matrizen (genannt A und B). Dies macht das Training schneller und erfordert weniger Speicher, da weniger Parameter aktualisiert werden müssen.

  2. Das liegt daran, dass anstatt die vollständige Gewichtsanpassung einer Schicht (Matrix) zu berechnen, sie diese als Produkt von 2 kleineren Matrizen approximiert, wodurch die Aktualisierung reduziert wird, die berechnet werden muss:\

2. **Hält die ursprünglichen Modellgewichte unverändert**: LoRA ermöglicht es Ihnen, die ursprünglichen Modellgewichte gleich zu lassen und nur die **neuen kleinen Matrizen** (A und B) zu aktualisieren. Dies ist hilfreich, da es bedeutet, dass das ursprüngliche Wissen des Modells erhalten bleibt und Sie nur das anpassen, was notwendig ist. 3. **Effizientes aufgabenspezifisches Feintuning**: Wenn Sie das Modell an eine **neue Aufgabe** anpassen möchten, können Sie einfach die **kleinen LoRA-Matrizen** (A und B) trainieren, während der Rest des Modells unverändert bleibt. Dies ist **viel effizienter** als das vollständige Neutrainieren des Modells. 4. **Speichereffizienz**: Nach dem Feintuning müssen Sie anstelle eines **komplett neuen Modells** für jede Aufgabe nur die **LoRA-Matrizen** speichern, die im Vergleich zum gesamten Modell sehr klein sind. Dies erleichtert es, das Modell an viele Aufgaben anzupassen, ohne zu viel Speicherplatz zu verwenden.

Um LoraLayers anstelle von linearen während eines Feintunings zu implementieren, wird hier dieser Code vorgeschlagen 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)

Referenzen

Last updated