English translation is not available yet. Showing Russian content.
Что такое FP16, BF16, FP8, INT8 quantization? Когда что использовать?
Краткий тезис
Квантование — это снижение точности чисел (весов и активаций модели) для уменьшения потребления памяти и ускорения вычислений. FP16 (полуточность) и BF16 (brain float) — 16-битные форматы с плавающей точкой: FP16 даёт высокую скорость на старых GPU, но страдает от underflow; BF16 сохраняет диапазон FP32, идеален для обучения. FP8 — новый 8-битный формат на H100, ускоряет инференс и fine-tuning. INT8 — целочисленное квантование, максимально быстрое на CPU и edge-устройствах, но с потерей качества. Выбор зависит от задачи: обучение → BF16, инференс на GPU → FP16/FP8, на CPU → INT8/GGUF.
1. Термин: Квантование (Quantization)
Что это Процесс преобразования чисел из формата с высокой точностью (например, FP32 — 32-битное число с плавающей точкой) в формат с меньшей разрядностью (FP16, INT8 и т.д.). Цель — уменьшить размер модели и ускорить вычисления за счёт более эффективного использования аппаратного обеспечения.
Зачем нужно квантование
- Снижение памяти Модель в FP32 занимает 4 байта на параметр, в FP16 — 2 байта, в INT8 — 1 байт. Для LLM с миллиардами параметров это критично.
- Ускорение инференса Меньший объём данных быстрее передаётся по шинам памяти, а специализированные инструкции (например, Tensor Cores на GPU) работают быстрее с низкоточными числами.
- Энергоэффективность Меньше бит → меньше энергопотребления, важно для мобильных и edge-устройств.
Основные типы квантования
- Post-Training Quantization (PTQ): Квантование уже обученной модели без дополнительного обучения. Быстро, но может потерять качество.
- Quantization-Aware Training (QAT): Модель обучается с учётом будущего квантования (имитация низкой точности во время forward pass). Качество выше, но требует переобучения.
2. FP16 (Float16 / Half Precision)
FP16 — 16-битный формат с плавающей точкой по стандарту IEEE 754. Структура: 1 бит знака, 5 бит экспоненты, 10 бит мантиссы.
Характеристики
- Диапазон ±65504 (максимальное значение), минимальное нормализованное ~6.1e-5.
- Точность: ~3.3 десятичных знака (из-за 10 бит мантиссы).
- Underflow: Числа меньше ~6.1e-5 округляются до нуля. Это главная проблема при обучении: градиенты могут «исчезать» (стать нулевыми).
Когда использовать
- Инференс на GPU с поддержкой FP16: Почти все современные GPU (NVIDIA Volta, Turing, Ampere, Hopper) имеют Tensor Cores, ускоряющие FP16 в 2–8 раз по сравнению с FP32.
- Fine-tuning с осторожностью Если градиенты не слишком малы, можно использовать FP16 с loss scaling (умножение функции потерь на коэффициент, чтобы избежать underflow). Но для обучения с нуля лучше BF16.
Пример кода (PyTorch):
import torch
model = model.half() # преобразование всех весов в FP16
input = input.half()
output = model(input)
3. BF16 (Brain Float 16)
BF16 — 16-битный формат, разработанный Google Brain. Структура: 1 бит знака, 8 бит экспоненты (как у FP32), 7 бит мантиссы.
Характеристики
- Диапазон такой же, как у FP32: ±3.4e38. Это полностью устраняет underflow.
- Точность: ~2.3 десятичных знака (меньше, чем у FP16, из-за меньшей мантиссы). Но для обучения это не критично: градиенты часто имеют шум, и потеря точности мантиссы компенсируется сохранением диапазона.
- Аппаратная поддержка NVIDIA A100, H100, а также TPU (Google). На старых GPU (V100) BF16 эмулируется программно, что медленно.
Когда использовать
- Обучение (training) LLM и других глубоких сетей: BF16 — стандарт де-факто. Он позволяет избежать underflow градиентов, не требуя loss scaling. Большинство современных фреймворков (PyTorch, TensorFlow, JAX) используют BF16 mixed precision.
- Fine-tuning Также предпочтителен, особенно если модель большая (например, LLaMA-70B).
Пример (PyTorch с AMP — Automatic Mixed Precision):
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast(dtype=torch.bfloat16):
output = model(input)
loss = loss_fn(output, target)
scaler.scale(loss).backward()
4. FP8 (Float8)
FP8 — 8-битный формат с плавающей точкой, впервые появившийся на NVIDIA H100 (Hopper) и Blackwell. Два основных варианта:
- E4M3 4 бита экспоненты, 3 бита мантиссы. Диапазон ±448, точность ~1.2 десятичных знака. Используется для весов и активаций.
- E5M2 5 бит экспоненты, 2 бита мантиссы. Диапазон ±57344, точность ~0.6 десятичных знака. Используется для градиентов (чтобы избежать underflow).
Характеристики
- Скорость В 2 раза быстрее FP16 на H100 благодаря вдвое меньшему объёму данных и оптимизированным Tensor Cores.
- Качество При правильном применении (с калибровкой и, возможно, QAT) потеря качества минимальна. Для инференса LLM FP8 часто даёт результаты, неотличимые от FP16.
Когда использовать
- Инференс на H100/B200 FP8 — лучший выбор для максимальной пропускной способности (throughput).
- Fine-tuning с FP8 Возможен, но требует осторожности: градиенты лучше хранить в E5M2, а веса — в E4M3. Используется в библиотеках типа Transformer Engine.
- Не подходит для Старых GPU (V100, A100 не поддерживают FP8 аппаратно). CPU (нет инструкций).
Пример (Transformer Engine):
import transformer_engine.pytorch as te
model = te.Linear(in_features, out_features, dtype=torch.float8)
5. INT8 (Integer 8-bit)
INT8 — целочисленное квантование. Веса и активации преобразуются в 8-битные целые числа (обычно со знаком, от -128 до 127). Требуется калибровка: подбор масштаба (scale) и смещения (zero point), чтобы минимизировать ошибку.
Характеристики
- Скорость Максимальная на CPU (использует AVX-512, VNNI инструкции) и на GPU с поддержкой INT8 Tensor Cores (Turing, Ampere, Hopper). На CPU может быть в 2–4 раза быстрее FP32.
- Качество Заметная потеря точности, особенно для LLM. Требует QAT или продвинутых методов (например, GPTQ, AWQ, GGUF).
- Размер Модель уменьшается в 4 раза по сравнению с FP32.
Когда использовать
- Инференс на CPU INT8 — стандарт для запуска LLM на CPU (например, через llama.cpp с форматом GGUF). Позволяет запускать модели с 7B параметров на обычном ноутбуке.
- Edge-устройства Мобильные телефоны, Raspberry Pi — INT8 даёт приемлемую скорость.
- GPU На H100 INT8 может быть быстрее FP8, но качество ниже. Используется редко для LLM, чаще для CV (Computer Vision).
Пример (PyTorch с динамическим квантованием):
import torch
model = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8
)
6. Сравнительная таблица форматов
| Формат | Разрядность | Диапазон | Точность (дес. знаков) | Underflow | Скорость (отн. FP32) | Аппаратная поддержка |
|---|---|---|---|---|---|---|
| FP32 | 32 бита | ±3.4e38 | ~7.2 | Нет | 1x (базовый) | Все GPU/CPU |
| FP16 | 16 бит | ±65504 | ~3.3 | Да | 2–8x (Tensor Cores) | V100, A100, H100, RTX |
| BF16 | 16 бит | ±3.4e38 | ~2.3 | Нет | 2–8x (Tensor Cores) | A100, H100, TPU |
| FP8 | 8 бит | ±448 (E4M3) / ±57344 (E5M2) | ~1.2 / ~0.6 | Частично | 4–16x (H100) | H100, B200 |
| INT8 | 8 бит | -128..127 | ~1.0 (после калибровки) | Нет (целые) | 2–4x (CPU), 4–8x (GPU) | Все CPU (AVX), GPU (Turing+) |
7. Когда что использовать: практическое руководство
7.1 Обучение (Training)
- Лучший выбор: BF16 Сохраняет диапазон FP32, нет underflow. Поддерживается на A100/H100. Если GPU не поддерживает BF16 (V100) → используйте FP16 с loss scaling.
- Не используйте INT8 (не подходит для обучения из-за низкой точности), FP8 (пока экспериментально, только fine-tuning).
7.2 Инференс на GPU
- H100/B200 FP8 → максимальная пропускная способность. Если качество падает → FP16.
- A100/V100/RTX 30xx FP16 → оптимальный баланс скорости и качества. BF16 тоже работает, но без прироста скорости (на A100 BF16 и FP16 одинаковы по скорости).
- Если модель не влезает в память: INT8 (через GPTQ или AWQ) — уменьшает размер в 2 раза по сравнению с FP16, но качество может упасть.
7.3 Инференс на CPU
- Единственный разумный выбор: INT8 (формат GGUF). Позволяет запускать LLM на CPU с приемлемой скоростью. FP16/FP32 слишком медленные.
- FP8 не поддерживается на CPU.
7.4 Fine-tuning (дообучение)
- BF16 (если доступен) или FP16 с loss scaling.
- FP8 fine-tuning — новая возможность на H100, позволяет ускорить процесс, но требует специальных библиотек (Transformer Engine) и осторожности с градиентами.
7.5 Краткая памятка
| Сценарий | Рекомендуемый формат | Причина |
|---|---|---|
| Обучение LLM | BF16 | Нет underflow, широкий диапазон |
| Инференс на H100 | FP8 | Максимальная скорость |
| Инференс на A100/V100 | FP16 | Хорошая скорость, доступно |
| Инференс на CPU | INT8 (GGUF) | Единственный вариант |
| Fine-tuning | BF16 / FP16 | Баланс качества и скорости |
| Edge / мобильные | INT8 | Энергоэффективность |
8. Дополнительные аспекты
8.1 Mixed Precision Training
Современный подход: часть операций (например, матричные умножения) выполняется в FP16/BF16, а часть (например, loss, softmax) — в FP32. Это даёт и скорость, и стабильность. Реализуется через AMP (Automatic Mixed Precision).
8.2 Loss Scaling для FP16
Если используете FP16 для обучения, обязательно применяйте GradScaler:
scaler = GradScaler()
with autocast():
output = model(input)
loss = loss_fn(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
8.3 Квантование LLM: GPTQ, AWQ, GGUF
Для INT8-квантования LLM существуют специализированные методы:
- GPTQ Post-training квантование, основанное на оптимальном округлении. Хорошо работает на GPU.
- AWQ Адаптивное квантование, учитывающее важность весов. Часто даёт лучшее качество, чем GPTQ.
- GGUF Формат для CPU-инференса (llama.cpp). Включает квантование от 2 до 8 бит.
8.4 Когда квантование не нужно
- Если модель уже помещается в память GPU и скорость устраивает.
- Если требуется максимальная точность (например, научные расчёты).
- Если модель очень маленькая (выигрыш от квантования незначителен).
Пет-проект для закрепления
Задача Сравнить скорость и качество инференса LLM (например, LLaMA-2-7B) в разных форматах: FP16, BF16, INT8 (GPTQ), FP8 (если есть H100). Оценить влияние на метрики (perplexity) и latency.
Инструменты
- Модель LLaMA-2-7B или Mistral-7B (доступны на Hugging Face).
- Библиотеки Transformers, Accelerate, bitsandbytes (для INT8), AutoGPTQ (для GPTQ), Transformer Engine (для FP8, если H100).
- Метрики: Perplexity (на датасете WikiText-2), latency (среднее время на токен), пропускная способность (токенов/сек).
Шаги:
- Загрузить модель в FP32 (базовый вариант).
- Преобразовать в FP16 (model.half()).
- Преобразовать в BF16 (model.to(torch.bfloat16)).
- Применить INT8 квантование через bitsandbytes (load_in_8bit=True).
- (Опционально) Применить GPTQ с 4-битным квантованием.
- Запустить инференс на одном и том же наборе промптов (100–500 примеров).
- Замерить perplexity и latency для каждого формата.
- Построить таблицу и графики.
Ожидаемый результат
- FP16 и BF16 дадут почти одинаковое качество (perplexity отличается <0.1), но BF16 может быть чуть медленнее на старых GPU.
- INT8 (bitsandbytes) покажет заметное падение качества (perplexity +0.5–1.0), но значительное ускорение на CPU.
- GPTQ (4-bit) может сохранить качество близкое к FP16 при вдвое меньшем размере.
- Вывод: для production на GPU — FP16/BF16; для CPU — INT8/GPTQ.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 665 | Что такое Agentic RAG и как он отличается от обычного RAG? |
| 667 | Как работает квантование через bitsandbytes и GPTQ? |
| 668 | Что такое vLLM и как оно ускоряет инференс? |
| 669 | Как работает PagedAttention? |
| 670 | Что такое speculative decoding? |
| 671 | Как вы деплоите LLM в production? |
Навигация
- Предыдущий: 665
- Следующий: 667
- Индекс: 00. Индекс разборов