Generative AI
LoRA (Low-Rank Adaptation)
Fine-tuning a massive generative model by updating every parameter is computationally exhausting. LoRA (Low-Rank Adaptation) freezes the original model and learns a tiny, efficient detour instead.
How decomposing a massive weight update into two low-rank matrices drastically reduces trainable parameters while maintaining learning capability.
Stage 1 of 4: Full-rank updates
Rank is 4, resulting in 512 trainable parameters, which is 12.5% of full rank. Loss is 0.53.
- Trainable weights
- Frozen base weights
- Loss
Standard fine-tuning updates millions of parameters in the massive base matrix W.
Check your understanding
3 questions in the bank. Each attempt draws a fresh set in a fresh order, so a second go is a real second go.
The problem with full fine-tuning
When a massive model like a Large Language Model (LLM) is pre-trained, it learns general patterns across billions of parameters, stored in massive weight matrices like the grey matrix you see here.
If you want to fine-tune it on a specific task—like writing code or speaking a specific language—the standard approach is to update every single parameter. This means you must load the entire model into GPU memory, compute gradients for every weight, and save a brand new multi-gigabyte copy of the model.
That is extremely expensive, slow, and often totally unnecessary.
Freezing the base
The first trick in LoRA is to stop updating the original weights altogether. We freeze .
In the simulation, this is when the padlock appears and turns grey. The gradients stop flowing through the massive matrix. The original knowledge of the model is perfectly preserved, which prevents catastrophic forgetting (where a model forgets how to speak English because it was fine-tuned too aggressively on French).
But if is frozen, how does the model learn anything new?
The LoRA bottleneck
Instead of changing , we add a new path next to it. We learn an additive update, , such that the new output is .
The magic of LoRA is that we do not make the same massive size as . Instead, we decompose it into two thin matrices: and .
If the original dimension is , then is and is . The bottleneck dimension is the rank.
By forcing the information to squeeze through this narrow rank , the number of parameters we have to train drops dramatically. For example, if and :
- A full update would need parameters.
- LoRA needs parameters. That is an 87.5% reduction, while often achieving the exact same performance.
Editing a masterpiece
Imagine you want to correct a few specific details on a massive, highly detailed map of the world (the base model).
Instead of redrawing the entire map from scratch (full fine-tuning), you place a sheet of clear tracing paper over it and only draw the new roads and borders on the tracing paper. The tracing paper is much smaller and lighter to carry (the LoRA weights), but when overlaid on the map, you get the updated world.
The Rank Trade-off
The rank is the most important hyperparameter in LoRA.
Grab the rank slider and sweep it from 1 to 64. As the rank increases, the matrices and physically widen, and the number of trainable parameters grows.
Simultaneously, watch the loss curve. Giving the model a higher rank gives it more "expressivity"—more capacity to learn complex updates—so the achievable loss floor drops.
Too low or too high?
If you set the rank too low (like for a complex task), the bottleneck is simply too tight. The matrices become vectors and lack the mathematical capacity to express the necessary weight updates. The loss will plateau early, leaving you with an underperforming model.
However, increasing the rank has diminishing returns. The difference between and is huge, but the difference between and is almost zero for most tasks, while doubling your memory footprint. You always want to find the lowest rank that reaches your target loss.
What to take away
LoRA proves that the updates needed to fine-tune a model have a much lower intrinsic dimension than the model itself. We do not need to update billions of parameters to teach an LLM a new trick; a few million, intelligently arranged in a low-rank bottleneck, are more than enough.
Reference
- LoRA Update
- h = Wx + ABx
- Trainable Parameters
- 2 × d × r
- Compression Ratio
- (2 × d × r) / d²
Break it on purpose
When the rank is too low, the matrices lack the capacity to express the necessary weight updates.