Как сравнивать 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-bit | 140 GB | 100% | 1× | Неприменимо (очень медленно) | Нет | High-end GPU (A100 80GB, H100) |
| GPTQ (4-bit) | 4-bit | ~35 GB | 98% | 1.2× | Не поддерживается | Да (128 сэмплов) | GPU, общие задачи (chat, summarization) |
| AWQ (4-bit) | 4-bit | ~35 GB | 99% | 1.1× | Не поддерживается | Да (активации) | GPU, задачи reasoning (математика, логика) |
| bitsandbytes (NF4) | 4-bit | ~35 GB | 96% | 0.9× | Нет (только GPU) | Нет | Быстрое прототипирование, Hugging Face |
| GGUF (Q4_K_M) | 4-bit | ~35 GB | 97% | 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. Метрики сравнения при выборе метода
- Perplexity (PPL): логарифмическая потеря на калибровочном датасете. Чем ниже, тем лучше. Сравниваем с FP16 бейзлайном.
- Latency (время на один токен): измеряется на целевом устройстве. Для чат-ботов важна латентность первого токена (TTFT).
- Throughput (токенов/сек): для батч-инференса. Методы с групповой квантизацией (GPTQ) выигрывают на больших батчах.
- Memory footprint: максимальный размер модели + кеш для KV (key-value cache). Для 70B в 4-bit ~35GB; с KV-кешем (до 64K контекста) может достигать 50 GB.
- Качество на задачах: 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 на стандартных бенчмарках.
Инструменты:
- Python, Hugging Face Transformers, bitsandbytes, AutoGPTQ (для GPTQ), AutoAWQ, evaluate, accelerate.
- GPU: хотя бы 16GB VRAM (подойдёт RTX 4060).
- Калибровочный датасет: 128 примеров из wikitext-2 или c4.
Шаги:
- Загрузите модель в FP16 (
torch.float16) и измерьте perplexity на wikitext-2 (1000 токенов). - Квантизуйте в 4-bit:
- GPTQ: используйте
AutoGPTQForCausalLM.from_quantizedс калибровкой. - AWQ: используйте
AutoAWQForCausalLM.from_quantized. - bitsandbytes:
AutoModelForCausalLM.from_pretrained(..., load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16).
- GPTQ: используйте
- Для каждого метода:
- Измерьте perplexity на том же подмножестве wikitext-2.
- Измерьте время генерации 100 токенов (среднее за 5 прогонов) через
time.time(). - Запишите пиковое потребление VRAM (nvidia-smi или
torch.cuda.max_memory_allocated()).
- Сравните результаты в таблице: метод, 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. Навигация
- Предыдущий: 846
- Следующий: 848
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 846
- Следующий: 848
- Индекс: 00. Индекс разборов