Квантование (Quantization): как сжать модели и вектора без критичной потери качества

Квантование — это снижение разрядности числовых представлений параметров и/или активаций нейросетей (например, с 16/32-бит с плавающей запятой до 8/4-бит целых форматов), чтобы уменьшить память, трафик и стоимость вычислений при исполнении модели в продакшне. На уровне продукта это один из главных рычагов эффективности: меньше ОЗУ/VRAM, выше пропускная способность, ниже задержка и счёт за вычисления на инференсе. Особенно заметен эффект в больших языковых моделях (LLM) и других авто-регрессионных системах на базе трансформерных моделей.

Квантование (Quantization): как сжать модели и вектора без критичной потери качества

Квантование бывает весовым (quantize weights), активаций (quantize activations) и смежных буферов (например, KV-кэш в генерации). Помимо моделей, часто квантуют векторные представления (эмбеддинги) и индексы, чтобы ускорить поиск и уменьшить стоимость хранения — это критично для больших корпусов и систем семантического поиска во векторных базах.

Зачем квантуют: экономика и инженерия

Ключевые эффекты:

  • Память и кэш: разрядность ×2–8↓ даёт кратную экономию VRAM/ОЗУ и выше hit-rate кэшей.
  • Пропускная способность: целочисленные ядра и более компактные тензоры повышают токены/сек и QPS.
  • Энергия и стоимость: меньше операций с плавающей запятой, меньше энергопотребление; проще масштабировать.
  • Доступность: крупные модели становятся исполнимыми на более дешёвом железе.

Компромисс — возможная деградация качества. Практика показывает: при аккуратных схемах INT8 дает близко к FP16 качество, INT4 требует хитростей (калибровки/учёта «выбросных» каналов), но радикально удешевляет прогон.

Базовые понятия: шкалы, нули и гранулярность

Квантование — это аппроксимация непрерывных значений конечным набором уровней. Математически используется линейная аффинная модель:

  • scale — множитель, переводящий целое число в реальное значение,
  • zero-point — смещение, выравнивающее «ноль» реального распределения к ближайшему целому.

Схемы:

  • Симметричное (zero-point = 0): проще и быстрее, часто применимо к весам.
  • Асимметричное: точнее для сдвинутых распределений (часто у активаций).
  • Per-tensor: одна шкала на весь тензор — дёшево, но грубо.
  • Per-channel: отдельная шкала на канал/строку — дороже, но точнее.
  • Group-wise: балансируем — одна шкала на группу каналов (например, по 64).

Для активаций полезны динамические шкалы (на лету по батчу), для весов — статические (фиксируются после калибровки/обучения).

Семейства подходов: PTQ vs QAT и гибриды

  • PTQ (Post-Training Quantization): квантуем готовую модель по калибровочному набору (несколько тысяч репрезентативных примеров). Быстро, дёшево, хороша для INT8; для INT4 нужны тонкие трюки (масштабирование каналов, outlier-обработка).
  • QAT (Quantization-Aware Training): обучаем с «встроенными» квантователями (фейковые квант-операции в графе). Дольше и дороже, но качество ближе к FP16 даже на малых битностях.
  • Гибриды: весовое квантование PTQ + «смягчение» активаций, донастройка небольшим числом шагов; локальные перетренировки проблемных слоёв; смешанные битности (например, INT8 для «хрупких» слоёв и INT4 для остальных).

Где «ломается» качество и как этого избежать

  • Выбросные каналы (outliers) в линейных слоях ломают глобальную шкалу. Решение: per-channel/group-wise шкалы, предварительное масштабирование каналов, «обнуление» особо шумных голов внимания.
  • Активации: широкие хвосты распределений. Решение: асимметричное квантование, динамические шкалы, клэмпинг (обрезка по перцентилям).
  • Нормализации/эмбеддинги: плохо переносят грубое квантование; иногда их оставляют в FP16/BF16.
  • KV-кэш: в авто-регрессии его объём растёт линейно с длиной контекста; INT8/INT4 кэш даёт большие выигрыши, но требует тестирования на деградацию.

Форматы и разрядности: что выбрать под сценарий

Формат Где применяют Качество (ориентир) Выигрыш по памяти Комментарии
FP16/BF16 Базовый прод-режим Эталон Хороший баланс скорость/качество
INT8 (W8A8 / W8A16) Универсально Близко к FP16 ~2× Хорошо поддерживается аппаратно
INT6 Эксперименты/ниши Небольшая деградация ~2.7× Реже поддерживается ядрами
INT4 (W4A16 / W4A8) LLM/инференс Заметный риск деградации без трюков ~4× Нужны калибровка и outlier-хаки
3-бит/тернар/бинар Научные/узкие Сильная деградация 5–16× Требуют спец-архитектур/обучения

