Квантование LLM: GGUF и AWQ для запуска 70B на домашнем ПК

Квантование LLM: сравнение форматов GGUF и AWQ для инференса 70B БЛОГ

⚡️ Кратко: ключевые факты и быстрый ответ

  • Пункт 1: Квантование сжимает веса модели с 16 бит до 4–8 бит, поэтому 70B вместо ~140 ГБ в FP16 начинает занимать 35–45 ГБ и помещается на одну потребительскую видеокарту.
  • Пункт 2: По данным замеров 2026 года современные K-кванты GGUF (например, Q4_K_M) и AWQ INT4 теряют менее 2% качества относительно FP16, и на большинстве прикладных задач эта разница незаметна.
  • Пункт 3: Практический выбор прост: GGUF — для CPU, Ollama и LM Studio; AWQ или GPTQ — для GPU-сервера на vLLM и SGLang; FP8 и FP4 — только под свежие флагманские ускорители с корректным путём исполнения.
  • Пункт 4: Главный подводный камень — агрессивное квантование бьёт по длинному контексту и работе с инструментами, поэтому качество обязательно замеряют на своих данных до вывода модели в работу.

Содержание
  1. Зачем квантовать LLM: арифметика памяти, скорости и цены железа
  2. GGUF, AWQ, GPTQ и FP8: какой формат подходит вашему железу
  3. Как читать маркировку Q4_K_M, Q5_K_S и IQ-типы квантов
  4. Сравнительная таблица: размер, скорость и потеря качества форматов
  5. Практика: запуск 70B модели в llama.cpp и Ollama шаг за шагом
  6. Шаг 1. Скачиваем веса
  7. Шаг 2. Запускаем в llama.cpp
  8. Шаг 3. Ollama — то же самое, но в одну строку
  9. Шаг 4. Замеряем скорость
  10. GPU-инференс на vLLM: AWQ против FP8 на одном ускорителе
  11. Как замерить качество кванта на своих данных и не потерять точность
  12. KV-кэш и длинный контекст: скрытый пожиратель видеопамяти
  13. Подводные камни: деградация на длинном контексте и ложная экономия
  14. Инженерная защита данных при локальном инференсе
  15. Часто задаваемые вопросы (FAQ)
  16. Влезет ли 70B-модель в 4 битах на одну видеокарту с 24 ГБ памяти?
  17. GGUF или AWQ — что брать под моё железо?
  18. Насколько реально проседает качество на 4 битах? Можно ли верить «потере менее 2%»?
  19. Какой тип квантования GGUF выбрать: Q4_K_M, Q5_K_M, Q6_K или Q8_0?
  20. Зачем квантовать KV-кэш и не убьёт ли это длинный контекст?
  21. 💡 В сухом остатке: главное

Зачем квантовать LLM: арифметика памяти, скорости и цены железа

Квантование сжимает веса LLM с 16 до 4–8 бит: 70B-модель усыхает со 140 ГБ до 35–40 ГБ, а просадка качества в GGUF K-Quant по замерам держится в пределах двух процентов.

Вся арифметика здесь упирается в одну строчку. Объём весов равен числу параметров, умноженному на биты и поделённому на восемь. Для 70B в FP16 это 70 млрд × 16 / 8 = 140 ГБ. В чистом INT4 — те же 70 млрд × 4 / 8 = 35 ГБ. Ровно в четыре раза меньше, и никакой магии.

Формат Бит на вес Размер 70B Что это даёт
FP16 / BF16 16 ≈140 ГБ Эталон качества, нужен кластер
FP8 / INT8 8 ≈70 ГБ Экономия вдвое, потери почти нулевые
INT4 (AWQ / GPTQ) 4 ≈35 ГБ GPU-сервер, vLLM, высокий батч
Q4_K_M (GGUF) 4,5–4,8 ≈40–42 ГБ CPU + GPU, Ollama, LM Studio
Q8_0 (GGUF) 8,5 ≈75 ГБ Почти эталон, но памяти вдвое больше

Обратите внимание на Q4_K_M: он тяжелее «чистого» INT4. Часть слоёв — эмбеддинги, выходной слой, первые и последние блоки — остаётся в повышенной точности, потому что именно они сильнее всего бьют по качеству. Отсюда и лишние 5–7 ГБ.

К весам нужно прибавить KV-кэш. Формула такая: 2 × число слоёв × число KV-голов × размерность головы × длина контекста × байты. Для 70B-архитектуры с 80 слоями, 8 KV-голов (GQA), head_dim 128 и FP16 это порядка 320 КБ на токен. На 8k контекста — около 2,7 ГБ, на 32k — уже 10,7 ГБ.

⚠️ Подводный камень: люди считают только веса и покупают две карты по 24 ГБ под Q4_K_M. По факту 40 ГБ весов + 10,7 ГБ KV на длинном контексте + 1,5–2 ГБ на активации и контекст CUDA дают около 53 ГБ. Двух карт не хватает, нужен пул на 64 ГБ и больше.

Дальше начинается выбор железа. Одна RTX 4090 на 24 ГБ 70B не удержит даже в INT4 — придётся выгружать слои на CPU, и скорость проваливается до единиц токенов в секунду. Две карты по 24 ГБ уже собирают модель целиком. Один ускоритель на 80 ГБ закрывает вопрос с запасом под длинный контекст.

FP16-вариант — это два A100 по 80 ГБ или четыре карты класса RTX 6000 Ada. Разница в требованиях к железу между FP16 и INT4 — не проценты, а порядок: домашняя сборка против серверной стойки.

