NormalFloat (NF4) and Double Quantization: The Information-Theoretic Foundations of QLoRA

Fine-tuning large language models under full 16-bit precision is governed by strict memory scaling laws. For a standard 65-billion parameter transformer model, storing weights in 16-bit BrainFloat (BF16) or Float16 (FP16) requires 130 GB of GPU memory. During training with standard first-order adaptive optimizers such as AdamW, each parameter requires an additional 2 bytes for gradients and 8 bytes for FP32 optimizer states (4 bytes for first-moment momentum and 4 bytes for second-moment varianc

10 min
NormalFloat (NF4) and Double Quantization: The Information-Theoretic Foundations of QLoRA

Fine-tuning large language models under full 16-bit precision is governed by strict memory scaling laws. For a standard 65-billion parameter transformer model, storing weights in 16-bit BrainFloat (BF16) or Float16 (FP16) requires 130 GB of GPU memory. During training with standard first-order adaptive optimizers such as AdamW, each parameter requires an additional 2 bytes for gradients and 8 bytes for FP32 optimizer states (4 bytes for first-moment momentum and 4 bytes for second-moment variance). When combined with activation memory and gradient checkpointing buffers, full-parameter fine-tuning of a 65B model exceeds 780 GB of high-bandwidth memory (VRAM), necessitating multi-node GPU clusters.

Parameter-Efficient Fine-Tuning (PEFT) methods, particularly Low-Rank Adaptation (Hu et al., 2021), drastically reduce optimizer and gradient footprints by freezing the base model weights and training small low-rank adapter matrices. However, standard LoRA still maintains the base model in 16-bit precision, keeping the baseline weight memory fixed at 130 GB for a 65B model and preventing single-GPU fine-tuning on standard 24 GB or 48 GB hardware.

QLoRA (Dettmers et al., 2023) introduced a framework that compresses base model weights to 4-bit precision while preserving full 16-bit task performance during backpropagation. This capability relies on three core mathematical and architectural mechanisms: 4-bit NormalFloat (NF4), Double Quantization (DQ), and Paged Optimizers.

The Information-Theoretic Foundations of NormalFloat (NF4)

Standard post-training quantization techniques typically discretize continuous parameters into uniform integer grids (such as INT4) or standard IEEE floating-point representations (such as FP4 with explicit exponent and mantissa bits). While functional for 8-bit representations, uniform and standard floating-point grids exhibit severe degradation at 4-bit precision.

Weight Distribution and the Quantile Principle

Pretrained neural network parameters do not follow a uniform distribution across their dynamic range. Statistical testing across Transformer architectures confirms that pretrained weight tensors follow zero-centered normal distributions with layer-dependent standard deviations:

WN(0,σ2)\mathbf{W} \sim \mathcal{N}(0, \sigma^2)

Shapiro-Wilk normality tests on foundational models demonstrate that the overwhelming majority of hidden unit weight distributions fit Gaussian profiles.

In information theory, quantizing a continuous random variable XX into 2k2^k discrete bins with minimal information loss requires maximizing the entropy of the quantized representation. Shannon entropy is maximized when each discrete bin has an identical probability mass under the data distribution:

P(X[bi,bi+1])=12ki{0,,2k1}P(X \in [b_i, b_{i+1}]) = \frac{1}{2^k} \quad \forall i \in \{0, \dots, 2^k - 1\}

When applied to arbitrary data distributions, this principle is known as Quantile Quantization. While exact empirical quantile estimation requires computing empirical cumulative distribution functions across every weight block (an operation with high computational complexity and vulnerability to outlier distortions), the fixed Gaussian property of pretrained neural weights allows computing an analytical quantile grid offline.

Failures of Uniform INT4 and Floating-Point FP4

The limitations of alternative 4-bit representations stem directly from bin allocation:

  • Uniform INT4 Quantization: Divides the bounding interval [c,c][-c, c] into equally spaced steps. Because the tails of a Gaussian distribution contain sparse data, uniform grids allocate excess discrete quantization levels to low-probability extremes while providing insufficient resolution in the dense region near zero, where most parameters reside.
  • Floating-Point FP4 (E2M1 and E3M0): Allocates bits between sign, exponent, and mantissa. While standard floating-point formats provide non-linear spacing that concentrates points near zero, their discrete levels do not match the exact theoretical quantiles of a normal distribution. In empirical evaluations across the Pile benchmark, standard FP4 (E2M1) exhibits higher perplexity than optimal quantile-derived formats.

Analytical Derivation of the NF4 Quantile Grid

To construct the kk-bit NormalFloat data type for a standard normal distribution N(0,1)\mathcal{N}(0, 1) normalized to the arbitrary range [1,1][-1, 1], the theoretical quantiles qiq_i are computed using the inverse cumulative distribution function (quantile function) QX(p)=Φ1(p)Q_X(p) = \Phi^{-1}(p):

qi=12(QX(i2k+1)+QX(i+12k+1))q_i = \frac{1}{2} \left( Q_X\left(\frac{i}{2^k + 1}\right) + Q_X\left(\frac{i+1}{2^k + 1}\right) \right)

For symmetric quantization, this formulation encounters a critical boundary condition: standard symmetric quantile division does not contain an exact representation for the value zero. In deep learning architectures, an exact discrete zero point is essential for representing zero-padded sequences, unactivated ReLU/SwiGLU units, and sparse parameters without numerical drift.

To resolve this, QLoRA constructs an asymmetric data type by estimating quantiles across two separate intervals:

  1. 2k12^{k-1} quantiles for the negative interval [1,0][-1, 0]
  2. 2k1+12^{k-1} + 1 quantiles for the positive interval [0,1][0, 1]

The two sets are unified, and the redundant zero entry is merged, yielding exactly 2k=162^k = 16 discrete levels for k=4k=4. The resulting 16 normalized values of the NF4 data type are:

  • Bin 0: -1.00000000
  • Bin 1: -0.69619280
  • Bin 2: -0.52507305
  • Bin 3: -0.39491749
  • Bin 4: -0.28444138
  • Bin 5: -0.18477343
  • Bin 6: -0.09105004
  • Bin 7: 0.00000000
  • Bin 8: 0.07958030
  • Bin 9: 0.16093020
  • Bin 10: 0.24611230
  • Bin 11: 0.33791524
  • Bin 12: 0.44070983
  • Bin 13: 0.56261700
  • Bin 14: 0.72295684
  • Bin 15: 1.00000000

Every weight tensor block is quantized by computing its absolute maximum value cFP32=absmax(W)c^{\text{FP32}} = \text{absmax}(\mathbf{W}), normalizing the tensor elements into [1,1][-1, 1], and mapping each normalized float to the nearest discrete index in the NF4 table.

Double Quantization (DQ): Compressing the Scale Factors

To maintain high precision during 4-bit quantization and prevent localized weight outliers from degrading entire parameter matrices, models are quantized in small discrete blocks rather than per-tensor or per-channel.

Double Quantization Architecture

The Block Size Overhead Dilemma

A block size of B1=64B_1 = 64 parameters provides strong numerical stability. However, each block requires storing an independent 32-bit floating-point scaling constant c1FP32c_1^{\text{FP32}}. Storing a 32-bit constant for every 64 weights adds a substantial memory footprint:

Quantization Constant Overhead=32 bits64 parameters=0.5 bits/parameter\text{Quantization Constant Overhead} = \frac{32 \text{ bits}}{64 \text{ parameters}} = 0.5 \text{ bits/parameter}

This scaling constant overhead increases the effective bit-width of a 4-bit quantized model from 4.0 bits to 4.5 bits per parameter, adding gigabytes of memory consumption across large model architectures.

Two-Level Hierarchical Quantization

Double Quantization treats the first-level scaling constants c1FP32c_1^{\text{FP32}} as input tensors for a secondary quantization step:

  1. First Quantization Level: Base weights W\mathbf{W} are partitioned into blocks of size B1=64B_1 = 64. For each block, an FP32 absolute maximum scale c1FP32c_1^{\text{FP32}} is computed.
  2. Mean-Centering: Because absolute maximum values c1FP32c_1^{\text{FP32}} are strictly non-negative (c10c_1 \ge 0), their empirical distribution has a positive non-zero mean. The mean μc1\mu_{c_1} is subtracted prior to secondary quantization to center the scale distribution around zero:

c~1=c1FP32μc1\tilde{c}_1 = c_1^{\text{FP32}} - \mu_{c_1}

  1. Second Quantization Level: The centered scales c~1\tilde{c}_1 are grouped into larger secondary blocks of size B2=256B_2 = 256 and quantized into 8-bit Float (FP8) representations (c1FP8c_1^{\text{FP8}}), using a second-level 32-bit scaling factor c2FP32c_2^{\text{FP32}}:

c1FP8=quantizeFP8(c~1absmax(c~1)),c2FP32=absmax(c~1)c_1^{\text{FP8}} = \text{quantize}_{\text{FP8}}\left( \frac{\tilde{c}_1}{\text{absmax}(\tilde{c}_1)} \right), \quad c_2^{\text{FP32}} = \text{absmax}(\tilde{c}_1)

Exact Memory Footprint Reduction

Under Double Quantization, storing the quantized scaling factors requires:

  • 8 bits for each first-level scale c1FP8c_1^{\text{FP8}} (shared across B1=64B_1 = 64 parameters)
  • 32 bits for each second-level scale c2FP32c_2^{\text{FP32}} (shared across B1×B2=64×256=16,384B_1 \times B_2 = 64 \times 256 = 16,384 parameters)
  • 32 bits for the global mean offset μc1\mu_{c_1} (amortized across the layer)

The resulting memory overhead per parameter is calculated as:

OverheadDQ=8 bits64+32 bits64×256=0.125+0.001953=0.127 bits/parameter\text{Overhead}_{\text{DQ}} = \frac{8 \text{ bits}}{64} + \frac{32 \text{ bits}}{64 \times 256} = 0.125 + 0.001953 = 0.127 \text{ bits/parameter}

Double Quantization slashes the scaling overhead from 0.5000.500 bits/parameter to 0.1270.127 bits/parameter, achieving a net reduction of 0.3730.373 bits per parameter. For a 65-billion parameter model, this reduction frees approximately 3.03 GB of GPU memory without altering the numerical precision of the underlying dequantized weights.

Dual Data Types and Dequantization GEMM Mechanics

QLoRA operates through a strict separation between its storage data type and its computation data type.

+-------------------------------------------------------------------+
|                        VRAM Storage (NF4)                         |
|  [4-bit Packed Weights] + [8-bit Quantized Scales] + [FP32 Scale] |
+-------------------------------------------------------------------+
                                  |
                   (On-the-fly register dequantization)
                                  v
+-------------------------------------------------------------------+
|                       SRAM / Registers (BF16)                     |
|                   Dequantized Base Weights W_BF16                 |
+-------------------------------------------------------------------+
                                  |
              +-------------------+-------------------+
              |                                       |
              v                                       v
    [Base Forward GEMM]                     [LoRA Forward GEMM]
    Y_base = X_BF16 * W_BF16                Y_lora = s * X * L1 * L2
              |                                       |
              +-------------------+-------------------+
                                  |
                                  v
+-------------------------------------------------------------------+
|                    Combined Layer Output (BF16)                   |
|                      Y = Y_base + Y_lora                          |
+-------------------------------------------------------------------+

Forward Pass Execution

Base model weights remain stored in VRAM as 4-bit NF4 integers alongside their hierarchical FP8 and FP32 quantization constants. During a forward linear projection Y=XW+sXL1L2\mathbf{Y} = \mathbf{X}\mathbf{W} + s\mathbf{X}\mathbf{L}_1\mathbf{L}_2:

  1. Input activation tensors XBF16Rb×h\mathbf{X}^{\text{BF16}} \in \mathbb{R}^{b \times h} are loaded in 16-bit BFloat16 precision.
  2. The custom CUDA dequantization kernel loads 4-bit packed NF4 weights into GPU shared memory and registers.
  3. The weights are dequantized on the fly into temporary 16-bit BFloat16 matrices using the nested dequantization function:

WBF16=doubleDequant(c2FP32,c1FP8,WNF4)=dequant(dequant(c2FP32,c1FP8),WNF4)\mathbf{W}^{\text{BF16}} = \text{doubleDequant}(c_2^{\text{FP32}}, c_1^{\text{FP8}}, \mathbf{W}^{\text{NF4}}) = \text{dequant}\left( \text{dequant}(c_2^{\text{FP32}}, c_1^{\text{FP8}}), \mathbf{W}^{\text{NF4}} \right)

  1. Tensor Core GEMM operations execute in full BF16 precision:

YBF16=XBF16WBF16+sXBF16L1BF16L2BF16\mathbf{Y}^{\text{BF16}} = \mathbf{X}^{\text{BF16}} \mathbf{W}^{\text{BF16}} + s \cdot \mathbf{X}^{\text{BF16}} \mathbf{L}_1^{\text{BF16}} \mathbf{L}_2^{\text{BF16}}

Where L1Rh×r\mathbf{L}_1 \in \mathbb{R}^{h \times r} and L2Rr×o\mathbf{L}_2 \in \mathbb{R}^{r \times o} represent the low-rank adapter matrices with rank rhr \ll h, and ss is the LoRA scaling hyperparameter αr\frac{\alpha}{r}.

Gradient Flow and Backward Pass Routing

During the backward pass, gradients are computed with respect to the loss function EE:

  • Gradients with respect to activations EX\frac{\partial E}{\partial \mathbf{X}} are computed by multiplying incoming upstream gradients with the dequantized weights WBF16\mathbf{W}^{\text{BF16}}, ensuring unhindered backpropagation through deep network layers.
  • Weight gradients for the 4-bit base model EW\frac{\partial E}{\partial \mathbf{W}} are never computed or stored, saving massive gradient memory buffers.
  • Adapter gradients EL1\frac{\partial E}{\partial \mathbf{L}_1} and EL2\frac{\partial E}{\partial \mathbf{L}_2} are computed in 16-bit precision and passed to the optimizer.

Paged Optimizers and CUDA Unified Memory

Even when model weights and optimizer states are compressed, LLM fine-tuning remains susceptible to transient out-of-memory (OOM) failures. These spikes occur during gradient checkpointing when processing long context windows or mini-batches with extreme token lengths.

QLoRA addresses this through Paged Optimizers, which leverage CUDA Unified Memory primitives:

  • Virtual Memory Allocation: Optimizer state tensors for the LoRA adapter parameters are allocated within pageable unified memory address spaces (cudaMallocManaged).
  • Demand Paging and Page Eviction: When GPU physical VRAM reaches capacity during activation recomputation peaks, the NVIDIA driver automatically evicts dormant optimizer state pages over PCIe to host CPU system memory.
  • Pre-Fetching on Update: Once the backward pass completes and the parameter update phase begins, evicted optimizer pages are paged back into GPU memory to execute the gradient update step.

Because optimizer state access occurs sequentially during parameter updates rather than continuously during GEMM execution, paging delays introduce near-zero training throughput overhead while preventing fatal OOM exceptions.

All-Linear Adapter Placement

In early parameter-efficient fine-tuning literature, LoRA adapters were predominantly attached only to multi-head attention query and value projection matrices (WqW_q and WvW_v).

Empirical research in the QLoRA study demonstrated that when base model weights are quantized to 4-bit, restricting adapter placement to WqW_q and WvW_v causes significant performance degradation compared to 16-bit full fine-tuning baselines.

Transformer Block Linear Layer Coverage in QLoRA:
├── Multi-Head Attention Sub-Layer
│   ├── Query Projection (W_q)       --> 4-bit NF4 Base + 16-bit LoRA
│   ├── Key Projection (W_k)         --> 4-bit NF4 Base + 16-bit LoRA
│   ├── Value Projection (W_v)       --> 4-bit NF4 Base + 16-bit LoRA
│   └── Output Projection (W_o)      --> 4-bit NF4 Base + 16-bit LoRA
└── SwiGLU Feed-Forward Sub-Layer
    ├── Gate Projection (W_gate)     --> 4-bit NF4 Base + 16-bit LoRA
    ├── Up Projection (W_up)         --> 4-bit NF4 Base + 16-bit LoRA
    └── Down Projection (W_down)     --> 4-bit NF4 Base + 16-bit LoRA

Because 4-bit quantization reduces the precision of the frozen representations across all layers, the model requires additional degrees of freedom across its feed-forward networks (FFN) and key/output projections to recover full representational capacity.

Applying LoRA across all linear layers (Wq,Wk,Wv,Wo,Wgate,Wup,WdownW_q, W_k, W_v, W_o, W_{\text{gate}}, W_{\text{up}}, W_{\text{down}}) fully closes the gap to 16-bit baselines. Because adapter parameters scale with rank rr (2×d×r2 \times d \times r per matrix) rather than full dimension (d2d^2), expanding adapter coverage across all seven linear projections increases total trainable parameter counts by only a fraction of a percent (typically from 0.1% to 0.4% of base parameters), adding negligible VRAM overhead while restoring full task performance.

Empirical Comparisons and Trade-Offs

Empirical evaluations across language modeling benchmarks demonstrate the precision benefits of information-theoretic quantization.

Perplexity and Zero-Shot Benchmarks

On the Pile Common Crawl benchmark evaluated across OPT, BLOOM, Pythia, and LLaMA architectures (ranging from 125M to 65B parameters), NF4 consistently outperforms uniform and floating-point alternatives:

  • 4-bit Integer (INT4): Mean Perplexity of 34.34
  • 4-bit Floating-Point FP4 (E2M1): Mean Perplexity of 31.07
  • 4-bit Floating-Point FP4 (E3M0): Mean Perplexity of 29.48
  • 4-bit NormalFloat (NF4 + DQ): Mean Perplexity of 27.41

On downstream evaluation suites including MMLU, Winogrande, ARC-Challenge, and HellaSwag, QLoRA models finetuned on instruction datasets (such as Guanaco 33B and 65B) match or exceed the performance of models fine-tuned in full 16-bit precision.

Operational Trade-Offs

Deploying QLoRA introduces specific engineering trade-offs:

  • Training vs. Inference Latency: QLoRA optimizes memory footprint for fine-tuning. Because weights must be dynamically dequantized to BF16 in registers during each forward pass, training throughput is slightly slower (approximately 20% to 30% compute overhead) compared to unquantized 16-bit LoRA running on clusters with unbounded VRAM.
  • Adapter Merging for Serving: After fine-tuning completes, adapter weights ΔW=sL1L2\Delta \mathbf{W} = s\mathbf{L}_1\mathbf{L}_2 can be explicitly dequantized and merged with the base model weights into FP16/BF16 checkpoints for low-latency production serving, or quantized into inference-optimized formats like AWQ, GPTQ, or Marlin kernels.
  • Hardware Compatibility: NF4 kernels require CUDA compute capability 7.0 or higher (Volta, Turing, Ampere, Ada Lovelace, and Hopper architectures). BF16 computation requires Ampere or newer GPUs (RTX 30xx/40xx, A100, H100); on older Turing hardware (T4, RTX 2080), computation falls back to FP16.

By formulating weight quantization as an information-theoretic optimization problem and eliminating scale constant overhead, NormalFloat4 and Double Quantization established that high-fidelity language model training does not require continuous 16-bit precision across base parameters.

Sources

Written by

More to read

  • Serverless GPU Inference in Production: Cold Starts, GPU Memory Snapshotting, and Weight Paging Architectures

    Serverless GPU Inference in Production: Cold Starts, GPU Memory Snapshotting, and Weight Paging Architectures Deploying large language models on dedicated cloud GPUs creates an uncomfortable financial trade-off: keeping enterprise accelerators such as NVIDIA H100s or A100s warm 24/7 costs thousands of dollars per instance each month, yet scaling instances to zero introduces severe latency penalties. When traffic arrives at a dormant node, a standard inference server cold start can take anywhere

    1 min
  • Transformer Feed-Forward Networks as Key-Value Memories: How First-Layer Keys and Second-Layer Values Store Knowledge

    Transformer Feed-Forward Networks as Key-Value Memories: How First-Layer Keys and Second-Layer Values Store Knowledge In modern autoregressive Transformers, the division of labor between attention heads and multi-layer perceptron (MLP) blocks is often summarized through a clean functional split: attention routes information across sequence positions, while feed-forward networks (FFNs) process information per position. Yet for years, the exact mechanism by which FFNs process that information rem

    1 min
  • Anthropic Bankers Pitch 00B+ Capital Raise at T Valuation Ahead of Historic IPO

    Investment banks underwriting Anthropic's planned initial public offering have initiated preliminary discussions with institutional investors and sovereign wealth funds, outlining a potential capital raise exceeding $100 billion at a valuation of up to $2 trillion, according to reporting from The New York Times. If executed at those terms, the flotation would represent the largest public market debut in history, surpassing both Saudi Aramco's $29.4 billion raise in 2019 and SpaceX's $75 billion

    1 min