The useful part, up front

What you’ll take away

  • LoRA freezes the pretrained weights and trains only two small low-rank matrices per adapted layer, whose product is added to the frozen weight [1][2].
  • The trainable count for one layer is r times the sum of its input and output dimensions, so rank and target-layer choice jointly determine the saving [1].
  • Adapters can be merged into the base for standalone inference, kept separate for task-switching, or unloaded to restore the original base [1][3].
  • Adaptation changes model behaviour through weights, while a document index supplies updatable external content at inference; they solve different problems and should be evaluated separately.
  • Reported parity with full fine-tuning is specific to the original experiments, so each new adapter should be compared with its frozen base on held-out task data [1][2].
01

Start with a frozen base model

Full fine-tuning changes every weight in a pretrained model during training, so each adapted copy must store a complete new set of weights. LoRA takes a different route: the original pretrained weights are kept frozen, meaning they do not receive updates, while only new small matrices are trained to adapt the model to new data [1][2]. This distinction is the whole point of the method, because it separates the shared base from the task-specific change.

The frozen base can then be reused as a starting point for several different tasks. Because the base does not change, multiple lightweight adapters can be built on top of the same pretrained weights, and each adapter can be stored and swapped separately from the large base model [1]. That portability is useful when one base model needs to support several behaviours without keeping a full fine-tuned copy for each one.

Freezing does not mean the model output stays the same. During a forward pass, the frozen weights and the trained adapter weights are combined to produce the adapted result [1]. The base supplies most of the pretrained knowledge, while the adapter supplies a learned correction for the new task, and training concentrates on that correction rather than rewriting the entire network.

Worked example: checking the matrix shapes. A hypothetical 8 by 4 weight with rank 2 gives factors that multiply back to 8 by 4.
A hypothetical 8 by 4 weight with rank 2 gives factors that multiply back to 8 by 4. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
02

Why two small matrices can stand in for one large update

A weight matrix in a neural network is a large table of numbers that transforms one set of values into another. If that table has many rows and columns, storing a full change to it would require changing every entry. LoRA represents the change with two smaller matrices instead, a technique called low-rank decomposition, so the number of values that must be learned stays low [1].

The two matrices work as a pair. One matrix first compresses the incoming information into a small intermediate space, and the second expands that compressed information back out to the size needed by the layer. Training adjusts the entries in these two smaller matrices, and their combined effect is the update that is added to the frozen base weight [1].

The word low-rank refers to the size of that intermediate space. A smaller intermediate space means fewer trainable numbers and a more constrained kind of change, while a larger one allows a richer update at the cost of more parameters. The rank, usually written as r, is therefore one of the main controls for how expressive and how economical an adapter is [1].

03

A worked example with dimensions checked

Consider a purely hypothetical layer whose frozen weight matrix W has 8 rows and 4 columns, so it contains 32 numbers in total. This example is invented only to make the arithmetic visible, and it does not describe any real model. If LoRA uses rank r equal to 2, the update is built from two smaller matrices whose shapes must fit together and must match the shape of W when multiplied [1].

The first factor, A, has shape 2 by 4, because it takes the 4 inputs and compresses them into 2 intermediate values. The second factor, B, has shape 8 by 2, because it takes those 2 intermediate values and expands them into 8 outputs. Multiplying B by A gives an 8 by 4 matrix, exactly the shape of W, so the update can be added to the frozen weight without a dimension error [1].

Now count the trainable numbers. Matrix A contains 2 times 4, or 8 numbers, and matrix B contains 8 times 2, or 16 numbers, for a total of 24 trainable numbers. A full update to W would have required 32 trainable numbers, so in this small example the saving is modest. The saving becomes dramatic only when the real layer dimensions are much larger than the chosen rank [1].

How the trainable count is built up. Each adapted layer adds its two factor sizes, and the total sums across all target layers.
Each adapted layer adds its two factor sizes, and the total sums across all target layers. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
04

Counting trainable parameters before you train

The number of trainable parameters in a LoRA model depends mainly on the rank r and the shape of each original weight matrix that receives an adapter [1]. For every adapted layer, you add the sizes of its two small matrices, and then you add those totals across all adapted layers. Layers without an adapter contribute no new trainable parameters, although the frozen base still has to be loaded for training and inference [1].