💡 Инсайт: скорость генерации упирается не в вычислитель, а в пропускную способность памяти. Потолок примерно равенПСП (пропускная способность памяти) / объём весов. Для карты с 936 ГБ/с и 40 ГБ весов это около 23 токенов в секунду теоретически, а на практике сообщество llama.cpp получает в 1,5–2 раза меньше. Квантование ускоряет инференс именно потому, что читает из памяти вчетверо меньше байт.

Качество при этом почти не страдает. По данным разбора методов квантования на AiManual, современные GGUF с K-Quant теряют менее 2% качества относительно FP16 — для большинства прикладных задач это незаметно. Оговорка одна: на задачах с длинными логическими цепочками и точным кодом разрыв чувствуется сильнее.

Хотите увидеть ту же логику на меньшем масштабе — у нас есть разбор про то, как локальная модель SQL на ноутбуке обошла флагмана в тестах: там квантование и есть тот самый рычаг, который позволил уложиться в потребительскую память.

GGUF, AWQ, GPTQ и FP8: какой формат подходит вашему железу

GGUF — для CPU, Ollama и LM Studio, AWQ и GPTQ — для GPU-инференса на vLLM, FP8 — для флагманских ускорителей уровня H100 и B200. Выбор формата диктует не мода, а связка «процессор + видеопамять + движок инференса».

Давайте разберем на пальцах. Модель на 70B в FP16 занимает около 140 ГБ — это четыре топовые видеокарты или одна серверная. В 4 битах те же веса сжимаются примерно до 35 ГБ плюс накладные расходы на кэш и метаданные. Разница между форматами не в степени сжатия, а в том, где и как быстро эти веса разворачиваются.

Формат Где живёт Железо Вес 70B Когда брать
GGUF (Q4_K_M, Q5_K_M) llama.cpp, Ollama, LM Studio CPU, любой GPU, Apple Silicon ~40 ГБ Домашний запуск, одна машина, гибкая выгрузка слоёв
AWQ (W4A16) vLLM, SGLang NVIDIA GPU от 16–24 ГБ ~40 ГБ Продакшен-API, диалоговые и инструкционные модели
GPTQ (INT4) vLLM, transformers NVIDIA GPU ~40 ГБ Старые конвейеры, где уже есть готовые веса
FP8 vLLM, TensorRT-LLM H100, B200 и новее ~70 ГБ Максимальная пропускная способность на флагманах

GGUF — это не просто формат, а целая экосистема вокруг llama.cpp. Файл хранит веса, словарь и конфигурацию архитектуры в одном переносимом контейнере, а собственные типы квантования заточены под эффективный инференс на CPU. По данным разбора AiManual, современные K-Quant-схемы вроде Q4_K_M теряют менее 2% качества относительно FP16 — на большинстве практических задач это не заметно.

Уместность формата хорошо видна на бытовых сценариях: если вы гоняете локальную модель на ноутбуке без дискретной видеокарты, альтернативы GGUF просто нет. Как в кейсе с локальной моделью SQL, которая обошла флагмана в тестах, — там решает не абсолютная точность, а возможность вообще запустить модель без облака.

На GPU-серверах правила меняются. AWQ учитывает не только веса, но и распределение активаций, поэтому при 4 битах держит смысл генерации лучше классического GPTQ — особенно на инструкционных моделях. Именно поэтому в разборе Serverflow AWQ называют следующим шагом после GPTQ, а не его заменой.

⚠️ Подводный камень: 4 бита не равны 4 битам. Q4_K_M, AWQ INT4 и GPTQ INT4 дают разный результат на одной и той же модели. Замерять качество нужно на своих данных и до выката в бой, иначе просадку вы поймаете уже на живых запросах.

FP8 — история для тех, у кого есть H100, B200 или свежие ускорители. Формат экономит память и ускоряет матричные операции, но требует корректного пути исполнения в рантайме. Практический разбор форматов 2026 года прямо предупреждает: без проверки качества на FP8 можно получить красивый график токенов в секунду и сломанную логику ответов. По данным обзора НЬЮ-ССТ, итоговое правило простое: GGUF для CPU и Ollama, AWQ или GPTQ для GPU на vLLM, FP8 для флагманов — и обязательный замер качества на своих данных перед каждым из них.

Как читать маркировку Q4_K_M, Q5_K_S и IQ-типы квантов

Маркировка кванта в GGUF читается в три шага: число бит на вес, метод сжатия и вариант размера. Q4_K_M означает 4 бита, метод K-quant и средний вариант — типовой компромисс между размером файла и качеством генерации.

Первая цифра после буквы Q — базовое число бит на параметр. Дальше идёт метод сжатия: буква K означает K-quant, где веса бьются на суперблоки по 256 значений, а внутри работают подблоки со своими масштабами. Такая схема заметно точнее старого линейного Q4_0 при почти том же размере файла.

Последняя буква — самая непонятная. Суффиксы S (small), M (medium) и L (large) показывают, сколько тензоров поднято в более высокий разряд. В Q4_K_M ключевые слои внимания и часть полносвязных слоёв уходят в Q6_K, а в Q4_K_S всё остаётся честным Q4_K. Разница в размере — единицы процентов, в качестве — куда заметнее.

Отдельная ветка — IQ-кванты. Перед сжатием модель прогоняют по калибровочному корпусу и смотрят, какие связи реально влияют на выход. Важные веса получают больше бит, второстепенные сжимаются агрессивнее.

