# Quantization in production: from 16-bit to 4-bit precision

[Skip to content](#lm-inhoud)Network/[NL](/en/quantization-in-productie-van-16-bit-naar-4-bit-precisie)EN[Hubhub.llmnet.nlCompare models on task, language, cost and licence.](https://hub.llmnet.nl/en/)[Communitycommunity.llmnet.nlPrompt techniques, patterns and system prompts.](https://community.llmnet.nl/en/)[APIapi.llmnet.nlLLMs in production: rate limits, routing, structured output.](https://api.llmnet.nl/en/)[Consultancyconsultancy.llmnet.nlRolling out AI in an organisation, pilot to production.](https://consultancy.llmnet.nl/en/)[Newsnieuws.llmnet.nlAI developments, explained for the Netherlands.](https://nieuws.llmnet.nl/en/)[Benchmarkbenchmark.llmnet.nlMeasure AI quality yourself, on your own tasks.](https://benchmark.llmnet.nl/en/)[Careersvacatures.llmnet.nlAI roles, salaries and career paths in the Netherlands.](https://vacatures.llmnet.nl/en/)[Learnleren.llmnet.nlAI concepts in plain language, beginner to builder.](https://leren.llmnet.nl/en/)[Guidegids.llmnet.nlRun AI privately on your own Mac, PC, NAS or home server.](https://gids.llmnet.nl/en/)[Directorydirectory.llmnet.nlMapping the AI ecosystem: tools, models, companies.](https://directory.llmnet.nl/en/)[Radarradar.llmnet.nlSignals from X, research and communities for indie developers.](https://radar.llmnet.nl/en/)[Appsapps.llmnet.nlReviews of AI apps and open-source repos, with tips for builders.](https://apps.llmnet.nl/en/)[llmnet.nl — main site](https://llmnet.nl/en/)[](https://x.com/intent/post?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie&text=Quantization%20in%20production%3A%20from%2016-bit%20to%204-bit%20precision)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie)[](https://www.reddit.com/submit?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie&title=Quantization%20in%20production%3A%20from%2016-bit%20to%204-bit%20precision)[](#)[](https://x.com/intent/post?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie&text=Quantization%20in%20production%3A%20from%2016-bit%20to%204-bit%20precision)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie)[](https://www.reddit.com/submit?url=https%3A%2F%2Fnieuws.llmnet.nl%2Fen%2Fquantization-in-productie-van-16-bit-naar-4-bit-precisie&title=Quantization%20in%20production%3A%20from%2016-bit%20to%204-bit%20precision)[](#)

 
# Quantization in production: from 16-bit to 4-bit precision

 By Ivo Donker — compiled with AI assistance (Claude & Gemini)

 In the core canon article on the shift toward compact architectures, [the analysis of small language models and efficient inference](https://nieuws.llmnet.nl/en/kleine-taalmodellen), it was already made clear that more compact parameters structurally reduce AI operating costs. Where model distillation and pruning intervene in the architecture itself, quantization directly modifies the numerical representation of weights and activations. In modern production pipelines, running unquantized 16-bit floating-point formats (FP16 or BF16) for large-scale LLM workloads is rarely defensible economically or operationally. By reducing weights to 8-bit or 4-bit precision, density per GPU doubles or quadruples.

 Yet reducing numerical precision is not a free optimization. As we descend from 16-bit floating point to 8-bit integers and subsequently to 4-bit quantization methods, a fundamental tension arises between memory savings, compute throughput, mathematical rounding errors, and task-specific degradation. This article dissects the precise mechanics of modern post-training quantization (PTQ) techniques, their interaction with hardware architectures, the implications for the KV cache, and the methodologies required to measurably manage quality loss in production environments.

 
## The mathematical foundation: linear transformations and rounding noise

 Quantization transforms a continuous or high-precision set of numbers into a discrete, low-precision number space. In a standard neural network, weights are typically stored in 16-bit floating point (IEEE 754 FP16 or Brain Floating Point BF16). An FP16 value consists of 1 sign bit, 5 exponent bits, and 10 mantissa bits, covering a broad dynamic range. In uniform affine quantization to, for example, an 8-bit integer (INT8), we map this dynamic range onto a scale of 256 integers (-128 to 127 for signed integers, or 0 to 255 for unsigned integers).

 The standard mathematical formula for uniform quantization relies on two crucial parameters: a scale factor (scale, $S$) and a zero-point offset (zero-point, $Z$). The transformation from a real-valued weight $x$ to an integer value $q$ is defined as:

 q = clip(round(x / S) + Z, q_min, q_max)

 To approximate the original value during matrix multiplications (dequantization), we apply the inverse transformation:

 x_approx = S * (q - Z)

 When the zero-point $Z$ equals zero, this is referred to as symmetric quantization. This significantly simplifies hardware-level multiplications, as no additional offset term needs to be processed during tensor dot-product calculations. Asymmetric quantization, on the other hand, uses a dynamic zero-point ($Z \neq 0$), which is valuable when weight distributions are skewed around zero, as is often the case with activations following a ReLU or GeLU layer.

 The loss of representational capacity, also known as quantization noise or rounding noise, is determined by the distance between consecutive quantization steps ($\Delta = S$). The fewer bits available, the larger $\Delta$ becomes and the more information is lost in the fine-grained tails of the weight distribution.

 
## Weight distributions and the challenge of 'outlier features'

 In language models up to 7 billion parameters, the weight matrices typically exhibit a more or less predictable Gaussian bell-shaped distribution. However, as models grow larger (especially beyond the 6.7B and 13B thresholds), a striking emergent phenomenon occurs: the emergence of systematic numerical outliers (emergent outlier features). In specific transformation layers, a fraction of the hidden dimensions (often less than 0.1% of the channels) exhibits activation values up to 100 times larger than the average activation magnitude.

 When we apply a uniform matrix-wide scale factor $S$ to a layer with extreme outliers, that single outlier forces an enormously large step size $\Delta$. As a result, all the remaining 99.9% of normal weights are compressed into just a handful of discrete values around zero, leading to a catastrophic collapse of the model's language proficiency and contextual coherence.

 To neutralize this phenomenon without excessive memory overhead, modern quantization methods break down the tensors into finer-grained structures:

 
 
- Per-tensor quantization: One scale factor for the entire matrix. Highly efficient in terms of metadata, but extremely vulnerable to outliers.
 
- Per-channel / Per-row quantization: Each row or column in the weight matrix receives its own scale factor. This effectively captures variation between different attention and projection heads.
 
- Block-wise / Group-wise quantization: Weights are partitioned into small sub-blocks (typically block sizes of 32, 64, or 128 elements). Each sub-block has its own $S$ and $Z$ parameters. This is the de facto standard for robust 4-bit reconstruction.
 

 
## PTQ versus QAT: two different paths to compression

 There are two fundamentally different routes to reduce a model's precision: Post-Training Quantization (PTQ) and Quantization-Aware Training (QAT).

 Post-Training Quantization (PTQ) is applied to an already fully trained base or instruction model. Here, the weights are frozen and converted using a representative calibration set of text data (usually 128 to 512 context blocks). The calibration set serves to observe the dynamic ranges of activations across layers and determine the optimal scale factors using techniques such as Mean Squared Error (MSE) minimization or Hessian curvature calculations. PTQ requires relatively little compute and can be completed within minutes to a few hours on a single GPU.

 Quantization-Aware Training (QAT) integrates rounding errors directly into the training process or fine-tuning phase. Because the discrete rounding function $\text{round}(x)$ has a zero derivative and blocks gradient descent via backpropagation, QAT utilizes a Straight-Through Estimator (STE). During the forward pass, weights are virtually quantized to simulate noise, while during the backward pass, unrounded real gradients flow through to the FP32 master weights. At extremely low bitrates (such as 2-bit and 3-bit), QAT yields significantly better perplexity scores than PTQ, but comes with substantial training costs and data requirements.

 
## The 4-bit Revolution: AWQ, GPTQ, and bitsandbytes dissected

 In modern production clusters, 4-bit PTQ dominates the landscape. Three specific implementations have shaped the market in recent years:

 
 
 
 
 Method | 
 Optimization type | 
 Target | 
 Inference speed | 
 VRAM reconstruction | 
 

 
 
 
 GPTQ (Layer-wise) | 
 Second-order Taylor / Inverse Hessian | 
 Weights (W4A16) | 
 High (with custom GEMM kernels) | 
 No reconstruction overhead | 
 

 
 AWQ (Activation-aware) | 
 Salience preservation on activation data | 
 Weights (W4A16) | 
 Very high (optimized for throughput) | 
 No reconstruction overhead | 
 

 
 NF4 / QLoRA (bitsandbytes) | 
 Information-theoretic quantile format | 
 Weights (W4A16) | 
 Moderate (high dequantization overhead) | 
 FP32/BF16 adapter combination | 
 

 
 SmoothQuant / FP8 | 
 Scale migration from activation to weight | 
 Weight + Activation (W8A8 / FP8) | 
 Maximum (native tensor core support) | 
 Minimal compute overhead | 
 

 
 
 

 GPTQ builds upon the classic Optimal Brain Surgeon algorithm. It processes a weight matrix layer by layer and updates the remaining unquantized weights every time a row is rounded, leveraging the inverse Hessian of the activations. This actively compensates for the introduction of rounding errors in earlier columns.

 AWQ (Activation-aware Weight Quantization) recognizes that not all weights are created equal. By observing activation magnitude during calibration, AWQ identifies the top 1% most critical weights ('salient weights'). Rather than leaving these weights in 16-bit (which would cause memory fragmentation), AWQ computes a per-channel mathematical scaling factor that dampens activation size and proportionally scales up the weight. As a result, the most important signal carriers fall within the most representative portion of the 4-bit grid without disrupting the matrix structure.

 NF4 (NormalFloat 4), introduced with QLoRA, moves away from the uniform linear grid. Because normalized neural network weights follow a standard normal distribution with mean 0 and variance $\sigma$ almost exactly, NF4 distributes the 16 available 4-bit discrete state points such that each quantile contains exactly the same probability mass. This minimizes the theoretical information loss per parameter.

 
## Hardware mechanics and inference engines in practice

 A persistent misconception about quantization is that it automatically halves computation time. On modern hardware, reality is more complex. To understand where the gains come from, we need to look at the bottleneck of LLM generation: Memory Bandwidth Bound vs. Compute Bound.

 During the generation phase (autoregressively emitting token by token), the GPU must load the entire set of model parameters for every generated token from the slower High Bandwidth Memory (HBM/VRAM) into the fast on-chip Static RAM (SRAM) registers. Because the arithmetic operation per weight is minimal at batch size 1 (a single multiplication per value), the Tensor Core spends most of its time waiting for data transfer. We call this memory bandwidth bound.

 A 4-bit model (W4A16) reduces the required data transfer across the memory bus by a factor of four. The GPU loads 4-bit integers into its registers, dequantizes them on-the-fly to FP16/BF16 in a handful of simple arithmetic clock cycles, and then executes the standard dot-product computation. Because the memory bus was the absolute bottleneck, this technique yields a dramatic increase in tokens per second per stream.

 For those who want to dive deeper into the hardware components, [the in-depth report on AI chips and hardware developments](https://nieuws.llmnet.nl/en/chips-en-hardware-race) provides insight into how modern processors handle transistor density and memory bandwidths. At the software level, this requires a specialized server architecture; in [the review of vLLM versus Ollama for production environments](https://radar.llmnet.nl/en/review-vllm-versus-ollama-voor-productie-op-eigen-servers) the performance differences of such inference engines are dissected down to the kernel level.

 
## The overlooked bottleneck: KV-cache quantization

 When scaling production systems to tens of thousands of concurrent users or processing long documents (32k to 128k context), the primary expansion risk for GPU memory is not weight memory, but the Key-Value (KV) cache For every token in the context, the model must retain the attention vectors of all preceding layers in VRAM.

 The memory usage of the standard FP16 KV-cache can be calculated exactly using the formula:

 Geheugen_KV (bytes) = 2 * n_layers * n_heads * d_head * n_ctx * batch_size * 2_bytes

 For a standard 70B parameter model with 80 layers, Grouped-Query Attention (8 key-value heads of dimension 128), and a context of 16,384 tokens, the KV-cache of a single request consumes approximately 5.37 GB of VRAM. With a modest batch of 16 concurrent requests, the KV-cache alone swallows 85 GB of memory — more than the capacity of an entire 80GB enterprise GPU.

 This is where KV-cache quantization (FP8, INT8, or INT4) relief. By asymmetrically quantizing the key and value vectors per token to 8-bit or 4-bit, the memory footprint of active sessions can be reduced by 50% to 75% without noticeable degradation in attention quality. To further optimize the interplay between context size and memory management, it is worth studying [how context caching reduces memory and token costs](https://nieuws.llmnet.nl/en/context-caching-hoe-slimme-opslag-de-tokenkosten-halveert), as this directly combines with KV-cache compression.

 
## Accelerating Throughput: The Synergy with Speculative Decoding

 Quantization can also be deployed strategically within advanced inference pipelines. A prime example is Speculative Decoding. Here, a small, compressed 'draft model' (such as a 4-bit quantized compact model) rapidly generates a series of 4 to 8 candidate tokens. The large, unquantized base model (the 'target model') then validates all these tokens in parallel in a single forward pass across the batch.

 Because the draft model is quantized, it easily fits on the same GPU alongside the primary model and executes its steps with minimal latency. How this mechanism mathematically guarantees that the final token distribution remains completely identical to that of the target model is detailed extensively in the guide on [speculative decoding and accelerating LLM inference](https://nieuws.llmnet.nl/en/speculative-decoding-versnelling-van-llm-inferentie).

 
## VRAM Calculation: Theoretical Model vs. Production Reality

 A common design pitfall in capacity planning is confusing bare parameter size with the total memory requirements of a running inference system. The total VRAM footprint ($M_{\text{total}}$) consists of four components:

 M_totaal = M_parameters + M_kv_cache + M_activaties + M_runtime_overhead

 
 
 
 
 Parameters | 
 Format | 
 Weight Memory | 
 KV-Cache (8k ctx, b=4) | 
 CUDA / Runtime Buffer | 
 Minimum GPU Size | 
 

 
 
 
 8B | 
 FP16 (16-bit) | 
 16.0 GB | 
 2.1 GB | 
 ~2.5 GB | 
 1x 24 GB (e.g., RTX 4090 / A10G) | 
 

 
 8B | 
 W4A16 (4-bit) | 
 4.8 GB | 
 2.1 GB | 
 ~2.0 GB | 
 1x 12 GB / 1x 16 GB | 
 

 
 70B | 
 FP16 (16-bit) | 
 140.0 GB | 
 5.4 GB | 
 ~5.0 GB | 
 2x 80 GB (H100 / A100) | 
 

 
 70B | 
 W4A16 (4-bit) | 
 38.5 GB | 
 5.4 GB | 
 ~4.0 GB | 
 1x 48 GB (A40 / RTX 6000) or 2x 24 GB | 
 

 
 70B | 
 W4A4 / FP8 | 
 38.5 GB | 
 2.7 GB (FP8 KV) | 
 ~3.5 GB | 
 1x 48 GB (high batch concurrency) | 
 

 
 
 

 As the table demonstrates, 4-bit quantization transforms the hardware requirements of a 70B parameter model from a multi-node or multi-GPU H100 cluster to a single enterprise card with 48 GB VRAM. This often reduces infrastructure costs by 60% to 80% per million tokens processed.

 
## Degradation measurement and quality monitoring: how do you measure loss?

 The core operational question is: what do we sacrifice in intelligence? Relying blindly on aggregated academic benchmarks (such as MMLU or GSM8k) often masks substantial quality pitfalls in specific production tasks.

 The standard mathematical benchmark for quantization quality is Perplexity (PPL) on a standardized dataset such as WikiText-2 or C4. Perplexity measures how well the model predicts the next token in a representative sequence of text. A perplexity increase of less than 0.1 points generally indicates virtually lossless compression.

 PPL = exp( - (1 / N) * sum( log P(x_i | x_<i) ) )

 In practice, however, degradations occur selectively:

 
 
- Mathematical and logical reasoning: Complex chain-of-thought deduction is particularly susceptible to rounding errors in deeper Mixture-of-Experts layers.
 
- Structured output and syntax: JSON schemas, YAML generation, and strict code indentation degrade faster under 4-bit quantization than fluent prose, because the logits for specific syntax tokens (curly braces, quotes) exhibit minute probability differences compared to regular text.
 
- Language-specific degradation (Dutch): Because Dutch makes up less than 2% of the training data in most open-weights models, the relevant sub-parameters are more sparsely distributed across the weight space. Under aggressive quantization, these less abundant channels are hit relatively harder by noise than the dominant English vectors.
 

 Continuous mapping of these quality shifts requires active monitoring. Read in [the article on measuring drift in production environments](https://benchmark.llmnet.nl/en/drift-meten-in-productie-modelprestaties-over-tijd-volgen) which metrics and automated evaluation harnesses can be systematically deployed to detect degradation early.

 
## Implementation: a robust AWQ conversion and loading pattern

 Below is a concrete Python pattern illustrating how a model is quantized using the AutoAWQ library and subsequently loaded with optimized W4A16 GEMM kernels for high-throughput inference.

 from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

model_pad = "meta-llama/Llama-3.1-8B-Instruct"
quant_pad = "./Llama-3.1-8B-Instruct-AWQ-4bit"

# 1. Laad het ongekwantiseerde basismodel en tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_pad, use_fast=True)
model = AutoAWQForCausalLM.from_pretrained(
 model_pad, 
 low_cpu_mem_usage=True,
 use_cache=False
)

# 2. Kwantisatieconfiguratie: 4-bit, groepgrootte 128, GEMM-optimalisatie
quant_config = {
 "zero_point": True,
 "q_group_size": 128,
 "w_bit": 4,
 "version": "GEMM"
}

# 3. Uitvoeren van de kalibratie en quantisatie
# Hier wordt een representatieve tekstdataset benut om salient weights te lokaliseren
model.quantize(tokenizer, quant_config=quant_config)

# 4. Opslaan van de gewichten en configuratie voor productie
model.save_quantized(quant_pad)
tokenizer.save_pretrained(quant_pad)

print("Quantisatie voltooid. Model gereed voor vLLM of TGI implementatie.")

 This model can then be served directly via the command-line interface within a production engine like vLLM, using native 4-bit kernel acceleration:

 python3 -m vllm.entrypoints.openai.api_server \
 --model ./Llama-3.1-8B-Instruct-AWQ-4bit \
 --quantization awq \
 --dtype float16 \
 --gpu-memory-utilization 0.90 \
 --max-model-len 8192 \
 --port 8000

 
## Decision framework for production teams

 Selecting the right quantization level involves balancing budget, latency requirements, and quality margins. The rules of thumb below provide guidance when configuring your inference stack:

 
 
- Choose FP16 / BF16 (unquantized) exclusively for embeddings training, base fine-tuning runs, or mission-critical legal and medical evaluations where any minor divergence in determinism is unacceptable.
 
- Choose FP8 / W8A8 when the hardware (e.g., Nvidia Ada Lovelace or Hopper architectures) supports native FP8 Tensor Cores. This doubles throughput with virtually 0.0% measurable degradation.
 
- Choose AWQ / GPTQ (W4A16) as the default choice for large-scale chat applications, extraction, summarization, and general interactive assistants. It balances maximum memory density with proven stability.
 
- Quantize the KV cache to FP8/INT8 as soon as the average context length per session exceeds 8,000 tokens or when high concurrency is required on limited hardware.
