Учебник

Большая нейросеть на своей видеокарте: GGUF, GPTQ, AWQ, EXL2

Модель Llama-3.3-70B в полном виде весит 140 ГБ - на одну карту не влезет. Квантование сжимает её до 40 ГБ, и она запускается на потребительской видеокарте. Разбираем четыре формата квантования: GGUF, GPTQ, AWQ, EXL2. Узнаете, какой выбрать под ваше железо и задачу, как сжать модель самому и не потерять качество. Без программиста - только практические шаги.

Макс Космов··7 мин чтения

У вас есть бизнес-задача, которую могла бы решить большая нейросеть: анализ договоров, генерация контента, обработка заявок. Но модель на 70 миллиардов параметров в полном формате весит 140 гигабайт - это кластер серверных видеокарт за сотни тысяч рублей. А после квантования (сжатия весов с float до 4-8 бит) та же модель занимает 40 гигабайт и запускается на одной потребительской карте за 1500-2000 долларов. Разница - порядок цены и доступность.

Квантование решает две задачи сразу: стоимость (меньше видеопамяти = дешевле сервер) и скорость (меньше данных = быстрее ответы). Потеря качества есть, но для большинства деловых задач она незаметна. Вот как это выглядит на примере Llama-3.1-8B:

Формат Снижение качества Размер модели
FP16 (оригинал) ноль 16 GB
Q8_0 +0,01 PPL (незаметно) 8,5 GB
Q5_K_M +0,07 PPL (незначительно) 5,3 GB
Q4_K_M +0,16 PPL (рабочий компромисс) 4,6 GB
Q3_K_M +0,61 PPL (заметно) 3,5 GB
Q2_K +2,22 PPL (значительная деградация) 2,8 GB

PPL (perplexity, мера неопределённости модели) - чем ниже, тем лучше. Разница между Q4_K_M и оригиналом на большинстве бизнес-задач не ощущается. Q3 и ниже - уже заметно, особенно в аналитических и точных задачах.

Существуют четыре основных формата квантованных моделей: GGUF, GPTQ, AWQ и EXL2. Каждый со своей нишей, сильными сторонами и ограничениями. Разберёмся, что выбрать под вашу задачу.

GGUF и llama.cpp: универсальный формат

GGUF (Generative Pre-trained Transformer Unified Format) - формат проекта llama.cpp. Главное преимущество: работает везде. Процессор, видеокарта NVIDIA, видеокарта AMD, Mac - один файл без лишних зависимостей. Если у вас нет мощной видеокарты, а есть только старый ПК или MacBook - GGUF ваш выбор.

Внутри GGUF есть несколько уровней сжатия. Буква K в названии означает K-quants - улучшенный алгоритм, который сжимает разные части модели с разной точностью. Встраивающие слои остаются в 6-8 битах, промежуточные - в 4-5. Это лучше, чем простое равномерное сжатие.

Q4_K_M -- 4,5 бита на параметр, рекомендуется по умолчанию
Q5_K_M -- 5,5 бита, лучший баланс если видеопамять позволяет
Q6_K -- 6,0 бит, очень близко к Q8 по качеству
Q8_0 -- 8,0 бит, практически без потерь

Уникальная особенность GGUF - гибридная работа CPU+GPU. Если видеокарты не хватает для всей модели, часть слоёв остаётся на процессоре. Например, на старой GTX 1060 с 6 ГБ вы запустите модель, которая целиком не влезает, распределив часть вычислений на процессор.

Следующая команда запускает модель, распределив 20 слоёв на видеокарту и 12 - на процессор. Это позволяет запустить большую модель на скромном железе.

./build/bin/llama-cli \
 -m ./llama-3.1-8b-q4_k_m.gguf \
 --n-gpu-layers 20 \
 --threads 8 \
 -p "Ваш запрос здесь"

Ни GPTQ, ни AWQ, ни EXL2 такого не умеют: им нужно, чтобы вся модель помещалась в видеопамять целиком.

GPTQ: квантование с калибровкой

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

Подходит для развёртывания через vLLM (высокопроизводительный сервер для запуска моделей) и TGI. На Hugging Face огромное количество готовых GPTQ-моделей от сообщества - не нужно квантовать самостоятельно.

Этот код квантует модель Mistral-7B в 4 бита с помощью AutoGPTQ. Параметр group_size=128 - стандартный размер группы весов при сжатии. Процесс занимает 10-20 минут на RTX 4090 и требует около 20 гигабайт видеопамяти. Если у вас нет такой карты - проще скачать готовую модель.

from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from transformers import AutoTokenizer