This arithmetic explains why target-layer choice matters as much as rank. Adapting only a few layers keeps the trainable count low, while adapting many layers multiplies the count even if each individual adapter is small. A configuration with a low rank applied everywhere can therefore contain more trainable parameters than a higher-rank adapter applied to only one or two layers [1].

It also explains why LoRA checkpoints are small. A saved adapter normally needs to store only the two small matrices for each adapted layer, plus any extra modules that were explicitly made trainable, rather than a complete copy of the base model [1][3]. The base checkpoint is still required to use the adapter, so the saving is in the adapted copy, not in eliminating the base entirely [3].

05

Choosing which layers receive an adapter

In principle, LoRA can be applied to any subset of weight matrices in a neural network to reduce the number of trainable parameters [1]. In practice, for Transformer models it is typically applied to attention blocks only, because that keeps the method simple and further reduces the number of trainable parameters [1]. The target_modules setting names the modules, such as attention blocks, that receive the low-rank update matrices [1].

The original implementation focused on adapting only the query and value projections in a Transformer, while noting that LoRA can be applied to other subsets of pretrained weights [3]. It also encouraged exploring other configurations, such as adapting embedding layers or multilayer perceptron layers, because the best configuration can vary by architecture and task [3]. There is no universal target set that is correct for every model and every task.

Target choice is therefore an experimental decision, not a default to copy blindly. Adapting fewer layers gives a smaller and more constrained update, while adapting more layers gives the update more places to act but also adds parameters and training cost. The right choice should be tested against the actual task, with the base model and adapter configuration recorded so results can be compared fairly [1][3].

06

Rank, scaling, and starting values

Rank is not the only control on an adapter. The update is multiplied by a scaling factor during every forward pass, and that factor is fixed at initialisation and depends on the rank [1]. In the original formulation the scaling uses lora_alpha divided by r, while rank-stabilised LoRA instead uses lora_alpha divided by the square root of r, which the documentation says was shown to work better and to stabilise adapters at higher ranks [1].

Starting values matter because training begins from the adapter, not from a random change to the base. By default, PEFT initialises weight A with Kaiming-uniform values and weight B as zeros, which results in an identity transform at the start, meaning the adapter initially adds no change to the base output [1]. A Gaussian initialisation for A, with B still zero, is also available and matches the way some other libraries initialise LoRA weights [1].

These details are easy to overlook because they do not change the shape of the adapter. Two adapters with the same rank and the same target layers can still behave differently if their scaling or initialisation differs. When comparing configurations, it is therefore important to record rank, alpha, scaling mode, and initialisation, not just the number of trainable parameters [1].

Attention projections versus other layers. Attention blocks are the typical starting point, but other dense layers can also be adapted.
Attention blocks are the typical starting point, but other dense layers can also be adapted. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
07

Merging, unmerging, and unloading an adapter

During training, the small adapter matrices are separate from the base weights. Once training is complete, those weights can be merged into a new weight matrix that is identical to the combined result, so the adapted model can be used as a standalone model [1]. Merging folds the learned update into the base weights, which removes the need to load the base and the adapter as separate pieces during inference [1].

The documentation notes that separately loading a base model and a LoRA model can cause latency during inference, and that merging the adapter weights with the base model eliminates that issue [1]. The original implementation similarly merges LoRA parameters into the pretrained ones when the model is switched to evaluation mode, and unmerges them when training resumes, unless merging is disabled [3]. Merging is therefore a deployment choice about how the final weights are packaged and served.

Merging is not the only option. PEFT provides merge_adapter to merge while retaining the wrapper model for later unmerging or adapter changes, unmerge_adapter to reverse that step, and unload to return the base model without the adapter merged in [1]. Unloading is useful when you want to reset to the original pretrained state, for example when trying out different adapters against the same base [1].

08

Keeping several adapters on one shared base

Because the base stays frozen, one pretrained model can support many lightweight adapters for different downstream tasks [1]. Each adapter stores only its small matrices, so a library of task-specific adapters can be much cheaper to keep than a library of full fine-tuned models. The original authors emphasise that this reduces storage for large models adapted to specific tasks and enables efficient task-switching during deployment [3].

