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

Как сравнивать quantization методы (GPTQ, AWQ, GGUF, bitsandbytes)?

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

Квантизация моделей — это снижение точности весов (например с 16-bit до 4-bit) для уменьшения потребления памяти и ускорения инференса, ценой небольшой потери качества. Выбор метода зависит от целевого устройства и приоритета: AWQ даёт лучшее качество на GPU для задач рассуждения, GPTQ — универсальный GPU-метод с хорошим балансом, GGUF оптимизирован для CPU/Edge, а bitsandbytes удобен для быстрого прототипирования. Сравнение проводят по трём осям: размер модели, качество (perplexity) и скорость инференса.


1. Термин: Квантизация (Quantization) в LLM

Квантизация — это процесс отображения непрерывных значений весов (FP16, FP32) в дискретный набор уровней (INT8, INT4, NF4). Цель — сжать модель для размещения на устройстве с ограниченной памятью (GPU с < 24 ГБ, CPU, мобильные чипы) и/или ускорить инференс за счёт более быстрых целочисленных операций.

Основные виды:

  • quantization|Post-Training Quantization (PTQ) — квантизация уже обученной модели без дополнительного обучения. Все популярные методы (GPTQ, AWQ, bitsandbytes) относятся к PTQ.
  • training|Quantization-Aware Training (QAT) — обучение с имитацией квантизации, даёт лучшее качество, но требует переобучения.

Термин «dataset|Калибровочный датасет»: небольшой набор примеров (обычно 128–256), используемый для подбора параметров квантизации (масштабы, смещения). Важен для сохранения качества.


2. Почему нельзя просто взять один метод?

Разные методы по-разному обрабатывают распределение весов и активаций. Для LLM критические — outlier-нейроны (веса с большими значениями). Если их квантизовать грубо, качество резко падает. Методы отличаются стратегией обработки аутлайеров, группировкой весов и поддержкой hardware.


3. GPTQ: групповая квантизация через оптимизацию по Гессиану

GPTQ (Generative Pre-trained Transformer Quantization) — метод, основанный на минимизации ошибки каждого слоя с учётом важности весов (вторых производных, гессиана). Ключевые особенности:

  • Групповая квантизация: веса делятся на группы (например, 128 весов в группе), внутри группы используется один масштаб и смещение (scale и zero-point). Это снижает погрешность.
  • Онлайн-компенсация: ошибка квантизации одного веса распределяется на остальные в слое (на основе гессиана). Поэтому качество выше, чем у наивного округления.
  • Поддержка калибровки: требует калибровочного датасета (обычно 128 семплов из обучающей выборки).

Результат: модель квантизуется в 4-bit или 3-bit с минимальной потерей качества (perplexity падает на 1–2% относительно FP16). Работает только на GPU (через CUDA-ядра).

Формула (интуитивно):

loss ≈ ∑ (W_fp16 - W_q)² / (масштаб + λ·H^-1)

где H — гессиан (аппроксимация). GPTQ минимизирует эту сумму.


4. AWQ: адаптивная квантизация на основе значимости каналов

AWQ (Adaptive Weight Quantization) — метод, который анализирует каналы (выходные нейроны) и определяет, какие из них содержат аутлайеры (важные для активаций). Особенности:

  • Scale-aware: для каждого канала вычисляется «важность» по разнице активаций при изменении масштаба. Каналы с большим влиянием квантизуются точнее (сохраняются в FP16 или используют более тонкие смещения).
  • Без калибровки на уровне слоёв: калибровочный датасет нужен, но только для анализа активаций (не для оптимизации весов). Это быстрее GPTQ.
  • Качество: обычно чуть выше, чем GPTQ при тех же 4-bit, особенно на задачах reasoning (GSM8K, MMLU). Но требует больше кода для инференса (специальные CUDA-кернелы).

Плюсы vs GPTQ: меньше времени на квантизацию (1-2 часа vs 4-6 для 70B модели), лучшая сохранность рассуждений.


5. GGUF: формат для CPU и GPU-Edge

GGUF — это не столько метод, сколько формат файла + библиотека инференса (llama.cpp). Внутри он использует квантизацию на основе блоков (блоки из 32 весов) с различными схемами (Q4_0, Q4_K_M, Q5_1 и т.д.). Особенности:

  • Квантизация + упаковка: веса хранятся в компактном формате с минимальным оверхедом. Например, Q4_K_M — 4-bit с миксом точности (часть весов 6-bit).
  • Гибрид CPU/GPU: можно загружать слои на GPU при наличии, иначе считает на CPU (оптимизировано под AVX2/NEON).
  • Качество: чуть ниже GPTQ/AWQ (97% от FP16 против 98-99%), но зато работает на любом железе.

GGUF — выбор для edge-устройств, серверов без GPU, или когда нужно быстро развернуть модель на CPU.


6. bitsandbytes: простота и интеграция с Hugging Face

bitsandbytes — библиотека от Hugging Face, предоставляющая квантизацию «на лету» через load_in_4bit=True. Особенности:

  • NF4 (NormalFloat4): нелинейная квантизация, основанная на нормальном распределении весов. Лучше адаптирует уровни под реальное распределение, чем линейная 4-bit.
  • LLM.int8: для 8-bit квантизации — смесь: нормальные веса в INT8, аутлайеры (значения > 6σ) остаются в FP16.
  • Минусы: скорость инференса может быть ниже, чем у специализированных методов (особенно при маленьких батчах), так как требуется распаковка на лету.
  • Качество: примерно 96-97% от FP16 (чуть хуже GPTQ). Но главное — простота: 2 строки кода.

