Learn › Paper Deep-Dives
·FREE·PAPER·12 min read

LoRA Paper Explained: Low-Rank Adaptation of Large Language Models (Hu et al., 2021) — Why Low Rank Is Enough

The LoRA paper (Hu et al., 2021) explained, grounded strictly in its own text: what BA actually means, the 21x amplification factor the authors measured, why r=1 sufficed, and the questions they left open.

Key points

  • LoRA freezes the pre-trained weights W0 and trains only a low-rank update BA.
  • On GPT-3 175B with r=4 applied to the query and value projection matrices, the checkpoint drops from 350GB to 35MB.
  • At deployment, W=W0+BA is merged, so zero additional inference latency is guaranteed by construction.
  • Adapters at batch 1 / sequence 128 degrade from 19.8ms to 23.9ms (+20.7%) and 25.8ms (+30.3%).
  • ΔW amplifies task-specific directions that were learned but not emphasized in pre-training, and r=1 can already suffice in some cases.
ModalitytextTaskfine-tuning

LoRA: Low-Rank Adaptation of Large Language Models

Primary source — what this article is built on

undefined2021-06-17→undefined2026-08-035y 2mo later

LoRA: Low-Rank Adaptation of Large Language ModelsEdward J. Hu, Yelong Shen, Phillip Wallis et al. · 2021-06-17 · v2arXiv:2106.09685Paper page·PDF
undefined

An important paradigm of natural language processing consists of large-scale pre-training on general domain data and adaptation to particular tasks or domains. As we pre-train larger models, full fine-tuning, which retrains all model parameters, becomes less feasible. Using GPT-3 175B as an example -- deploying independent instances of fine-tuned models, each with 175B parameters, is prohibitively expensive. We propose Low-Rank Adaptation, or LoRA, which freezes the pre-trained model weights and injects trainable rank decomposition matrices into each layer of the Transformer architecture, greatly reducing the number of trainable parameters for downstream tasks. Compared to GPT-3 175B fine-tuned with Adam, LoRA can reduce the number of trainable parameters by 10,000 times and the GPU memory requirement by 3 times. LoRA performs on-par or better than fine-tuning in model quality on RoBERTa, DeBERTa, GPT-2, and GPT-3, despite having fewer trainable parameters, a higher training throughput, and, unlike adapters, no additional inference latency. We also provide an empirical investigation into rank-deficiency in language model adaptation, which sheds light on the efficacy of LoRA. We release a package that facilitates the integration of LoRA with PyTorch models and provide our implementations and model checkpoints for RoBERTa, DeBERTa, and GPT-2 at https://github.com/microsoft/LoRA.


Can you keep a hundred copies of a 175B model?

You want one large pre-trained model adapted to many downstream tasks. The obvious route is full fine-tuning, and its central defect is that the new model has as many parameters as the original (§1). What was a mere inconvenience for GPT-2 or RoBERTa large becomes a critical deployment problem for GPT-3 at 175 billion parameters. That is where the paper starts.

Its numbers are concrete. Full fine-tuning GPT-3 175B consumes 1.2TB of VRAM during training. With r=4r=4 and only the query and value projection matrices adapted, the checkpoint you have to store drops from 350GB to 35MB — roughly a 10,000x reduction (§4.2). Footnote 4 is refreshingly blunt about what this does and doesn't buy you: you still need the 350GB base model at deployment, but hosting 100 adapted models costs 350GB+35MB×100≈354GB350\mathrm{GB}+35\mathrm{MB}\times100\approx354\mathrm{GB} rather than 100×350GB≈35TB100\times350\mathrm{GB}\approx35\mathrm{TB}.

As an analogy, full fine-tuning rewrites the whole dictionary; LoRA seals the original and writes only the diff on a separate sheet. But that analogy only explains the storage bill. Why the diff can be so thin is the paper's real subject.

The intuition: adaptation amplifies directions that are already there

The hypothesis runs like this. Prior work (Li et al. 2018a; Aghajanyan et al. 2020) showed that over-parametrized models actually reside on a low intrinsic dimension. From that, the authors hypothesize that the change in weights during adaptation, ΔW\Delta W, also has a low "intrinsic rank" (§1).

