English translation is not available yet. Showing Russian content.
Почему 4-bit inference иногда медленнее 8-bit?
Краткий тезис
4-bit квантование уменьшает объём весов модели в два раза по сравнению с 8-bit, что сокращает memory traffic (bandwidth перемещение данных из VRAM в вычислительные ядра) и позволяет разместить модель на GPU с меньшей памятью. Однако деквантование INT4 обратно в FP16 перед каждым умножением требует дополнительных вычислений (dequantization overhead). При малых batch size (1–8) этот overhead перевешивает выигрыш от уменьшенного memory traffic, и 8-bit оказывается быстрее. С ростом batch size (≥32) система становится memory-bound, и экономия на загрузке данных начинает доминировать – 4-bit выигрывает по пропускной способности.
1. Термины: 4-bit и 8-bit inference
Inference (инференс) – этап работы нейросети, когда она применяется для обработки новых данных (предсказания). Quantization (квантование) – снижение точности представления весов или активаций (например, с FP16 до INT4/8) для уменьшения размера модели и ускорения вычислений. 4-bit inference означает, что веса модели хранятся в 4-битном формате (INT4), а 8-bit inference – в 8-битном (INT8).
При инференсе с квантованными весами обычно требуется их деквантование (dequantization) обратно в FP16/FP32, потому что современные тензорные ядра GPU (Tensor Cores) оптимизированы для FP16 операций, а INT4-INT8 умножения поддерживаются не напрямую или с ограничениями.
Ключевое понятие – memory traffic: объём данных, передаваемых из глобальной памяти GPU (VRAM) в регистры/SRAM. Чем меньше разрядность, тем меньше traffic на один параметр, но деквантование добавляет вычисления.
2. Устройство деквантования (dequantization) на GPU
Процесс прохода квантованного веса через тензорное ядро (например, в NVIDIA Ampere или Ada Lovelace) выглядит так:
- Загрузка INT4-веса из VRAM в регистр (4 бита).
- Деквантование до FP16:
w_fp16 = scale * (w_int4 - zero_point)
– это несколько арифметических операций (умножение, сложение, возможно преобразование формата). - Умножение FP16*FP16 с активацией в тензорном ядре.
Почему это дороже, чем INT8?
- INT8 занимает 8 бит, деквантование до FP16 требует аналогичных операций (scale, zero_point), но объём данных на один вес вдвое меньше в INT4 – меньше memory traffic, но больше вычислительных операций на каждый элемент.
- GPU выполняет деквантование на CUDA core, а не на Tensor Core, что замедляет общий pipeline, если доля деквантования велика.
3. Влияние batch size
Производительность инференса зависит от того, является ли операция compute-bound (ограничена вычислительными ресурсами) или memory-bound (ограничена пропускной способностью памяти).
- Малый batch (1–8): активации занимают мало места, узким местом становится последовательная обработка (latency). Деквантование – последовательная операция, она добавляет фиксированные накладные расходы (overhead) на каждый слой. Для INT4 этот overhead больше, чем для INT8, поэтому общее время прохода возрастает.
- Большой batch (≥32): количество данных, перемещаемых из памяти, резко растёт. Пропускная способность VRAM (bandwidth) становится главным лимитом. INT4 экономит ~50% bandwidth по сравнению с INT8, что даёт прирост throughput (образцов в секунду). Деквантование теперь распараллеливается на всех CUDA cores, и его относительная доля уменьшается.
Таблица зависимости (пример для модели ~7B параметров на GPU A100):
| Batch size | 4-bit latency (ms) | 8-bit latency (ms) | Отношение |
|---|---|---|---|
| 1 | 12.5 | 10.2 | +22% медленнее |
| 8 | 18.4 | 16.7 | +10% медленнее |
| 32 | 35.1 | 38.5 | -9% быстрее |
| 64 | 62.3 | 73.9 | -16% быстрее |
Числа примерные, зависят от специфики модели, библиотеки квантования (GPTQ, AWQ, GGUF) и архитектуры GPU.
4. Memory-bound vs compute-bound: количественный анализ
Memory-bound – когда время выполнения ограничено скоростью чтения/записи из памяти.
Compute-bound – когда упирается в вычислительную мощность ядер.
Формула Operational Intensity (Roofline model):
[
[text](/wiki/text){Operational Intensity} = \frac{[text](/wiki/text){FLOPs}}{[text](/wiki/text){Bytes loaded}}
]
- Для INT8: на каждый вес загружается 1 байт, FLOPs на деквантование ~1-2.
- Для INT4: загружается 0.5 байта, FLOPs на деквантование ~1-2.
При малом batch операционная интенсивность низкая (мало FLOPs на байт), модель compute-bound из-за деквантования. При большом batch количество активаций растёт, число FLOPs на слой увеличивается, но объём весов остаётся тем же – интенсивность растёт, и модель становится memory-bound.
Ключевой параметр: batch size, при котором происходит пересечение границы между режимами, зависит от:
- количества параметров модели (большие модели – раньше становятся memory-bound),
- ширины слоёв (больше FLOPs на слой – раньше compute-bound),
- скорости деквантования в конкретной реализации.
5. Аппаратные особенности (Tensor Cores, CUDA cores)
Современные GPU (NVIDIA A100, H100, RTX 4090) имеют специализированные Tensor Cores, которые могут выполнять операцию FP16*FP16 за один такт, но не умеют напрямую обрабатывать INT4 без деквантования. Деквантование выполняется на CUDA cores (обычные ALU), которые медленнее.
- В 8-bit квантовании существует оптимизированный pipeline: Tensor Cores могут выполнять INT8 умножения с накоплением в INT32, а затем преобразование в FP16. Это почти не требует дополнительных операций.
- В 4-bit квантовании деквантование до FP16 обязательно, и его нельзя полностью скрыть за конвейером загрузки данных, поэтому overhead заметнее.
Некоторые реализации (например, bitsandbytes для 4-bit QLoRA, формат NF4) используют особые схемы деквантования, которые частично совмещают чтение и вычисление, но фундаментально overhead остаётся.
6. Когда 4-bit быстрее? Когда 8-bit?
| Условие | Рекомендуемое квантование | Причина |
|---|---|---|
| batch size ≤ 8, низкая пропускная способность критична (например, чат-бот в реальном времени) | 8-bit | Меньше overhead деквантования, ниже latency |
| batch size ≥ 32, высокая throughput важна (батчевая обработка, генерация ответов) | 4-bit | Экономия bandwidth даёт прирост образцов/с |
| Модель не помещается в 8-bit на данной GPU (например, 70B модель на 24GB) | 4-bit | Единственный способ инференса (цена latency оправдана) |
| Гибридный сценарий: часть слоёв – 4-bit (для памяти), другая – 8-bit (для скорости) | Mixed precision | Компромисс между размером и производительностью |
7. Пример кода: замеры с библиотекой transformers + bitsandbytes
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "meta-llama/Llama-2-7b-chat-hf"
# 4-bit инференс
model_4bit = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_4bit=True,
device_map="auto"
)
# 8-bit инференс
model_8bit = AutoModelForCausalLM.from_pretrained(
model_name,
load_in_8bit=True,
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
prompts = ["Напиши код на Python для сортировки списка."] * batch_size # изменяем batch_size
# Замер времени
import time
for model, name in [(model_4bit, "4-bit"), (model_8bit, "8-bit")]:
inputs = tokenizer(prompts, return_tensors="pt", padding=True).to("cuda")
start = time.time()
outputs = model.generate(**inputs, max_new_tokens=50)
latency = time.time() - start
print(f"{name} latency (batch={batch_size}): {latency:.3f}s")
Результаты подтвердят, что при batch=1 8-bit быстрее, при batch=64 – 4-bit.
8. Важные нюансы и практические рекомендации
- Деквантование зависит от реализации: библиотека
GPTQ(черезauto-gptq) часто быстрееbitsandbytesдля 4-bit, потому что использует INT4 с групповым квантованием и оптимизированные ядра. - Формат хранения: 4-bit данные обычно упаковываются в 32-bit регистры (8 значений INT4 в одном 32-битном слове). Деквантование требует unpacking, что добавляет overhead.
- Кэш-эффекты: при малом batch данные весов могут помещаться в L1/L2 кэш GPU, тогда memory traffic не является узким местом – overhead деквантования проявляется сильнее.
- Активации тоже квантуются: если в модели применяется activation quantization (например, INT8), это может изменить balance. 4-bit для активаций обычно не используется (сильная потеря точности).
- Latency vs throughput: для серверных нагрузок (высокий batch) 4-bit выгоден, для девайсов (batch=1) – 8-bit.
Пет-проект для закрепления
Задача: Сравнить инференс 4-bit и 8-bit на одной и той же модели (LlaMA-2-7B) при разных batch size (1, 2, 4, 8, 16, 32, 64) и построить график зависимости latency/throughput от batch.
Инструменты:
- Python,
transformers,bitsandbytes,auto-gptq(опционально), torch.utils.benchmarkилиtimeit,matplotlibдля графиков.
Шаги:
- Загрузить модель в 4-bit и 8-bit версиях.
- Для каждого batch size сгенерировать фиксированное количество токенов (например, 50).
- Замерить среднее время по 10 прогонам.
- Посчитать throughput (batch_size / latency).
- Построить два графика: latency vs batch, throughput vs batch.
Ожидаемый результат:
- При batch ≤ 8 latency 4-bit выше, чем 8-bit.
- При batch ≥ 32 throughput 4-bit выше.
- Точка пересечения будет смещаться в зависимости от модели и библиотеки.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 443 | Какие методы квантования (GPTQ, AWQ, GGUF) вы знаете? |
| 445 | Как влияет квантование на качество генерации (perplexity)? |
| 442 | Что такое NF4 квантование и чем отличается от INT4? |
| 446 | Как выбрать степень квантования под конкретную архитектуру GPU? |
| 401 | Как устроен инференс LLM (pipeline, KV cache)? |
| 447 | Что такое Group-квантование (group size) и как оно влияет на скорость? |
Навигация
- Предыдущий: 443
- Следующий: 445
- Индекс: 00. Индекс разборов