Quantization: Running LLMs Cheaper and Faster

Fractional CTO · Founder of Injuria.ai
Large language models (LLMs) are defined by their scale. Models with tens or hundreds of billions of parameters can generate remarkably coherent text, write code, and reason about complex topics. This scale, however, comes at a steep price. The parameters, or weights, that store the model's learned knowledge are typically represented as 32-bit or 16-bit floating-point numbers. A 70 billion parameter model requires at least 140 gigabytes of GPU memory just to load its weights in a 16-bit format, placing it far outside the reach of consumer hardware and making large-scale deployment extremely expensive.
Quantization is the most effective and widely adopted technique for solving this problem. It is the process of reducing the numerical precision of a model's weights. By converting weights from, for example, 16-bit floating-point numbers to 8-bit or even 4-bit integers, quantization can shrink a model's size by a factor of 2 to 8 times. This reduction in memory footprint and memory bandwidth requirements makes inference significantly faster and cheaper. It enables massive models to run on smaller, more affordable GPUs, or even on CPUs and edge devices, fundamentally changing the economics and accessibility of AI.
How Quantization Works: The Core Mechanism
At its heart, quantization is a mapping exercise. It translates numbers from a data type that uses many bits, like 32-bit floating point (FP32[1]), to a data type that uses fewer bits, like 8-bit integer (INT8[2]). This process inevitably involves a loss of precision, so the goal of any quantization algorithm is to perform this mapping in a way that minimizes the impact on the model's final output accuracy.
The process for the most common type, asymmetric quantization, can be broken down into a few steps:
- Determine the Range: For a given set of weights (typically in a single layer of the neural network), find the minimum and maximum floating-point values. This defines the input range.
- Calculate the Scale Factor: The scale is a floating-point number that defines the ratio between the input range and the target integer range. For INT8, the target range is typically -128 to 127. The formula is
scale = (max_float - min_float) / (max_int - min_int). - Calculate the Zero-Point: The zero-point is an integer value that ensures the floating-point value of 0.0 maps correctly to a quantized integer. This is crucial for handling padding and other operations where zero has a special meaning. It effectively shifts the integer range to align with the floating-point range. The formula is
zero_point = round(quantized_min - float_min / scale). - Quantize: Each floating-point weight is converted to its integer equivalent using the formula:
quantized_value = round(original_value / scale) + zero_point.
When the model performs inference, it can either use hardware that supports direct computation with these integers or de-quantize them back to floating-point numbers on the fly using the inverse formula: dequantized_value = (quantized_value - zero_point) * scale. The de-quantized value will be an approximation of the original, with the difference being the quantization error.
A Concrete Example
Let's walk through an example using a small tensor of FP32 weights and quantizing them to INT8.
import numpy as np
# 1. A small sample of original FP32 weights
weights_fp32 = np.array([-1.2, -0.5, 0.0, 0.3, 0.8, 1.5], dtype=np.float32)
# 2. Define the target integer range (INT8: -128 to 127)
q_min, q_max = -128, 127
# 3. Find the range of the original FP32 weights
min_val, max_val = np.min(weights_fp32), np.max(weights_fp32)
# min_val = -1.2, max_val = 1.5
# 4. Calculate the scale factor and zero-point
scale = (max_val - min_val) / (q_max - q_min)
# scale = (1.5 - (-1.2)) / (127 - (-128)) = 2.7 / 255 ≈ 0.010588
zero_point_float = q_min - min_val / scale
# zero_point_float = -128 - (-1.2 / 0.010588) ≈ -128 + 113.3 = -14.7
zero_point = int(round(zero_point_float))
# zero_point = -15
# 5. Quantize the weights to INT8
quantized_weights = np.round(weights_fp32 / scale + zero_point).clip(q_min, q_max).astype(np.int8)
# Example calculation for weight 1.5:
# round(1.5 / 0.010588 - 15) = round(141.6 - 15) = round(126.6) = 127
# Example calculation for weight -1.2:
# round(-1.2 / 0.010588 - 15) = round(-113.3 - 15) = round(-128.3) = -128
# Resulting quantized tensor:
# [-128, -62, -15, 13, 61, 127]
# 6. De-quantize to see the precision loss
dequantized_weights = (quantized_weights.astype(np.float32) - zero_point) * scale
# Resulting de-quantized tensor (approximations of the original):
# [-1.196, -0.498, 0.000, 0.296, 0.805, 1.503]
As the example shows, the de-quantized values are very close but not identical to the originals. Sophisticated quantization algorithms focus on minimizing this error across billions of weights to preserve the model's overall performance.
History and Key Concepts
Quantization is not a new idea. Its principles originate in digital signal processing[3], where continuous analog signals are converted into discrete digital values. In machine learning, its use for compressing convolutional neural networks (CNNs) for mobile and embedded devices became popular in the mid-2010s, with seminal work like the "Deep Compression[4]" paper from 2015 demonstrating its effectiveness.
However, the extreme scale and sensitivity of LLMs presented new challenges. While CNNs could often be quantized to INT8 with minimal accuracy loss, early attempts to do the same with large transformer models resulted in significant performance degradation. This led to the development of several key concepts and techniques tailored for modern AI workloads.
Important Data Types
Understanding quantization requires familiarity with the data types involved:
- FP32 (Single Precision): The 32-bit floating-point standard. It offers a wide dynamic range and high precision, and was the default for training early neural networks.
- FP16 (Half Precision): An IEEE 754 standard[5] 16-bit float. It halves the memory usage of FP32 but has a much more limited dynamic range, making it susceptible to underflow errors (numbers becoming zero) during training.
- Bfloat16 (BF16): A 16-bit format developed by Google for deep learning[6]. It maintains the same dynamic range as FP32 by allocating more bits to the exponent, but has less precision. This tradeoff makes it excellent for training and inference, and it has become a de facto standard for modern LLMs.
- INT8 and INT4: 8-bit and 4-bit integers. These are the primary targets for quantization, offering 4x and 8x memory savings over FP32, respectively. Their limited capacity to represent information makes the quantization process critical.
Post-Training vs. Quantization-Aware Training
There are two primary approaches to applying quantization:
-
Post-Training Quantization (PTQ): This is the most common and straightforward method. A fully trained, high-precision model is taken and its weights are converted to a lower precision. This process is fast and does not require access to the original training data or pipeline. It usually requires a small "calibration" dataset (a few hundred examples) to analyze the activation distributions and determine the optimal quantization parameters (scale and zero-point). Most modern LLM quantization techniques are forms of PTQ.
-
Quantization-Aware Training (QAT): In this approach, the effects of quantization are simulated during the model training process. The forward pass of the training step calculates the quantization error, and the backpropagation step allows the model to learn weights that are more robust to this error. QAT typically yields higher accuracy than PTQ but is much more computationally expensive and complex, as it requires a full training or fine-tuning run. For this reason, it's less common for large-scale LLMs where PTQ methods have become sufficiently advanced.
The Modern Landscape of LLM Quantization
The unique properties of LLMs, particularly the presence of significant outlier values in their weight distributions, spurred a wave of research into better quantization methods. Today, several sophisticated techniques are widely used.
GPTQ
Published in 2022, GPTQ[7] (Generative Pre-trained Transformer Quantizer) was a significant breakthrough in post-training quantization for LLMs. Its core innovation is a layer-wise quantization approach. Instead of quantizing all weights at once, GPTQ processes the model one layer at a time. After quantizing a layer, it adjusts the weights of the remaining layers to compensate for the quantization error it just introduced. This one-shot error compensation makes it far more accurate than naive PTQ, enabling models to be quantized down to 3 or 4 bits with only minor increases in perplexity (a measure of prediction error).
GGUF and llama.cpp
For the open-source community, one of the most influential developments has been the llama.cpp[8] project. Initially created to run the Llama model on a MacBook CPU, it has evolved into a high-performance inference engine for a wide range of models. The project introduced the GGUF file format, a container designed specifically for quantized models. GGUF supports dozens of different quantization schemes, including various 2-bit to 8-bit methods. These "k-quants" use techniques like block-based quantization, where scale and min/max values are stored for small blocks of weights, improving accuracy over per-tensor methods.
QLoRA and NF4
The QLoRA paper[9] from 2023 introduced a method to finetune a quantized LLM, a task previously thought to be impractical. It combined several key innovations:
- 4-bit NormalFloat (NF4): A new 4-bit data type that is information-theoretically optimal for data drawn from a normal distribution, which is a good approximation for neural network weights.
- Double Quantization: A clever technique to further reduce memory overhead by quantizing the quantization parameters themselves. For example, the scale factor for each block of weights is itself quantized.
- Paged Optimizers: To manage memory spikes during the finetuning process, QLoRA uses NVIDIA's Unified Memory[10] to automatically page optimizer states between GPU and CPU RAM.
The combined result was revolutionary: QLoRA made it possible to finetune a 65-billion parameter model on a single consumer GPU with 24GB of VRAM, democratizing access to large-scale model customization.
AWQ
Activation-aware Weight Quantization (AWQ)[11] is another advanced PTQ method based on a simple but powerful observation: not all weights are equally important. By analyzing the activations flowing through the model, AWQ identifies a small fraction (around 1%) of weights that are most critical for the model's performance. It then selectively preserves these salient weights in higher precision while quantizing the rest of the weights more aggressively. This approach protects the model from the large quantization errors that outliers can cause, achieving state-of-the-art results for 4-bit quantization.
The Real Tradeoffs: A Decision Lens for Leaders
Quantization is not a free lunch. It involves a fundamental tradeoff between efficiency and fidelity. For technical leaders and engineers, the decision of whether, when, and how to use quantization requires a clear understanding of these tradeoffs.
Performance vs. Accuracy
This is the central dilemma. Lowering bit-depth reduces memory usage and increases inference speed, but it also increases quantization error, which can degrade model quality.
- Memory: Moving from FP16 to INT8 halves memory usage. Moving to INT4 quarters it. This is the primary driver for quantization, as it determines which GPU class is required to run a model.
- Speed: Smaller data types mean less data needs to be moved from VRAM to the GPU's processing cores. This reduces memory bandwidth bottlenecks, which is often the limiting factor in LLM inference. Modern GPUs and CPUs have specialized, highly optimized instructions for integer arithmetic (NVIDIA Tensor Cores[12], for example), making INT8 and INT4 computations significantly faster than floating-point operations.
- Accuracy: The impact on accuracy is highly task-dependent. For many tasks, a well-quantized 4-bit model (using AWQ or GPTQ) performs nearly identically to its FP16 counterpart. However, for tasks requiring deep reasoning or nuanced understanding, the precision loss can lead to a measurable drop in quality, the loss of emergent abilities, or an increase in hallucinations.
Cost and Implementation
- Inference Cost: This is where quantization provides the most significant savings. A model that can run on an NVIDIA A10G (24GB VRAM) instead of an A100 (80GB VRAM) has a dramatically lower hourly cost. Higher throughput from faster inference also means fewer GPUs are needed to serve the same number of users.
- Implementation Cost: Applying PTQ methods is computationally cheap. Quantizing a large model with GPTQ or AWQ might take a few hours on a single GPU. The engineering effort is also relatively low, as libraries like Hugging Face Transformers[13] have integrated these methods. QAT, on the other hand, has a very high implementation cost, equivalent to a full model finetune.
When to Use Quantization
- Production Inference at Scale: For nearly all deployments serving real-time user traffic, quantization is a default best practice. The cost savings are too large to ignore.
- Edge and On-Device Deployment: It's a necessity. Running models on phones, laptops, or in-car systems is often impossible without aggressive quantization to meet strict memory and power constraints.
- Development and Research: For individuals and smaller organizations, quantization (especially via QLoRA) makes it feasible to experiment with and finetune large models on accessible, consumer-grade hardware.
When to Be Cautious
- High-Stakes, Precision-Sensitive Tasks: If your application involves medical analysis, legal contract review, or complex scientific reasoning, you must be extremely cautious. Always start with the highest precision model (FP16/BF16) as a baseline. If you need to quantize for cost reasons, you must perform rigorous, task-specific evaluation to ensure the quantized model's outputs are still safe and accurate. Do not rely solely on general benchmarks like perplexity.
- Evaluating New Model Capabilities: When testing the limits of a new foundation model, use its native precision. Quantization can sometimes silently erase subtle, emergent abilities that are only present in the full-precision version.
Common Misconceptions
1. "Quantization is just rounding numbers."
This is a vast oversimplification. Naive rounding would lead to catastrophic performance loss. Modern quantization is a principled mapping process involving scale factors and zero-points, often guided by sophisticated, error-minimizing algorithms like GPTQ and AWQ that are specifically designed for the statistical properties of neural network weights.
2. "A 4-bit model is always worse than an 8-bit model."
Not necessarily. Model scale often matters more than bit-depth. A larger, more capable model (e.g., a 70B parameter model) quantized to 4-bits will almost always outperform a smaller model (e.g., a 13B parameter model) running at 8-bits or even 16-bits. The key is to start with the best possible full-precision model and then apply quantization, rather than using a smaller model at higher precision.
3. "You need the original training data to quantize a model."
This is false for the most common methods. Post-Training Quantization (PTQ) techniques only require the already-trained model and, in most cases, a small calibration dataset of a few hundred unlabeled examples to analyze weight and activation distributions. This makes it easy to quantize pre-trained models released by others. Only Quantization-Aware Training (QAT) requires access to the full training pipeline.
Current Status and The Future
Quantization is no longer a niche research topic; it is a standard, production-ready tool in the MLOps lifecycle. Major frameworks like PyTorch and TensorFlow[14] provide mature quantization APIs. The Hugging Face ecosystem has deeply integrated methods like GPTQ, AWQ, and QLoRA, making them accessible with a few lines of code. High-performance inference servers like vLLM[15] and Text Generation Inference (TGI) support these formats out of the box for maximum throughput.
The de facto standard for running quantized models on consumer hardware is GGUF, driven by the vibrant community around llama.cpp. For GPU-based cloud deployment, AWQ and GPTQ are the dominant formats.
The future of quantization is pushing toward even lower bit-depths. Active research is exploring 3-bit, 2-bit, and even 1.58-bit (ternary) representations. The primary challenge remains the same: how to shrink models further without sacrificing the complex reasoning and knowledge that makes them so powerful. As these techniques mature, they will continue to drive down the cost of AI, making powerful models more accessible and ubiquitous than ever.
Sources (15)
- Wikipedia - Single-precision floating-point format
- Wikipedia - Integer (computer science)
- Wikipedia - Quantization (signal processing)
- arXiv - Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding
- Wikipedia - Half-precision floating-point format
- Google Cloud - BFloat16
- arXiv - GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
- GitHub - ggerganov/llama.cpp
- arXiv - QLoRA: Efficient Finetuning of Quantized LLMs
- NVIDIA Developer Blog - Unified Memory in CUDA 6
- arXiv - AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration
- NVIDIA - Tensor Core GPUs
- Hugging Face - Quantization
- TensorFlow - Model optimization
- GitHub - vllm-project/vllm