model_path = "mistralai/Mistral-7B-Instruct-v0.3"
output_path = "./mistral-7b-gptq-4bit"

tokenizer = AutoTokenizer.from_pretrained(model_path)

quantize_config = BaseQuantizeConfig(
 bits=4,
 group_size=128,
 desc_act=True,
)

calib_data = ["...пример текста..."] * 512

model = AutoGPTQForCausalLM.from_pretrained(
 model_path,
 quantize_config=quantize_config
)

model.quantize(calib_data)
model.save_quantized(output_path, use_safetensors=True)
tokenizer.save_pretrained(output_path)

Загрузка готовой GPTQ-модели проста:

from auto_gptq import AutoGPTQForCausalLM

model = AutoGPTQForCausalLM.from_quantized(
 "./mistral-7b-gptq-4bit",
 device_map="cuda:0"
)

AWQ: умное квантование с учётом активаций

AWQ (Activation-aware Weight Quantization) перед сжатием анализирует, какие веса модели важнее для вычислений. Важные каналы сохраняются с большей точностью, менее важные сжимаются агрессивнее. Результат: при том же объёме файла AWQ чуть точнее GPTQ на аналитических задачах - например, при анализе договоров или финансовых отчётов.

Хорошо интегрируется с vLLM через флаг --quantization awq - это делает AWQ предпочтительным выбором для серверного развёртывания.

Этот код квантует модель Qwen3-32B в 4 бита через AutoAWQ. Параметр version: "GEMM" оптимален для пакетной обработки (когда много запросов одновременно), version: "GEMV" - для единичных запросов.

from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer

model_path = "Qwen/Qwen3-32B"
output_path = "./qwen3-32b-awq-4bit"

tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoAWQForCausalLM.from_pretrained(
 model_path,
 safetensors=True,
 trust_remote_code=True
)

quant_config = {
 "zero_point": True,
 "q_group_size": 128,
 "w_bit": 4,
 "version": "GEMM"
}

model.quantize(tokenizer, quant_config=quant_config)
model.save_quantized(output_path)
tokenizer.save_pretrained(output_path)

EXL2: максимальная скорость на NVIDIA

EXL2 - наиболее технически продвинутый формат. Он позволяет задать дробное количество бит: 4,5 или 5,5 бит на параметр. Алгоритм квантует каждую матрицу весов с оптимальной точностью исходя из её чувствительности. Итоговый файл содержит слои с разным квантованием, что даёт лучшее качество при том же среднем объёме.

Ограничение: работает только на видеокартах NVIDIA. Для AMD - не подходит. Если у вас AMD, смотрите в сторону AWQ или GGUF.

Следующая команда квантует Llama-3.1-8B в 5 бит на параметр. Итоговый файл занимает около 5 гигабайт, а скорость генерации в 2-3 раза выше, чем у GGUF Q5_K_M при размещении всей модели на видеокарте.

python -m exllamav2.convert \
 --model_dir ./llama-3.1-8b-hf \
 --output_dir ./llama-3.1-8b-exl2-5bpw \
 --bits 5 \
 --cal_dataset wikitext \
 --cal_rows 256

Этот код загружает и запускает EXL2-модель. ExLlamaV2DynamicGenerator обеспечивает эффективную параллельную генерацию.

from exllamav2 import ExLlamaV2, ExLlamaV2Config, ExLlamaV2Cache
from exllamav2.generator import ExLlamaV2DynamicGenerator

config = ExLlamaV2Config("./llama-3.1-8b-exl2-5bpw")
model = ExLlamaV2(config)
cache = ExLlamaV2Cache(model, max_seq_len=8192)
model.load_autosplit(cache)

generator = ExLlamaV2DynamicGenerator(model=model, cache=cache)
output = generator.generate(prompt="Привет", max_new_tokens=200)

TabbyAPI - популярный OpenAI-совместимый сервер для EXL2.

Сравнение форматов

Критерий GGUF GPTQ AWQ EXL2
Качество при 4 битах Хорошее Хорошее Хорошее Очень хорошее
Скорость генерации Базовая Хорошая Хорошая Высокая
Работа на процессоре Да Нет Нет Нет
Частичная загрузка на GPU Да Нет Нет Нет
AMD Да Частично Частично Нет
Интеграция с vLLM Да Да Да Нет
Дробное число бит Нет Нет Нет Да

Как сквантовать модель самостоятельно в GGUF

Если нужная модель ещё не квантована или хотите сделать это для своей дообученной версии (например, вы обучили модель на своих документах и хотите её сжать), процесс состоит из двух шагов.

