LoRA and Beyond:
Five LLM Fine-Tuning Techniques, Explained
Full fine-tuning a 7B model needs over 100GB of GPU memory. Five techniques get most of the benefit for a fraction of that. How each one works, drawn out, with the numbers from its paper and a guide to choosing.
By Serverless Ventures
Published: October 25, 2026 · Read time: ~9 minutes
The short version
Updating every weight of a large language model is out of reach for most teams. The fix is parameter-efficient fine-tuning (PEFT): freeze the model and train a small add-on that captures how the weights should change.
LoRA does this with two thin matrices whose product approximates the update. Its descendants each change one thing. LoRA-FA freezes half of the add-on to save memory. VeRA shares it across layers and trains only scaling vectors. Delta-LoRA lets the frozen weights move too. LoRA+ trains the two halves at different speeds.
For most teams the practical answer is still LoRA or QLoRA, with the LoRA+ learning-rate trick. Reach for the others when a specific limit, such as memory, adapter count or quality, gets in the way.
Why fine-tuning an LLM is different
Classic fine-tuning updates every parameter. For an LLM that means holding much more than the model itself in GPU memory. A common rule of thumb for mixed-precision training with the Adam optimizer is about 16 bytes per parameter: 2 for the weights, 2 for the gradients, 4 for a full-precision master copy, and 8 for Adam's two running statistics. Activations come on top of that.
| Model size | Weights alone (16-bit) | Full fine-tune, before activations |
|---|---|---|
| 7B | ~14GB | ~112GB |
| 13B | ~26GB | ~208GB |
| 70B | ~140GB | ~1.1TB |
Storage is a second problem. Every fully fine-tuned variant is a complete copy of the model. Ten customers with ten custom models means ten copies of 140GB.
The one idea you need: rank
An LLM's weights are matrices. A single attention projection in a 7B-class model is roughly 4,096 by 4,096, about 16.8 million numbers. The rank of a matrix is how many independent directions it really contains. A matrix of low rank can be written exactly as the product of two thin matrices.
The insight behind LoRA, building on earlier research into the "intrinsic dimension" of fine-tuning, is that the change fine-tuning makes to a weight matrix has low rank, even when the matrix itself does not. So instead of learning a 4,096 by 4,096 update, you learn a 4,096 by 8 matrix and an 8 by 4,096 matrix and multiply them. That is 65,536 numbers instead of 16.8 million, 0.4% of the original.
W is a d × k weight matrix. B is d × r and A is r × k, where the rank r is small (often 8 to 64). The fine-tuned layer computes (W + BA)x.
1. LoRA: learn the change, not the weights
LoRA (Low-Rank Adaptation; Hu et al., Microsoft, 2021) places the pair B and A beside a frozen weight matrix. A starts random and B starts at zero, so on step one the model behaves exactly like the base model. Training adjusts only B and A, and the output is scaled by a constant α/r so you can change the rank without re-tuning the learning rate.
On GPT-3 175B, the paper reports 10,000 times fewer trainable parameters and 3 times less GPU memory than full fine-tuning, with quality on par or better. A checkpoint shrinks from 350GB to about 35MB. After training you can merge BA into W, so inference costs exactly the same as the base model. Or you can keep adapters separate and swap them per request.
The catch: freezing W saves gradients and optimizer state, but activations for the LoRA path still have to be stored for backpropagation. On long sequences, that becomes the memory bottleneck.
2. LoRA-FA: freeze A, train only B
LoRA-FA (Frozen-A; Zhang et al., 2023) targets that activation cost. To compute the gradient for A, LoRA must keep the full layer input, d numbers per token. If A never changes, only B needs a gradient, and B's gradient needs just A's output, r numbers per token. With r at 8 and d at 4,096, that is a big difference.
Training half the matrices sounds like a big sacrifice, but a random projection keeps most of the information, and B can learn to use it. The paper reports quality comparable to LoRA and full fine-tuning on benchmarks from GLUE to GSM8K and HumanEval, with significantly lower activation memory and compute. Use it when long sequences or big batches make activation memory the limit.
3. VeRA: share the matrices, train only vectors
VeRA (Vector-based Random Matrix Adaptation; Kopiczko et al., 2023) goes further. In LoRA, every adapted layer has its own B and A. VeRA creates one random pair, freezes it, and shares it across all layers. Each layer then learns two vectors: d scales the r inner dimensions and b scales the output. The update becomes Λb B Λd A, where Λ means a diagonal matrix built from a vector.
Because the random matrices can be regenerated from a seed, they do not even need to be saved. The paper reports about 10 times fewer trainable parameters than LoRA at comparable quality. For a 4,096 by 4,096 layer that is a few thousand numbers per layer. That matters when you store or serve thousands of personalized adapters. Since the matrices are random rather than learned, VeRA usually needs a higher rank than LoRA to match it.
4. Delta-LoRA: let the frozen weights move
Every technique so far leaves W untouched, which caps what a low-rank update can express. Delta-LoRA (Zi et al., 2023) updates W too, without paying for W's gradients. After each step it computes how much the product BA changed, Δ(BA) = Bt+1At+1 − BtAt, and adds a scaled copy of that difference to W.
The insight is that this difference already points in the direction the full gradient would push W. So W gets a useful update with no extra memory for gradients or optimizer state. The paper reports results ahead of LoRA and other low-rank methods at memory and compute costs comparable to LoRA. One practical point, our inference rather than the paper's: because W changes, it has to be kept at a precision you can write to, which does not fit naturally with a 4-bit QLoRA base.
5. LoRA+: train B faster than A
LoRA+ (Hayou, Ghosh and Yu, 2024) changes nothing in the architecture. It changes one hyperparameter. Standard LoRA trains B and A with the same learning rate. The authors show that for wide models this is mathematically inefficient, because the two matrices play different roles. B should learn much faster.
The fix is a single ratio: give B a learning rate λ times A's, with 16 a common default. The paper reports 1 to 2 percent better results and up to about 2 times faster fine-tuning at the same compute. It costs nothing extra and combines with almost every other technique here, so it is the easiest win on the list.
Two more worth knowing
Dettmers et al. (2023) store the frozen base model in a 4-bit format (NF4), quantize the quantization constants themselves, and page optimizer state to CPU memory during spikes. LoRA trains on top in 16-bit. The result: a 65B model fine-tuned on a single 48GB GPU. It is the default way most people fine-tune on one card.
Liu et al. (2024) split each weight into a magnitude and a direction, train the magnitude directly, and use LoRA for the direction. This mirrors how full fine-tuning changes weights more closely and narrows the quality gap with it, with no added inference cost once merged.
Others you will meet in libraries: rsLoRA scales by α/√r so higher ranks keep learning, while PiSSA and OLoRA start B and A from a decomposition of W instead of random noise, which often converges faster.
Side by side
Trainable parameters for a single 4,096 by 4,096 layer at rank 8, compared with full fine-tuning:
| Technique | What trains | Trainable / layer | Best when |
|---|---|---|---|
| Full fine-tune | W | 16,777,216 | You have the GPUs and need every last point |
| LoRA | B, A | 65,536 | The default starting point |
| LoRA-FA | B | 32,768 | Activation memory is the limit |
| VeRA | b, d | 4,104 | Storing or serving many adapters |
| Delta-LoRA | B, A (W follows) | 65,536 | LoRA quality falls short |
| LoRA+ | B, A (B faster) | 65,536 | Always; it is a free upgrade |
VeRA's per-layer count excludes the shared random matrices, which are frozen and can be regenerated from a seed. In practice VeRA is run at a higher rank than LoRA, which adds only a few hundred numbers per layer.
Try it
Hugging Face's PEFT library implements most of these. A LoRA setup that adapts every linear layer:
from peft import LoraConfig, get_peft_model
config = LoraConfig(r=16, lora_alpha=32, lora_dropout=0.05,
target_modules="all-linear")
model = get_peft_model(base_model, config)
model.print_trainable_parameters()
From there, each variant is a small change. Set use_dora=True for DoRA or use_rslora=True for rsLoRA. Build the optimizer with create_loraplus_optimizer for LoRA+ or create_lorafa_optimizer for LoRA-FA. Use VeraConfig in place of LoraConfig for VeRA. For QLoRA, load the base model in 4-bit with bitsandbytes first.
Before you fine-tune at all
These techniques make fine-tuning cheap. They do not make it the right tool. Fine-tuning is good at teaching a model a format, a style, a domain vocabulary or a narrow skill. It is poor at teaching it facts that change, which belong in retrieval. Better prompting closes more of the gap than most teams expect.
Whatever you choose, build the evaluation set first: a few hundred real examples with a clear way to score them. Without it you cannot tell whether LoRA, DoRA or a better prompt actually helped, and every technique above is guesswork.
Our read
LoRA or QLoRA, all linear layers, the LoRA+ ratio. That covers most needs. Move on only when an evaluation shows a gap.
A few megabytes per customer, swappable at request time on one base model, makes per-customer customization a serving feature rather than a training project.
The gap between LoRA variants is a few points. The gap between a clean dataset and a noisy one is usually much larger. Spend there first.
Sources: Hu et al., LoRA: Low-Rank Adaptation of Large Language Models (2021); Zhang et al., LoRA-FA: Efficient and Effective Low Rank Representation Fine-tuning (2023, revised); Kopiczko, Blankevoort and Asano, VeRA: Vector-based Random Matrix Adaptation (2023); Zi et al., Delta-LoRA: Fine-Tuning High-Rank Parameters with the Delta of Low-Rank Matrices (2023); Hayou, Ghosh and Yu, LoRA+: Efficient Low Rank Adaptation of Large Models (2024); Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs (2023); Liu et al., DoRA: Weight-Decomposed Low-Rank Adaptation (2024); Hugging Face PEFT LoRA guide. Memory figures are rule-of-thumb estimates; actual use depends on sequence length, batch size and framework.