Section 7.3 then measures it. For WqW_q in the 48th layer of GPT-3, Table 7 compares Frobenius norms after projecting WW onto the subspace spanned by the singular vectors of ΔW\Delta W. At r=4r=4, ∥U⊤WqV⊤∥F=0.32\|U^\top W_q V^\top\|_F = 0.32 while ∥ΔWq∥F=6.91\|\Delta W_q\|_F = 6.91 — an amplification factor of roughly 21. Projecting onto WqW_q's own top directions instead gives 21.67 (with ∥Wq∥F=61.95\|W_q\|_F = 61.95), so ΔW\Delta W is not simply repeating the dominant directions of WW. A random matrix projection gives 0.02, so it isn't uncorrelated either. (For singular vectors, projections and low-rank approximation themselves, see Singular Value Decomposition and Low-Rank Approximation.)

FIG 1Rotate the two vectors and watch the dot product and cosine move. The projection in §7.3 and the subspace overlap in Figure 3 both reduce to this one question — how much do two directions agree?

The paper's conclusion: ΔW\Delta W "amplifies the important features for specific downstream tasks that were learned but not emphasized in the general pre-training model" (§7.3). Fine-tuning, on this reading, isn't building capability from nothing — it's pushing up a handful of equalizer sliders. Which is exactly why you don't need many sliders.

What was wrong with the existing options

Parameter-efficient adaptation predates LoRA. Section 3 sorts it into two families: adding adapter layers, and optimizing input-layer activations (prefix/prompt methods).

Adapters add inference latency. Adapter layers sit in sequence with the base model, so their compute is always on the critical path, and while you can prune layers, "there is no direct way to bypass the extra compute in adapter layers" (§3). Table 1 reports single forward passes on GPT-2 medium, averaged over 100 trials on an NVIDIA Quadro RTX8000. At batch 32 / sequence 512 the penalty is a modest +2.2% to +3.0%. At batch 1 / sequence 128, 19.8ms becomes 23.9ms (+20.7%) and 25.8ms (+30.3%). In online inference with small batches this is not negligible (§3, Appendix B). Sharding makes it worse, since the added depth needs more synchronous GPU operations like AllReduce and Broadcast.

Prefix methods are hard to optimize and eat your context. The paper observes that prefix tuning "is difficult to optimize and that its performance changes non-monotonically in trainable parameters," and adds the more fundamental objection: reserving part of the sequence length for adaptation necessarily reduces the sequence length available to the downstream task (§3).

LoRA's core claim — the update is low rank — is faster to feel than to read. Slide the rank and find where the error collapses.

FIG 2A 28×28 matrix rebuilt from two thin factors (B·A) at rank r. The error collapses as r rises — the very reason ΔW=BA works

The full mathematical floor — eigenvalues, SVD, dot products — is laid out in The linear algebra under LoRA and RAG.

The mechanism: freeze W0W_0, train only BABA

For a pre-trained weight matrix W0∈Rd×kW_0\in\mathbb{R}^{d\times k}, the update is constrained to a low-rank decomposition (§4.1):

W0+ΔW=W0+BA,B∈Rd×r, A∈Rr×k, r≪min⁡(d,k)W_0+\Delta W=W_0+BA,\quad B\in\mathbb{R}^{d\times r},\ A\in\mathbb{R}^{r\times k},\ r\ll\min(d,k)

Spelled out in words: whatever fine-tuning would have written into the weight matrix, LoRA forces you to write as one tall thin matrix times one short wide one. AA squeezes the input down to rr numbers and BB opens it back out, so every change has to pass through a waist rr values wide — and rr is deliberately chosen far smaller than either side of W0W_0.

and the forward pass is Equation (3):

h=W0x+ΔWx=W0x+BAxh=W_0x+\Delta Wx=W_0x+BAx

The same line in words: the layer's output is what the frozen original would have produced, plus a correction computed from the very same input xx. The two paths sit side by side rather than one after the other — and that is precisely what later lets you fold BABA back into W0W_0 and pay nothing for it at inference time.