IQ4_XS — ровно такой случай. Он весит около 4,25 бита на параметр против 4,85 у Q4_K_M: файл меньше, а качество держится сопоставимое. Плата за это — калибровочная матрица значимости при сборке кванта и более скромная скорость на процессорах без AVX2, где часть инструкций уходит в медленный запасной путь.

Квант Бит на вес Размер для 70B Типичный разброс качества
FP16 16 ~140 ГБ эталон
Q8_0 8,5 ~74 ГБ практически неотличимо
Q6_K 6,6 ~57 ГБ доли процента
Q5_K_M 5,7 ~50 ГБ около 1%
Q4_K_M 4,85 ~42 ГБ менее 2%
IQ4_XS 4,25 ~37 ГБ порядка 2%
Q3_K_M 3,9 ~34 ГБ заметная деградация логики
IQ2_M 2,7 ~24 ГБ ломается на сложных задачах

Размеры посчитаны как «число параметров × бит на вес ÷ 8» и у конкретных моделей гуляют на 1–3% из-за словаря и служебных тензоров. Оценка качества — усреднённая по публичным замерам; на вашей задаче цифры могут отличаться сильнее.

⚠️ Подводный камень: IQ-кванты почти всегда требуют матрицы значимости при сборке, иначе результат выходит хуже обычного Q4. Плюс свежие сборки движка поддерживают их неодинаково — если модель уходит в бесконечный повтор, первым делом проверяйте версию llama.cpp, а не обвиняйте модель.

💡 Инсайт: Не гонитесь за минимальным файлом. На 70B переход с Q4_K_M на Q5_K_M стоит около 8 ГБ оперативной памяти, а вот откат к Q3_K_M уже рушит цепочки рассуждений на задачах вроде анализа кода. Порог «дешевле, но ещё работает» проходит где-то по Q4.

По данным разбора форматов GGUF и INT4, современные K-методы дают потерю качества меньше 2% на четырёх битах, и для большинства практических сценариев это незаметно. Но проверять на своих данных всё равно обязательно.

Как это выглядит в деле на домашнем железе, мы разбирали в материале про локальную модель SQL, которая обошла флагмана в тестах — там квантованные веса решали судьбу всей затеи.

Сравнительная таблица: размер, скорость и потеря качества форматов

Для 70B-модели переход с FP16 на 4-битное квантование сжимает веса примерно с 140 до 40–43 ГБ, то есть втрое с лишним, а потеря качества по практическим замерам обычно укладывается в 2%.

Дальше начинается арифметика, которая не врёт. Один параметр в FP16 занимает 2 байта — значит, 70 млрд × 2 = 140 ГБ. Восемь бит дают около 70 ГБ, четыре — порядка 35 ГБ. Реальный файл всегда тяжелее «чистой» математики, потому что метаданные и критичные тензоры в GGUF остаются в повышенной точности. Поэтому Q4_K_M у 70B весит не 35, а 40–43 ГБ.

И ещё один момент, который чаще всего ломает планы. Размер файла — это не требуемая память. К весам добавляется KV-кэш, и на длинном контексте он съедает гигабайты. У типичной 70B-архитектуры с 8 KV-головами и 80 слоями один токен контекста стоит около 0,3 МБ; на 8K это ~2,5 ГБ, а на 32K — уже ~10 ГБ.

⚠️ Подводный камень: цифры в таблице — порядок величин, а не гарантия. Скорость меняется от драйверов, версии движка, длины контекста и того, сколько слоёв ушло на CPU. Перед выбором формата прогоните свои задачи на своём железе и только потом фиксируйте конфигурацию.

Формат Размер весов 70B Скорость, ток/с (ориентир для 2×24 ГБ) Память с контекстом 8K Падение качества
FP16 / BF16 ~140 ГБ не, только выгрузка на CPU ~145 ГБ эталон, 0
FP8 ~70 ГБ высокая, но нужен GPU с аппаратной поддержкой FP8 ~73 ГБ менее 0,5%
Q8_0 (INT8) ~70–75 ГБ единицы, с выгрузкой на CPU ~75 ГБ ~0,5–1%
Q6_K ~57–60 ГБ 5–10 ~60 ГБ менее 1%
Q5_K_M ~48–50 ГБ 5–12 ~51 ГБ ~1%
Q4_K_M ~40–43 ГБ 8–15 ~43–45 ГБ 1–2%
AWQ INT4 (W4A16) ~38–40 ГБ 15–25 на vLLM ~42 ГБ 1–2%, точнее классического GPTQ на диалоговых моделях
GPTQ INT4 ~35–38 ГБ 15–25 на vLLM ~40 ГБ 1–2%, на инструкциях чуть слабее AWQ
Q3_K_M ~33–35 ГБ 10–20 ~36 ГБ заметное: провалы в логике и коде
2-битные (IQ2 и аналоги) ~20–22 ГБ 15–25 ~23 ГБ сильное, для сложных задач не годится
Размеры весов — расчёт по разрядности и данные практических обзоров; скорость — порядок величин, зависит от GPU и длины контекста

Главный вывод таблицы не в килобайтах, а в том, что 4-битные K-кванты перестали быть компромиссом. По данным практического руководства по квантованию LLM, современные GGUF-форматы с K-Quant теряют менее 2% качества относительно FP16, и для большинства прикладных задач это незаметно.

