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) выглядит так:

  1. Загрузка INT4-веса из VRAM в регистр (4 бита).
  2. Деквантование до FP16:
    w_fp16 = scale * (w_int4 - zero_point)
    – это несколько арифметических операций (умножение, сложение, возможно преобразование формата).
  3. Умножение 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 size4-bit latency (ms)8-bit latency (ms)Отношение
112.510.2+22% медленнее
818.416.7+10% медленнее
3235.138.5-9% быстрее
6462.373.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 для графиков.

Шаги:

  1. Загрузить модель в 4-bit и 8-bit версиях.
  2. Для каждого batch size сгенерировать фиксированное количество токенов (например, 50).
  3. Замерить среднее время по 10 прогонам.
  4. Посчитать throughput (batch_size / latency).
  5. Построить два графика: 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) и как оно влияет на скорость?

Навигация