Примечание: WkAx означает k-бит веса и x-бит активации. Смеси «W4A16» популярны, потому что квантовать активации сложнее, а весы дают большую экономию.

Квантование в LLM и трансформерах

Особенности:

  • Линейные проекции внимания (Q/K/V/O) и FFN-проекции — главные «пожиратели» памяти и FLOPs: они первые кандидаты на квантование.
  • Эмбеддинги/LayerNorm часто оставляют в FP16/BF16.
  • Групповая гранулярность (например, per-group на 64 канала) балансирует качество и производительность.
  • KV-кэш: INT8 кэш даёт большой прирост на длинных контекстах; для INT4 — осторожность и проверка задач (суммаризация, код и т. п.).

Практические паттерны:

  • Weight-only INT4/INT8 для линейных + активации в FP16 → дёшево и стабильно.
  • Outlier-Routing: отдельная обработка каналов с большими значениями (оставить их в FP16).
  • Смешанные битности: первые/последние слои и проекции внимания — в INT8, «толстый» FFN — в INT4.

Квантование активаций: боль и способы смягчить

  • Калибровка на репрезентативном распределении: прогоняем N батчей «как в проде», замеряем диапазоны и ставим scale/zero-point.
  • Перцентильный клэмпинг (например, 99.9%): режем хвосты, уменьшая динамический диапазон.
  • Сдвиг и масштаб (Smooth/Activation-aware): перераспределяем нагрузку между весами и активациями, чтобы уложиться в INT8/INT4 без «пересветов».
  • Динамическое квантование: шкалы вычисляются на лету; полезно на CPU-пайплайнах.

Эмбеддинги, индексы и поиск: квантовать можно (и нужно)

Квантование применимо не только к моделям, но и к векторным представлениям:

  • Скалярное INT8: хранить эмбеддинги в int8 с per-dim шкалами — быстро и дёшево; падение качества поиска часто умеренное.
  • PQ (Product Quantization): классический способ сильного сжатия больших коллекций (компромисс Recall/память).
  • IVF-PQ/гибриды: комбинируют кластеризацию и PQ, чтобы ещё уменьшить RAM у индексов.

Это сильно влияет на инфраструктуру RAG и рекомендательные системы. Для деталей по индексам и компромиссам см. базовые статьи про эмбеддинги и базы (см. «См. также»).

Калибровка: откуда взять данные и сколько нужно

  • Соберите срез реального трафика: 1–5 тыс. запросов/фрагментов обычно достаточно для INT8; для INT4 лучше 10–50 тыс.
  • Стратифицируйте по типам задач и длинам контекста.
  • Избегайте утечек приватных данных: анонимизируйте и фильтруйте PII до калибровки.
  • Ведите версионирование: какая выборка, какие шкалы, какое падение метрик.

Метрики качества квантования

Класс Метрики Что измеряем
Ядровые LLM-метрики Perplexity/accuracy на бенчах Глобальная деградация
Прикладные Pass@k/Exact-match/BLEU/ROUGE Задачи кода/суммаризации/QA
Поиск/индексы Recall@k, NDCG@k Влияние на RAG и рекомендации
Пользовательский UX Оценки/рейтинги/доля исправлений Жизненная полезность
Производство Цена/1k токенов, P50/P95 Экономику и SLA

Важно разводить офлайн и онлайн: офлайн-бенчи не всегда ловят мелкие, но важные для UX деградации.

Производительность: где «живут» выигрыши

  • Память/полосы: главное ограничение LLM — пропускная способность памяти; 8/4-бит радикально снижает трафик между памятью и ALU.
  • Аппаратные ядра: INT8 широко поддержан (CPU VNNI, GPU Tensor-ядра), INT4 — опционно, зависит от библиотеки и поколения железа.
  • Кёрнелы: специализированные операторы для int-матриц, кэш-дружелюбные раскладки (row-major/col-major/препакованные).
  • Совместимость с оптимизациями внимания: квантованные линейные слои часто сочетаются с flash-attention и GQA/MQA, но требуют проверок производительности.

Риски и безопасность

  • Дрейф распределений: если прод меняется относительно калибровки, шкалы «стареют» → пересчитать.
  • Погрешности в критических системах: для регуляторных/ризиковых кейсов оставляйте «хрупкие» узлы в FP16.
  • Атаки на квантованную модель: adversarial-шумы могут искажать разряжённые представления — применяйте фильтры и детекторы.
  • Лицензии/данные калибровки: не используйте приватные данные без прав; храните обезличенные срезы.

