Projekt 4: Finjustera en modell med LoRA
Förträna en liten teckenmodell på en text, finjustera den med LoRA på en annan stil, jämföra rank 1/4/16 och full finjustering på perplexitet, tränade parametrar och katastrofal glömska — och skriva ner slutsatsen i labbjournalen.
Teori
Basmodellen kan bara det den förtränats på. LoRA lägger till BA i attention-projektionerna (och ev. MLP) och tränar bara dem. Mät på tre saker: perplexitet på den nya stilen, parametrar som tränats, och perplexitet på den gamla texten efteråt (glömska).
Deluppgifter
- LoRA-injektion —
inject_lora(model, r, alpha, targets)byter angivna nn.Linear (namn innehåller 'qkv'/'proj'/'mlp') mot LoRALinear och fryser resten;count_trainable(model). - perplexitet —
perplexity(model, data, ctx)= exp(medel-cross-entropy) över löpande fönster. - experimentet —
experiment(ranks, steps, seed)→ dict per konfiguration {ppl_new, ppl_old, trainable}, inklusive 'full'.
Godkänt när: ppl_gain_r4 >= 1.2
Startkoden
körs i en isolerad sandlåda på servernimport math
import torch
import torch.nn as nn
import torch.nn.functional as F
from tinygpt import CharTokenizer, TinyGPT, train, batches # levereras i readonly-filen tinygpt.py
class LoRALinear(nn.Module):
def __init__(self, base, r=4, alpha=8):
super().__init__()
self.base = base
for p in base.parameters():
p.requires_grad = False
self.r, self.alpha = r, alpha
self.A = nn.Parameter(torch.randn(r, base.in_features) * 0.01)
self.B = nn.Parameter(torch.zeros(base.out_features, r))
def forward(self, x):
return self.base(x) + (self.alpha / self.r) * (x @ self.A.T) @ self.B.T
def inject_lora(model, r=4, alpha=8, targets=("qkv", "proj")):
# TODO: frys allt; för varje named_module som är nn.Linear och vars namn innehåller något target: byt ut mot LoRALinear
...
def count_trainable(model):
return sum(p.numel() for p in model.parameters() if p.requires_grad)
@torch.no_grad()
def perplexity(model, data, ctx=64, n=40, seed=0):
# TODO: n slumpade fönster (generator med seed); cross-entropy; return exp(medel)
...
def experiment(ranks=(1, 4, 16), steps=300, seed=0):
# TODO: förträna på base_text (600 steg), spara; för varje r: kopiera, inject_lora, träna på new_text; mät ppl_new/ppl_old/trainable; 'full' = träna alla
...
Du skriver koden, tester du inte ser avgör om den håller. Skapa ett gratis konto för att köra labben.
Prova diagnosenSkapa konto gratisFörväntade resultat
LoRA r=4 sänker perplexiteten på nya stilen med minst 20 % jämfört med basmodellen, tränar < 15 % av parametrarna, och glömmer mindre än full finjustering (ppl_old lägre).
Vanliga fel
- Injicerar LoRA i embeddings/head också — då tränas för mycket.
- Glömmer frysa basen → 'LoRA' blir full finjustering.
- Mäter perplexitet på träningsfönstren.