Лучше всего подходит для прототипирования и исследовательских проектов, где не хочется возиться с калибровкой.


7. Сравнительная таблица методов

МетодФорматПамять (70B)Качество (% от FP16)Скорость (GPU)Скорость (CPU)КалибровкаКогда использовать
FP16 (baseline)16-bit140 GB100%Неприменимо (очень медленно)НетHigh-end GPU (A100 80GB, H100)
GPTQ (4-bit)4-bit~35 GB98%1.2×Не поддерживаетсяДа (128 сэмплов)GPU, общие задачи (chat, summarization)
AWQ (4-bit)4-bit~35 GB99%1.1×Не поддерживаетсяДа (активации)GPU, задачи reasoning (математика, логика)
bitsandbytes (NF4)4-bit~35 GB96%0.9×Нет (только GPU)НетБыстрое прототипирование, Hugging Face
GGUF (Q4_K_M)4-bit~35 GB97%0.6× (on GPU)0.2× (CPU, 8-ядерный)Нет (встроено)CPU, Edge, кросс-платформенность

Пояснения:

  • Скорость измерена относительно FP16 на одном GPU (NVIDIA A100). Для GPU-методов (GPTQ/AWQ) инференс быстрее за счёт меньшего объёма данных, но накладные расходы на распаковку снижают прирост.
  • GGUF на GPU медленнее, так как не оптимизирован для CUDA-kernels (обычно используется llama.cpp с CPU). На CPU он — единственный из списка, кто даёт приемлемую скорость.
  • Качество — приблизительная perplexity на стандартных бенчмарках (WikiText2). Для точных цифр нужно тестировать на своей задаче.

8. Метрики сравнения при выборе метода

  1. Perplexity (PPL): логарифмическая потеря на калибровочном датасете. Чем ниже, тем лучше. Сравниваем с FP16 бейзлайном.
  2. Latency (время на один токен): измеряется на целевом устройстве. Для чат-ботов важна латентность первого токена (TTFT).
  3. Throughput (токенов/сек): для батч-инференса. Методы с групповой квантизацией (GPTQ) выигрывают на больших батчах.
  4. Memory footprint: максимальный размер модели + кеш для KV (key-value cache). Для 70B в 4-bit ~35GB; с KV-кешем (до 64K контекста) может достигать 50 GB.
  5. Качество на задачах: MMLU (общие знания), GSM8K (математика), HumanEval (код). AWQ часто показывает лучший результат на GSM8K, GGUF — чуть хуже.

9. Практические рекомендации

  • У вас дорогой GPU с большим VRAM (≥80GB): используйте FP16 (максимальное качество) или AWQ, если не хватает памяти.
  • GPU с 24-48GB: AWQ для приоритета качества, GPTQ для компромисса, bitsandbytes если лень считать калибровку.
  • CPU только (сервер, ноутбук): GGUF (формат Q4_K_M) — наилучшая производительность на CPU. Для ARM (Apple Silicon) – GGUF с оптимизациями под Metal.
  • Edge-устройство (Raspberry Pi, мобилка) : GGUF с самой низкой точностью (Q2_K, Q3_K) — единственный вариант.
  • Прототипирование и эксперименты: bitsandbytes, так как не требует предварительной квантизации (загружается на лету).

10. Пет-проект для закрепления

Задача: Сравнить GPTQ, AWQ и bitsandbytes на модели Llama 3.1 8B на стандартных бенчмарках.

Инструменты:

Шаги:

  1. Загрузите модель в FP16 (torch.float16) и измерьте perplexity на wikitext-2 (1000 токенов).
  2. Квантизуйте в 4-bit:
    • GPTQ: используйте AutoGPTQForCausalLM.from_quantized с калибровкой.
    • AWQ: используйте AutoAWQForCausalLM.from_quantized.
    • bitsandbytes: AutoModelForCausalLM.from_pretrained(..., load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16).
  3. Для каждого метода:
    • Измерьте perplexity на том же подмножестве wikitext-2.
    • Измерьте время генерации 100 токенов (среднее за 5 прогонов) через time.time().
    • Запишите пиковое потребление VRAM (nvidia-smi или torch.cuda.max_memory_allocated()).
  4. Сравните результаты в таблице: метод, perplexity, latency (мс/токен), VRAM (GB).

Ожидаемый результат: Вы увидите, что AWQ даёт PPL ≈ 5.2 (против 5.0 в FP16), GPTQ ≈ 5.3, bitsandbytes ≈ 5.5. Latency: GPTQ/AWQ ~20-25 мс/токен, bitsandbytes ~30-35 мс/токен. VRAM: 4-bit ~5.5 GB (против 15 GB в FP16). Это закрепит понимание trade-off'ов.


11. Связь с другими вопросами

ВопросТема
846Как уменьшить размер модели для RAG?
845Оптимизация инференса: tensor parallelism, batching
844Сравнение методов инференса на GPU и CPU
843Как измерить latency и throughput в LLM?
842Развёртывание LLM: ONNX, TensorRT, vLLM

12. Навигация


Навигация