English translation is not available yet. Showing Russian content.

GGUF vs GPTQ vs AWQ — сравнение форматов квантизации для локального запуска?

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

GGUF, GPTQ и AWQ — три популярных формата квантизации больших языковых моделей (LLM) для локального запуска. GGUF ориентирован на CPU и гибридные сценарии (часть слоёв на GPU), обеспечивая максимальную совместимость со слабым железом. GPTQ — формат для GPU, оптимизированный на скорость инференса за счёт групповой квантизации. AWQ — более современный подход, который учитывает распределение активаций и достигает лучшего баланса между качеством и скоростью на GPU. Выбор формата определяется доступным оборудованием и приоритетами (качество, скорость, универсальность).


1. Что такое квантизация и зачем она нужна?

Квантизация — это процесс снижения точности весов модели (например, с 16-битных чисел с плавающей точкой до 4-битных целых). Цель — уменьшить размер модели и ускорить инференс, жертвуя небольшим падением качества.

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

Для локального запуска LLM квантизация критична: модель в 4 бита занимает в 4 раза меньше памяти, чем в 16 бит, что позволяет запускать 7B-модели на видеокартах с 6-8 ГБ VRAM или даже на CPU с 8-16 ГБ RAM.


2. Обзор форматов: GGUF, GPTQ, AWQ

ФорматРазработчикОсновной бэкендЦелевое железо
GGUFllama.cpp communityllama.cppCPU, CPU+GPU (гибрид)
GPTQFrantar et al. (2022)AutoGPTQ, ExLlamaGPU (CUDA)
AWQLin et al. (2023)AutoAWQ, vLLM, TGIGPU (CUDA)

GGUF (GPT-Generated Unified Format) — эволюция GGML, разработан для llama.cpp. Поддерживает различные типы квантизации (q4_0, q4_K_M, q5_1 и др.) и позволяет распределять слои между CPU и GPU.

GPTQ (GPT Post-Training Quantization) — метод, основанный на оптимальном квантовании с учётом гессиана. Использует групповую квантизацию (group size 128 или 32) и требует GPU для инференса.

AWQ (Activation-Aware Weight Quantization) — улучшение над GPTQ: анализирует распределение активаций и масштабирует веса важных каналов, сохраняя их в FP16, а остальные квантизует сильнее. Даёт лучшее качество при той же битности.


3. GGUF: CPU-first и гибридный режим

GGUF — самый универсальный формат для локального запуска. Он поддерживает:

  • Чистый CPU — модель целиком в RAM, инференс на процессоре (медленно, но работает на любом железе).
  • Гибрид CPU+GPU — часть слоёв (обычно последние) выгружается на GPU, остальные на CPU. Позволяет использовать даже 4-6 ГБ VRAM для 7B-модели.
  • Разные типы квантизации — от q2_K (2 бита, сильно теряет качество) до q8_0 (8 бит, почти без потерь). Самые популярные: q4_K_M (4 бита, хороший баланс) и q5_K_M (5 бит, чуть лучше качество).

Инструменты: llama.cpp, Ollama, LM Studio, text-generation-webui.

Пример загрузки модели GGUF через llama.cpp (Python bindings):

from llama_cpp import Llama

llm = Llama(
    model_path="models/llama-3-8b-instruct.Q4_K_M.gguf",
    n_gpu_layers=-1,  # все слои на GPU, если хватает VRAM
    n_ctx=4096,
    verbose=False
)
output = llm("Какой формат квантизации лучше для CPU?", max_tokens=100)
print(output["choices"][0]["text"])

Плюсы GGUF:

  • Работает на CPU (без GPU вообще).
  • Гибкое распределение нагрузки.
  • Огромное сообщество, множество предварительно квантизованных моделей на Hugging Face.

Минусы:

  • Скорость на GPU ниже, чем у GPTQ/AWQ (из-за накладных расходов llama.cpp).
  • Меньше оптимизаций для современных GPU (например, нет поддержки Tensor Cores в полной мере).

4. GPTQ: GPU-only, скорость и эффективность