Adapters can also be combined. PEFT provides add_weighted_adapter to combine multiple LoRAs into a new adapter using a user-provided weighting scheme [1]. That makes it possible to blend the updates from several adapters, although the result is a new combined adapter whose behaviour still needs to be evaluated rather than assumed to be the sum of the individual strengths [1].

Portability has a limit that is easy to miss. An adapter is only meaningful together with the base model it was trained on, and the original checkpoint must still be available to use it [3]. An adapter trained for one base model, one set of target layers, or one scaling configuration should not be assumed to work with a different base or a different configuration without checking shapes and evaluating the combination [1][3].

Merge, keep separate, or unload. The same trained adapter can be folded into the base, swapped between tasks, or removed.
The same trained adapter can be folded into the base, swapped between tasks, or removed. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
09

Adaptation is not the same as adding a document index

A LoRA adapter changes how a model processes input by changing its weights. A document index, by contrast, stores external documents or passages so that relevant text can be retrieved and shown to the model at inference time. The two approaches solve different problems: adaptation teaches the model a new behaviour or style, while retrieval supplies specific facts or passages that the model can read in context. This section is a general explanation and is not presented as sourced from the LoRA references cited elsewhere in this article.

This distinction matters when choosing a tool. If the goal is to make a model answer in a particular format, follow a particular style, or perform a narrow task more reliably, training an adapter on examples of that behaviour is the relevant approach. If the goal is to answer questions about documents that change frequently, or to cite specific passages, an index that can be updated without retraining is usually the more direct approach, because the knowledge lives outside the weights.

The two can be used together, but they should not be confused. An adapter can learn to use retrieved context in a consistent way, while the index supplies the actual content for each query. Evaluating them separately is important: a model that performs well with retrieved documents may still fail without them, and an adapter that improves style may do nothing to improve factual coverage of new documents.

10

Evaluating an adapter and avoiding common failures

LoRA is reported to perform comparably to full fine-tuning in the original experiments, but that finding is specific to the models, tasks, and configurations studied and should not be read as a guarantee of equal quality for every new task [1][2]. The safe approach is to evaluate the adapted model on held-out data that represents the real task, and to compare it with the frozen base model on the same data. Without that comparison, there is no evidence that the adapter helped at all [1].

Several failures are common and preventable. A rank that is too small may be unable to express the needed change, while a rank that is large, combined with many target layers, can add back much of the parameter cost that LoRA was meant to avoid [1]. Mismatched target layers, a wrong or mismatched base checkpoint, or omitting the pretrained base before loading the LoRA checkpoint can also produce a model that runs but behaves incorrectly. Loading a LoRA-only checkpoint with strict=False after the pretrained checkpoint has been loaded is the expected procedure in the original implementation, not an error in itself [3]. Each of these should be checked before drawing conclusions about the method itself.

A short checklist keeps the work honest. Record the base checkpoint, target modules, rank, alpha, scaling mode, and initialisation; count the trainable parameters including biases and saved modules; verify that the adapter shapes match the base layers; evaluate the base and the adapted model on the same held-out task data; and decide explicitly whether to merge, keep the adapter separate, or unload it for deployment [1][3]. If any step is missing, the result is hard to reproduce or trust.

Layers of a LoRA deployment. The base, adapter, and serving choices stack in a fixed order from shared weights to task behaviour.
The base, adapter, and serving choices stack in a fixed order from shared weights to task behaviour. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
Follow the evidence

Sources & further reading

Explore the references behind this guide. External pages may change after our review.

  1. LoRA · Hugging Face
    Hugging Face · Accessed 6 Nov 2026
  2. LoRA: Low-Rank Adaptation of Large Language Models - Microsoft Research
    Microsoft Research · Accessed 6 Nov 2026
  3. GitHub - microsoft/LoRA: Code for loralib, an implementation of "LoRA: Low-Rank Adaptation of Large Language Models" · GitHub
    Microsoft / LoRA project · Accessed 6 Nov 2026

Article updated 6 Nov 2026.

Found something we should revisit?

Good explanations get better with thoughtful feedback.

Suggest a correction