[Перевод] Разбираемся с суффиксами квантования LLM: что на самом деле значат Q4_K_M, Q6_K и Q8_0

Привет!
Задумывались, какую версию квантованной LLM выбрать: Q4_K_M, Q6_K или Q8_0? Насколько Q6_K хуже справляется с задачами по сравнению с Q8_0? И что вообще означают все эти буквы в суффиксах?

Примечание: это адаптированный перевод моей статьи на Medium. Перевод был сделан при помощи мозга, а не нейросетей или Google Translate.

Типичные муки выбора при загрузке квантованной LLM с Hugging Face
Типичные муки выбора при загрузке квантованной LLM с Hugging Face

В статье разберёмся, что означают суффиксы вроде Q4_K_M, почему Q4 ≠ int4, и как не потеряться на собеседовании, если спросят про тонкости квантования.
Давайте разбираться!

Как понимать суффиксы

Квантование — это всегда компромисс между точностью, скоростью и размером модели. Суффиксы вроде Q4_K_M помогают быстро понять, в какую сторону сдвинут этот баланс.

Что значат суффиксы:

  • Q — означает, что модель квантована

  • Цифра после Q (например, Q4) — количество бит на один вес

  • K — группировка весов (каждая группа имеет свой scale и zero-point)

  • 0 — без группировки (устаревшая схема)

  • M — средняя точность

  • L — низкая точность, выше скорость, но ниже качество

Что именно значит группировка (K и 0), разберём чуть позже.

Суффикс высокой точности (например, H) обычно не используется — и на то есть причина. Отсутствие M или L означает, что используется наилучшая (дефолтная) точность для данной битности. Суффиксы M и L применяются только к 4- и 5-битным форматам. Начиная с 6 бит, точность уже близка к float, а ниже 4 — она всегда низкая, и нет смысла уточнять.

Итак, давайте разберём, что конкретно означает суффикс Q4_K_M:

  • Q4 — квантованная модель с 4-битными весами

  • K — группировка весов (по 64 и более), с индивидуальным масштабом

  • M — средняя точность (оптимальный баланс между качеством и размером)

Веса

Что означает, что на один вес приходится 4 или 8 бит? Веса — это числовые параметры, определяющие, насколько сильно каждый вход влияет на выход нейрона. Именно они участвуют в каждом шаге инференса: умножаются, складываются и передаются дальше по слоям модели.

Цифра перед b в названии модели (например, Gemini-12b) указывает, сколько миллиардов весов в ней. Например, в Gemini-12b — 12 миллиардов весов, и при генерации одного токена может использоваться от 1 до 12 миллиардов весов в разных слоях сети. При обучении веса обычно сохраняются в формате Float32 или Float16 — то есть занимают 32 или 16 бит каждый.

как хранится Float32 (источник: puntoflotante.net)
как хранится Float32 (источник: puntoflotante.net)

Использовать такие модели в изначальном виде невозможно на обычном железе. Чтобы сделать модели легче, был введён процесс квантования — перевод весов из float в int с меньшим числом бит. Идея простая - уменьшить количество бит, в которых хранится значение каждого веса.

Казалось бы, можно просто обрезать Float32 до Int4 — но это не работает:

int8(0.123456) = 0

Наивное округление обнуляет значение и полностью теряет информацию. Даже если извлечь только мантиссу, она всё равно будет слишком длинной, чтобы уложиться в 4–6 бит — и точность резко упадёт.

Поэтому вместо грубого округления используют масштабирование (scale), нулевую точку (zero point) и группировку.

Пример:

Оригинальные веса: [0.11, 0.09, 0.12, 0.10, ..., 0.15]
Scale = 0.005
Zero point = 0.08
Квантованные значения: [6, 2, 8, 4, ..., 14]

В момент инференса веса восстанавливаются так:

вес = scale * квант + zero_point

При деквантовании (переводе int значений назад во float во время инференса) квантованные 6, 2, 8 становятся:

Как видим, даже при 4 битах на вес можно достичь приличной точности — благодаря масштабированию и группировке.
💡 Вывод: при Q4 квантовании мы НЕ просто сжимаем 32- и 16- битовые Float в Int4 - мы сохраняем метаданные для каждой группы, которые позволяют нам восстанавливать числа с высокой степенью точности.

Группировка (K и 0)

Масштаб (scale) и нулевая точка (zero point) вычисляются отдельно для каждой группы весов. Это позволяет эффективно сжать значения весов до 4–6 бит при минимальной потере точности. Обычно веса делятся на группы фиксированной длины — например, по 64 элемента подряд.

Возникает логичный вопрос: подбираются ли веса в группы по схожести значений?
Нет. Группы формируются не по значению весов, а по их порядку в памяти (или в тензоре модели). Это сохраняет структуру модели и эффективно работает с памятью GPU. Например, квантизатор может просто взять первые 64 значения из тензора и сформировать из них одну группу.

иллюстративный тензор исключительно для примера
иллюстративный тензор исключительно для примера


Это и означает суффикс K: группировка весов, обеспечивающая более точное и адаптивное квантование.
Если вместо K указано 0 (например, Q4_0), значит используется упрощённая схема без группировки: общий scale применяется ко всему тензору (или строке тензора). Это быстрее, но менее точно.

Без группировки диапазон значений, покрываемый 4-битным квантованием, приходится распространять на весь тензор. Это снижает точность восстановления исходных весов.

💡 Вывод: если есть выбор между K и 0, почти всегда стоит выбирать K. Модели с 0 подойдут только при жёстких ограничениях по железу.

Вместо итогов

Эта статья — лишь базовое введение в тему квантования нейросетевых моделей. Мы не затрагивали более продвинутые техники, такие как QAT (quantization-aware training), а также различия между статическим и динамическим квантованием.

Тем не менее, даже простое понимание суффиксов вроде Q4_K_M, Q6_K и Q8_0 уже даёт практическую опору при выборе модели под ваше оборудование и задачи.

💡 Конечно, теория — это лишь начало.

Чтобы по-настоящему разобраться в квантованных форматах, надо попробовать их в деле. Скачайте модели (например Qwen или Gemma) в форматах Q4_K_M, Q6_K, Q8_0. Прогоните их на сложных промптах. Сравните скорость, стабильность, качество отклика. Понять все оттенки квантования можно только одним способом — пропустить их через собственное железо.