GPTQ — стандарт для инференса на GPU. Он квантизует веса группами (обычно 128 или 32 параметра) и использует обратную связь по ошибке для минимизации потерь.

  • Требования: только GPU (CUDA). CPU-инференс не поддерживается (или крайне медленный через неофициальные порты).
  • Скорость: очень высокая, особенно на современных картах (RTX 3090/4090, A100). Использует оптимизированные CUDA-ядра.
  • Качество: при group size = 128 почти не уступает FP16, при group size = 32 ещё лучше, но больше размер.

Инструменты: AutoGPTQ, ExLlamaV2, text-generation-webui (через ExLlama).

Пример загрузки GPTQ через AutoGPTQ:

from transformers import AutoTokenizer
from auto_gptq import AutoGPTQForCausalLM

model_name = "TheBloke/Llama-2-7B-Chat-GPTQ"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoGPTQForCausalLM.from_quantized(
    model_name,
    device="cuda:0",
    use_triton=False,
    use_safetensors=True
)
inputs = tokenizer("Расскажи про GPTQ.", return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))

Плюсы GPTQ:

  • Максимальная скорость на GPU.
  • Хорошее качество при правильном group size.
  • Широкая поддержка в инференс-движках (ExLlama, vLLM, TGI).

Минусы:

  • Не работает на CPU.
  • Размер модели чуть больше, чем у GGUF (из-за хранения масштабов и нулевых точек).
  • Требует больше VRAM для загрузки (из-за буферов).

5. AWQ: лучший trade-off quality/speed на GPU

AWQ — эволюция GPTQ. Основная идея: не все веса одинаково важны. AWQ анализирует активации на небольшом калибровочном датасете и определяет, какие каналы (выходные нейроны) наиболее чувствительны к квантизации. Эти каналы остаются в FP16, остальные квантизуются в 4 бита.

  • Качество: часто превосходит GPTQ при той же битности (меньше perplexity на бенчмарках).
  • Скорость: сопоставима с GPTQ, иногда быстрее за счёт меньшего количества операций с FP16.
  • Совместимость: поддерживается vLLM, TGI (Hugging Face), AutoAWQ, ExLlamaV2.

Инструменты: AutoAWQ, vLLM, Text Generation Inference (TGI).

Пример загрузки AWQ через vLLM:

from vllm import LLM, SamplingParams

llm = LLM(model="TheBloke/Llama-2-7B-Chat-AWQ", quantization="awq")
sampling_params = SamplingParams(temperature=0.7, max_tokens=100)
outputs = llm.generate("Сравни AWQ и GPTQ.", sampling_params)
print(outputs[0].outputs[0].text)

Плюсы AWQ:

  • Лучшее качество среди 4-битных форматов.
  • Хорошая скорость на GPU.
  • Поддержка в современных движках (vLLM, TGI).

Минусы:

  • Не работает на CPU.
  • Меньше предварительно квантизованных моделей, чем у GGUF/GPTQ (но быстро растёт).
  • Калибровка требует небольшого датасета (обычно 128-512 примеров).

6. Сравнительная таблица

КритерийGGUFGPTQAWQ
Целевое железоCPU, CPU+GPUGPU (CUDA)GPU (CUDA)
Скорость на GPUСредняяВысокаяВысокая
Скорость на CPUСредняя (зависит от RAM)Не поддерживаетсяНе поддерживается
Качество (perplexity)Хорошее (зависит от типа)ХорошееОтличное
Размер моделиМинимальный (q4_K_M ~4.5 ГБ для 7B)Средний (~5 ГБ для 7B)Средний (~5 ГБ для 7B)
Гибкость (частичная выгрузка на GPU)ДаНетНет
Экосистемаllama.cpp, Ollama, LM StudioAutoGPTQ, ExLlama, vLLMAutoAWQ, vLLM, TGI
Простота использованияВысокая (готовые файлы)Средняя (нужен выбор group size)Средняя (нужна калибровка)
Поддержка новых архитектурБыстрая (llama.cpp активно обновляется)Средняя (зависит от бэкенда)Средняя (но растёт)

7. Как выбрать формат?

Сценарий 1: Только CPU (или очень слабая GPU, 4-6 ГБ VRAM)

  • Выбор: GGUF (q4_K_M или q5_K_M).
  • Причина: только GGUF работает на CPU; гибридный режим позволит задействовать даже маленькую видеокарту.

