DL0087 QLoRA: 4-bit Quantized LoRA

What is QLoRA, and how does it combine 4-bit quantization with LoRA?

Answer

QLoRA (Dettmers et al., 2023) is a fine-tuning recipe that keeps the entire base model frozen in 4-bit precision and trains only LoRA adapters in 16-bit on top of it, so the memory that would have held gradients and optimizer state for billions of parameters simply never gets allocated. During the forward pass each 4-bit weight block is dequantized to bf16 on the fly, used for the matrix multiply, and discarded; the backward pass dequantizes again to propagate gradients through the frozen weights into the adapters, which are the only tensors that receive updates. Three components make the 4-bit base workable: the NF4 data type, which places its 16 levels at quantiles of a normal distribution rather than uniformly, double quantization of the per-block scaling constants, and paged optimizers that offload optimizer state through unified memory when a long-sequence step spikes. The headline result was fine-tuning a 65B model on a single 48 GB GPU while matching 16-bit LoRA quality on instruction-following benchmarks. Note that QLoRA quantizes the frozen base, never the adapters or the gradients, so all learning still happens in bf16.

(1) NF4 (4-bit NormalFloat): pretrained weights within a block are approximately zero-centered Gaussian, so NF4 spaces its levels at quantiles of a standard normal instead of uniformly, which is information-theoretically optimal for that assumption and beats 4-bit float or int at equal bit width.
(2) Blockwise Absmax Scaling: weights are quantized in blocks of 64 with one absmax constant per block, which localizes outliers so a single large weight cannot crush the resolution of an entire tensor.
(3) Double Quantization: those constants are themselves quantized to 8-bit with a second-level fp32 scale per 256 constants, cutting the metadata overhead from 0.5 to about 0.127 bits per parameter (roughly 3 GB on a 65B model).
(4) Only Adapters Train: gradients pass through the frozen 4-bit weights but are stored only for A and B, so optimizer state scales with the adapter rank, not with model size.
(5) Paged Optimizers: optimizer states live in NVIDIA unified memory and are paged to host RAM during transient spikes, which is what keeps a 33B or 65B single-GPU run from OOM-ing on a long batch.

Block diagram of a QLoRA linear layer: input X feeds a frozen NF4 base weight with its double-quantized absmax constants, which is dequantized to bf16 for the matmul, while a parallel bf16 LoRA A and B path scaled by alpha over r is added to produce output Y, with dashed gradient arrows returning only into A and B

Figure 1: One QLoRA linear layer. The NF4 weight and its quantization constants are read-only, the bf16 copy exists only for the duration of the matmul, and the dashed path shows that gradients terminate at the low-rank adapters.

Mathematical Formulation:
Y = X\,\mathrm{dq}(W_4) + \frac{\alpha}{r}\,X A B
\mathrm{dq}(W_4)_{ij} = c_i\,z_{q_{ij}}
c_i = \mathrm{absmax}(W_i)
b = 4 + \frac{8}{64} + \frac{32}{64 \cdot 256}
b \approx 4.127\ \text{bits per parameter}

Where:

  • Y is the layer output and X the bf16 input activation; both stay in 16-bit throughout.
  • W_4 is the frozen base weight stored as NF4 indices, and \mathrm{dq} is the dequantization that reconstructs a bf16 tile just before the matmul.
  • i indexes the blocks of 64 weights, q_{ij} \in \{0,\ldots,15\} is the stored 4-bit code, and z_k are the fixed NF4 levels, obtained from normal quantiles and rescaled to [-1, 1] with an exact zero.
  • c_i is the per-block absmax constant; double quantization stores it in 8 bits with one fp32 scale per 256 constants.
  • A \in \mathbb{R}^{d \times r} and B \in \mathbb{R}^{r \times k} are the trainable bf16 adapters of rank r (the paper uses r = 64 on every linear layer), scaled by \alpha / r; B starts at zero so the layer initially reproduces the quantized base model.
  • b is the effective storage cost per base parameter: 4 bits of payload plus 0.125 bits of 8-bit constants plus 0.002 bits of second-level scales.
Horizontal stacked bar chart of training memory for a 7B model: full fine-tuning totals 112 GB with 14 GB weights, 14 GB gradients and 84 GB optimizer states; 16-bit LoRA totals 16.6 GB; QLoRA totals 6.2 GB with a 3.6 GB NF4 base

Figure 2: Illustrative state memory for a 7B model with rank-64 adapters on all linear layers. LoRA removes the optimizer and gradient bulk, and QLoRA then shrinks the remaining frozen weights from 14 GB to 3.6 GB; activation memory is excluded.

AspectQLoRA (NF4 base)16-bit LoRAFull Fine-Tuning
Base weight storageNF4, about 4.13 bits per parameter with double quantizationbf16, 16 bits per parameterbf16 weights plus an fp32 master copy
Trainable parameters (7B)About 160M in bf16 at rank 64 on all linear layersIdentical adapter countAll 7B parameters
State memory (7B)About 6 GBAbout 17 GBAbout 112 GB, needs sharding across GPUs
Step timeSlowest: dequantization runs in both forward and backwardFastest of the two adapter methodsHighest total compute and communication
Instruction-tuning qualityMatches 16-bit LoRA when adapters cover every linear layerReference point for adapter tuningPreferred with very large in-domain corpora or heavy domain shift
DeploymentAdapter cannot fold into NF4 losslessly; merge into the 16-bit base, then requantizeMerge into bf16 weights for zero added latencyOne merged checkpoint per task

Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *