Руководство по квантизации моделей: от основ до продакшен-сервинга
Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.
Квантизация использует меньше битов для представления значений модели. В пайплайне сервинга можно квантизовать веса, активации, KV cache или их комбинацию, причем каждая цель решает свою задачу сервинга.
Выбирайте цель исходя из текущего боттлнека: память под веса, вычисления активаций, размер KV cache, ядра, железо, калибровочные данные или качество. 4-битная модель может поместиться в VRAM, но работать медленно из-за неоптимизированного ядра, как показывает бенчмарк JarvisLabs для vLLM. FP8 хорошо работает на железе NVIDIA Hopper с совместимым рантаймом, но не дает нативных преимуществ на неподдерживаемых GPU. Матрица совместимости TensorRT-LLM показывает поддерживаемые варианты. При длинном контексте или высокой конкурентности квантизация KV cache может сэкономить больше памяти, чем квантизация весов.
ML- и платформенные инженеры могут определить боттлнек, выбрать подходящий формат и рантайм, а затем проверить именно этот путь сервинга до деплоя.
Краткое сравнение артефактов и методов см. в материале Форматы квантизации LLM.
1. Начинайте с боттлнека
Перед выбором разрядности определите, что ограничивает workload. Это может быть память под веса модели, вычисления на этапе префилла, пропускная способность при декоде или KV cache, а не численная точность сама по себе.
Типичные боттленеки и отправные точки:
| Если проблема в этом | Начните отсюда | Типичные инструменты | Проверьте до деплоя |
|---|---|---|---|
| Веса модели не помещаются в VRAM | Weight-only квантизация W4A16 | AWQ или GPTQ с llm-compressor или GPTQModel | Perplexity, кодинг, ризонинг, следование инструкциям |
| Сервинг с высоким 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-encoding | llama.cpp, Ollama, LM Studio | Латентность промпта, использование RAM, выбранный tensor encoding и субъективное качество вывода |
| Адаптерный файн-тюнинг должен помещаться на одном GPU | NF4 / QLoRA | bitsandbytes, peft | Loss файн-тюнинга и качество объединенной модели |
| Пайплайн генерации изображений слишком большой или медленный | Специфичная для diffusion INT4 или FP8 | SVDQuant, Nunchaku, torchao, NVIDIA ModelOpt | Визуальные артефакты, соответствие промпту, латентность, VRAM |
Используйте эту таблицу как карту. В следующих разделах объясняется, почему эти отправные точки различаются.
Обозначения в рецептах сервинга
- W{x}A{y} указывает точность для поддерживаемых операций с весами и активациями, обычно в GEMM-путях serving engine. W4A16 хранит веса в 4-битном формате, а активации оставляет в 16-битной точности. W8A8 использует 8-битные веса и активации в поддерживаемых вычислительных путях, но автоматически не определяет persistent storage dtype каждого runtime-тензора.
- FP8, INT8, INT4, NF4 — это числовые форматы. Они определяют, какие значения можно представить.
- GPTQ, AWQ, SmoothQuant, QuaRot — это алгоритмы. Они определяют, как преобразовать обученную модель в формат с меньшей точностью.
- GGUF — файловый формат, который хранит тензоры и метаданные для GGML- и
llama.cpp-подобных рантаймов. Файл GGUF может содержать неквантизованные типы тензоров, напримерF16,BF16илиF32, а также квантизованные encoding. Доступные пресеты включаютQ4_K_M,Q5_K_M,Q8_0,IQ*,TQ*иMXFP4. Выбранный tensor encoding определяет вариант квантизации. Сам по себеGGUFне описывает serving-рецепт CUDA в формате FP8 W8A8. - KV cache — это кэш аттеншна, используемый во время генерации. В нем хранятся предыдущие keys и values, чтобы модель не пересчитывала весь диалог при генерации каждого токена.
- Квантизация KV cache сохраняет кэшированные activation-тензоры key/value в формате с меньшей точностью — например, FP8, INT8, INT4 или INT2, в зависимости от поддержки рантайма. Это отличается от prefix caching, PagedAttention и offload: они определяют, переиспользуются ли записи кэша, как они выделяются и где хранятся.
- GEMM означает general matrix multiply — умножение матриц общего вида. Большая часть времени инференса трансформера уходит на умножение матриц.
2. Квантизация — это управляемое округление
Квантизация отображает значения высокой точности в меньшее множество представимых значений — это базовое определение, используемое и в концептуальном руководстве по квантизации Hugging Face Optimum, и в TensorRT-LLM. Вы экономите память и пропускную способность, но вносите ошибку округления.
INT4 предоставляет лишь 16 дискретных значений, поэтому отображение весов BF16 на эту сетку создает ошибку округления. Методы вроде GPTQ, AWQ и SVDQuant направлены на сохранение выбросов и снижение ошибки реконструкции. Хорошее отображение экономит память с небольшой потерей качества. Плохое ухудшает ризонинг, следование инструкциям или визуальную достоверность.
Симметричное и асимметричное отображение
Согласно affine mapping, используемому в распространенных руководствах по квантизации, квантизация отображает непрерывное float-значение на дискретную сетку.
- — исходное значение высокой точности.
- — квантизованное значение.
- — scale, или размер шага.
- — zero point, целочисленная позиция, представляющая
0.0. - — целевой диапазон целых чисел. Знаковые 4-битные значения часто используют .
Симметричная квантизация центрирует сетку вокруг нуля и задает :
Это удобно для железа, поскольку runtime-математике не нужно вычитать смещение zero point. Стек квантизации PyTorch предоставляет эти affine scale и zero-point параметры как примитивные параметры квантизации в torchao.
Асимметричная квантизация сдвигает сетку, чтобы покрыть скошенные диапазоны:
Такая сдвинутая сетка лучше сохраняет активации, принимающие только положительные значения, но смещение добавляет вычисления, если ядро не обрабатывает его эффективно.
Гранулярность scale имеет значение
Scale-фактор может охватывать весь tensor весов, один канал или небольшую группу значений. В документации vLLM по FP8 KV cache используется то же различие между стратегиями scale per-tensor и per-attention-head. Меньшие группы обычно лучше сохраняют качество, но требуют больше метаданных scale.
| Гранулярность scale | Что использует один scale | Влияние на качество и выполнение |
|---|---|---|
| Per tensor | Вся матрица весов | Требует мало метаданных, но один выброс может растянуть сетку и снизить точность по всему слою. |
| Per channel | Одна выходная строка | Не дает каналам с узкими диапазонами делить широкий диапазон другого канала. Многие 8-битные пути для весов используют такую гранулярность. |
| Per group | Блок в строке, обычно 64 или 128 значений | Ограничивает влияние выброса небольшим блоком ценой дополнительных scale. AutoGPTQ использует group_size=128 в своих примерах GPTQ. |
Веса статичны, поэтому их scale можно вычислить offline до загрузки модели. Активации меняются с каждым токеном, поэтому их диапазоны зависят от workload.
| Масштабирование активаций | Когда runtime выбирает scale | Преимущество | Режим сбоя или стоимость |
|---|---|---|---|
| Static | Offline на основе датасета для калибровки | Не требует вычислять scale во время инференса. | Промпты за пределами калиброванной длины или распределения могут обрезать пики активаций и ухудшить вывод. |
| Dynamic | Во время каждого forward pass | Адаптируется к текущим значениям активаций и смеси промптов. | Вычисление диапазонов на каждом слое добавляет нагрузку и требует оптимизированных ядер. |
KV cache занимает промежуточное положение. Keys и values изначально являются runtime activation-тензорами: каждый слой вычисляет их из hidden states во время forward pass. После генерации они перестают быть временными промежуточными результатами matmul и становятся persistent serving state, который attention считывает при обработке следующих токенов.
Serving engine может хранить это состояние в формате меньшей точности и держать scale-метаданные рядом с ним. Quantized KV Cache в vLLM, FP8 KV Cache в TensorRT-LLM и Transformers QuantizedCache предоставляют такую настройку.
Точность хранения кэша остается отдельной от точности активаций внутри linear-ядер. «Квантизация KV cache» обозначает одну оптимизацию кэша, а не все методы повторного использования, выделения или перемещения записей кэша.
PTQ и QAT выполняются на разных этапах
Post-training quantization, или PTQ, сжимает уже обученную модель. Quantization-aware training, или QAT, знакомит модель с шумом квантизации во время обучения, чтобы она могла адаптироваться.
| Метод | Когда изучаются диапазоны | Используйте, когда | Цена |
|---|---|---|---|
| Weight-only PTQ | Offline для статичных весов | Модель не помещается в память или decode упирается в bandwidth | Активации по-прежнему выполняются в 16-битном формате |
| Static PTQ | Offline на основе калибровочных промптов | Нужен быстрый W8A8-serving | Калибровочные данные должны соответствовать production-трафику |
| Dynamic PTQ | Runtime, для каждого batch или activation path | Распределения входов сильно различаются | Дополнительная runtime-нагрузка и более узкая поддержка железа |
| QAT | Во время обучения | PTQ ломает качество чувствительной модели | Полная инфраструктура обучения и намного больше вычислений |
Калибровочные данные должны быть похожи на трафик, который вы будете обслуживать. Например, путь калибровки KV cache в vLLM использует подготовленный датасет через llm-compressor. Если production-промпты — это длинные RAG-трейсы, короткие абзацы из Wikipedia дадут аккуратные цифры на бенчмарке и сломанный деплой. Калибровка выбирает статичные scale и диапазоны активаций или кэша на основе распределения коротких текстов; она не настраивает фиксированные параметры модели. Реальные промпты с длинным контекстом могут порождать другие паттерны активаций. Оценки квантизации на длинном контексте напрямую измеряют этот риск.
3. Числовые форматы определяют требования к железу
Числовой формат определяет, какие значения модель может представлять в памяти. Для эффективных вычислений нужны runtime-ядра и аппаратная поддержка той же разрядности и формата. TensorRT-LLM документирует и список рецептов, и матрицу поддержки железа.
| Формат | Хранение одного значения | Хороший вариант по умолчанию | Основной риск |
|---|---|---|---|
| BF16 / FP16 | 2 байта | Базовый инференс и сервинг, совместимый с обучением | Высокое потребление VRAM и большой трафик памяти |
| FP8 | 1 байт | Высокопроизводительный W8A8-serving на Ada, Hopper, Blackwell | Нужны нативные FP8 tensor cores и поддержка рантайма |
| INT8 | 1 байт | W8A8-serving на старом железе или hardware не от NVIDIA | Выбросы активаций и чувствительность к статичной калибровке |
| INT4 | 0,5 байта | W4A16, когда основное ограничение — память под веса | Потеря качества на небольших моделях и моделях с тяжелым ризонингом |
| FP4 / NVFP4 | ~0,5 байта | Эксперименты эпохи Blackwell и ранние serving-пути | Специфичные для железа требования к компилятору и рантайму |
| Кодировки / пресеты llama.cpp GGUF | Переменный | Локальный инференс на CPU, Apple Silicon, десктопах и edge | GGUF — контейнер. Tensor encoding — это выбор квантизации. |
| NF4 | 0,5 байта | Обучение адаптеров через QLoRA | Обычно неподходящий формат экспорта для production-serving |
BF16 и FP16 используют по 16 бит, но распределяют точность по-разному и поэтому по-разному выходят из строя. BF16 сохраняет 8-битный диапазон экспоненты FP32 и реже переполняется. FP16 имеет больше бит мантиссы и более узкий диапазон экспоненты, поэтому пики активаций требуют большего внимания. В оценке Kurtic et al. BF16 явно используется как baseline при сравнении FP8-, INT8- и INT4-форматов сервинга.
У FP8 есть два распространенных варианта. E4M3 дает более высокую точность и обычно используется для forward-весов и активаций. E5M2 предоставляет больший динамический диапазон и лучше подходит для градиентов или нестабильных activation path. vLLM предоставляет оба dtype для FP8 E4M3 и E5M2 KV cache. В исследовании Kurtic et al. на ACL 2025, «Give Me BF16 or Give Me Death», FP8 W8A8 оказался практически lossless для семейства Llama-3.1 более чем на 500 000 оценок. Результат относится к этому семейству моделей, набору оценок и конфигурации сервинга. Для каждого деплоя по-прежнему нужен собственный quality gate.
Blackwell добавляет microscaling-форматы, такие как MXFP8 и NVFP4. Вместо одного scale для всего тензора или строки microscaling использует очень маленькие блоки. Объяснение NVFP4 от NVIDIA описывает 4-битные floating-point-значения в блоках по 16 элементов, с FP8 scale-факторами и scale верхнего уровня FP32. Такой подход должен обеспечить footprint, близкий к INT4, сохранив поведение floating point. Однако для него нужны соответствующая архитектура железа, компилятор и поддержка рантайма, поэтому TensorRT-LLM перечисляет поддержку FP4 и FP8 по поколениям GPU.
4. Weight-only и weight-activation квантизация
Обозначение WxAy описывает точность весов и активаций, которые по-разному нагружают GPU во время инференса.
На этапе prefill модель обрабатывает входной промпт. Этот этап обычно упирается в вычисления, поскольку GPU выполняет большие умножения матриц; поэтому рецепты W8A8 FP8/INT8 важны для сервинга, ориентированного на throughput.
На этапе decode модель генерирует по одному токену за раз. Этот этап часто упирается в пропускную способность памяти: GPU постоянно загружает веса из VRAM, чтобы получить следующий токен. Weight-only-методы вроде GPTQ и AWQ снижают это давление, уменьшая объем весов в байтах.
W4A16 сжимает веса, но оставляет активации в BF16 или FP16. GPU загружает меньше байтов весов, а затем деквантизует их обратно в формат более высокой точности для умножения. Это помогает при decode и проблемах с размещением модели в памяти. Вычислительно-зависимый prefill может почти не выиграть, поскольку математика по-прежнему выполняется в 16-битном формате.
W8A8 сжимает веса и activation-тензоры, используемые поддерживаемыми matmul-ядрами. Если железо имеет нативные tensor cores для вычислений низкой точности, serving engine может выполнять математику матриц напрямую в FP8 или INT8. Поэтому FP8 может ускорить high-throughput serving, снижая трафик памяти и используя более быстрые вычисления. KV cache имеет собственную настройку хранения, поэтому отдельно проверьте cache dtype или cache implementation рантайма.
Если модель едва помещается в VRAM, начните с weight-only квантизации, чтобы уменьшить footprint. Если модель помещается, но испытывает проблемы с throughput при больших batch, оцените FP8 или INT8 W8A8 для ускорения вычислительной фазы. Если проблемы с памятью возникают только в длинных диалогах, сначала оцените слагаемое KV cache. Проверьте квантизацию KV cache, если оно доминирует. Включайте prefix caching, если доминируют повторяющиеся префиксы.
5. Алгоритмы и runtime-ядра
Алгоритмы квантизации, такие как GPTQ и AWQ, определяют, как веса модели отображаются в формат меньшей точности. Runtime-ядра, такие как Marlin или кастомные ядра vLLM, — это низкоуровневый GPU-код, выполняющий умножение матриц. Сильно сжатая модель будет работать быстро только при наличии оптимизированного ядра для конкретного формата квантизации.
Бенчмарк vLLM от JarvisLabs для Qwen2.5-32B-Instruct на NVIDIA H200 наглядно показывает влияние ядра:
| Квантизация / ядро | 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 |
Не переносите эти числа напрямую на свой стек. Они получены для одной модели, одного класса GPU и одной программной конфигурации. Они показывают более узкий вывод: название алгоритма в чекпоинте не говорит, насколько быстрым будет сервинг.
Например, AWQ и Marlin-AWQ используют одинаковые 4-битные веса. Реализация Marlin намного быстрее, потому что ее CUDA-ядро объединяет деквантизацию и умножение матриц в одну высокооптимизированную операцию GPU.
Бенчмарк baseline и сжатых вариантов на одной и той же смеси промптов и одним и тем же инструментом. Запускайте каждый вариант как сервер и задавайте ему стабильное API-имя модели; vllm bench serve отправляет запросы в этот API, а не загружает чекпоинт самостоятельно:
vllm serve ./outputs/Qwen2.5-32B-Instruct-AWQ-W4A16 \
--served-model-name qwen2.5-32b-awq \
--host 127.0.0.1 \
--port 8000
vllm bench serve \
--backend openai \
--base-url http://127.0.0.1:8000 \
--endpoint /v1/completions \
--model qwen2.5-32b-awq \
--dataset-name sharegpt \
--num-prompts 200 \
--input-len 1024 \
--output-len 256
Отслеживайте throughput, TTFT, межтокенную латентность, использование памяти и качество на задачах. Если часть показателей движется в противоположных направлениях, именно этот trade-off нужно увидеть до выхода в production.
Меню алгоритмов
Используйте эту таблицу как карту, а не как рейтинг:
| Алгоритм | Распространенный формат | Что стремится сохранить | Основная стоимость |
|---|---|---|---|
| GPTQ | W4A16 | Послойную реконструкцию с оценками Hessian | Медленная калибровка и более сложная обработка |
| AWQ | W4A16 / W4A8 | Важные activation-каналы | Нужны калибровка и fused serving-ядра |
| SmoothQuant | W8A8 | Поведение активаций INT8 за счет переноса масштаба выбросов в веса | Настройка scale для каждой модели |
| QuaRot / SpinQuant | W4A4 / W4A8 | Снижение давления activation-выбросов через rotations | Сложность runtime-rotation |
| HQQ | W4A16 / W2A16 | Быстрое weight-only-сжатие без калибровки | На очень низкой разрядности качество требует downstream-проверок |
| QLoRA (NF4) | NF4 | Память для обучения адаптеров | Не лучший вариант по умолчанию для сервинга |
| K-quants / IQ-quants в llama.cpp GGUF | Смешанные tensor encoding низкой разрядности | Качество локального инференса на байт | Не предназначены для облачного batch-serving |
Toolchain активно развивается. AutoGPTQ был переведен в архив в апреле 2025 года, а AutoAWQ — переведен в архив и официально deprecated в мае 2025 года. Для новых чекпоинтов compressed-tensors, используемых через vLLM, начинайте с llm-compressor. Используйте GPTQModel, если нужен актуальный GPTQ-путь с Marlin, Machete, memory-опциями для MoE или disk offload.
Pruning и distillation также снижают стоимость сервинга через отдельные workflow. Структурированная разреженность 2:4 удаляет веса по шаблону, который могут использовать sparse tensor cores NVIDIA. Distillation обучает меньшую student-модель имитировать большую и может хорошо работать на узких задачах. Включайте любой из этих вариантов в shortlist только при готовности проекта к дополнительной pruning- или training-работе.
6. Память для сервинга — это не только веса
Сжатый чекпоинт — лишь часть footprint памяти для сервинга. Перед тем как решать, достаточно ли квантизации весов, оцените весь runtime. PagedAttention показывает, что KV cache — один из главных компонентов serving-памяти.
Offline-квантизация может выполняться послойно. Инструменты вроде llm-compressor загружают один transformer-блок, выполняют калибровку и математику квантизации, записывают сжатый блок и переходят к следующему. Пиковое потребление GPU-памяти при этом ближе к размеру крупнейшего активного слоя плюс калибровочные буферы. CPU RAM и диск для исходного чекпоинта все равно нужны, но GPU не обязательно хранит всю модель BF16.
Пиковое потребление GPU-памяти во время offline-квантизации может выглядеть так:
Сервинг предъявляет более жесткие требования. Весь сжатый чекпоинт должен постоянно находиться в памяти вместе с KV cache и runtime-буферами. KV cache растет вместе с длиной контекста и размером активного batch:
Где:
- — число слоев.
- — число key-value attention heads. Grouped-query attention уменьшает его, позволяя множеству query heads совместно использовать меньшее число KV heads.
- — размерность каждой head, обычно 128 или 256.
- — число токенов промпта плюс число сгенерированных токенов.
- — активный serving batch.
- — 2 для BF16 или FP16 и 1 для FP8 или INT8. Режим FP8 KV cache в vLLM — serving-пример, используемый в этой статье.
Квантизация KV cache меняет хранение, а reuse — аллокацию
KV cache можно квантизовать во время инференса. На каждом шаге decode для нового токена создаются K- и V-activation-тензоры. Модель W8A8 может уже использовать FP8 или INT8 для поддерживаемой projection-математики, но кэш остается отдельным storage-объектом.
Многие serving-стеки хранят этот объект в dtype модели или кэша. Чтобы изменить его, включите KV-cache dtype, используйте чекпоинт с cache scale или выберите реализацию квантизованного кэша.
При включенной квантизации KV cache engine записывает записи как представление меньшей точности плюс scale. При последующем attention кэш либо деквантизуется внутри ядра, либо на некоторых бэкендах часть операции attention выполняется в квантизованном домене.
Стабильная документация Quantized KV Cache в vLLM напрямую предоставляет эту настройку через kv_cache_dtype="fp8" или --kv-cache-dtype fp8. vLLM поддерживает форматы кэша FP8 E4M3 и E5M2, а также стратегии scale per-tensor и per-attention-head. Можно использовать scale по умолчанию или калибровку по датасету через llm-compressor. С FlashAttention 3 vLLM также может выполнять операции attention в домене FP8, квантизуя query в дополнение к key и value.
TensorRT-LLM предоставляет FP8 KV cache через KvCacheConfig(dtype='fp8') и перечисляет FP8 KV cache и NVFP4 KV cache как отдельные quantization recipes, отличные от квантизации весов и активаций. В Hugging Face Transformers также есть путь QuantizedCache через cache_implementation="quantized": hqq поддерживает форматы кэша int2, int4 и int8, а quanto — int2 и int4.
Обычный KV caching сохраняет предыдущие keys и values, чтобы не пересчитывать их. Prefix caching повторно использует блоки кэша между запросами с одинаковым префиксом. PagedAttention уменьшает фрагментацию и улучшает аллокацию, а KV offload перемещает блоки кэша между уровнями памяти. Совместимость этих комбинаций зависит от рантайма. QuantizedCache в Hugging Face не поддерживает offloading. vLLM документирует квантизованный KV cache отдельно от prefix caching и других функций управления кэшем. Проверяйте каждую комбинацию в рантайме, который будете деплоить.
Риск для качества здесь отличается от weight-only PTQ. Квантизация KV cache вносит ошибку в состояние attention, считываемое на каждом последующем шаге decode. Отдельно тестируйте retrieval в длинном контексте, поведение в многоходовых диалогах, безопасность и отказы, форматирование tool use и латентность вывода. KVQuant, KIVI и исследование FP8 KV cache в vLLM рассматривают квантизацию KV cache как отдельную задачу.
Размер модели и длина контекста сами по себе не определяют, превзойдет ли сжатие кэша еще один раунд сжатия весов. Вычислите байты кэша по приведенному выше уравнению, используя число KV heads модели, размерность head, активный batch и dtype кэша. Затем сравните результат с объемом памяти, сэкономленным при переходе между двумя конкретными форматами весов, например BF16 и INT4. Если кэш больше, тестирование квантизации KV cache в FP8 может освободить больше serving-памяти, чем дальнейшее уменьшение весов.
7. Железо сужает выбор
Footprint весов легко оценить по числу параметров и точности хранения — тот же подход к 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 всего | ~109 GB | ~55 GB |
MoE-модели могут активировать меньше параметров на токен, но полный набор весов все равно должен где-то находиться, если только рантайм не поддерживает offload. Матрица поддержки квантизации TensorRT-LLM рассматривает семейства MoE-моделей как отдельные deployment targets со своими поддерживаемыми рецептами.
Железо деплоя ограничивает жизнеспособные форматы квантизации:
- Сервинг на CPU зависит от vector instructions, таких как AVX-512 или AMX. Файл GGUF, загружаемый через
llama.cpp, — практичный вариант. - Apple Silicon использует unified memory, поэтому локальные модели могут занимать большой общий пул RAM вместо выделенной VRAM. GGUF и
llama.cppостаются распространенным путем для локального рантайма, поскольку GGUF создан для GGML-экзекьюторов. - NVIDIA Ampere поддерживает serving-пути с INT8 tensor cores, но не нативную FP8 W8A8-математику на tensor cores. Распространенные варианты — weight-only квантизация W4A16 или статичный INT8, что соответствует матрице поддержки железа TensorRT-LLM.
- NVIDIA Ada и Hopper поддерживают FP8-serving в TensorRT-LLM. FP8 W8A8-serving стоит протестировать на этих GPU.
- NVIDIA Blackwell добавляет поддержку NVFP4 и microscaling, но программный путь по-прежнему важен. Считайте ранние стеки floating point низкой разрядности чувствительными к версии.
8. Калибровка и оценка перед деплоем
Модель, которая загрузилась, прошла smoke test. Для деплоя нужны проверки качества и сервинга на целевом workload. Современные оценки квантизации показывают разные результаты для сервинга LLM, задач с длинным контекстом и моделей с тяжелым ризонингом.
Для калибровки используйте промпты, похожие на production-трафик:
- Включайте RAG-трейсы, SQL-запросы, истории агентов, кодинговые задачи, payload tool call и системные промпты из целевого workload. Static PTQ зависит от соответствия калибровочных данных production-распределению.
- Сопоставляйте длины последовательностей. Короткие одноповоротные промпты не проявят поведение активаций в длинном контексте.
- Оставляйте
embed_tokensиlm_headв формате более высокой точности, если это позволяет метод или runtime; это распространенный паттерн исключения в рецептах LLM Compressor. - Используйте достаточно примеров, чтобы стабилизировать диапазоны активаций. В примере KV cache для vLLM задано
NUM_CALIB_SAMPLES = 512. Считайте это одним документированным примером, а не универсальным числом. Подходящее количество примеров зависит от метода, модели, длины последовательности и production-workload. - Перед использованием production-логов удаляйте секреты и приватные пользовательские данные.
При оценке проверяйте и языковое качество, и поведение сервинга:
- Perplexity на стандартном корпусе выявляет общую деградацию языка, но бенчмарк JarvisLabs напоминает, что perplexity и throughput могут изменяться независимо.
- Доменные задачи выявляют сбои, которые скрывает perplexity. Используйте HumanEval для кодинга, MMLU для общих знаний и AIME или MATH-500 для математического ризонинга, если эти домены важны.
- Для агентных систем важны проверки формата. Тестируйте соответствие JSON Schema, markdown-вывод, форму tool call и поведение отказа, поскольку оценки квантизованных моделей могут не заметить application-level сбои, даже когда агрегатная точность на бенчмарке остается стабильной.
- Тесты длинного контекста выявляют ущерб от квантизации KV cache. Needle-in-a-haystack — грубый тест, но результаты квантизации на длинном контексте показывают, почему такие проверки должны входить в deploy gate.
- В load tests нужно отчитываться о throughput, TTFT, межтокенной латентности, максимальной емкости batch и пиковой памяти. vLLM предоставляет эти измерения через
vllm bench serve.
Модели с тяжелым ризонингом оценивайте особенно тщательно. Квантизация sub-4-bit или W4A4 без rotations может ухудшить точность ризонинга, даже если baseline perplexity остается стабильной; это основной вывод исследования reasoning-моделей после квантизации.
9. Workflow companion-репозитория
Companion-репозиторий slavadubrov/model-compression-demo предназначен для воспроизводимости процесса принятия решений. Он использует uv и фокусируется на планировании, рецептах, dry run и конфигурациях бенчмарков, основанных на тех же источниках, что и эта статья: vLLM, LLM Compressor, TensorRT-LLM и статьях об алгоритмах.
Публичный README на ревизии 8b45003849e830bed2ff341a9f027b017d932c1f проверен 16.08.2026. Companion checkout отсутствует в этом workspace, поэтому я не мог запустить его CLI здесь. Приведенные ниже команды являются иллюстративными, пока вы не запустите их из этого зафиксированного checkout; кроме того, план бенчмарка по-прежнему требует целевого железа для сервинга.
Не копируйте результат FP8-рецепта из этой зафиксированной ревизии. Ее команда recipe --algorithm fp8-dynamic создает внутренне несовместимые model и output path. Команда намеренно не приведена здесь, пока companion не будет исправлен.
Склонируйте репозиторий и изучите поддерживаемые алгоритмы:
git clone https://github.com/slavadubrov/model-compression-demo.git
cd model-compression-demo
git checkout 8b45003849e830bed2ff341a9f027b017d932c1f
uv run python demo.py list-algorithms
Начните с планирования и 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
Затем сгенерируйте рецепт и выполните 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
Для планирования сервинга и бенчмарков:
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
Наконец, сравните базовую и сжатую модели с явными порогами:
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
Выполняйте работу по порядку: спланируйте целевой вариант, оцените память, выполните dry run рецепта, проведите бенчмарк сервинга, затем сравните качество с порогами. Эта последовательность отражает разделение, описанное в статье между оценкой памяти, бенчмаркингом рантайма и оценкой качества.
10. Для diffusion-моделей нужен отдельный путь
Diffusion- и diffusion-transformer-пайплайны имеют другое поведение активаций, чем авторегрессионные LLM. SVDQuant рассматривает квантизацию diffusion как отдельную задачу, связанную с activation-выбросами.
Авторегрессионные LLM генерируют по одному токену за раз. Diffusion-модели выполняют повторяющиеся шаги денойзинга, и распределения их активаций меняются в процессе. Стандартный 4-битный проход квантизации для LLM может уменьшить память diffusion-модели, но при этом создать сильные визуальные артефакты. Специализированные для diffusion методы, такие как SVDQuant / Nunchaku и квантизация diffusion в NVIDIA ModelOpt, учитывают это иное поведение активаций.
Используйте следующие консервативные эвристики, а не универсальные настройки по умолчанию. Каждый пайплайн, компонент, модель и runtime требуют отдельных тестов:
- На первом сравнении оставьте VAE в 16-битном формате. Эта консервативная эвристика уменьшает один из источников артефактов изображений. Переходите к меньшей точности только после валидации метода и целевого пайплайна.
- Сначала попробуйте DiT или U-Net backbone, поскольку на него часто приходится наибольшая доля параметров. Это эвристика, поэтому проверьте память, латентность и качество изображений для целевого пайплайна. Методы квантизации diffusion используют такой же покомпонентный подход.
- Обрабатывайте text encoders отдельно. Квантизация T5-XXL или CLIP может повлиять на соответствие промпту или рендеринг текста в конкретном пайплайне, поэтому оценивайте их независимо, не предполагая поведения обычного трансформера.
- Используйте diffusion-aware методы, такие как SVDQuant, когда основной проблемой являются activation-выбросы.
- Оценивайте результат по изображениям, а не по текстовым метрикам. Проверяйте соответствие промпту, рендеринг текста, оттенки кожи, цветовой баланс, мелкие детали, латентность и VRAM.
Если в evaluation set есть только простые или распространенные промпты, вы пропустите edge-case-сбои. Добавляйте сложные случаи: мелкий текст, руки, повторяющиеся объекты, структурированные макеты и промпты с negative constraints, поскольку сбои квантизации diffusion проявляются визуально, а не в perplexity языковой модели.
11. Production-настройки по умолчанию
Для enterprise-сервинга LLM начните с baseline BF16 в том же serving engine, который планируете использовать. Если цель — throughput и железо это поддерживает, протестируйте FP8 W8A8. Если модель не помещается, протестируйте AWQ или GPTQ W4A16 с ядрами класса Marlin. Если проблема в длинном контексте или конкурентности, протестируйте квантизацию KV cache в FP8. Если проблема в повторяющихся префиксах, дополнительно включите prefix caching. Выпускайте сжатую версию только после прохождения и quality-, и serving-бенчмарков.
Для локального и edge-инференса начните с файла GGUF, используя Q4_K_M или Q5_K_M. Если память позволяет и качество важнее footprint, переходите на Q8_0 GGUF. Переход ниже 4 бит — крайняя мера, а не вариант по умолчанию.
Для файн-тюнинга используйте NF4 с QLoRA, чтобы дешево обучать адаптеры. Оцените адаптер в приложении до объединения. После объединения экспортируйте его в реально нужный serving-артефакт: совместимый с llama.cpp файл GGUF, AWQ/GPTQ/compressed-tensors-чекпоинт, FP8-serving-чекпоинт или BF16.
Для diffusion начните с этих консервативных эвристик и визуально протестируйте каждую комбинацию пайплайна, модели и рантайма. Текстовая perplexity не покажет, сломался ли image-пайплайн, поэтому используйте diffusion-специфичные свидетельства, такие как SVDQuant, и визуальную оценку.
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, Quantization. Docs.
- vLLM Quantized KV Cache Docs: проект vLLM, Quantized KV Cache. Docs.
- vLLM Benchmark Docs: проект vLLM, vllm bench serve. Docs.
- LLM Compressor Docs: проект vLLM, 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: локальный runtime-моделей Ollama. Website.
- LM Studio: локальный AI-runtime LM Studio. Website.
- AutoGPTQ status: репозиторий AutoGPTQ, архивирован в апреле 2025 года. GitHub.
- AutoAWQ status: репозиторий AutoAWQ, архивирован и deprecated в мае 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 и llama.cpp. GGUF, llama.cpp.
- Hugging Face GGUF Docs: Hugging Face, GGUF. Docs.
- Reference Repository: slavadubrov/model-compression-demo.