Part X froze a whole network and fine-tuned one number. A real language model's weight matrices have millions of entries — freezing the matrix is easy, but fine-tuning even a small fraction of millions of numbers is still a lot of numbers. What if the update those numbers need turns out to have far fewer real degrees of freedom than it looks like?
A 4x4 target update, approximated by the product of two length-4 vectors — 8 numbers standing in for 16. Step through training and watch that low-rank approximation converge onto the real target.
LoRA — short for Low-Rank Adaptation — freezes a pretrained weight matrix and represents the fine-tuning update as a low-rank product instead of a full matrix:
- — the original pretrained weight matrix, kept frozen throughout fine-tuning.
- — the effective weight matrix used after applying the fine-tuning update.
- — the fine-tuning update itself, decomposed into a low-rank product rather than stored as a full matrix.
- — one trainable low-rank factor, of shape .
- — the other trainable low-rank factor, of shape .
- — the size of the original (square) weight matrix.
- — the rank of the update, chosen much smaller than .
- Parameter cost drops from quadratic to linear
A full update to an matrix costs trainable parameters. A rank- update costs only . For a attention matrix and :
- Full update: parameters
- LoRA update: parameters
- Ratio: — under half a percent
- The catch: rank is capped at r
can only ever be rank , however training goes. If the update a task actually needs has higher intrinsic rank than , LoRA simply cannot represent it exactly.
The target update, the full fine-tune's result after one step, and LoRA's result after 100 steps — visually indistinguishable. Full fine-tuning used 16 parameters and one step; LoRA used 8 parameters and a hundred steps to land in the same place.
A 4x4 target update that happens to be exactly rank-1 — for some vectors :
- Full fine-tuning: trivial, but 16 parameters
Each of the 16 entries is its own independent quadratic loss, same shape as every "ideal learning rate" example from earlier in this course. At , a full update matches the target exactly in one step.
- LoRA: 8 parameters, but a harder optimization
makes the loss a product of two vectors, not a sum of independent terms — no one-step closed form. After 100 gradient steps at , the loss drops to : effectively exact, at half the parameter count.
- The learned vectors aren't unique — and that's fine
The trained don't match directly — scaling up and down by the same factor leaves unchanged, so infinitely many pairs solve this exactly. What matters is the product, and that converges to the true update regardless of which particular pair training lands on.
Find the step count, among the three candidates, where LoRA's loss has dropped below 1e-10.
LoRA doesn't make fine-tuning cheaper by approximating carelessly — it bets that the update a specific task actually needs has low intrinsic rank, a bet that holds remarkably often in practice for large pretrained models. When that bet is right, as in this worked example, a rank-1 or rank-8 update recovers essentially the same result as fine-tuning every parameter, at a tiny fraction of the cost. The next chapter looks at a different way large models save compute: routing each input through only a handful of specialized sub-networks instead of the whole model at once.