The two methods train exactly the same thing. The difference is only in how the frozen base weights are stored — 4-bit instead of 16-bit. Almost every practical difference follows from that one decision.
The memory gap
For Llama 3.1 8B, rank 16, 2048 tokens, batch 1, gradient checkpointing on:
| LoRA bf16 | QLoRA NF4 | Difference | |
|---|---|---|---|
| Weights | 16.06 GB | 4.42 GB | 11.64 GB |
| Everything else | 2.34 GB | 1.79 GB | 0.55 GB |
| Total | 18.40 GB | 6.21 GB | 12.19 GB |
A 3× reduction, and it lands exactly where it matters: it moves an 8B model from “needs a 24GB card with no room” to “fits a 16GB card alongside a batch of 2”.
The scaling is linear in parameters, so it gets more dramatic as models grow. A 70B model is 141GB at bf16 and 39GB at NF4 — the difference between an eight-GPU node and one H100.
The quality gap
Smaller than the internet suggests, and conditional.
- On narrow tasks (classification, extraction, structured output, tone) the gap is typically under one point on task metrics. Data quality dominates it.
- On precision-sensitive tasks (arithmetic, exact string copying, strict schema validation) 4-bit storage does measurably hurt. If your evaluation includes exact-match on long outputs, test bf16 LoRA before committing.
- On very small datasets the gap widens, because the model leans harder on the frozen weights it already has.
The original QLoRA work matched 16-bit LoRA on their benchmarks for a 65B model. That is an existence proof, not a guarantee for your task. Measure it on your own held-out set — it costs one extra run.
The speed gap
QLoRA dequantises weights on every forward and backward pass. That is real overhead:
| LoRA bf16 | QLoRA | |
|---|---|---|
| Relative throughput | 100% | 60–80% |
| 8B, 5k examples, 3 epochs | ~2.0 h | ~2.8 h |
| Cost on a 4090 at $0.44/h | $0.88 | $1.23 |
On small runs this is noise. On a 70B run across several days it is a line item, and bf16 LoRA on a bigger card can be cheaper overall despite the higher hourly rate.
The merging difference
LoRA adapters merge into the bf16 base weights with no loss. QLoRA adapters must merge into a bf16 base and then be re-quantised if you want a 4-bit deployment — two quantisation steps, twice the fidelity loss.
If you plan to serve the merged model rather than the adapter, this alone can decide it.
Decision table
| Your situation | Choose |
|---|---|
| Model at bf16 exceeds your GPU memory | QLoRA |
| 7–8B model on a 24GB card, experimenting | QLoRA |
| 7–8B model on a 24GB card, final run, precision-sensitive task | LoRA bf16 |
| 70B on a single 80GB card | QLoRA |
| 70B on multi-GPU with room to spare | LoRA bf16 |
| You will merge and serve the weights | LoRA bf16 |
| Throughput is the binding constraint | LoRA bf16 |
| You have 30 minutes and one rented card | QLoRA |
The version nobody mentions
Train in QLoRA to find out whether the task is learnable, then rerun the winning configuration in bf16 LoRA once you know it works. The first run answers the question cheaply; the second produces the artifact you ship. That pattern costs less than committing to the expensive path before you have evidence.
Work out which side of the memory line you are on with the VRAM calculator, or read how QLoRA works for the mechanism.