Hire AI Developers Need An Online Store? Client Contracts & NDAs Grow Your Sales Funnel
Hire AI Developers Grow Your Sales Funnel

LoRA and QLoRA: Parameter-Efficient Fine-Tuning Explained

Updated July 2026
LoRA (Low-Rank Adaptation) fine-tunes a model by adding small trainable matrices to its layers instead of updating all weights. QLoRA combines this with 4-bit quantization, cutting memory requirements by 75% so you can fine-tune a 70B model on a single GPU. Together, these techniques made fine-tuning accessible to any developer with a modern graphics card.

The Problem LoRA Solves

Full fine-tuning updates every parameter in the model. For Llama 3.1 8B, that is 8 billion parameters, each stored as a 16-bit floating point number, requiring 16GB of VRAM just for the weights. During training, you also need memory for gradients (another 16GB), optimizer states (32GB for Adam), and activations (variable, typically 8-16GB). A full fine-tune of an 8B model needs 80GB+ of VRAM, which requires at minimum an A100 80GB GPU. For a 70B model, you need 4-8 A100s.

This hardware barrier locked fine-tuning behind enterprise-grade infrastructure. Researchers at Microsoft introduced LoRA in 2021 to solve this problem. Their insight was that the weight changes during fine-tuning have low intrinsic dimensionality, meaning you can represent the adaptation in a much smaller space without losing meaningful quality.

How LoRA Works Technically

LoRA freezes the original model weights and adds two small matrices (called A and B) to each targeted layer. Matrix A has dimensions (d x r) and matrix B has dimensions (r x d), where d is the layer's hidden dimension and r is the LoRA rank, a hyperparameter you choose. The rank r is much smaller than d, typically 8 to 64 compared to d values of 4,096 or higher.

During a forward pass, the original weight matrix W produces its usual output, and the LoRA matrices produce a parallel output: input * A * B. The two outputs are added together: output = W(x) + (alpha/r) * B(A(x)). The scaling factor alpha/r controls how strongly the LoRA adaptation influences the final output.

During training, only matrices A and B receive gradient updates. The original weights W remain frozen. For a layer with d=4096 and r=16, the original weight matrix has 4096 x 4096 = 16.7 million parameters. The LoRA matrices have (4096 x 16) + (16 x 4096) = 131,072 parameters, which is 0.78% of the original. Across all targeted layers in an 8B model, the total trainable parameter count is typically 20-40 million, roughly 0.3-0.5% of the full model.

This reduction in trainable parameters has three practical benefits. First, memory usage drops dramatically because you only store gradients and optimizer states for the small LoRA matrices. Second, training is faster because backpropagation only flows through the small matrices. Third, the LoRA adapter (the A and B matrices) is a small file, typically 50-200MB, that can be loaded and unloaded from the base model without touching the original weights. You can maintain multiple LoRA adapters for different tasks and swap them in milliseconds.

How QLoRA Extends This

QLoRA, introduced by Dettmers et al. in 2023, adds 4-bit quantization to the LoRA approach. Before applying LoRA, the base model is loaded in 4-bit NormalFloat (NF4) precision instead of the usual 16-bit. This reduces the base model's memory footprint by approximately 75%. An 8B model that needs 16GB in fp16 fits in roughly 5GB in 4-bit quantization.

The key innovation in QLoRA is that the LoRA adapters themselves still operate in 16-bit precision. Only the frozen base weights are quantized. This means the trainable parameters maintain full precision for accurate gradient computation, while the bulk of the model (the frozen weights) is compressed to save memory. The forward pass dequantizes the base weights on the fly, computes the output, and the LoRA contribution is added at full precision.

QLoRA also introduced double quantization: quantizing the quantization constants themselves. Normal quantization stores a scaling factor for each block of weights. Double quantization quantizes these scaling factors as well, saving an additional 0.5GB or so on large models. The quality impact is negligible, but the memory savings make a difference when you are working at the margins of GPU capacity.

With QLoRA, fine-tuning an 8B model requires approximately 6-8GB of VRAM (model weights + LoRA adapters + training state), well within the capacity of a 24GB consumer GPU like the RTX 4090. Fine-tuning a 70B model requires approximately 40-48GB, which fits on a single A100 80GB. This is the breakthrough that made fine-tuning of large models accessible without multi-GPU setups.