Дальше выбор диктует не качество, а движок. GGUF живёт в llama.cpp, Ollama и LM Studio — это домашний и CPU-сценарий. AWQ и GPTQ нужны там, где стоит vLLM или серверный конвейер обработки запросов: у AWQ активационно-осознанное квантование даёт более высокую точность на диалоговых моделях, о чём пишут в разборе AWQ от Serverflow. А FP8 и FP4 — история для ускорителей уровня H100 и B200, на потребительском железе они пока либо не заведутся, либо не дадут выигрыша.

Примерно так же мы разбирали экономию ресурсов в материале про локальную модель SQL, которая обошла флагмана в тестах — правильный формат важнее, чем лишние гигабайты.

💡 Инсайт: берите Q4_K_M как точку старта для дома и AWQ INT4 — для сервера на vLLM. Опускаться ниже 4 бит стоит только тогда, когда модель иначе физически не помещается в память: выигрыш в гигабайтах там уже не отбивает провалов в логических рассуждениях.

Практика: запуск 70B модели в llama.cpp и Ollama шаг за шагом

Запуск 70B-модели локально — это три шага: скачать GGUF-веса в квантовании Q4_K_M, поднять их через llama.cpp или Ollama и замерить скорость встроенными утилитами llama-bench либо флагом —verbose.

Сразу про железо, чтобы не терять вечер впустую. Файл Q4_K_M для 70B весит около 42–43 ГБ, плюс KV-кэш. Комфортно это живёт на 48 ГБ видеопамяти (две карты по 24 ГБ) или на Mac с 64 ГБ единой памяти. На одиночной карте с 24 ГБ придётся выгружать слои частично, и скорость упадёт в разы.

Шаг 1. Скачиваем веса

pip install -U "huggingface_hub[cli]"

hf download bartowski/Llama-3.3-70B-Instruct-GGUF \
  --include "*Q4_K_M.gguf" \
  --local-dir ./models

Утилита hf — это переименованный huggingface-cli. Часть репозиториев отдаёт веса нарезанными на куски вида ...-00001-of-00002.gguf. Их склеивают в один файл командой llama-gguf-split --merge, иначе движок просто не увидит модель.

Шаг 2. Запускаем в llama.cpp

llama-cli -m ./models/Llama-3.3-70B-Instruct-Q4_K_M.gguf \
  -ngl 99 --ctx-size 8192 -t 8 \
  -p "Объясни разницу между Q4_K_M и Q5_K_M"

Ключ -ngl 99 отправляет в ускорение все слои, --ctx-size задаёт окно контекста. Если карт две, добавьте --tensor-split 1,1 и --split-mode layer — так веса разложатся по устройствам ровно.

Шаг 3. Ollama — то же самое, но в одну строку

ollama pull llama3.3:70b-instruct-q4_K_M
ollama run llama3.3:70b-instruct-q4_K_M

Ollama сама подберёт раскладку между видеопамятью и процессором, а покажет её команда ollama ps. Нужен свой файл — заведите Modelfile с директивой FROM /путь/к/модели.gguf.

Шаг 4. Замеряем скорость

llama-bench -m model.gguf -p 512 -n 128 -r 3

Утилита вернёт два честных числа: pp512 — скорость обработки промпта и tg128 — скорость генерации, токенов в секунду. В Ollama тот же замер даёт флаг --verbose, где это строки «prompt eval rate» и «eval rate».

⚠️ Подводный камень: Ollama по умолчанию занижает окно контекста, а при его ручном увеличении KV-кэш съедает ещё несколько гигабайт — на 70B при 8 тыс. токенов это порядка 2,5 ГБ. Плюс первый прогрев после загрузки всегда медленнее: замеряйте не первую, а третью итерацию.

💡 Инсайт: генерация упирается в пропускную способность памяти, а не в число ядер. Оценка сверху — объём весов делить на полосу: 42 ГБ / 100 ГБ/с ≈ 2,4 токена в секунду для процессора на DDR5. Отсюда вывод: апгрейд памяти даёт больше, чем апгрейд процессора.

Квантование Размер 70B Под что подходит
Q4_K_M ~42–43 ГБ базовый выбор для 48 ГБ видеопамяти и 64 ГБ единой памяти
Q5_K_M ~50 ГБ чуть выше точность, нужен запас памяти
Q8_0 ~75 ГБ почти FP16, но дома уже тесно
FP16 ~140 ГБ эталон для сравнения, не для ноутбука

По данным разбора на AiManual, современные K-кванты теряют менее 2% качества относительно FP16 — для большинства задач это незаметно. Но замер на своих данных никто не отменял: прогоните десяток типовых запросов и сравните ответы с FP16 глазами, а не по цифре в названии файла.

Если 70B на домашнем железе всё ещё тяжеловата, начните с моделей меньшего размера — в материале про локальную модель SQL, которая обошла флагмана в тестах, показан похожий сценарий для компактных весов.

GPU-инференс на vLLM: AWQ против FP8 на одном ускорителе

На одной видеокарте vLLM поднимает 70B-модель либо в AWQ, либо в FP8. Веса AWQ занимают около 35 ГБ, FP8 — примерно 70 ГБ. Отсюда развилка по железу: int4 стартует на 48 ГБ, FP8 требует 80 ГБ и ускорителя Ada или Hopper.

Считаем на пальцах. 70 млрд параметров при 4 битах дают 35 ГБ (в гибибайтах ≈32,6), при 8 битах — уже 70 ГБ, а в FP16 — 140 ГБ. Но веса это только часть уравнения: сверху ложатся KV-кэш, активации и буферы CUDA-графов. Именно поэтому 48-гигабайтная карта тянет 70B в AWQ и гарантированно падает на FP8.