Пошаговый чек-лист внедрения

  • Опишите целевые метрики качества и экономики (P95, токены/сек, цена/1k токенов, Recall@k).
  • Выберите гранулярность: per-tensor/per-channel/group-wise; симметрия для весов, асимметрия для активаций.
  • Соберите калибровочную выборку, зафиксируйте версию и состав.
  • Начните с INT8 весов и (при необходимости) активаций; измерьте качество.
  • Точечно переведите «дорогие» слои в INT4, оставив хрупкие в INT8/FP16.
  • Проверьте KV-кэш в INT8/INT4 на длинных контекстах.
  • Запустите онлайн-эксперимент (A/B), смотрите UX и расходы.
  • Автоматизируйте перекалибровку при дрейфе входных данных.
  • Включите логирование: версия шкал, кёрнелов, падение метрик, экономия ресурсов.
  • Задокументируйте путь отката на FP16/BF16.

Таблица: схемы квантования и компромиссы

Схема Где уместна Плюсы Минусы
PTQ INT8 (W8A8/W8A16) Универсальный старт Быстро, аппаратно поддержано Иногда деградация на хвостах
QAT INT8 Узкие требования к качеству FP16-близкое качество Дороже по обучению
Weight-only INT4 (A16) LLM-инференс ~4× память↓, просто в проде Риск падения без калибровки
Mixed-precision (INT4/INT8/FP16) Прод-компромиссы Баланс качества/цены Сложнее оркестрация
KV-кэш INT8/INT4 Длинные контексты Сильная экономия памяти Потенциальная деградация
Эмбеддинги INT8 / PQ Векторные БД Хранение×10–16↓ Потери Recall@k/NDCG@k

Таблица: ориентиры экономии

Что квантуем Разрядность Экономия памяти Влияние на скорость Комментарии
Веса LLM FP16 → INT8 ~2× + Часто «бесплатно» по качеству
Веса LLM FP16 → INT4 ~4× ++ Нужны трюки с outliers
Активации FP16 → INT8 ~2× + Требует калибровки
KV-кэш FP16 → INT8 ~2× ++ на длинном контексте Критично для длинных диалогов
Эмбеддинги FP32 → INT8 ~4× ++ (I/O↓) Проверяйте Recall@k
Индексы (PQ) FP32 → PQ 10–16× ++ Тюнинг кодбуков обязателен

Частые ошибки и анти-паттерны

  • Одна шкала на всё: per-tensor на «неровных» слоях убивает качество — берите per-channel/group-wise.
  • Без калибровки: INT8/INT4 «наугад» приводит к случайным деградациям.
  • Квантовать всё: оставьте эмбеддинги/LayerNorm в FP16, если падают метрики.
  • Оценивать только офлайн: без A/B легко «не заметить» UX-регресс.
  • Нет плана отката: меняйте разрядности конфигом, а не пересборкой всего сервиса.

FAQ

INT8 всегда безопаснее INT4? Как правило — да: INT8 ближе к FP16 по качеству и лучше поддержан. INT4 даёт больше выигрыша по памяти, но требует тщательной калибровки и смешанных схем.

Нужно ли квантовать активации? Не всегда. Часто достаточно кванта весов + FP16 активации. Квантование активаций усложняет жизнь и требует хорошей калибровки.

Что делать с деградацией на отдельных задачах? Локально верните проблемные слои в INT8/FP16, примените per-channel и перераспределение шкал; увеличьте выборку калибровки.

Можно ли квантовать только KV-кэш? Да, это даёт большую экономию на длинных контекстах. Но обязательно проверяйте задачи с длинной памятью (суммаризация, диалог).

Как квантование влияет на RAG? Через две плоскости: скорость/стоимость генерации и качество поиска (если квантуете эмбеддинги/индексы). Следите за Recall@k/NDCG@k.

Нужно ли делать QAT для продакшна? Только если PTQ не держит нужные метрики. QAT дороже и дольше, но иногда незаменим для критичных KPI.

Словарь терминов

  • Квантование (quantization) — понижение разрядности численных представлений весов/активаций/векторов.
  • PTQ/QAT — пост-тренировочное и «осведомлённое о квантовании» обучение.
  • scale / zero-point — параметры линейной аппроксимации float → int и обратно.
  • Per-tensor / per-channel / group-wise — гранулярность шкал.
  • Outliers — выбросные каналы/значения, ломающие глобальные шкалы.
  • KV-кэш — буфер ключей/значений внимания в авто-регрессии.
  • PQ (Product Quantization) — способ сжатия эмбеддингов/индексов в векторном поиске.

См. также

Инференс Большие языковые модели (LLM) Трансформер (Transformer) Эмбеддинги Векторная база данных Стек инференса LLM

Task Runner