Start studying
Module 10 · Fine-Tuning Module contents
Module 10  ·  Card 6 / 15intermediate

QLoRA

QLoRA quantizes the frozen base model to 4-bit precision.

LoRA adapters are then trained on top of that compressed base.

This cuts memory use dramatically with little quality loss.

It puts fine-tuning a large model within reach of a single consumer GPU.

It is the standard approach for fine-tuning on limited hardware.

Learn in depth ↓
Module 10 · Fine-Tuning · 15 concepts
In depth  /  15 lines

QLoRA, in more detail

QLoRA combines quantisation with LoRA to fine-tune large models on modest hardware.

LoRA already avoids storing gradients for the base weights.

The frozen base still has to sit in memory in full precision.

At two bytes per parameter, a 70B model needs 140 GB just to be present.

QLoRA quantises that frozen base to four bits, cutting it to roughly 35 GB.

The base is never updated, so precision matters less than it would during full training.

LoRA adapters are trained on top in higher precision.

Gradients flow back through the quantised weights without updating them.

It introduced 4-bit NormalFloat, a format matched to how weights are actually distributed.

Double quantisation compresses the quantisation constants themselves for a further saving.

Paged optimizers spill memory to system RAM when a spike would otherwise crash the run.

Together these fit a 65B fine-tune onto a single 48 GB GPU.

The quality loss against full-precision LoRA is small enough to accept in most cases.

It is the standard approach for anyone fine-tuning without a cluster.

Training is slower per step, since weights are dequantised on the fly.

Want the full technical article? Wikipedia ↗
Deep dive

What is underneath QLoRA

Quantise the frozen part, train in full precision

LoRA already freezes the base model, so the frozen weights are read and never updated. QLoRA's observation is that a read-only weight does not need 16 bits.

Wbase:4-bit,A,B:bf16W_{\mathrm{base}} : \text{4-bit}, \qquad A, B : \text{bf16}
y=dequant(Wbase)x+αrBAx\mathbf{y} = \mathrm{dequant}(W_{\mathrm{base}})\mathbf{x} + \frac{\alpha}{r} B A \mathbf{x}

The base is stored in 4 bits, dequantised to bf16 one block at a time inside the matrix multiply, and the adapters stay in full precision because they are the thing being learned.

14 GB→3.5 GB14 \text{ GB} \to 3.5 \text{ GB}

That is what puts a 7-billion-parameter fine-tune on a consumer card, and a 65-billion one on a single 48 GB card.

NF4, the data type

qi=the i-th quantile of N(0,1)q_i = \text{the } i\text{-th quantile of } \mathcal{N}(0,1)

Neural weights are approximately normally distributed, so a uniform 4-bit grid wastes most of its levels on values that almost never occur.

NF4 places its 16 levels at the quantiles of a normal distribution, so each level is equally likely to be used.

w^=qc⋅sb\hat{w} = q_{c} \cdot s_{b}

Each block of 64 weights carries its own scale sbs_b, since a single scale across a whole tensor would be dominated by its largest outlier.

Double quantisation

sb:fp32,  one per 64 weights  ⟹  0.5 bits per weights_b : \text{fp32}, \; \text{one per 64 weights} \implies 0.5 \text{ bits per weight}

Those block scales are themselves a real cost. Quantising them too, in blocks of 256, cuts the overhead to about 0.127 bits per weight.

It is a small saving in percentage terms and it is most of a gigabyte on a large model, which is often the difference between fitting and not.

Paged optimisers

Memory use spikes when a long sequence arrives, and a spike that exceeds the card kills a run that has been going for hours.

Paged optimiser states move to CPU memory when the GPU is under pressure and come back when it is not, using the same unified memory mechanism as operating system paging.

It makes the failure mode slow rather than fatal, which is the difference between a finished run and a lost one.

One fine-tune, in order

  1. Load the base model with 4-bit NF4 quantisation and double quantisation on.
  2. Attach LoRA adapters to the attention and feed-forward projections.
  3. Train with a paged optimiser and gradient checkpointing.
  4. Save only the adapter, a few tens of megabytes.
  5. For serving, either keep the quantised base with the adapter attached, or merge the adapter into the full precision base.

Step five has a trap. Merging bf16 adapters into a 4-bit base and saving the result loses precision twice, so the merge should be done against the original weights.

What it costs

speed≈0.7×LoRA in bf16\text{speed} \approx 0.7 \times \text{LoRA in bf16}

Dequantisation happens on every forward pass, so training is roughly a third slower than unquantised LoRA on hardware that had the memory anyway.

Quality, on the published comparisons, is within noise of 16-bit LoRA, which is the result that made the method standard rather than a compromise.

The base model's own accuracy does drop slightly under 4-bit quantisation, and the adapter is trained against the quantised base, so it learns to compensate for exactly that error.

Test yourself

One question on this card. Every option explains itself once you pick, right or wrong.

Question 1
What does QLoRA add on top of LoRA?
Fine-Tuning

15 concepts in this module, then a graded test with every answer explained.

Study this module →
↑↓ move↵ openesc close