Параметр AWQ (W4A16) FP8 (W8A8)
Битность весов 4 8
Вес модели 70B ≈35 ГБ ≈70 ГБ
Минимум видеопамяти 48 ГБ 80 ГБ
Рабочие архитектуры Ampere, Ada, Hopper Ada, Hopper
Ядра в vLLM awq_marlin fp8, fp8_marlin

Конфигурация для int4 выглядит буднично:

python -m vllm.entrypoints.openai.api_server \
  --model /models/your-org/70b-awq \
  --quantization awq_marlin \
  --dtype float16 \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.92 \
  --tensor-parallel-size 1

Вариант под FP8 отличается парой флагов, зато требует соответствующего железа:

python -m vllm.entrypoints.openai.api_server \
  --model /models/your-org/70b-fp8 \
  --quantization fp8 \
  --kv-cache-dtype fp8 \
  --max-model-len 16384 \
  --gpu-memory-utilization 0.90

Теперь про пропускную способность под батчами. На одиночном запросе декодирование упирается в пропускную способность видеопамяти: чем меньше байт весов читает ускоритель на каждый токен, тем выше скорость. Здесь AWQ отыгрывает заметно.

С ростом батча узкое горлышко смещается к вычислительным блокам, и более быстрые FP8-ядра начинают сокращать разрыв. Плюс int4 освобождает память под KV-кэш, а это прямой путь к большему числу одновременных сессий в continuous batching. Что выгоднее в вашем профиле нагрузки, покажет только замер: универсальной цифры «на столько-то процентов» не существует.

💡 Инсайт: Считайте не только веса, но и свободный остаток под KV-кэш. Флаг --gpu-memory-utilization 0.90 и ограничение --max-model-len часто дают больше прироста суммарной пропускной способности, чем смена формата квантования.

⚠️ Подводный камень: FP8-ядра требуют архитектуры Ada или Hopper. На Ampere (например, A100) запуск с --quantization fp8 не поднимется, и никакой --dtype это не обойдёт.

Частые ошибки загрузки весов в vLLM выглядят так:

  • «Unknown quantization method» — флаг есть, а сборка vLLM старая. Обновите пакет, ядро awq_marlin появилось не сразу.
  • Нет quantization_config в config.json — автодетект молчит, и модель грузится как обычная, а затем падает на несовпадении размеров тензоров. Указывайте --quantization руками.
  • GGUF в vLLM — поддержка ограничена, это формат экосистемы llama.cpp и Ollama. Для GPU-сервера берите AWQ или GPTQ.
  • Скачан не весь набор шардов — ошибка вида «Cannot find the file» лечится повторной загрузкой репозитория целиком.
  • Не влез KV-кэш — уменьшайте --max-model-len, а не надейтесь на чудо.

Если ускорителя под рукой нет вовсе, взгляните на наш разбор про локальную модель, которая обошла флагмана в тестах. А за деталями активационно-осознанного квантования и того, почему int4 обходит классический GPTQ на диалоговых моделях, идите к разбору AWQ от Serverflow.

Как замерить качество кванта на своих данных и не потерять точность

Качество кванта проверяют на своём наборе из 30–100 живых промптов: сравнивают ответы INT4-версии с FP16 по метрикам задачи, а не по перплексии, и держат расхождение в пределах 1–3%.

Перплексия для диалоговых моделей — плохой судья. Она усредняет всё подряд и почти не реагирует на то, что для вас критично: сломанный JSON, потерянное имя клиента, ответ не на русском.

Поэтому набор задач собирают из реальных обращений. Минимум четыре корзины: извлечение сущностей и структурированный вывод, ответы по вашей базе знаний, многошаговые логические рассуждения, следование формату и роли.

Тип задачи Что сравниваем Рабочий порог расхождения
Извлечение сущностей, JSON Доля полностью корректных структур до 1 процентного пункта к FP16
Ответы по базе знаний Доля фактически верных ответов 1–3% относительного падения
Многошаговые рассуждения Доля верных цепочек вывода до 3–5% — иначе меняем квант
Формат и роль Доля валидных ответов, доля отказов, смены языка, повторы любое падение — красный флаг
Скорость и память Токены в секунду, время до первого токена, объём видеопамяти не качество, но фиксируем всегда

⚠️ Подводный камень: Сравнивать кванты нужно при одинаковом шаблоне чата, системном промпте и температуре 0. Если этого не сделать, разброс генерации окажется шире разницы между весами, и вы будете измерять шум, а не деградацию модели.

Единого отраслевого порога не существует — он выводится из цены ошибки. Для чат-бота с консультациями 3% потерянных фактов терпимо, для парсера счетов даже один процент битых структур означает ручной разбор.

По данным разбора методов квантования, современные GGUF-схемы с K-Quant на 4 битах часто теряют менее 2% качества относительно FP16, и для большинства практических задач это незаметно. А в блоге Serverflow отмечают, что AWQ при INT4 обычно точнее классического GPTQ именно на instruction и диалоговых моделях.

Диалоговым моделям нужны свои метрики: доля валидных ответов, доля отказов, средняя длина, повторы, соблюдение персоны. Плюс парные слепые сравнения — один промпт, два ответа, оценщик не знает, где FP16.