During training W0W_0 is frozen and receives no gradient updates. Three design points matter.

  1. Initialization: AA is random Gaussian, BB is zero, so ΔW=BA\Delta W=BA is zero at the start of training and the model is exactly the base model (§4.1).
  2. Scaling: ΔWx\Delta Wx is scaled by αr\frac{\alpha}{r}, with α\alpha constant in rr. The paper notes that "when optimizing with Adam, tuning α\alpha is roughly the same as tuning the learning rate if we scale the initialization appropriately," and states plainly that they set α\alpha to the first rr they try and do not tune it. The point of the scaling is to avoid retuning hyperparameters as you vary rr (§4.1).
  3. Merging: at deployment you explicitly compute and store W=W0+BAW=W_0+BA and run inference normally. Switching tasks means subtracting BABA and adding a different B′A′B'A'. This is what guarantees zero additional inference latency by construction (§4.1) — the clean separation from adapter layers.

On placement: of the four self-attention matrices (Wq,Wk,Wv,WoW_q,W_k,W_v,W_o) and the two MLP matrices, the paper restricts itself to attention weights and freezes the MLP, citing simplicity and parameter efficiency, and explicitly leaves adaptation of MLP layers, LayerNorms and biases to future work (§4.2). For what each of those four matrices actually does, see Attention from Scratch.

The authors also argue LoRA is a generalization of full fine-tuning: apply it to all weight matrices, train the biases too, and raise rr to the rank of the pre-trained matrices, and you roughly recover full fine-tuning's expressiveness. As trainable parameters grow, LoRA converges toward training the original model, whereas adapter methods converge to an MLP and prefix methods to a model that cannot take long inputs (§4.1).

What the experiments showed

Evaluation spans RoBERTa and DeBERTa (GLUE), GPT-2 (E2E NLG), and GPT-3 175B (WikiSQL, MNLI, SAMSum), all on NVIDIA Tesla V100 (§5). In most experiments LoRA is applied only to WqW_q and WvW_v (§5.1).

Limitations and open questions

Acknowledged by the paper:

Note as of this writing in 2026 (the author's annotation, not a claim from the paper): the experiments here target 2021-era models (RoBERTa, DeBERTa, GPT-2, GPT-3 175B). LoRA has since spawned many variants, including combinations with quantized base models, but every number in this article is from this paper; none come from later work.

Practical takeaways

The following are the author's operational readings of what the paper reports.

How this shows up at work — LoRA in practice

The reason this 2021 paper still gets read on the job is that its footnote-4 arithmetic is a serving-architecture argument, not a training trick. Two roles hit it constantly.

The ML engineer who has to make one base model serve many behaviours. A request arrives to add a domain-specific behaviour — a support tone, a schema-constrained output, a customer's house style — and the honest full fine-tuning answer is another checkpoint the size of the original. LoRA turns that into a per-task artifact small enough to keep dozens of, alongside a single shared base. The decision you are actually making is where the tenancy boundary sits: one merged model per task, or one base with modules selected per request.

The person who owns the latency budget. Whether an adaptation method can ship behind an existing serving SLO is decided by §3 and §4.1, not by an accuracy table. The mergeability argument — W=W0+BAW=W_0+BA computed once, offline — is what lets you promise the serving path is bit-for-bit the shape it was before.

The knobs you touch in a LoRA config are the paper's symbols under slightly different names: rank r is rr, lora_alpha is α\alpha from the α/r\alpha/r scaling, and target_modules is the §7.1 question of which matrices to attach to — the paper's own choice being the query and value projections. Serving then needs an explicit merge step that folds BABA into the base weights before the model is loaded for inference.

Places this goes wrong in production:

The question worth being able to answer out loud: why does zero added latency hold for LoRA but not for adapters? The answer is not "LoRA is smaller." It is that BABA is applied in parallel to W0W_0 on the same input, so it can be summed into the weights ahead of time, while an adapter layer sits in sequence and there is no arithmetic that makes a serial block disappear.

Summary

Original paper: Hu et al., "LoRA: Low-Rank Adaptation of Large Language Models" (arXiv:2106.09685, 2021 / v2)

References

  1. Edward J. Hu, Yelong Shen, Phillip Wallis, Zeyuan Allen-Zhu et al.. (2021-06-17) LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685Paper page·PDF

This article is written from the source paper above. Where they differ, the original is authoritative.

Published by TechAthletes · Editorial policy · How we cite · Corrections

Comments

Sign in to comment