Сценарий 2: GPU с 8-12 ГБ VRAM, нужна максимальная скорость

  • Выбор: GPTQ (group size 128) или AWQ.
  • Причина: оба формата дают высокую скорость; AWQ предпочтительнее, если качество важнее.

Сценарий 3: GPU с 16+ ГБ VRAM, приоритет качества

  • Выбор: AWQ (или GPTQ с group size 32).
  • Причина: AWQ показывает наименьшую потерю качества; можно также рассмотреть 8-битные версии (FP8, но они реже).

Сценарий 4: Универсальность (запуск на разных машинах)

  • Выбор: GGUF.
  • Причина: один файл работает и на CPU, и на GPU; можно легко перенести модель.

8. Практические аспекты: конвертация и инференс

Конвертация модели в GGUF

Используется скрипт convert.py из llama.cpp:

python convert.py --outfile model.gguf --outtype q4_K_M model.pt

Или скачать готовый файл с Hugging Face (например, от TheBloke).

Конвертация в GPTQ

from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
quantize_config = BaseQuantizeConfig(bits=4, group_size=128)
model = AutoGPTQForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", quantize_config)
model.quantize()
model.save_quantized("llama-2-7b-gptq")

Конвертация в AWQ

from awq import AutoAWQForCausalLM
model = AutoAWQForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf")
model.quantize(tokenizer, quant_config={"bits": 4, "group_size": 128})
model.save_quantized("llama-2-7b-awq")

Замер скорости (пример на Python)

import time

def measure_speed(model, tokenizer, prompt, n_runs=10):
    inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
    start = time.time()
    for _ in range(n_runs):
        model.generate(**inputs, max_new_tokens=50)
    end = time.time()
    return (end - start) / n_runs

9. Влияние на качество: метрики

Основная метрика — perplexity (перплексия) на калибровочном датасете (например, WikiText-2). Чем ниже perplexity, тем лучше качество.

ФорматPerplexity (WikiText-2, Llama 2 7B)
FP16 (baseline)5.47
GGUF q4_K_M5.65
GPTQ (group 128)5.61
AWQ (group 128)5.55

Данные приблизительные, но тенденция: AWQ ближе всего к FP16, GGUF и GPTQ чуть хуже. На реальных задачах разница может быть незаметна.


10. Ограничения и подводные камни

  • Совместимость: не все движки поддерживают все форматы. Например, vLLM не поддерживает GGUF, а llama.cpp не поддерживает GPTQ/AWQ.
  • Скорость загрузки: GGUF-файлы загружаются быстрее, чем GPTQ (из-за отсутствия необходимости распаковывать масштабы).
  • Поддержка новых архитектур: новые модели (Mamba, RWKV) могут не иметь готовых квантизаций. GGUF обычно адаптируется быстрее.
  • Калибровочный датасет: для AWQ и GPTQ нужен репрезентативный датасет. Если датасет не подходит, качество может упасть.
  • Ошибки округления: при очень низкой битности (2-3 бита) даже AWQ может давать артефакты.

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

Задача: Сравнить три формата на одной модели (например, Llama 3 8B) по скорости инференса, размеру файла и качеству (perplexity на датасете WikiText-2).

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

Шаги:

  1. Скачать оригинальную модель (FP16) с Hugging Face.
  2. Квантизовать её в три формата:
    • GGUF q4_K_M (через llama.cpp convert.py)
    • GPTQ group_size=128 (через AutoGPTQ)
    • AWQ group_size=128 (через AutoAWQ)
  3. Для каждого формата:
    • Измерить размер файла.
    • Загрузить модель и прогнать 100 запросов, замерить среднее время генерации 50 токенов.
    • Вычислить perplexity на 1000 примерах из WikiText-2.
  4. Составить таблицу результатов.

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

ФорматРазмер (ГБ)Время на токен (мс)Perplexity
GGUF4.7255.65
GPTQ5.1125.61
AWQ5.0115.55

Вывод: AWQ даёт лучшее качество и скорость, но требует GPU; GGUF — универсальный выбор для слабого железа.


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

ВопросТема
207Основы квантизации LLM
208Бинарная квантизация (1 бит)
210Локальный запуск LLM (Ollama, LM Studio)
211vLLM и оптимизация инференса
212Сравнение бэкендов (llama.cpp, ExLlama, vLLM)
213Выбор модели для локального запуска

Навигация