И не забывайте про вторую половину уравнения: токены в секунду и потребление памяти. Иногда лишний процент точности не стоит просадки скорости вдвое. Хороший пример того, как цифры обретают смысл только на своём железе и своём наборе задач, — тесты локальной модели SQL на ноутбуке.

В сухом остатке: до 2% расхождения — берём квант в работу, 3–5% — разбираемся по типам ошибок, больше — ищем другую схему или другую модель.

KV-кэш и длинный контекст: скрытый пожиратель видеопамяти

KV-кэш хранит ключи и значения всех предыдущих токенов и растёт линейно с длиной контекста: у 70B-модели с GQA это примерно 320 КиБ на токен в FP16, то есть 10 ГиБ на 32 тысячи токенов.

Механика простая. При генерации каждый новый токен «оглядывается» на все предыдущие, и чтобы не пересчитывать их заново на каждом шаге, движок складывает промежуточные тензоры K и V в память. Освобождается она только после завершения генерации — не после ответа в чате, а именно после закрытия сессии.

Формула бюджета выглядит так: 2 × число слоёв × число KV-голов × размер головы × 2 байта. Для типовой 70B с 80 слоями, 8 KV-головами и головой в 128 элементов получается те самые 320 КиБ на токен. Если модель собрана на классическом многоголовом внимании без GQA, множьте на восемь — и это уже другой разговор про железо.

⚠️ Подводный камень: KV-кэш не делится между запросами. Четыре параллельных диалога при контексте 32k — это около 40 ГиБ только под кэш, поверх весов. Именно поэтому инференс-серверы упираются в память раньше, чем в вычислители.

Длина контекста FP16 Q8_0 Q4_0
8 192 токена 2,5 ГиБ 1,3 ГиБ 0,7 ГиБ
32 768 токенов 10 ГиБ 5,3 ГиБ 2,8 ГиБ
65 536 токенов 20 ГиБ 10,6 ГиБ 5,6 ГиБ
131 072 токена 40 ГиБ 21,3 ГиБ 11,3 ГиБ
Расчёт для одной последовательности, 70B с GQA (80 слоёв, 8 KV-голов, голова 128)

Теперь про квантование самого кэша. В llama.cpp это делается двумя флагами: --cache-type-k q8_0 --cache-type-v q8_0, и обязательно вместе с --flash-attn — без него квантование V просто не включится. В vLLM аналог называется --kv-cache-dtype fp8 и работает на свежих ускорителях.

💡 Инсайт: Ключи и значения неравноценны. K-кэш переносит Q8_0 практически без последствий, а V-кэш чувствительнее: снижение до Q4_0 уже заметно на длинных диалогах и задачах поиска факта в середине документа. Компромисс — K в Q8_0, V в Q8_0; Q4_0 оставляйте на крайний случай, когда контекст важнее тонкой связности ответа.

Отдельно про честность цифр. Тезис «4-битное квантование теряет менее 2% качества» из обзоров относится к весам модели, а не к KV-кэшу — это разные истории, и переносить одну оценку на другую некорректно. Данные по потере качества при квантовании кэша сильно зависят от модели и длины контекста, поэтому замер на своих данных до боевого запуска обязателен.

Рабочая конфигурация для домашнего узла на 48 ГБ: 70B в Q4_K_M, контекст 32k, K и V в Q8_0, включённый flash attention. Это даёт около 5 ГиБ под кэш и оставляет запас под буферы и пакетную обработку. Если нужен контекст 128k, честнее взять модель с архитектурой, сжимающей кэш на уровне внимания (семейство DeepSeek с его MLA), чем выжимать FP16 на потребительской карте.

Подробный разбор типов квантования и их влияния на инференс есть в материале LLM-инференс в продакшене: квантование и KV-кэш, а базовые оценки потерь качества — в обзоре AiManual по квантованию LLM. Из наших прошлых разборов пригодится история про локальную модель SQL на ноутбуке — там как раз видно, как настройки памяти решают, поедет модель или нет.

Подводные камни: деградация на длинном контексте и ложная экономия

Самый компактный квант почти всегда проигрывает на длинном контексте и на задачах, где нужна точность: общие замеры этого не показывают, потому что 4 бита бьют не по среднему качеству, а по «хвостам» поведения модели.

По данным разбора на AiManual, современные схемы с K-квантованием к началу 2026 года теряли менее 2% качества относительно FP16. Звучит как разрешение брать Q4 и не думать.

Но эти проценты собраны на коротких вопросах-ответах. А 70B-модель вы тащите на потребительское железо ради длинных документов, больших файлов кода и многошаговых рассуждений. Вот там и вылезает разница.

⚠️ Подводный камень: Деградация кванта проявляется не в общих тестах, а в трёх местах: точное извлечение факта из середины длинного контекста, удержание жёсткого формата ответа (JSON, SQL) и редкие языки или нишевые библиотеки в коде. На Q4 там начинаются пропуски и «галлюцинации по мелочи», которых на Q5_K_M или Q6_K просто нет.

Отдельная ловушка — арифметика памяти. Вы ужимаете веса 70B с 140 ГБ в FP16 до ~42 ГБ в Q4_K_M и радуетесь освободившимся ~98 ГБ. Но память ест не только вес модели.

Кэш ключей и значений растёт линейно с длиной контекста. Для типовой 70B-архитектуры с групповым вниманием это порядка 0,3 МБ на токен. На 128 тыс. токенов набегает около 39 ГБ — и половина вашей экономии испаряется прямо в диалоге.

