中文翻译暂不可用,显示俄语原文。

Что такое FP16, BF16, FP8, INT8 quantization? Когда что использовать?

Краткий тезис

Квантование — это снижение точности чисел (весов и активаций модели) для уменьшения потребления памяти и ускорения вычислений. FP16 (полуточность) и BF16 (brain float) — 16-битные форматы с плавающей точкой: FP16 даёт высокую скорость на старых GPU, но страдает от underflow; BF16 сохраняет диапазон FP32, идеален для обучения. FP8 — новый 8-битный формат на H100, ускоряет инференс и fine-tuning. INT8 — целочисленное квантование, максимально быстрое на CPU и edge-устройствах, но с потерей качества. Выбор зависит от задачи: обучение → BF16, инференс на GPUFP16/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)Аппаратная поддержка
FP3232 бита±3.4e38~7.2Нет1x (базовый)Все GPU/CPU
FP1616 бит±65504~3.3Да2–8x (Tensor Cores)V100, A100, H100, RTX
BF1616 бит±3.4e38~2.3Нет2–8x (Tensor Cores)A100, H100, TPU
FP88 бит±448 (E4M3) / ±57344 (E5M2)~1.2 / ~0.6Частично4–16x (H100)H100, B200
INT88 бит-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 Краткая памятка

СценарийРекомендуемый форматПричина
Обучение LLMBF16Нет underflow, широкий диапазон
Инференс на H100FP8Максимальная скорость
Инференс на A100/V100FP16Хорошая скорость, доступно
Инференс на CPUINT8 (GGUF)Единственный вариант
Fine-tuningBF16 / 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.

Инструменты

Шаги:

  1. Загрузить модель в FP32 (базовый вариант).
  2. Преобразовать в FP16 (model.half()).
  3. Преобразовать в BF16 (model.to(torch.bfloat16)).
  4. Применить INT8 квантование через bitsandbytes (load_in_8bit=True).
  5. (Опционально) Применить GPTQ с 4-битным квантованием.
  6. Запустить инференс на одном и том же наборе промптов (100–500 примеров).
  7. Замерить perplexity и latency для каждого формата.
  8. Построить таблицу и графики.

Ожидаемый результат

  • 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?

Навигация