Руководство по квантизации моделей: от основ до продакшен-сервинга
Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.
Квантизация использует меньше битов для представления значений модели. В пайплайне сервинга можно квантизовать веса, активации, KV cache или их комбинацию, и каждая цель решает свою задачу сервинга.
Выбирайте цель исходя из текущего боттлнека: память под веса, вычисления над активациями, размер KV cache, kernels, железо, калибровочные данные или качество. 4-битная модель может поместиться в VRAM, но работать медленно с неоптимизированным kernel’ом — это показывает бенчмарк vLLM от JarvisLabs. FP8 хорошо работает на железе NVIDIA Hopper с совместимым рантаймом, но не даёт нативных преимуществ на GPU без поддержки этого формата. Матрица hardware support в TensorRT-LLM показывает поддерживаемые варианты. Для длинных контекстов или высокой конкурентности квантизация KV cache может сэкономить больше памяти, чем квантизация весов.
Если вы ML- или platform-инженер и выбираете вариант квантизации для модели, которую нужно сервить, это руководство для вас. После чтения вы сможете сопоставить боттлнек с подходящим форматом, рантаймом и планом валидации ещё до деплоя.
Краткий материал со сравнением артефактов и методов см. в статье LLM Quantization Formats.
1. Начните с боттлнека
Прежде чем выбирать разрядность, выясните, что ограничивает workload. Это может быть память под веса модели, вычисления на этапе префилла, пропускная способность при декодировании или KV cache, а не числовая точность сама по себе.
Типичные боттленеки и отправные точки:
| Если проблема в этом | Начните отсюда | Типичные инструменты | Что проверить перед деплоем |
|---|---|---|---|
| Веса модели не помещаются в VRAM | weight-only квантизация W4A16 | AWQ или GPTQ с llm-compressor или GPTQModel | Перплексия, кодинг, ризонинг, следование инструкциям |
| Сервинг с высоким throughput упирается в вычисления | FP8 или INT8 W8A8 | FP8 PTQ, SmoothQuant, TensorRT-LLM, vLLM | Throughput, TTFT, точность задач |
| Длинный контекст или высокая конкурентность заполняют GPU | Квантизация KV cache | vLLM, TensorRT-LLM или Transformers QuantizedCache | Retrieval по длинному контексту, латентность, безопасность и качество |
| Локальный инференс на CPU, Apple Silicon или десктопе | Файлы GGUF с локальными tensor encodings | llama.cpp, Ollama, LM Studio | Латентность промпта, использование RAM, выбранное tensor encoding и субъективное качество вывода |
| Адаптерный файн-тюнинг должен поместиться на одном GPU | NF4 / QLoRA | bitsandbytes, peft | Loss при файн-тюнинге и качество объединённой модели |
| Пайплайн генерации изображений слишком большой или медленный | Специфичная для diffusion INT4 или FP8 | SVDQuant, Nunchaku, torchao, NVIDIA ModelOpt | Визуальные артефакты, соответствие промпту, латентность, VRAM |
Используйте эту таблицу как карту. В следующих разделах объясняется, почему отправные точки различаются.
Обозначения в serving-рецептах
- W{x}A{y} показывает точность вычислений для поддерживаемых весов и активаций, обычно на GEMM-путях в serving engines. W4A16 хранит веса в 4-битном формате, а активации оставляет в 16-битной точности. W8A8 использует 8-битные веса и активации на поддерживаемых compute-путях, но автоматически не определяет persistent storage dtype каждого tensor’а рантайма.
- FP8, INT8, INT4, NF4 — это числовые форматы. Они определяют, какие значения можно представить.
- GPTQ, AWQ, SmoothQuant, QuaRot — это алгоритмы. Они определяют, как преобразовать обученную модель в формат с меньшей точностью.
- GGUF — файловый формат, который хранит tensor’ы и метаданные для GGML и рантаймов в стиле
llama.cpp. Файл GGUF может содержать неквантизованные типы tensor’ов, такие какF16,BF16илиF32, а также квантизованные encodings. В пресеты входятQ4_K_M,Q5_K_M,Q8_0,IQ*,TQ*иMXFP4. Именно tensor encoding определяет вариант квантизации. Один лишьGGUFне описывает serving-рецепт CUDA в формате FP8 W8A8. - KV cache — это кэш аттеншна, используемый при генерации. Он хранит предыдущие keys и values, чтобы модель не пересчитывала весь диалог для каждого токена.
- Квантизация KV cache хранит кэшированные tensor’ы активаций key/value в формате с меньшей точностью — например, FP8, INT8, INT4 или INT2, в зависимости от поддержки рантайма. Это отличается от prefix caching, PagedAttention и offload: они определяют, переиспользуются ли записи кэша, как они аллоцируются или где находятся.
- GEMM означает general matrix multiply. Большая часть времени инференса transformer-модели уходит на матричное умножение.
2. Квантизация — это контролируемое округление
Квантизация отображает значения высокой точности в меньшее множество представимых значений — это базовое определение, используемое и в Hugging Face Optimum, и в TensorRT-LLM. Вы экономите память и bandwidth, но одновременно добавляете ошибку округления.
INT4 предоставляет всего 16 дискретных значений, поэтому отображение BF16-весов на эту сетку создаёт ошибку округления. Методы вроде GPTQ, AWQ и SVDQuant стараются сохранить outlier’ы и уменьшить ошибку реконструкции. Хорошее отображение экономит память при минимальной потере качества. Плохое ухудшает ризонинг, следование инструкциям или визуальную fidelity.
Симметричное и асимметричное отображение
В соответствии с affine mapping, используемым в распространённых руководствах по квантизации, квантизация отображает непрерывное float-значение на дискретную сетку.
- — исходное значение высокой точности.
- — квантизованное значение.
- — scale, или размер шага.
- — zero point, целочисленная позиция, представляющая
0.0. - — целевой диапазон integer-значений. Знаковые 4-битные значения часто используют .
Симметричная квантизация центрирует сетку вокруг нуля и задаёт :
Это удобно для железа, поскольку вычислениям рантайма не нужно вычитать смещение zero point. Стек квантизации PyTorch предоставляет выбор affine scale и zero point как примитивные параметры квантизации в torchao.
Асимметричная квантизация сдвигает сетку, чтобы покрыть смещённые диапазоны:
Такая сетка может лучше сохранять активации, принимающие в основном положительные значения, но смещение добавляет вычисления, если kernel не умеет эффективно его обрабатывать.
Гранулярность scale имеет значение
Scale-фактор может охватывать весь tensor весов, один channel или небольшую group значений. В документации vLLM по FP8 KV cache используется то же различие между per-tensor и per-attention-head стратегиями scale. Малые группы обычно лучше сохраняют качество, но требуют больше метаданных scale.
| Гранулярность scale | Что использует один scale | Влияние на качество и выполнение |
|---|---|---|
| Per tensor | Вся weight matrix | Требует мало метаданных, но один outlier может растянуть сетку и снизить точность по всему layer. |
| Per channel | Одна output row | Не даёт channel’ам с узкими диапазонами использовать общий широкий диапазон другого channel. Многие 8-битные weight-пути используют эту гранулярность. |
| Per group | Block внутри row, обычно 64 или 128 значений | Ограничивает влияние outlier’а небольшим block’ом ценой дополнительных scale. AutoGPTQ использует group_size=128 в своих примерах GPTQ. |
Веса статичны, поэтому их scale можно вычислить offline до загрузки модели. Активации меняются с каждым токеном, поэтому их диапазоны зависят от workload.
| Масштабирование активаций | Когда рантайм выбирает scale | Преимущество | Режим отказа или стоимость |
|---|---|---|---|
| Static | Offline по calibration dataset | Не требует вычислять scale во время инференса. | Промпты, выходящие за пределы калиброванных длины или распределения, могут обрезать пики активаций и портить вывод. |
| Dynamic | Во время каждого forward pass | Адаптируется к текущим значениям активаций и смеси промптов. | Вычисление диапазонов на каждом layer добавляет работу и требует оптимизированных kernels. |
KV cache занимает промежуточное положение. Keys и values начинаются как runtime-тензоры активаций: каждый layer вычисляет их из hidden states во время forward pass. После генерации они перестают быть временными промежуточными результатами matmul и становятся persistent serving state, который аттеншн читает для последующих токенов.
Serving engine может хранить это состояние в формате с меньшей точностью, сохраняя рядом метаданные scale. Quantized KV Cache в vLLM, FP8 KV Cache в TensorRT-LLM и Transformers QuantizedCache предоставляют такой выбор хранения.
Точность хранения кэша остаётся отдельной от точности активаций внутри linear kernels. «Квантизация KV cache» обозначает одну оптимизацию кэша, а не все техники переиспользования, аллокации или перемещения записей кэша.
PTQ и QAT выполняются на разных этапах
Post-training quantization, или PTQ, сжимает уже обученную модель. Quantization-aware training, или QAT, знакомит модель с шумом квантизации во время обучения, чтобы она могла адаптироваться.
| Метод | Когда изучаются диапазоны | Используйте, когда | Цена |
|---|---|---|---|
| Weight-only PTQ | Offline, для статичных весов | Модель не помещается или decode ограничен bandwidth | Активации по-прежнему выполняются в 16-битном формате |
| Static PTQ | Offline, по calibration prompts | Нужен быстрый W8A8 serving | Calibration data должны соответствовать production |
| Dynamic PTQ | Runtime, для batch или activation path | Распределения входов сильно меняются | Дополнительная работа во время выполнения и более узкая поддержка hardware |
| QAT | Во время обучения | PTQ ломает качество чувствительной модели | Полная training-инфраструктура и значительно больше вычислений |
Calibration data должны быть похожи на traffic, который вы будете сервить. Например, KV-cache calibration path в vLLM использует curated dataset через llm-compressor. Если production-промпты — это длинные RAG traces, короткие абзацы из Wikipedia дадут аккуратные числа на benchmark’е и сломанный deployment. Модель настроит activation scales под короткий текст, а затем столкнётся с другими паттернами активаций на реальных промптах с длинным контекстом. Эвалы квантизации на длинном контексте измеряют этот риск напрямую.
3. Числовые форматы определяют требования к железу
Числовой формат определяет, какие значения модель может хранить в памяти. Для эффективных вычислений нужны runtime kernels и hardware support для той же разрядности и формата. TensorRT-LLM документирует и список рецептов, и матрицу поддержки hardware.
| Формат | Хранение на значение | Хороший default для | Основной риск |
|---|---|---|---|
| BF16 / FP16 | 2 bytes | Базового инференса и serving, совместимого с training | Большое потребление VRAM и высокий traffic по memory bandwidth |
| FP8 | 1 byte | High-throughput W8A8 serving на Ada, Hopper, Blackwell | Нужны native FP8 tensor cores и поддержка рантайма |
| INT8 | 1 byte | W8A8 serving на старом или не-NVIDIA hardware | Outlier’ы активаций и чувствительность к static calibration |
| INT4 | 0.5 bytes | W4A16, когда основной лимит — память под веса | Потеря качества на небольших или reasoning-heavy моделях |
| FP4 / NVFP4 | ~0.5 bytes | Экспериментов эпохи Blackwell и ранних serving paths | Специфичные для hardware требования к compiler и runtime |
| llama.cpp GGUF encodings / presets | Variable | Локального CPU, Apple Silicon, десктопа и edge-инференса | GGUF — контейнер. Tensor encoding — выбор квантизации. |
| NF4 | 0.5 bytes | Обучения QLoRA-адаптеров | Обычно неподходящий export format для production serving |
BF16 и FP16 используют по 16 бит, но распределяют точность по-разному и поэтому по-разному выходят из строя. BF16 сохраняет 8-битный exponent range FP32 и лучше защищён от overflow. У FP16 больше mantissa bits и уже exponent range, поэтому пики активаций требуют большей осторожности. В оценке Kurtic et al. явно используется BF16 как baseline при сравнении serving-форматов FP8, INT8 и INT4.
У FP8 есть два распространённых варианта. E4M3 даёт больше точности и обычно используется для forward weights и активаций. E5M2 даёт больший dynamic range и лучше подходит для gradients или нестабильных activation paths. vLLM предоставляет оба FP8 E4M3 и E5M2 KV-cache dtypes. В исследовании Kurtic et al. для ACL 2025 «Give Me BF16 or Give Me Death» FP8 W8A8 оказался практически lossless для семейства Llama-3.1 более чем на 500 000 eval’ов. Этот результат относится к данному семейству моделей, набору эвалов и конфигурации serving. Для каждого deployment всё равно нужен собственный quality gate.
Blackwell добавляет microscaling-форматы, такие как MXFP8 и NVFP4. Вместо одного scale для всего tensor или row microscaling использует очень маленькие blocks. В объяснении NVFP4 от NVIDIA описаны 4-битные floating-point значения в blocks по 16 элементов, с FP8 scale factors и более высоким scale уровня FP32. Такой подход стремится дать footprint, близкий к INT4, сохранив поведение floating-point. Однако он требует соответствующих архитектуры hardware, compiler и runtime support, поэтому TensorRT-LLM перечисляет поддержку FP4 и FP8 для разных поколений GPU.
4. Weight-only против weight-activation квантизации
Обозначение WxAy описывает точность весов и активаций, которые по-разному нагружают GPU во время инференса.
Во время префилла модель обрабатывает входной промпт. Этот этап обычно ограничен вычислениями, поскольку GPU выполняет большие матричные умножения. Поэтому W8A8 FP8/INT8 recipes важны для serving, ориентированного на throughput.
Во время decode модель генерирует по одному токену за раз. Этот этап часто ограничен memory bandwidth, поскольку GPU постоянно загружает веса из VRAM, чтобы получить следующий токен. Weight-only-исследования вроде GPTQ и AWQ уменьшают это давление, сокращая число bytes весов.
W4A16 сжимает веса, а активации оставляет в BF16 или FP16. GPU загружает меньше bytes весов, затем деквантизует их обратно в формат более высокой точности для умножения. Это помогает при decode и проблемах с размещением модели в памяти. Для compute-bound префилла выигрыш может быть небольшим, поскольку математика по-прежнему выполняется в 16-битном формате.
W8A8 сжимает веса и tensor’ы активаций, используемые поддерживаемыми matmul kernels. Если hardware имеет native low-precision tensor cores, serving engine может выполнять математику непосредственно в FP8 или INT8. Поэтому FP8 может помочь high-throughput serving, уменьшая memory traffic и используя более быстрые вычисления. У KV cache есть собственная настройка хранения, поэтому отдельно проверьте cache dtype или cache implementation рантайма.
Если модель едва помещается в VRAM, начните с weight-only квантизации, чтобы уменьшить footprint. Если модель помещается, но не справляется с throughput при больших batch’ах, оцените FP8 или INT8 W8A8, чтобы ускорить compute-фазу. Если проблемы с памятью возникают только в длинных диалогах, сначала оцените вклад KV cache. Протестируйте квантизацию KV cache, когда этот вклад доминирует. Включайте prefix caching, когда доминируют повторяющиеся prefixes.
5. Алгоритмы против runtime kernels
Алгоритмы квантизации, такие как GPTQ или AWQ, определяют, как веса модели отображаются в формат меньшей точности. Runtime kernels, такие как Marlin или custom kernels vLLM, — это низкоуровневый GPU-код, выполняющий матричное умножение. Сильно сжатая модель будет работать быстро только при наличии оптимизированного kernel для её конкретного формата квантизации.
Бенчмарк vLLM от JarvisLabs на Qwen2.5-32B-Instruct с NVIDIA H200 наглядно показывает влияние kernel:
| Квантизация / kernel | Perplexity, меньше — лучше | Pass@1, больше — лучше | Throughput | TTFT |
|---|---|---|---|---|
| FP16 baseline | 6.56 | 56.1% | 461 tok/s | 57.7 ms |
| AWQ | 6.84 | 51.8% | 68 tok/s | 277.8 ms |
| GPTQ | 6.90 | 46.3% | 277 tok/s | 107.1 ms |
| Marlin-GPTQ | 6.97 | 45.7% | 712 tok/s | 51.9 ms |
| Marlin-AWQ | 6.84 | 51.8% | 741 tok/s | 73.5 ms |
| GGUF Q4_K_M | 6.74 | 51.8% | 93 tok/s | 958.0 ms |
| bitsandbytes | 6.67 | 51.8% | 168 tok/s | 135.3 ms |
Не переносите эти числа напрямую на свой stack. Они получены для одной модели, одного класса GPU и одной software-конфигурации. Они показывают более узкий тезис: название алгоритма в checkpoint не говорит, насколько быстрым будет serving.
Например, AWQ и Marlin-AWQ используют одни и те же 4-битные веса. Реализация Marlin намного быстрее, потому что её CUDA kernel объединяет деквантизацию и матричное умножение в одну высокооптимизированную GPU-операцию.
Бенчмарк baseline и сжатых вариантов выполняйте на одной и той же смеси промптов и с одним и тем же инструментом, например vllm bench serve:
vllm bench serve \
--model ./outputs/Qwen2.5-32B-Instruct-AWQ-W4A16 \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256
Отслеживайте throughput, TTFT, межтокенную латентность, использование памяти и качество задач. Если некоторые показатели движутся в противоположных направлениях, именно этот trade-off нужно увидеть до выхода в production.
Меню алгоритмов
Используйте эту таблицу как карту, а не как рейтинг:
| Алгоритм | Распространённый формат | Что он старается сохранить | Основная стоимость |
|---|---|---|---|
| GPTQ | W4A16 | Порубежную реконструкцию с использованием оценок Hessian | Медленная калибровка и более сложная обработка |
| AWQ | W4A16 / W4A8 | Важные activation channels | Нужны калибровка и fused serving kernels |
| SmoothQuant | W8A8 | Поведение активаций INT8 за счёт переноса outlier scale в веса | Настройка scale для каждой модели |
| QuaRot / SpinQuant | W4A4 / W4A8 | Снижение давления activation outlier’ов с помощью rotation | Сложность rotation во время выполнения |
| HQQ | W4A16 / W2A16 | Быстрое weight-only-сжатие без калибровки | На очень малой разрядности качество требует downstream-проверок |
| QLoRA (NF4) | NF4 | Память для обучения адаптеров | Не лучший default для serving |
| llama.cpp GGUF K-quants / IQ-quants | Смешанные low-bit tensor encodings | Качество локального инференса на byte | Не предназначены для cloud batch serving |
Toolchain активно развивается. AutoGPTQ был заархивирован в апреле 2025 года, а AutoAWQ — заархивирован и официально deprecated в мае 2025 года. Для новых compressed-tensors checkpoints, которые потребляет vLLM, начинайте с llm-compressor. Используйте GPTQModel, когда нужен актуальный GPTQ path с Marlin, Machete, memory options для MoE или disk offload.
Pruning и distillation также снижают стоимость serving, но через отдельные workflows. Structured sparsity 2:4 удаляет веса по паттерну, который могут использовать NVIDIA sparse tensor cores. Distillation обучает меньшую student-модель копировать большую и может хорошо работать на узких задачах. Включайте любой из этих вариантов в shortlist только если проект может поддержать дополнительные pruning или training.
6. Serving-память — это не только веса
Сжатый checkpoint — лишь часть memory footprint при serving. Прежде чем решать, достаточно ли квантизации весов, оцените весь runtime. PagedAttention показывает, что KV cache — значимая составляющая serving-памяти.
Offline-квантизация может выполняться с ограничением по layer. Инструменты вроде llm-compressor могут загрузить один transformer block, выполнить калибровку и квантизацию, записать сжатый block и перейти к следующему. Это удерживает пиковое потребление GPU-памяти ближе к размеру крупнейшего активного layer плюс calibration buffers. Вам всё равно понадобятся CPU RAM и disk для исходного checkpoint, но GPU не обязательно должен держать всю BF16-модель.
Пиковое потребление GPU-памяти во время offline-квантизации может выглядеть так:
Serving строже. Весь сжатый checkpoint должен постоянно находиться в памяти вместе с KV cache и runtime buffers. KV cache растёт с длиной контекста и размером активного batch:
Где:
- — количество layers.
- — число key-value attention heads. Grouped-query attention уменьшает его, позволяя множеству query heads совместно использовать меньшее число KV heads.
- — размерность каждой head, обычно 128 или 256.
- — prompt tokens плюс сгенерированные tokens.
- — активный serving batch.
- — 2 для BF16 или FP16 и 1 для FP8 или INT8. Режим FP8 KV cache в vLLM — пример serving stack, используемый в этой статье.
Квантизация KV cache меняет хранение, а reuse — аллокацию
KV cache можно квантизовать во время инференса. Каждый decode step создаёт K- и V-тензоры активаций для нового токена. W8A8-модель может уже использовать FP8 или INT8 для поддерживаемой projection math, но cache остаётся отдельным объектом хранения.
Многие serving stacks хранят этот объект в dtype модели или cache dtype. Чтобы изменить его, включите KV-cache dtype, используйте checkpoint с cache scales или выберите quantized cache implementation.
При включённой квантизации KV cache engine записывает entries как представление меньшей точности плюс scales. Позднее аттеншн либо деквантизует cache внутри своего kernel, либо на некоторых backends выполняет часть attention operation в quantized domain.
Стабильная документация Quantized KV Cache в vLLM напрямую предоставляет эту возможность через kv_cache_dtype="fp8" или --kv-cache-dtype fp8. vLLM поддерживает форматы cache FP8 E4M3 и E5M2, а также стратегии scale per-tensor и per-attention-head. Получить scales можно тремя способами: defaults, estimation во время warmup и dataset calibration через llm-compressor. С FlashAttention 3 vLLM также может выполнять attention operations в FP8 domain, квантизуя queries вдобавок к keys и values.
TensorRT-LLM предоставляет FP8 KV cache через KvCacheConfig(dtype='fp8') и перечисляет FP8 KV cache и NVFP4 KV cache как отдельные quantization recipes, отличные от квантизации weights/activations. В Hugging Face Transformers также есть path QuantizedCache через cache_implementation="quantized"; hqq поддерживает форматы cache int2, int4 и int8, а quanto — int2 и int4.
Обычный KV caching хранит предыдущие keys и values, чтобы не пересчитывать их. Prefix caching переиспользует cache blocks между запросами с одинаковым prefix. PagedAttention уменьшает fragmentation и улучшает аллокацию, а KV offload перемещает cache blocks между уровнями памяти. Эти комбинации зависят от runtime. QuantizedCache в Hugging Face не поддерживает offloading. vLLM документирует quantized KV cache отдельно от prefix caching и других функций cache management. Проверяйте каждую комбинацию в используемом runtime.
Риск для качества также отличается от weight-only PTQ. Квантизация KV cache вносит ошибку в attention state, который читается на каждом последующем decode step. Отдельно тестируйте retrieval по длинному контексту, multi-turn поведение, безопасность и отказы, форматирование tool use и latency вывода. KVQuant, KIVI и исследование FP8 KV cache в vLLM оценивают квантизацию KV cache как отдельную задачу.
Размер модели и длина контекста сами по себе не определяют, даст ли compression cache больший выигрыш, чем ещё один раунд сжатия весов. Рассчитайте bytes кэша по приведённому выше уравнению, используя число KV heads модели, размерность head, активный batch и cache dtype. Затем сравните результат с количеством bytes, сэкономленных между двумя конкретными форматами весов, например BF16 и INT4. Если cache больше, тестирование квантизации FP8 KV cache может освободить больше serving-памяти, чем дальнейшее уменьшение весов.
7. Hardware сужает меню вариантов
Footprint весов легко оценить по числу parameters и точности хранения — тот же принцип sizing, который используется в обсуждениях serving-памяти вокруг KV cache:
| Размер модели | Веса BF16 | Веса FP8 / INT8 | Веса INT4 |
|---|---|---|---|
| 7B / 8B | ~14–16 GB | ~7–8 GB | ~3.5–4 GB |
| 14B | ~28 GB | ~14 GB | ~7 GB |
| 32B / 34B | ~64–68 GB | ~32–34 GB | ~16–17 GB |
| 70B | ~140 GB | ~70 GB | ~35 GB |
| 109B MoE | ~218 GB total | ~109 GB | ~55 GB |
MoE-модели могут активировать меньше parameters на токен, но полный набор весов всё равно должен где-то находиться, если runtime не поддерживает offload. Матрица поддержки квантизации в TensorRT-LLM рассматривает семейства MoE-моделей как deployment targets с собственными поддерживаемыми recipes.
Hardware deployment ограничивает набор жизнеспособных форматов квантизации:
- CPU serving зависит от vector instructions, таких как AVX-512 или AMX. Файл GGUF, загруженный через
llama.cpp, — практичный вариант. - Apple Silicon использует unified memory, поэтому локальные модели могут задействовать большой общий пул RAM вместо выделенной VRAM. GGUF и
llama.cppостаются распространённым путём для local runtime, поскольку GGUF создан для GGML executors. - NVIDIA Ampere поддерживает serving paths с INT8 tensor cores, но не native FP8 W8A8 tensor-core math. Типичный выбор — weight-only квантизация W4A16 или static INT8, в соответствии с матрицей поддержки hardware TensorRT-LLM.
- NVIDIA Ada и Hopper поддерживают FP8 serving paths в TensorRT-LLM. На этих GPU стоит протестировать FP8 W8A8 serving.
- NVIDIA Blackwell добавляет поддержку NVFP4 и microscaling, но software path всё ещё имеет значение. Ранние low-bit floating-point stacks следует считать чувствительными к версиям.
8. Калибровка и evaluation перед deploy
Модель, которая загружается, прошла smoke test. Для deployment нужны проверки качества и serving на целевом workload. Недавние эвы квантизации показывают разные результаты для LLM serving, задач с длинным контекстом и reasoning-heavy моделей.
Для калибровки используйте промпты, похожие на production:
- Добавьте RAG traces, SQL queries, истории агентов, code tasks, payloads tool calls и system prompts из целевого workload. Static PTQ зависит от того, насколько calibration data соответствуют production distribution.
- Сопоставьте sequence lengths. Короткие промпты в один turn не покажут поведение активаций на длинном контексте.
- Оставляйте
embed_tokensиlm_headв формате более высокой точности, если это позволяет метод или runtime — это распространённый pattern исключений в LLM Compressor recipes. - Используйте достаточно samples, чтобы стабилизировать activation ranges. В примере vLLM для KV cache задано
NUM_CALIB_SAMPLES = 512. Считайте это одним документированным примером, а не универсальным числом. Нужное количество samples зависит от метода, модели, sequence length и production workload. - Редактируйте secrets и private user data перед использованием production logs.
Для evaluation проверяйте и качество языка, и поведение serving:
- Perplexity на стандартном corpus выявляет общее ухудшение языка, но benchmark JarvisLabs напоминает, что perplexity и throughput могут меняться независимо.
- Domain tasks выявляют ошибки, которые скрывает perplexity. Используйте HumanEval для coding, MMLU для общих знаний и AIME или MATH-500 для mathematical reasoning, если эти области важны.
- Format checks важны для agentic systems. Проверяйте соответствие JSON Schema, markdown output, форму tool call и поведение отказа, поскольку evals квантизованных моделей могут пропустить application-level failures, даже если aggregate benchmark accuracy остаётся стабильной.
- Long-context tests выявляют ущерб от квантизации KV cache. Needle-in-a-haystack — грубый тест, но результаты квантизации на длинном контексте показывают, почему такие проверки должны входить в deploy gate.
- Load tests должны показывать throughput, TTFT, межтокенную latency, максимальную batch capacity и peak memory. vLLM предоставляет эти измерения через
vllm bench serve.
Reasoning-heavy модели оценивайте строго. Квантизация ниже 4 бит или W4A4 без rotation может ухудшить точность ризонинга, даже если baseline perplexity выглядит стабильной. Это основной вывод исследования reasoning-моделей после квантизации.
9. Workflow companion repository
Companion repository slavadubrov/model-compression-demo предназначен для воспроизводимости процесса принятия решений. Он использует uv и сосредоточен на planning, recipes, dry runs и benchmark configs, основанных на тех же источниках, что и эта статья: vLLM, LLM Compressor, TensorRT-LLM и algorithm papers.
Публичный README на revision 8b45003849e830bed2ff341a9f027b017d932c1f был проверен 2026-08-16. Companion checkout отсутствует в этом workspace, поэтому я не мог выполнить его CLI здесь. Приведённые ниже команды иллюстративны, пока вы не запустите их из этого pinned checkout; benchmark plan также требует целевого serving hardware.
Не копируйте output FP8 recipe из этой pinned revision. Её команда recipe --algorithm fp8-dynamic создаёт internally inconsistent model и output path. Команда пока опущена до исправления companion repository.
Склонируйте repository и изучите поддерживаемые алгоритмы:
git clone https://github.com/slavadubrov/model-compression-demo.git
cd model-compression-demo
git checkout 8b45003849e830bed2ff341a9f027b017d932c1f
uv run python demo.py list-algorithms
Начните с planning и sizing:
uv run python demo.py plan \
--model-preset qwen3-8b \
--goal fit-memory \
--hardware ampere \
--context 4096 \
--concurrency 4
uv run python demo.py estimate \
--model-preset qwen3-8b \
--scheme w4a16 \
--context 4096 \
--concurrency 4
uv run python demo.py plan \
--model-preset qwen3-0.6b \
--hardware cpu
Затем сгенерируйте recipe и выполните preview квантизации, прежде чем тратить время GPU:
uv run python demo.py recipe --algorithm gptq-w4a16
uv run python demo.py quantize --dry-run
uv run python demo.py quantize \
--algorithm gptq-w4a16 \
--model Qwen/Qwen3-8B \
--dry-run
Для serving и планирования benchmark’ов:
uv run python demo.py serve-command \
--algorithm fp8-dynamic \
--fp8-kv-cache \
--enable-prefix-caching
uv run python demo.py benchmark-plan \
--model Qwen/Qwen3-8B \
--algorithms gptq-w4a16,rtn-w8a16,fp8-dynamic \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256 \
--output-json reports/quantization-benchmark-plan.json
Наконец, сравните base и compressed models с явными thresholds:
uv run python demo.py quality-eval \
--base-model Qwen/Qwen3-8B \
--compressed-model outputs/Qwen3-8B-W4A16 \
--mode all \
--lm-eval-task hellaswag \
--lm-eval-limit 50 \
--max-perplexity-delta-pct 5 \
--output-json reports/qwen3-8b-w4a16-quality.json
Выполняйте работу по порядку: спланируйте target, оцените память, выполните dry run recipe, проведите benchmark serving, затем сравните качество с thresholds. Эта последовательность отражает разделение в статье между memory sizing, runtime benchmarking и quality evaluation.
10. Для diffusion-моделей нужен отдельный path
Diffusion- и diffusion-transformer-пайплайны имеют другое поведение активаций по сравнению с autoregressive LLM. SVDQuant рассматривает квантизацию diffusion как отдельную задачу, связанную с outlier’ами активаций.
Autoregressive LLM генерируют по одному токену за раз. Diffusion-модели выполняют повторяющиеся denoising steps, и распределения их активаций меняются в процессе. Стандартный 4-битный LLM quantization pass может уменьшить memory footprint diffusion-модели, но при этом вызвать серьёзные визуальные артефакты. Diffusion-focused методы вроде SVDQuant / Nunchaku и diffusion quantization в NVIDIA ModelOpt учитывают это другое поведение активаций.
Используйте следующие пункты как консервативные heuristics, а не универсальные defaults. Каждый pipeline, component, model и runtime требует отдельных тестов:
- Для первого сравнения оставьте VAE в 16-битном формате. Эта консервативная heuristic уменьшает один из источников image artifacts. Понижайте точность только после валидации методом и целевым pipeline.
- Сначала попробуйте DiT или U-Net backbone, поскольку на него часто приходится наибольшая доля parameters. Это heuristic, поэтому проверьте memory, latency и image quality для целевого pipeline. Методы квантизации diffusion-моделей используют такой же component-level подход.
- Обрабатывайте text encoders отдельно. Квантизация T5-XXL или CLIP может повлиять на prompt alignment или рендеринг текста в конкретном pipeline, поэтому оценивайте их независимо, не предполагая поведения обычного transformer.
- Используйте diffusion-aware методы, такие как SVDQuant, когда основной проблемой являются activation outlier’ы.
- Оценивайте результат по изображениям, а не по text metrics. Проверяйте соответствие промпту, рендеринг текста, оттенки кожи, цветовой баланс, мелкие детали, latency и VRAM.
Если evaluation set содержит только простые или распространённые промпты, edge-case failures останутся незамеченными. Добавьте сложные случаи: мелкий текст, руки, повторяющиеся объекты, structured layouts и промпты с negative constraints, поскольку ошибки diffusion-квантизации проявляются визуально, а не в perplexity language model.
11. Production defaults
Для enterprise LLM serving начните с BF16 baseline в том serving engine, который планируете использовать. Если цель — throughput и hardware это поддерживает, протестируйте FP8 W8A8. Если модель не помещается, попробуйте AWQ или GPTQ W4A16 с kernels класса Marlin. Если проблема в длинном контексте или конкурентности, протестируйте квантизацию FP8 KV cache. Если проблема в повторяющихся prefixes, также включите prefix caching. Выпускайте сжатую версию только после прохождения quality и serving benchmarks.
Для локального и edge-инференса начните с файла GGUF с Q4_K_M или Q5_K_M. Если память позволяет и качество важнее footprint, переходите на Q8_0 GGUF. Переход ниже 4 бит — крайняя мера, а не default.
Для файн-тюнинга используйте NF4 с QLoRA, чтобы дёшево обучать adapters. Оцените adapter в приложении до merge. После merge экспортируйте модель в тот serving artifact, который действительно нужен: GGUF file, совместимый с llama.cpp, checkpoint AWQ/GPTQ/compressed-tensors, serving checkpoint FP8 или BF16.
Для diffusion начните с этих консервативных heuristics и визуально тестируйте каждую комбинацию pipeline/model/runtime. Text perplexity не покажет, сломался ли image pipeline, поэтому используйте diffusion-specific evidence, например SVDQuant, и визуальную evaluation.
References
- JarvisLabs vLLM Benchmarks: JarvisLabs, vLLM Quantization Complete Guide and Benchmarks, 2026. JarvisLabs.
- Hugging Face Optimum Quantization Guide: Hugging Face, Quantization conceptual guide. Docs.
- vLLM Quantization Docs: vLLM project, Quantization. Docs.
- vLLM Quantized KV Cache Docs: vLLM project, Quantized KV Cache. Docs.
- vLLM Benchmark Docs: vLLM project, vllm bench serve. Docs.
- LLM Compressor Docs: vLLM project, LLM Compressor. Docs.
- GPTQModel: ModelCloud, GPTQModel. GitHub.
- TensorRT-LLM Quantization: NVIDIA, TensorRT-LLM Quantization. Docs.
- NVIDIA NVFP4: NVIDIA, Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. Blog.
- Hugging Face QuantizedCache: Hugging Face, Cache strategies: Quantized cache. Docs.
- NVIDIA Model Optimizer: NVIDIA, Model Optimizer. GitHub.
- torchao Quantization: PyTorch, torchao quantization overview. Docs.
- bitsandbytes Quantization: Hugging Face, bitsandbytes. Docs.
- HQQ: Dropbox, Half-Quadratic Quantization. GitHub.
- PEFT: Hugging Face, Parameter-Efficient Fine-Tuning. Docs.
- Ollama: Ollama local model runtime. Website.
- LM Studio: LM Studio local AI runtime. Website.
- AutoGPTQ status: AutoGPTQ repository, archived April 2025. GitHub.
- AutoAWQ status: AutoAWQ repository, archived and deprecated May 2025. GitHub.
- GPTQ: Frantar et al., GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers, NeurIPS 2023. arXiv:2210.17323.
- Marlin: Frantar et al., MARLIN: Mixed-Precision Auto-Regressive Parallel Inference on Large Language Models, arXiv:2408.11743. arXiv:2408.11743.
- AWQ: Lin et al., AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration, MLSys 2024. arXiv:2306.00978.
- SmoothQuant: Xiao et al., SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models, ICML 2023. arXiv:2211.10438.
- QuaRot: Ashkboos et al., QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs, NeurIPS 2024. arXiv:2404.00456.
- SpinQuant: Meta AI Research, SpinQuant: LLM Quantization with Learned Rotations, arXiv:2405.16406. arXiv:2405.16406.
- QLoRA / NF4: Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, NeurIPS 2023. arXiv:2305.14314.
- SVDQuant / Nunchaku: MIT HAN Lab, SVDQuant: Absorbing Outliers by Low-Rank Components for 4-Bit Diffusion Models, ICLR 2025. arXiv:2411.05007, Nunchaku.
- vLLM PagedAttention: Kwon et al., Efficient Memory Management for Large Language Model Serving with PagedAttention, SOSP 2023. arXiv:2309.06180.
- Grouped-Query Attention: Ainslie et al., GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints, EMNLP 2023. arXiv:2305.13245.
- vLLM FP8 KV Cache: Kubler, Kurtic, Wilkinson et al., The State of FP8 KV-Cache and Attention Quantization in vLLM, vLLM Blog, April 2026. vLLM Blog.
- KIVI: Liu et al., KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache, ICML 2024. arXiv:2402.02750.
- KVQuant: Hooper et al., KVQuant: Towards 10 Million Context Length LLM Inference with KV Cache Quantization, NeurIPS 2024. arXiv:2401.18079.
- LLM Serving Evaluation: Kurtic et al., “Give Me BF16 or Give Me Death”? Accuracy-Performance Trade-Offs in LLM Quantization, ACL 2025. arXiv:2411.02355.
- Long-context Quantization Evaluation: Mekala et al., Does quantization affect models’ performance on long-context tasks?, arXiv:2505.20276. arXiv:2505.20276.
- Reasoning Evaluation: Quantization Hurts Reasoning? An Empirical Study on Quantized Reasoning Models, arXiv:2504.04823. arXiv:2504.04823.
- SlideSparse: SlideSparse: Fast and Flexible (2N-2):2N Structured Sparsity, arXiv:2603.05232v1. arXiv:2603.05232v1.
- HumanEval: OpenAI, HumanEval. GitHub.
- MMLU: Hendrycks et al., Measuring Massive Multitask Language Understanding. arXiv:2009.03300.
- MATH-500: Hugging Face H4, MATH-500. Dataset.
- GGUF and llama.cpp: ggml-org, GGUF file format and llama.cpp. GGUF, llama.cpp.
- Hugging Face GGUF Docs: Hugging Face, GGUF. Docs.
- Reference Repository: slavadubrov/model-compression-demo.