Отсюда второй смысл «ложной экономии»: люди ужимают веса, а потом получают падение скорости на длинных запросах и ошибки при переполнении контекста. Лечится это квантованием самого кэша (в 8 бит) и честным лимитом длины, а не выбором ещё более жёсткого кванта весов.

💡 Инсайт: Замеряйте качество на своих данных до боевого запуска. Возьмите 30–50 реальных задач с длинным контекстом и прогоните две-три конфигурации рядом: Q4_K_M, Q5_K_M, Q6_K. Разница в размере между ними — единицы гигабайт, а разница в поведении на вашем сценарии может быть принципиальной.

Полезный ориентир: GGUF с K-квантами — для CPU и локальных сборок, AWQ и GPTQ — для GPU-инференса на vLLM. Про требования к железу и подбор конфигурации мы подробно разбирали в материале про локальную модель SQL на ноутбуке — там как раз про то, где компактный квант вытягивает, а где нет.

Правило простое: выбирайте самый компактный квант, который проходит ваши замеры, а не тот, что влезает в память. Влезть — этонеобходимое условие, но не доказательство работоспособности.

Инженерная защита данных при локальном инференсе

Локальный инференс защищает данные только при трёх условиях: модель не отправляет телеметрию, журналы обезличены, а исходящий трафик проходит через управляемый шлюз.

Запуск весов на своём железе сам по себе ничего не гарантирует. Большинство утечек случается не на этапе генерации, а на периферии: отладочные журналы клиентов пишут полные подсказки, приложения втихую отправляют метрики, а конвейер обработки сохраняет кэш ключей и значений на диск — и там исходный диалог лежит открытым текстом.

Проверка занимает пять минут. Задайте модели вопрос с меткой-маркером вроде «тестовый договор № 000» и поищите эту строку по каталогам с журналами и кэшем. Находится чаще, чем хочется.

📌 Важно: обезличивать нужно на входе, до попадания данных в модель. Фильтрация на выходе бесполезна: чувствительный фрагмент уже прошёл через кэш, журналы и, возможно, второй контур.

Базовая схема маскирования выглядит так. Модуль распознавания сущностей вырезает из текста имена, телефоны, почту, номера счетов и адреса, подставляя вместо них стабильные маркеры вида «PERSON_1» и «PHONE_2». Модель работает с обезличенным текстом, а обратная замена происходит в приложении, которое держит карту соответствий у себя.

Карту лучше хранить в памяти процесса и уничтожать после завершения сессии. Регулярные выражения уверенно ловят телефоны и почту, но спотыкаются на именах в косвенных падежах и на адресах — здесь нужен нормальный распознаватель сущностей, а не набор шаблонов.

⚠️ Подводный камень: маркеры ломают связность ответа. Модель видит неестественный текст и путает роли, поэтому замену стоит тестировать на реальных сценариях, а не на одном демо-примере.

Второй контур — сетевая изоляция. У локальной модели не должно быть исходящего доступа в интернет: ни для проверки обновлений, ни для отправки статистики. На практике это отдельный сегмент сети, белый список адресов и прокси, пропускающий лишь разрешённые маршруты.

Если внешний API всё же нужен, перед ним ставят шлюз, который проверяет запросы и ведёт журнал. Тогда решение о том, что уходит наружу, принимает инфраструктура, а не разработчик в спешке перед демонстрацией.

Канал утечки Что попадает наружу Инженерная мера
Журналы приложения Полные подсказки и ответы Отключить запись содержимого, оставить метаданные
Телеметрия клиента Версия, окружение, иногда тексты Блокировка доменов на уровне шлюза
Кэш ключей и значений Фрагменты диалога Хранить в памяти или шифровать том
Внешний API Обезличенный текст Обязательное маскирование перед отправкой

Отдельная головная боль — агенты с доступом к базам. Подключение ИИ к корпоративным хранилищам удобно, но именно там проще всего потерять контроль над тем, какие строки уезжают в подсказку; типовые грабли мы разбирали в материале про MCP-протокол и корпоративные базы данных. Технические детали по кэшу и его влиянию на память подробно разобраны в разборе квантования LLM от AiManual.

Правовые нормы динамичны и требуют предварительной проверки юристами компании. Инженерная часть неизменна: минимум данных на входе, отсутствие лишних исходящих каналов и журналы, которые не превращаются во вторую копию базы.

Часто задаваемые вопросы (FAQ)

Влезет ли 70B-модель в 4 битах на одну видеокарту с 24 ГБ памяти?

Короткий ответ: целиком — нет. Считаем на пальцах. Веса 70B в FP16 занимают около 140 ГБ, в 8-битном формате — примерно 70 ГБ, а в 4-битном K-кванте — порядка 40 ГБ.

Теперь добавьте KV-кэш: для типовой 70B с групповым вниманием на каждый токен контекста уходит около 0,3 МБ в FP16, то есть 8K контекста — это ещё примерно 2,5 ГБ. Плюс буферы активаций и накладные расходы рантайма. На старте получается 45–48 ГБ, и это без запаса на длинную переписку.

Рабочих сценариев четыре: выгрузить часть слоёв на центральный процессор (в llama.cpp это делается ключом -ngl), ужаться до 2–3 бит, взять две карты по 24 ГБ или спуститься на модели класса 30–32B. Первый путь самый популярный, но не бесплатный.

