Train a difference, not the weights
Full fine-tuning updates every parameter. LoRA freezes them all and learns a small additive correction instead.
- : the pretrained weight matrix, , frozen and never touched.
- : a new matrix, , initialised to zero.
- : a new matrix, , initialised randomly.
- : the rank, and the one number you choose. Typically 8, 16 or 64.
Because starts at zero, starts at zero, and the model at step zero is exactly the pretrained model.
The arithmetic that makes it worth doing
For a attention projection, full fine-tuning trains 16.8 million parameters.
At LoRA trains , which is 0.39% of them.
The saving compounds: optimiser state for Adam is two extra numbers per trainable parameter, so cutting the trainable count by 250x cuts optimiser memory by 250x too.
For a 7 billion parameter model in 16-bit, full fine-tuning with Adam needs over 100 GB for weights, gradients and optimiser state.
With LoRA it needs little more than the 14 GB the frozen weights take, plus activations.
The scaling factor
- : a constant, usually fixed while is varied.
Dividing by means the size of the update does not change when you change the rank, so a learning rate tuned at still works at .
Without it, raising the rank would silently raise the effective learning rate as well, and the two effects would be impossible to separate.
One training step, in order
- Forward through the frozen as normal.
- Forward the same input through then , scaled by .
- Add the two outputs together.
- Backward: gradients flow only into and .
- The optimiser updates and and nothing else.
The bet it is making
The claim is that the useful update has low intrinsic rank: adapting a model to a new task moves it in far fewer directions than it has parameters.
That is a hard ceiling, not a tendency. Whatever and learn, the correction can never have rank above .
It holds well for adapting style, format and domain, and badly for teaching genuinely new knowledge. That is the honest boundary between when LoRA is enough and when it is not.
Merging
The product can be computed once and folded into the original weights, after which inference costs exactly what the base model cost.
That is the practical difference from adapters: LoRA adds no latency at serving time, because at serving time it no longer exists as a separate thing.