Transformers documentation
Понятия квантования
Понятия квантования
Квантованное число может принимать лишь одно из небольшого набора значений: 256 для int8 и 16 для int4, поэтому любой метод квантования вносит ошибку округления. Методы различаются тем, как они предотвращают ухудшение выходных данных модели из-за этой ошибки. На этой странице объясняются решения, лежащие в основе этих различий: как числа отображаются на этот небольшой набор, какие тензоры подвергаются квантованию, какие типы данных используются и когда происходит квантование.
Если вы только начинаете знакомиться с квантованием в Transformers, начните с Обзора.
Сокращение разрядности значений
Квантование отображает диапазон значений высокой точности на небольшой набор целых чисел, которые может представить тип с низким числом бит. int8 может представить 256 целых чисел, [-128, 127], а int4 — 16.
Аффинное квантование — наиболее распространённое отображение. Оно берёт минимальное и максимальное значения тензора и растягивает диапазон целых чисел на этот интервал. В примере ниже тензор со значениями от -1.8 до 2.4 отображается в int8, при этом 0.0 соответствует -19.
bf16 -1.8 0.0 2.4
├────────────────┼──────────────────────┤
▼ ▼ ▼
int8 -128 -19 127Два параметра определяют отображение.
Значение scale
S— это размер одного целочисленного шага в исходных единицах.Нулевая точка
Z— это целое число, представляющее0.0.
Значение x квантуется в целое число q путем деления на масштаб и сдвига на нулевую точку.
Декуантизация обращает отображение и возвращает приближённое значение x. Разница между x и его приближением — это ошибка округления.
В примере выше S составляет примерно 0.0165, а Z равно -19. Значение 0.5 квантуется в 11, а 11 деквантуется примерно в 0.494, что дает ошибку округления около 0.006.
┌─────┐ quantize ┌────┐ dequantize ┌───────┐ │ 0.5 │ ──────────▶ │ 11 │ ───────────▶ │ 0.494 │ └─────┘ └────┘ └───────┘
Аффинная квантизация существует в двух формах.
- Квантование Asymmetric использует формулы, приведённые выше. Оно отображает точный диапазон, поэтому при отсутствии центрирования весов относительно нуля ни одно представимое значение не пропадает.
- Квантование Symmetric предполагает, что диапазон равен
[-a, a]и фиксируетZна 0, поэтому хранится только масштаб. Вычисления становятся дешевле, но если веса смещены в одну сторону от нуля, часть представимых значений остаётся неиспользованной.
Выберите уровень детализации
Один масштаб для всего тензора дёшев в хранении, но один крупный выброс расширяет диапазон и раздвигает представимые значения для всех остальных весов. Меньшие группы позволяют каждому масштабу покрывать более узкий диапазон.
- Per-tensor использует один масштаб и одну нулевую точку для всего тензора.
- Per-channel использует один масштаб для каждого выходного канала, то есть для каждой строки матрицы весов.
- Режим per-group или per-block использует один масштаб для каждой группы последовательных значений, например, для 128 весов. Каждая группа требует дополнительного места в памяти для хранения своего масштаба.
На диаграмме ниже показаны три варианта для матрицы весов с тремя строками. Каждый s — это один масштаб.
per-tensor per-channel per-group ┌────────────┐ ┌────────────┐ ┌──────┬──────┐ │ │ │ │ s0 │ s0 │ s1 │ │ │ ├────────────┤ ├──────┼──────┤ │ s │ │ │ s1 │ s2 │ s3 │ │ │ ├────────────┤ ├──────┼──────┤ │ │ │ │ s2 │ s4 │ s5 │ └────────────┘ └────────────┘ └──────┴──────┘
Большинство методов с низким разрядным числом выполняют квантование по группам. По умолчанию GPTQ использует группы из 128 весов, а Fine-grained FP8 — блоки 128x128. Форматы FP4, описанные в разделе Data types, закладывают размер блока непосредственно в сам формат.
Квантование весов или активаций
Методы различаются по тому, какие тензоры они квантуют, и именно это определяет, где выполняется умножение матриц.
- Методы Weight-only хранят веса в пониженной точности, оставляя активации в bf16 или fp16. Перед каждым matmul ядро деквантует веса в dtype вычислений с более высокой точностью. bitsandbytes 4-bit, AWQ, GPTQ и HQQ работают именно так. В bitsandbytes
bnb_4bit_compute_dtypeзадаёт этот dtype вычислений. - Методы Weight-and-activation квантуют также активации, и матричное умножение выполняется непосредственно в пониженной точности. Для этого требуется аппаратное обеспечение, поддерживающее матричное умножение в пониженной точности, например FP8 на современных GPU. Схема часто обозначается как W8A8 для 8-битных весов и активаций.
Методы с квантованием только весов экономят память, но не всегда ускоряют выполнение, поскольку деквантование добавляет вычислительную нагрузку к каждой операции матричного умножения. Они ускоряют генерацию, когда модель ограничена пропускной способностью памяти (memory-bound). При генерации по одному токену за раз GPU тратит большую часть каждого шага на чтение весов из памяти, а не на вычисления. Чтение весов в 4-битном формате перемещает в четыре раза меньше данных, чем веса в bf16, и эта экономия может перевесить затраты на деквантование.
Методы квантования весов и активаций полезны, когда модель ограничена по вычислительным ресурсам (compute-bound), например, на этапе prefill или при работе с большими батчами, поскольку само умножение матриц в пониженной точности выполняется быстрее. Некоторые методы переключаются между двумя режимами. NVFP4 выполняет умножение матриц с 4-битовыми весами и 4-битовыми активациями на этапе prefill и с 4-битовыми весами и 16-битовыми активациями на этапе декодирования.
Типы данных
Тип данных определяет, какие значения может представлять квантованное число.
int8 и int4
int8 и int4 представляют собой равномерно расположенные целые числа и используют аффинное отображение, описанное выше. int4 может представлять только 16 значений, поэтому он теряет больше точности, чем int8. Методы, использующие int4, как правило, выполняют квантование по группам или используют калибровку для сохранения точности.
Большинство аппаратных платформ не имеют 4-битного типа хранения, поэтому два значения int4 упаковываются в один байт. Например, первое значение может занимать младшие 4 бита, а второе — старшие 4 бита. Ядра распаковывают значения перед вычислениями с ними.
┌──────┐ ┌──────┐ ┌──────┬──────┐ │ val1 │ │ val2 │ │ val2 │ val1 │ │ 0101 │ │ 0011 │ → │ 0011 │ 0101 │ 1 byte └──────┘ └──────┘ └──────┴──────┘ int4 int4 high low
Некоторые 4-битные типы распределяют свои представимые значения неравномерно, чтобы соответствовать распределению весов. bitsandbytes NF4 размещает больше значений вблизи нуля, где сосредоточена большая часть весов.
FP8
FP8 сохраняет плавающую структуру из знака, экспоненты и мантиссы в 8 битах. Его представимые значения расположены ближе друг к другу вблизи нуля и дальше друг от друга при больших абсолютных значениях, что соответствует распределению значений в весах и активациях.
FP8 существует в двух вариантах.
- E4M3 имеет 4 бита экспоненты и 3 бита мантиссы. Он обеспечивает более высокую точность, но охватывает меньший диапазон значений. Это стандартный выбор для весов и активаций на этапе инференса.
- E5M2 имеет 5 бит для экспоненты и 2 бита для мантиссы. Он охватывает более широкий диапазон, но с меньшей точностью.
E4M3 ┌─┬───────┬─────┐
│S│E E E E│M M M│
└─┴───────┴─────┘
E5M2 ┌─┬─────────┬───┐
│S│E E E E E│M M│
└─┴─────────┴───┘
S sign E exponent M mantissaFP8 matmuls требуют аппаратной поддержки, например, NVIDIA GPU с вычислительной мощностью 8.9 или выше (Ada, Hopper, Blackwell), AMD Instinct MI300 и Intel XPU. Transformers поддерживает FP8 через Fine-grained FP8, FBGEMM FP8 и compressed-tensors.
FP4 с блочными масштабами
FP4 имеет 1 бит знака, 2 бита экспоненты и 1 бит мантиссы (E2M1). Он представляет только значения 0, 0.5, 1, 1.5, 2, 3, 4 и 6, как положительные, так и отрицательные. Из-за столь малого количества значений форматы FP4 не могут работать с одним масштабом на тензор. Вместо этого масштаб привязывается к каждому небольшому блоку значений, а сами масштабы хранятся как часть формата.
| Формат | Размер блока | Масштабирование по блокам | Дополнительный масштаб |
|---|---|---|---|
| MXFP4 | 32 значения | 8-битная степень двойки (E8M0) | None |
| NVFP4 | 16 значений | FP8 | Один масштаб FP32 на тензор |
MXFP4 — это формат микромасштабирования. Масштаб, являющийся степенью двойки, лишь сдвигает экспоненту, поэтому его применение дёшево, но он может принимать только значения, являющиеся степенями двойки. NVFP4 использует более мелкие блоки и масштаб FP8, который может принимать значения между степенями двойки. Это позволяет сохранить большую точность, но требует масштаба на уровне тензора, который удерживает масштабы блоков FP8 в допустимых пределах. Four Over Six и FP-Quant также генерируют веса в формате NVFP4 или MXFP4.
Та же идея блоков проявляется и при 8 битах. MXFP8 хранит значения FP8 с масштабами, кратными степени двойки, а Тонкозернистый FP8 загружает их.
Кодовые книги
Ниже 4 бит некоторые методы перестают округлять каждый вес до ближайшего представимого значения. Они квантуют группы весов совместно как векторы. Кодовая книга содержит набор выученных векторов, а каждая группа весов хранится в виде индекса ближайшего к ней вектора. По умолчанию AQLM использует группы из 8 весов и 16-битный индекс, что соответствует 2 бита на вес. VPTQ также использует кодовые книги. Поиск хороших кодовых книг требует длительной оптимизации на калибровочных данных, поэтому такие модели квантуются заранее и загружаются в виде контрольных точек.
Когда происходит квантование
Модель квантуется либо после обучения, либо в процессе обучения. Большинство методов в Transformers выполняют квантование после обучения.
Квантование после обучения
Постобучающая квантизация (PTQ) квантует уже обученную модель, не изменяя то, что она усвоила. Методы PTQ различаются по необходимости в данных, и именно это определяет, в какую группу в таблице оглавления документации попадает данный метод.
- Без калибровочных данных масштабы определяются исключительно по весам, а квантование выполняется достаточно быстро, чтобы проходить в процессе загрузки модели. Так работают bitsandbytes, HQQ и torchao. Эти методы перечислены в разделе Квантование при загрузке.
- При наличии данных калибровки метод прогоняет небольшой набор данных через модель и использует активации, чтобы определить, как квантовать каждый слой. Как правило, калибровка обеспечивает более высокую точность при 4 битах и ниже, но занимает от нескольких минут до нескольких часов.
Методы калибровки используют активации по-разному. GPTQ квантует слой по одной колонке за раз и корректирует оставшиеся колонки, чтобы компенсировать ошибку округления каждой колонки. AWQ находит каналы весов с наибольшими активациями и масштабирует их перед округлением, чтобы защитить их.
То, как выполняется калибровка, определяет, как вы будете использовать этот метод в Transformers.
- GPTQ выполняет калибровку внутри
from_pretrained, если вы передаётеdatasetв GPTQConfig, поэтому он указан в разделе Квантование при загрузке. - Другие методы калибровки, такие как AWQ, AutoRound, AQLM и VPTQ, выполняют калибровку в собственных библиотеках. Transformers загружает результат, поэтому они перечислены в разделе Загрузка предварительно квантованных контрольных точек.
Обучение с учетом квантования
Обучение с учётом квантования (QAT) имитирует квантование в процессе обучения. На прямом проходе значения округляются так, как это делает квантование, при этом градиенты обновляют веса с полной точностью, благодаря чему модель учится компенсировать ошибку округления. Как правило, QAT обеспечивает наилучшую точность при очень низких разрядностях, но требует обучения модели.
Модели BitNet обучаются именно таким образом, с их 1.58-битными весами в цикле, а Transformers загружает обученные контрольные точки.
Ресурсы
- Основы квантования с Hugging Face
- Квантование: подробный обзор
- Введение в квантование, приготовленное в 🤗 с 💗🧑🍳
- Лекция 5 EfficientML.ai — Квантование, часть I
- Как заставить глубокое обучение работать на полную мощность: с нуля
- Ускорение генеративного ИИ с PyTorch, часть 2: оптимизации LLM