Почему он бьёт по скорости? Локальный инференс упирается в пропускную способность памяти: чтобы сгенерировать один токен, нужно прочитать все веса целиком. Пропускная способность оперативной памяти примерно на порядок ниже, чем у видеопамяти, поэтому каждый слой, уехавший на процессор, режет итоговую скорость в разы.

GGUF или AWQ — что брать под моё железо?

Разделяйте два мира. GGUF — это формат-экосистема вокруг llama.cpp: веса, метаданные квантования, словарь и конфигурация архитектуры лежат в одном переносимом файле, а типы квантования заточены под эффективный инференс на центральном процессоре. Это де-факто стандарт для локального запуска в Ollama и LM Studio.

AWQ — история про сервер с GPU. Это активационно-осознанное квантование: оно бережнее относится к тем весам, которые сильнее влияют на результат, и потому даёт более высокую точность, чем классический GPTQ при сжатии до INT4, особенно на инструкционных и диалоговых моделях. Живёт это в vLLM и похожих движках с быстрыми ядрами.

Практическое правило простое: домашняя машина и Ollama — GGUF; продакшн-API на видеокартах — AWQ или GPTQ. Для современных ускорителей уровня H100 и B200 рынок всё сильнее двигается в сторону FP8 и FP4, но там критично наличие рабочего пути исполнения и обязательная проверка качества.

Насколько реально проседает качество на 4 битах? Можно ли верить «потере менее 2%»?

По данным AiManual на февраль 2026, современные методы квантования (особенно GGUF с K-Quant) достигли уровня, когда 4-битное сжатие часто теряет менее 2% качества по сравнению с FP16 — для большинства прикладных задач это незаметно.

Но здесь кроется ловушка. Два процента — это усреднённая цифра по общим метрикам, а не гарантия для вашей задачи. Просадка вылезает там, где нужна точность: длинные цепочки логических рассуждений, генерация кода, редкие языки, извлечение фактов из документа. И чем агрессивнее сжатие (2–3 бита), тем заметнее деградация.

Поэтому рабочая практика — подбирать формат под конкретное железо и обязательно замерять качество на своих данных до боя. Соберите 30–50 реальных запросов из вашего сценария, прогоните их через FP16 и через кандидата в 4 битах и сравните ответы вслепую. Полчаса работы, зато никаких сюрпризов в продакшене.

Какой тип квантования GGUF выбрать: Q4_K_M, Q5_K_M, Q6_K или Q8_0?

Q4_K_M — рабочая лошадка. Это разумный компромисс между размером, скоростью и качеством, с которого стоит начинать почти всегда. Важно понимать: K-кванты — не то же самое, что старые типы вида Q4_0, разница в качестве ответов между ними вполне ощутима.

Дальше по возрастанию: Q5_K_M и Q6_K берут, если память позволяет и хочется быть ближе к FP16. Q8_0 почти не теряет в качестве, но по объёму приближается к исходной точности — смысл теряется, вы платите гигабайтами за доли процента.

Ниже Q4 опускаться стоит только под давлением обстоятельств: Q3_K_M и Q2_K заметно сдают на сложных задачах. Ориентир для 24 ГБ: 30–32B в Q4_K_M укладывается вместе с приличным контекстом, а 70B в том же формате — нет.

Зачем квантовать KV-кэш и не убьёт ли это длинный контекст?

Потому что кэш растёт линейно с длиной контекста, а не с числом параметров. Для типовой 70B с групповым вниманием один токен контекста в FP16 занимает около 0,3 МБ: 8K — примерно 2,5 ГБ, 32K — уже около 10 ГБ. На карте с 24 ГБ это очень чувствительная статья расходов.

Сжатие KV-кэша до 8 бит срезает эти объёмы примерно вдвое, до 4 бит — вчетверо. В llama.cpp тип кэша задаётся отдельными ключами для K и V, в серверных движках есть свои режимы пониженной точности. Начинайте с 8 бит — это почти бесплатный выигрыш по памяти.

Плата за агрессивное сжатие — деградация на длинных диалогах: модель начинает путать порядок событий и хуже воспроизводит точные факты из начала контекста. Если ваш сценарий — работа с большими документами или долгие беседы, оставьте 8 бит и не жадничайте с 4.

⚠️ Подводный камень: «Потеря менее 2%» из обзоров — это средняя температура по больнице. На ваших данных просадка может оказаться и в разы выше, поэтому замер на собственном наборе запросов до запуска в работу — не паранойя, а обязательный шаг.

💡 В сухом остатке: главное

Рынок технологий движется с бешеной скоростью. Не ведитесь на маркетинговый хайп: всегда тестируйте модели на реальных сценариях вашей команды и замеряйте финальную окупаемость.

Чек-лист для внедрения на практике:

  • ✅ Практический шаг 1: Посчитайте бюджет памяти — веса, KV-кэш, буферы активаций — и только потом выбирайте разрядность квантования.
  • ✅ Практический шаг 2: Соберите небольшой набор реальных задач на 50–100 примеров и прогоните его на FP16 и на кандидатных квантах.
  • ✅ Практический шаг 3: Зафиксируйте порог допустимого расхождения в точности и сверяйте с ним каждый новый формат перед обновлением.
  • ✅ Практический шаг 4: Замерьте скорость генерации и задержку первого токена на своей конфигурации, а не по чужим бенчмаркам.

Обсудить материал и поделиться своими бенчмарками можно в комментариях к блогу.

Редактор
Оцените автора
Добавить комментарий

Отправляя данную форму вы соглашаетесь с политикой конфиденциальности сайта