Квантизация LLM¶
~9 минут чтения
Предварительно: базовые понятия о нейросетях, инференсе LLM
Зачем это нужно¶
Llama 3.1 70B в FP16 занимает 140 GB -- не влезает даже на 2x A100 (80 GB). Квантизация до INT4 сжимает до 35 GB -- запускается на одном GPU. Качество при этом падает на 1-3% по бенчмаркам.
Аналогия: представьте фотографию 50 мегапикселей. Для Instagram достаточно 2 мегапикселей -- визуально разницу не увидите, но файл в 25 раз меньше. Квантизация делает то же самое с весами: снижает "разрешение" чисел (FP16 -> INT4), сохраняя смысл.
Ключевой вопрос: какие веса можно округлить безболезненно, а какие -- нет. AWQ и GPTQ отвечают на него по-разному.
Обзор¶
Квантизация -- снижение точности весов модели для уменьшения памяти и ускорения инференса.
| Precision | Bytes/param | 7B model | 70B model |
|---|---|---|---|
| FP32 | 4 | 28 GB | 280 GB |
| FP16/BF16 | 2 | 14 GB | 140 GB |
| INT8 | 1 | 7 GB | 70 GB |
| INT4 | 0.5 | 3.5 GB | 35 GB |
Comparison Table (2026)¶
| Method | Primary Hardware | Quantization | Memory Reduction | Throughput |
|---|---|---|---|---|
| GGUF | CPU, Apple M-series | 4-bit | 40-50% | 35-45 tok/s |
| GPTQ | GPU (NVIDIA/AMD) | 8/4/3/2-bit | 40-50% | 50-60 tok/s |
| AWQ | GPU, Edge | 4-bit, FP8 | 40-50% | 45-55 tok/s |
| Marlin | GPU (kernel) | - | - | 2-10× faster |
| FP8 | H100/MI300X | 8-bit | 50% | Near-FP16 |
1. Baseline Quantization¶
Symmetric Quantization¶
Symmetric pitfall
Если веса не центрированы вокруг нуля — тратится битовый диапазон.
Asymmetric Quantization¶
Advantage: Использует полный битовый диапазон.
Limitation: Оба метода treat все веса одинаково, но некоторые важнее других.
2. AWQ (Activation-Aware Weight Quantization)¶
Paper: Lin et al., MLSys 2024 — arXiv:2306.00978
Core Insight¶
Если \(X\) (activation) большой — ошибка в \(W\) усиливается.
Key Insight
Защитить "salient" веса через масштабирование — не все веса одинаково важны.
Finding Salient Weights¶
Каналы с высоким \(s_x\) — важные, ошибки в их весах больше влияют на output.
Per-Channel Scaling¶
Где \(s = s_x^\alpha\) — per-channel scaling factor.
Alpha (α) parameter: - α = 0: Без scaling = baseline quantization - α = 1: Maximum protection - 0 < α < 1: Balance (оптимален ~0.5)
Optimization Problem¶
AWQ Process¶
- Calibration: Run 128-512 samples → collect activation stats
- Search: Find optimal α per layer
- Scale: Multiply weights by \(s = s_x^\alpha\)
- Quantize: Asymmetric group-wise quantization
- Store: Quantized weights + scaling factors
3. GPTQ (General Post-Training Quantization)¶
Paper: Frantar et al., arXiv:2210.17323
Core Insight¶
Quantize weights one at a time, adjust remaining weights to compensate error.
Uses Hessian matrix for second-order information.
Hessian Matrix¶
For squared error loss: $$ H = 2 \times X \times X^T $$
- Diagonal H[i][i]: Sensitivity of output to weight column i
- Off-diagonal H[i][j]: How weight columns i and j interact
Error Compensation¶
After quantizing weight at column \(q\) with error \(\delta_q\):
Column-wise Quantization¶
Key: Quantize columns left-to-right, adjust only unquantized columns.
Quantization grid (scale, zero-point): Calculated row-wise or group-wise Actual quantization: Column-by-column with error compensation
Lazy Batching¶
- Quantize batch of B columns (typically 128)
- Accumulate update terms
- Apply all updates at once
Reduces memory operations by factor of B.
GPTQ Process¶
- Calibration: Run 128-1024 samples → compute Hessian
- Cholesky: Decompose H for numerical stability
- Grid calculation: Per-row or per-group scale/zero-point
- Column-wise quantization: Process in batches with error compensation
- Store: Quantized weights + scales + zero-points
4. GGUF (GPT-Generated Unified Format)¶
Developer: llama.cpp team (Georgi Gerganov)
Purpose¶
CPU + Apple M-series optimized format with GPU offload support.
File Format¶
GGUF File Structure:
├── Header (magic, version, tensor count)
├── Metadata (key-value pairs)
├── Tensor Info (names, types, dimensions)
└── Tensor Data (quantized weights)
Quantization Types¶
| Type | Bits/weight | Quality | Speed |
|---|---|---|---|
| Q4_0 | 4.0 | Low | Fast |
| Q4_K_M | ~4.5 | Good | Fast |
| Q5_K_M | ~5.5 | Better | Medium |
| Q6_K | 6.0 | High | Slower |
| Q8_0 | 8.0 | Best | Slowest |
When to Use GGUF¶
- CPU inference
- Apple M-series (Metal support)
- Mobile / Edge devices
- Limited GPU memory
- Cross-platform compatibility
Usage Example¶
# Convert to GGUF
python convert-hf-to-gguf.py /path/to/model --outfile model-f16.gguf --outtype f16
# Quantize
./llama-quantize model-f16.gguf model-q4_k_m.gguf Q4_K_M
# Run
./llama-cli -m model-q4_k_m.gguf -p "Hello" -n 128
5. Marlin Kernel¶
Paper: Frantar et al., PPoPP 2025 — arXiv:2408.11743
Not a quantization method — optimized CUDA kernel for running quantized models.
Speedup¶
| Method | Standard | With Marlin | Speedup |
|---|---|---|---|
| GPTQ | 276 tok/s | 712 tok/s | 2.6× |
| AWQ | 68 tok/s | 741 tok/s | 10.9× |
Key Optimizations¶
- Async-Copy (Bypass L1): DRAM → L2 → SMEM directly
- L2 Cache Optimization: 80-95% hit rate vs 30-50%
- Double Buffering: Load tile B while computing tile A
- Fused Dequantization: Dequantize + compute in same kernel
- Warp-Level Parallelism: Coalesced memory access
6. FP8 Quantization (2025-2026)¶
Format¶
E4M3: 1 sign + 4 exponent + 3 mantissa (for activations) E5M2: 1 sign + 5 exponent + 2 mantissa (for gradients)
Hardware Support¶
- NVIDIA H100/H200 (native FP8 tensor cores)
- AMD Instinct MI300X
- Intel Gaudi2
Training with FP8¶
Papers (Jan 2026): - "FP8-RL: Practical Low-Precision Stack for LLM RL" — arXiv:2601.18150 - "Jet-RL: On-Policy FP8 Reinforcement Learning" — arXiv:2601.14243 - "MOSS: Efficient FP8 LLM Training" — OpenReview Dec 2025
Benefits¶
- 2× memory reduction vs FP16
- Near-FP16 quality
- Faster training on H100
Challenges¶
- Train-inference mismatch
- Numerical stability
- Requires careful scaling
7. HeRo-Q (Jan 2026)¶
Paper: arXiv:2601.21626
Hessian-based stable low-bit quantization. Outperforms GPTQ, AWQ, SpinQuant on Llama and Qwen models. Better numerical stability via Hessian analysis. Best for ultra low-bit (2-3 bit) quantization.
8. BitsandBytes (NF4)¶
Developer: Tim Dettmers
Key Feature¶
On-the-fly quantization during model loading — no pre-quantized files needed.
NF4 vs FP4¶
NF4 (NormalFloat4): Optimized for Gaussian-distributed weights - More levels near zero (where most weights are) - Less error for neural networks
FP4 (FloatingPoint4): Standard floating point - Uniformly spaced in log scale - General purpose
Double Quantization¶
Quantize the quantization constants (absmax values) for extra compression.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
)
9. Benchmark Results (Qwen2.5-32B on H200)¶
Perplexity (Wikitext-2)¶
| Method | Perplexity | vs FP16 |
|---|---|---|
| FP16 | 9.42 | Baseline |
| AWQ-4bit | 9.58 | +1.7% |
| GPTQ-4bit | 9.61 | +2.0% |
| GGUF-Q4_K_M | 9.72 | +3.2% |
| bnb-NF4 | 9.68 | +2.8% |
HumanEval Pass@1¶
| Method | Score | vs FP16 |
|---|---|---|
| FP16 | 51.2% | Baseline |
| AWQ-4bit | 49.8% | -1.4% |
| GPTQ-4bit | 50.1% | -1.1% |
| Marlin-GPTQ | 50.1% | -1.1% |
Inference Speed (ShareGPT)¶
| Method | Throughput | Latency (TTFT) |
|---|---|---|
| FP16 | 52 tok/s | 1.8s |
| GPTQ | 276 tok/s | 0.9s |
| AWQ | 68 tok/s | 1.2s |
| Marlin-GPTQ | 712 tok/s | 0.4s |
| Marlin-AWQ | 741 tok/s | 0.4s |
| GGUF (GPU) | 180 tok/s | 0.6s |
10. Decision Framework¶
By Hardware¶
graph TD
START{"Hardware?"} -->|"CPU / Apple M"| GGUF["GGUF"]
START -->|"GPU"| GPU{"GPU tier?"}
GPU -->|"High-end (H100/H200)"| HI["GPTQ + Marlin or FP8"]
GPU -->|"Consumer GPU"| CON["AWQ or GPTQ"]
style GGUF fill:#e8f5e9,stroke:#4caf50
style HI fill:#e8eaf6,stroke:#3f51b5
style CON fill:#fff3e0,stroke:#ef6c00
By Use Case¶
| Use Case | Recommended |
|---|---|
| Production inference | GPTQ + Marlin |
| Edge/Mobile | GGUF or AWQ |
| Instruction-tuned models | AWQ |
| Maximum quality | GPTQ (4-bit) or FP8 |
| Quick deployment | BitsandBytes (load_in_4bit) |
| Apple Silicon | GGUF |
By Priority¶
| Priority | Method |
|---|---|
| Quality | GPTQ > AWQ > GGUF |
| Speed | Marlin > GPTQ > AWQ > GGUF |
| Memory | All 4-bit similar (~4× reduction) |
| Ease of use | bnb > GGUF > AWQ > GPTQ |
11. Code Examples¶
GPTQ Quantization¶
from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig
# Quantization config
quantization_config = GPTQConfig(
bits=4,
dataset="c4",
group_size=128,
desc_act=False,
)
# Load and quantize
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
quantization_config=quantization_config,
device_map="auto",
)
AWQ Quantization¶
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
model = AutoAWQForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")
# Quantize
model.quantize(
tokenizer,
quant_config={
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
}
)
model.save_quantized("./llama-3.1-8b-awq")
vLLM with Quantization¶
from vllm import LLM
# Load pre-quantized AWQ model
llm = LLM(
model="hugging-quants/Meta-Llama-3.1-8B-AWQ-INT4",
quantization="awq",
dtype="float16",
)
# Or GPTQ
llm = LLM(
model="hugging-quants/Meta-Llama-3.1-8B-GPTQ-INT4",
quantization="gptq",
dtype="float16",
)
GGUF with llama.cpp¶
from llama_cpp import Llama
llm = Llama(
model_path="./models/llama-3.1-8b-q4_k_m.gguf",
n_ctx=4096,
n_gpu_layers=35, # Offload to GPU
)
output = llm("Q: Hello? A:", max_tokens=128)
Для интервью¶
Q: "Что такое квантизация и зачем она нужна для LLM?"¶
Strong: "Квантизация снижает точность весов (FP16 -> INT4/INT8). Для 7B модели: FP16 = 14 GB, INT4 = 3.5 GB -- 4x экономия памяти. Два подхода: post-training quantization (PTQ) без дообучения и quantization-aware training (QAT) с дообучением. PTQ проще, QAT точнее. Основные методы: GPTQ (Hessian-based error compensation), AWQ (activation-aware scaling), GGUF (CPU-optimized format)."
Red flag: "Квантизация делает модель меньше" (не объясняет как и какой ценой).
Q: "AWQ vs GPTQ -- в чем принципиальная разница?"¶
Strong: "GPTQ -- second-order: квантизует веса по одному, компенсируя ошибку через Hessian (\(w_i \leftarrow w_i - \frac{\delta_q}{H[q][q]} \times H[q][i]\)). AWQ -- activation-aware: не все веса одинаково важны, защищает 'salient' веса через scaling (\(S_{ij} = |W_{ij}| \cdot \|X_j\|_2\)). GPTQ чуть точнее (perplexity +2.0% vs +1.7% для AWQ на Qwen2.5-32B), AWQ лучше для instruction-tuned моделей и проще в deployment."
Red flag: "GPTQ лучше потому что использует Hessian" (AWQ сравнима по качеству и часто лучше для chat моделей).
Q: "Как задеплоить 70B модель на 24GB GPU?"¶
Strong: "70B в FP16 = 140 GB. INT4 = 35 GB -- все еще > 24 GB. Варианты: (1) GPTQ 3-bit + Marlin kernel (24-28 GB, quality drop ~5%), (2) GGUF Q4_K_M с GPU offload (часть слоев на CPU), (3) tensor parallelism на 2x 24GB GPU в INT4. Оптимально: AWQ INT4 + 2 GPU + Marlin kernel = ~18 GB per GPU, throughput 700+ tok/s."
Red flag: "Просто квантизовать в INT4 и загрузить" (не влезет -- 35 GB > 24 GB).
Q: "NF4 vs FP4 -- почему NF4 лучше для нейросетей?"¶
Strong: "Веса нейросетей распределены по Гауссу -- больше значений около нуля, мало на краях. NF4 (NormalFloat4) оптимизирует уровни квантизации под это распределение: больше уровней около нуля, меньше на краях. FP4 распределяет уровни равномерно в log-scale. Результат: NF4 дает меньшую ошибку квантизации для типичных весов. Double quantization (квантизация absmax значений) дает дополнительные ~0.4 бита экономии."
INT4 != 4x speedup
Квантизация до INT4 дает 4x экономию памяти, но НЕ 4x speedup. Причина: LLM inference memory-bound (bottleneck = memory bandwidth, не compute). INT4 ускоряет только memory transfer. Реальный speedup: 1.5-2.5x на стандартном GPU. Для максимального speedup нужен специализированный kernel (Marlin: 2-10x) который fuses dequantization + computation. Правило: квантизация = memory savings first, speedup second.
Calibration data matters
GPTQ и AWQ требуют калибровочные данные (128-1024 примера). Если калибровка на C4 (English text), а модель для code generation -- quality drop будет БОЛЬШЕ чем в benchmarks. Всегда калибруйте на данных близких к target domain. WikiText-2 perplexity -- ориентир, не гарантия.
13. Formulas Summary¶
Asymmetric Quantization¶
AWQ Scaling¶
GPTQ Error Compensation¶
Memory Savings¶
Where \(P\) = parameters, \(b\) = bits per weight
14. Sources & Further Reading¶
Papers¶
- GPTQ: Frantar et al. (2022) — arXiv:2210.17323
- AWQ: Lin et al. (2024) — arXiv:2306.00978
- Marlin: Frantar et al. (2025) — arXiv:2408.11743
- FP8-RL: arXiv:2601.18150 (Jan 2026)
- MOSS (FP8 Training): OpenReview Dec 2025
- HeRo-Q: arXiv:2601.21626 (Jan 2026)
Guides & Benchmarks¶
- JarvisLabs: "Complete Guide to LLM Quantization with vLLM" (Jan 2026)
- dasroot.net: "GGUF vs GPTQ vs AWQ Comparison" (Jan 2026)
- Kaitchup Index: Quantized LLM Leaderboard
Tools¶
- auto-gptq: github.com/AutoGPTQ/AutoGPTQ
- auto-awq: github.com/casper-hansen/AutoAWQ
- llama.cpp: github.com/ggml-org/llama.cpp
- bitsandbytes: github.com/bitsandbytes-foundation/bitsandbytes
- vLLM: github.com/vllm-project/vllm
See Also¶
- Оптимизация инференса -- общий обзор техник оптимизации, квантизация как одна из них
- Прунинг LLM -- удаление весов вместо снижения точности, часто комбинируют (P-KD-Q pipeline)
- Дистилляция знаний LLM -- альтернативный подход: обучить маленькую модель вместо квантизации большой
- vLLM и Paged Attention -- serving engine с нативной поддержкой GPTQ/AWQ/FP8 квантизации
- Распределенное обучение -- FSDP/DeepSpeed при QAT (quantization-aware training) на нескольких GPU