DoRA: The 2024-2026 Evolution

DoRA (Weight-Decomposed Low-Rank Adaptation) improves on standard LoRA by decomposing the weight update into two components: magnitude and direction. In standard LoRA, the matrices A and B jointly learn both how much to change the output (magnitude) and in what direction to change it (direction). DoRA separates these, allowing each component to be learned independently.

The practical result is that DoRA converges faster and often matches full fine-tuning quality at the same LoRA rank where standard LoRA falls slightly short. In benchmarks, DoRA at rank 16 typically matches LoRA at rank 32-64, which means you can use a lower rank (saving memory and compute) without sacrificing quality.

In 2026, the default recommendation for most fine-tuning projects is QLoRA + DoRA. The PEFT library from Hugging Face supports DoRA natively by adding use_dora=True to the LoRA configuration. There is no significant computational overhead compared to standard LoRA, so there is no reason not to use it unless you are working with a framework that does not support it yet.

Choosing Your LoRA Parameters

Rank (r): The most important hyperparameter. Higher rank captures more complex adaptations but increases memory usage and training time linearly. For most fine-tuning tasks (style transfer, domain adaptation, output formatting), r=16 is sufficient. For tasks that require learning complex new behaviors (like teaching a model to use a new set of tools), try r=32 or r=64. Ranks above 64 rarely provide additional benefit and start approaching the cost of full fine-tuning.

A practical way to choose rank: start with r=16. If the fine-tuned model's quality is insufficient, increase to r=32 and retrain. If r=32 is still not enough, the problem is likely with your data quality or quantity rather than the rank.

Alpha: Set alpha = 2 * r as a starting point (e.g., alpha=32 for r=16). This gives a scaling factor of 2.0, which provides enough learning signal for the LoRA weights to influence the model's outputs meaningfully. If training is unstable (loss oscillates), reduce alpha. If training converges too slowly, increase alpha. In practice, the alpha/r ratio of 2.0 works well across a wide range of tasks and you rarely need to change it.

Target modules: At minimum, target the attention projection layers: q_proj, k_proj, v_proj, and o_proj. These control how the model attends to different parts of the input, which is the primary mechanism for behavioral changes. For more thorough adaptation, also include the MLP layers (gate_proj, up_proj, down_proj). Including MLP layers roughly doubles the trainable parameter count and training time, but can improve quality on tasks that require the model to learn new knowledge rather than just new behaviors.

Dropout: LoRA dropout randomly zeros out adapter weights during training to prevent overfitting. Use 0.05 for datasets over 2,000 examples, 0.1 for 500-2,000 examples, and 0.15 for fewer than 500 examples. Dropout adds minimal computational overhead and is a simple but effective regularization technique.

Adapter Management in Production

One of LoRA's strongest practical advantages is adapter portability. The fine-tuned behavior lives in a small adapter file (50-200MB for an 8B model) separate from the multi-gigabyte base model. This enables several production patterns that are impossible with full fine-tuning.

Multi-tenant serving: Load one base model and swap LoRA adapters per request based on the customer or task. A single GPU hosts the 8B base model plus dozens of LoRA adapters in memory. Each request routes to the appropriate adapter. Frameworks like vLLM and Lorax support this natively, batching requests across different adapters for efficiency.

A/B testing: Train two LoRA adapters with different training data or hyperparameters and route 50% of traffic to each. Compare performance metrics and keep the winner. This is far cheaper than hosting two separate full models.

Rollback: If a new fine-tune performs worse than the previous version, swap back to the old adapter instantly. No model reloading, no infrastructure changes. Version your adapters like code and keep the last 3-5 versions available for immediate rollback.

Merging: For simplified deployment, merge the LoRA adapter into the base model weights to create a single model file. This eliminates the adapter loading step and simplifies the inference pipeline, but you lose the ability to swap adapters. Merge when you are deploying a single-purpose model that will not change frequently.

Key Takeaway

LoRA and QLoRA made fine-tuning accessible by reducing trainable parameters to less than 1% of the model and cutting memory requirements by 75%. Use QLoRA + DoRA with rank 16 as your starting point. Target attention layers, set alpha to 2x your rank, and enjoy the ability to swap fine-tuned behaviors in and out of a single base model.