Первый шаг конвертирует модель из формата Hugging Face в промежуточный GGUF-файл в полной точности. Второй шаг сжимает его до нужного уровня.

# Шаг 1: конвертировать HF-модель в GGUF F16
python convert_hf_to_gguf.py \
 --model ./my-hf-model \
 --outfile ./my-model-f16.gguf

# Шаг 2: квантовать в нужный формат
./build/bin/llama-quantize \
 ./my-model-f16.gguf \
 ./my-model-q4_k_m.gguf \
 Q4_K_M

Обратите внимание: промежуточный F16-файл занимает примерно 2 гигабайта на каждый миллиард параметров. Для модели 70B потребуется 140 гигабайт на диске.

После квантования полезно проверить качество. Эта команда измеряет perplexity на стандартном тестовом наборе. Если разница с F16 больше 0,5 - возможна проблема с данной архитектурой.

./build/bin/llama-perplexity \
 -m ./my-model-q4_k_m.gguf \
 -f wikitext-2-raw-v1/wiki.test.raw \
 --ctx-size 512

Когда что выбирать

GGUF (Q4_K_M или Q5_K_M):

  • Процессор или гибридная работа CPU+GPU
  • Mac через llama.cpp или Ollama
  • Видеокарты AMD на Linux
  • Нужна широкая совместимость без зависимостей
  • Начинающие - проще всего настроить

EXL2 (4,5-6 бит):

  • Видеокарта NVIDIA, вся модель помещается в видеопамять
  • Нужна максимальная скорость генерации
  • TabbyAPI или прямая Python-интеграция

AWQ:

  • Развёртывание через vLLM в продуктивной среде
  • Пакетная обработка и предоставление инференса как услуги
  • Аналитические задачи

GPTQ:

  • Большой выбор готовых моделей на Hugging Face
  • Интеграция с vLLM и TGI
  • Нужна конкретная готовая квантованная модель без самостоятельного квантования

Типичные ошибки

Слишком агрессивное сжатие. Q2 и Q3 заметно деградируют на точных задачах: юридический анализ, математика, технические расчёты. Если работаете с договорами или финансами - не ниже Q5_K_M.

Нехватка места на диске. Промежуточный F16-файл при самостоятельном квантовании в GGUF занимает вдвое больше итогового. Учитывайте это при планировании дискового пространства.

EXL2 на AMD. ExLlamaV2 не поддерживает ROCm. На AMD с Linux лучший вариант по скорости - AWQ через vLLM с ROCm-портом.

Частые вопросы

Q4_K_M или Q5_K_M - какой выбрать для GGUF?

Q4_K_M - для большинства задач. Разница с Q5_K_M на повседневных задачах практически незаметна. Q5_K_M стоит выбрать для юридических и технических текстов, математики, длинных аналитических цепочек. Разница по объёму для 8B-модели: Q4_K_M - 4,6 гигабайта, Q5_K_M - 5,3 гигабайта. Если видеопамять позволяет - берите Q5_K_M.

AWQ или GPTQ для аналитических задач?

По большинству тестов AWQ чуть точнее на аналитических задачах - за счёт учёта активаций при квантовании. Разница на практике: 0,5-2% по точности. Выбор скорее определяется экосистемой: нужен vLLM - оба работают, нужна быстрая готовая модель с Hugging Face - у GPTQ богаче выбор.

Можно ли сквантовать до 8 бит без потери качества?

Q8_0 в GGUF и INT8 дают качество практически идентичное оригиналу. Разница менее 0,02 PPL. Для большинства задач неощутима. Это де-факто квантование без потерь - выгода только в размере файла и скорости загрузки.

EXL2 работает только на NVIDIA - что делать с AMD?

На AMD с ROCm лучший вариант по скорости - AWQ через vLLM с ROCm-портом. GGUF через llama.cpp с HIP-бэкендом тоже даёт хорошую скорость на RX 7900 XTX.

Как самостоятельно сквантовать модель с Hugging Face в GGUF?

Три шага: скачать через huggingface-cli, конвертировать через convert_hf_to_gguf.py из репозитория llama.cpp, сжать через llama-quantize. Весь процесс занимает 20-60 минут в зависимости от размера. Главное требование - достаточно оперативной памяти для промежуточного F16-файла.

Что дальше

Следующий шаг - развёртывание на собственном сервере для корпоративной безопасности: как запустить LLM-стек с изоляцией от интернета. Если хотите выбрать видеокарту под нужное квантование - изучите гайд по GPU для локального инференса.

AI Компас (t.me/kosmoslab_ai) - канал для предпринимателей в РФ и СНГ, которые применяют AI в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.