WHAT is the trade we make? We give up the ability to freely reshape every weight, and bet that a low-capacity add-on is enough to specialise a model that already learned general features. Empirically, this bet usually wins.
We want a module that (1) can be inserted without breaking the pretrained forward pass, (2) has few parameters, (3) can express a useful transformation.
Cheap capacity → factorize. A full learned map Rd→Rd costs d2 params. Force it through a bottleneck r: down-project d→r, then up-project r→d. Params drop to 2dr. With r≪d, that's tiny.
Why this step?2dr≪d2 when r≪d. For d=1024,r=16: 2dr=32,768 vs d2≈106.
Add nonlinearity. Two stacked linears collapse to one linear map. Insert σ so the adapter can learn a nonlinear correction.
Why? Without σ, WupWdown is just a rank-r linear map — less expressive.
Wrap in a residual. Initialize Wup≈0 so at the start Adapter(h)≈h.
Why? If the adapter starts as near-identity, the frozen model's behaviour is preserved on step 0, so training starts from a known-good point and won't destroy pretrained knowledge.
The real token queries Q now attend over extra learned key/value slots. Since softmax mixes over all keys, the prefix can inject task-specific information into every position.
Only Pk,Pv (size 2pd per layer) are trained; WQ,WK,WV stay frozen.
Why parametrize K,V and not just prepend embeddings? Prepending raw embeddings ("prompt tuning") only affects layer 0; directly writing keys/values at every layer gives more control and trains more stably. (In practice a small MLP reparametrizes the prefix during training for stability.)
The 20% you must know: both freeze the backbone; adapters add a bottleneck FFN with residual init-to-identity; prefix tuning prepends learned key/value vectors; both train ~0.1–3% of weights and give one shared model + tiny per-task deltas.
Recall Feynman: explain to a 12-year-old
Imagine a super-smart robot that already read every book. You don't want to re-teach it everything just to do your homework. So you clip a tiny helper gadget onto it (adapter) or hand it a secret cheat-note it reads before every answer (prefix). The robot's big brain stays exactly the same — you only train the tiny gadget or the little note. That's cheap, fast, and you can keep 100 different gadgets for 100 different jobs, all clipping onto the same one robot.
What problem does PEFT (adapters / prefix tuning) solve?
Full fine-tuning needs a full model copy per task (O(W) params); PEFT freezes the backbone and trains only ~0.1–3% new params, one shared model + tiny deltas.
Write the adapter forward equation.
Adapter(h)=h+Wupσ(Wdownh) with Wdown∈Rr×d, Wup∈Rd×r.
Why does an adapter use a bottleneck dimension r≪d?
To cut params from d2 (full map) to 2dr; low capacity is cheap and acts as a regularizer.
Why does an adapter need a nonlinearity σ?
Two stacked linear maps collapse into one; σ lets the adapter learn a nonlinear correction (otherwise only a rank-r linear map).
Why initialize Wup≈0 in an adapter?
So Adapter(h)≈h at step 0 (near-identity), preserving pretrained behaviour and starting from a known-good point.
Approx trainable params for adapters across L layers?
≈2Lkdr (k adapters/layer), independent of vocab and sequence length.
In prefix tuning, what exactly is learned?
Per-layer key/value prefix matrices Pk,Pv∈Rp×d; queries stay real, K and V get the learned prefix prepended.
Prefix-tuning attention equation?
K′=[Pk;K],V′=[Pv;V], then softmax(QK′⊤/d)V′.
Prefix tuning vs prompt tuning?
Prompt tuning edits only layer-0 input embeddings; prefix tuning injects learned K/V at every layer — more expressive/stable.
Prefix param count formula?
≈2Lpd (keys+values over L layers, prefix length p).
Steel-man: why is full fine-tuning NOT always better than PEFT?
On small data it overfits and forgets; PEFT's low capacity regularizes and often matches FT at ~100× lower storage.
Compute cost of a length-p prefix on a length-n sequence?
Attention becomes O((n+p)2) — longer effective sequence per token.
Dekho, ek bada LLM already language ko samajh chuka hai — usne internet ka bahut saara text padh liya. Ab agar tum har naye task ke liye poore model ko dobara train karo (full fine-tuning), to har task ke liye ek alag 7B-parameter copy banani padegi. Ye storage aur compute dono mein bahut mehenga hai. Iska smart solution hai PEFT: model ko freeze kar do, aur sirf thode se naye chhote parameters train karo jo model ko task ki taraf steer karein.
Do popular tarike hain. Adapter ek chhota bottleneck FFN hai jo har layer ke andar daala jaata hai: pehle dimension ko d se r (jahan r bahut chhota hai) tak neeche laate hain, phir nonlinearity, phir wapas d tak up-project, aur ek residual +h add karte hain. Wup ko lagbhag zero se init karte hain taaki shuru mein adapter almost identity ho — matlab pretrained model ka behaviour kharab na ho. Params sirf 2dr — poore model ka ~1%.
Prefix tuning mein hum weights ko haath nahi lagate. Har attention layer mein hum kuch learnable "nakli tokens" ke key/value vectors (Pk,Pv) prepend kar dete hain. Real tokens ke queries in extra learned keys/values pe bhi attend karte hain, jisse har position pe task-specific information inject ho jaati hai. Ye discrete prompt words nahi hain — ye continuous vectors hain, har layer mein, isliye zyada powerful.
Core baat yaad rakho: "Freeze the giant, train the tiny." Ek hi bada model rakho, aur har task ke liye sirf ek chhota MB-size delta save karo. Isse 100 customers ko serve karna sasta ho jaata hai, aur choti dataset pe overfitting/forgetting bhi kam hoti hai kyunki capacity kam hai (natural regularizer).