Трендовые github проекты в нашем телеграм канале. Подпишись → llama.cpp, GGUF и квантование Q4_K_M: маршрут от весов до чата в браузере
Локальный инференс большой языковой модели упирается в одну цифру — объём видеопамяти. У модели с 27 млрд параметров веса в 16-битном формате занимают около 54 ГБ, а типичная домашняя видеокарта верхнего сегмента несёт 24 ГБ VRAM. Разница закрывается квантованием: если ужать каждый параметр примерно до 4,8 бита, файл уменьшается втрое, модель целиком помещается в память карты, и генерация идёт на полной скорости GPU без обращения к системной RAM.
Ниже — полный путь для конфигурации с одной картой архитектуры Ampere (24 ГБ VRAM), шестиядерным CPU и 32 ГБ оперативной памяти. Всё делается через llama.cpp, собранный из исходников.
Инструменты, которые нужно поставить заранее
Сборка и подготовка модели тянут за собой цепочку зависимостей. На Windows список такой:
- Python 3.12 (x64) — нужен для CLI Hugging Face и для скрипта конвертации в GGUF. При установке обязательно отметить «Add python.exe to PATH».
- Hugging Face CLI — ставится как
pip install -U huggingface-hub hf_xet. Пакетhf_xetподключает Rust-реализацию протокола Xet и заметно ускоряет загрузку файлов на десятки гигабайт. - Git for Windows — для клонирования репозитория
llama.cpp. - CUDA Toolkit 12.8 — даёт компилятор
nvccи библиотеки CUDA Runtime, к которым линкуется сервер. Ставить выборочной установкой (Custom), из компонентов достаточно самого пункта «CUDA». Драйвер GPU и Toolkit — разные вещи, нужны оба. - CMake 3.20+ — генерирует план сборки. Сам код не компилирует, только находит
nvccи MSVC и настраивает их вызовы. - MSVC из Visual Studio Community 2022 или Build Tools — рабочая нагрузка «Разработка классических приложений C++», внутри неё компилятор и Windows SDK.
- Ninja — исполняет план сборки, распараллеливая независимые задачи. Ставится через
winget install Ninja-Ninja.Ninja. - OpenSSL 3.x (Full) — необязательная зависимость. С ней сервер умеет принимать HTTPS-соединения; без неё соберётся и будет работать по HTTP.
Ключевой момент: команду сборки надо запускать в терминале x64 Native Tools Command Prompt for VS 2022. Только в нём в переменных PATH, INCLUDE и LIB прописаны cl.exe, линковщик и заголовки Windows SDK. В обычном cmd сборка падает с ошибкой No CMAKE_CXX_COMPILER could be found.
Сборка llama-server под свою карту
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
mkdir build && cd build
cmake .. -G Ninja -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=86 ^
-DGGML_CUDA_F16=1 -DCMAKE_BUILD_TYPE=Release ^
-DOPENSSL_ROOT_DIR="C:/Program Files/OpenSSL-Win64"
cmake --build . --config Release
Что задают флаги:
-DGGML_CUDA=ON— собрать с поддержкой GPU, иначе получится сборка только под CPU.-DCMAKE_CUDA_ARCHITECTURES=86— целевая архитектура (86 — Ampere). Код под другие поколения карт не собирается, размер бинарника меньше.-DGGML_CUDA_F16=1— 16-битная арифметика в части вычислений на GPU: меньше расход памяти, выше скорость.-DCMAKE_BUILD_TYPE=Release— оптимизированная сборка без отладочной информации.
После завершения исполняемые файлы (llama-server, llama-quantize и другие) появятся в build/bin.
Для скрипта конвертации convert_hf_to_gguf.py понадобится отдельное виртуальное окружение: у него тяжёлые зависимости (torch, transformers, gguf, numpy, sentencepiece, protobuf). В корне llama.cpp выполняется python -m venv venv, активация, затем pip install -r requirements.txt.
Загрузка весов
hf download Qwen/Qwen3.8-27B --local-dir D:\models\src
В репозитории лежат веса в формате safetensors, разбитые на части, плюс config.json, файлы токенайзера и generation_config.json. Совокупный объём — около 54 ГБ, свободного места нужно не меньше 60 ГБ. Загрузка возобновляемая: если сеть оборвалась или компьютер ушёл в сон, повторный запуск той же команды докачивает недостающие части. На канале 5 Мбит/с полная загрузка занимает примерно сутки, поэтому в настройках питания стоит выставить «Сон — Никогда».
Конвертация в GGUF
python convert_hf_to_gguf.py D:\models\src ^
--outfile D:\models\out\model-F16.gguf --outtype f16
GGUF — самодостаточный бинарный контейнер: в одном файле лежат веса всех слоёв, метаданные архитектуры (число слоёв, размер скрытого слоя, число головок внимания, размер контекста), токенайзер и параметры шаблона диалога. Из-за этого формат стал стандартом для локального запуска — его понимают llama.cpp, Ollama, LM Studio.
Скрипт делает три вещи: читает исходник, переименовывает тензоры из соглашений Hugging Face (model.layers.0.self_attn.q_proj.weight) в имена llama.cpp (blk.0.attn_q.weight) по таблицам соответствий, приводит тип и пакует всё в один файл. С --outtype f16 каждый вес переводится из исходного BF16 в F16. Размер при этом почти не меняется (~54 ГБ): разница между BF16 и F16 — в раскладке 16 бит (у BF16 шире экспонента, у F16 длиннее мантисса), число бит на параметр одинаковое. Уменьшение файла происходит на следующем шаге.
Квантование Q4_K_M
build\bin\llama-quantize D:\models\out\model-F16.gguf ^
D:\models\out\model-Q4_K_M.gguf Q4_K_M
Инструменту не нужен Python: это готовый бинарник из сборки, работает на CPU за счёт нескольких ядер, время ограничено чтением 54 ГБ с диска — порядка 10 минут. Мастер-файл F16 остаётся нетронутым, из него потом можно собрать другой вариант квантования.
Как расшифровывается Q4_K_M:
- 4 — примерно 4 бита на вес. Значения не обрезаются напрямую: тензор делится на группы, для каждой подбирается масштаб и смещение, в файл пишутся 4-битные индексы плюс коэффициенты, при загрузке значения восстанавливаются приблизительно.
- K — семейство K-quants с двухуровневым масштабированием. Веса тензора бьются на суперблоки по 256 значений, каждый суперблок — на 8 блоков по 32. У каждого малого блока свой масштаб и смещение, у суперблока — дополнительный общий масштаб повышенной точности. За счёт этого ошибка округления частично компенсируется, и при том же числе бит качество заметно выше, чем у старых одноуровневых схем Q4_0.
- M — смешанная точность. Большинство тензоров в 4 битах, но самые чувствительные к качеству (выходной слой, часть MLP-проекций) хранятся в Q6_K. Это стоит несколько процентов размера и ощутимо улучшает ответы.
Ориентировочная карта размеров для модели на 27B:
| Тип | Бит на вес | Размер файла |
|---|---|---|
| Q4_K_S | ~4,5 | ~15 ГБ |
| Q4_K_M | ~4,8 | ~16–17 ГБ |
| Q5_K_M | ~5,9 | ~20 ГБ |
| Q6_K | ~6,6 | ~22 ГБ |
| Q8_0 | ~8,5 | ~29 ГБ |
В 24 ГБ VRAM влезают варианты до Q6_K включительно; Q8_0 туда уже не помещается. Q4_K_M даёт лучший баланс размера и качества и оставляет запас памяти под контекст. Квантование односторонее — F16 из Q4_K_M не восстановить, поэтому мастер-файл лучше сохранить.
Запуск и разбор параметров llama-server
llama-server -m ./model-Q4_K_M.gguf -ngl 999 --port 8882 ^
--temp 0.6 --top-p 0.95 --top-k 20 --min-p 0.0 ^
-t 6 -c 64000 ^
--cache-type-k q8_0 --cache-type-v q8_0 ^
--parallel 1 --flash-attn on ^
--reasoning-budget 8192 --spec-type draft-mtp --spec-draft-n-max 3 ^
--cache-ram 16384
Что стоит за основными ключами:
-ngl 999— сколько слоёв модели разместить на GPU. Значение выше числа слоёв (у этой модели их 64) означает «все на карту».--port 8882— TCP-порт. После старта веб-интерфейс открывается поhttp://localhost:8882, а программный доступ — через OpenAI-совместимый эндпоинт/v1/chat/completionsна том же порту.--temp 0.6 --top-p 0.95 --top-k 20— параметры выборки, рекомендованные для этого семейства моделей. Их же можно переопределять прямо в запросах к API.-t 6— число CPU-потоков, по количеству физических ядер процессора.-c 64000— размер контекстного окна в токенах. Большой контекст требует много памяти под KV-кэш.--cache-type-k q8_0 --cache-type-v q8_0— хранить KV-кэш в 8-битном формате вместо F16: вдвое меньше памяти при почти незаметной потере качества. Именно это позволяет уложить 64k контекста в оставшуюся после весов VRAM.--parallel 1— один слот обработки, для одного пользователя. Экономит память.--flash-attn on— оптимизированный алгоритм внимания: меньше памяти и быстрее на этапе attention.--reasoning-budget 8192— потолок на «размышляющую» часть ответа, чтобы модель не думала бесконечно.--spec-type draft-mtp --spec-draft-n-max 3— спекулятивное декодирование через встроенный в модель модуль Multi-Token Prediction: черновик предлагает до 3 токенов вперёд, основная модель проверяет их за один шаг, генерация ускоряется.--cache-ram 16384— потолок системной RAM под KV-кэш (МБ), если он не влез в видеопамять.
При старте сервер печатает лог загрузки: архитектуру, распределение слоёв между GPU и CPU, размер KV-кэша и строку вида listening on http://127.0.0.1:8882.
Если генерация медленная
На описанной конфигурации ожидаемая скорость — от 30 токенов в секунду без спекулятивного декодирования до 55 с включённым MTP. Если фактическая скорость упала до 5–10 токенов в секунду, почти наверняка часть весов не поместилась в VRAM и уехала в системную память: узким местом становится пропускная способность DDR4. В логах сервера будет сообщение о нехватке видеопамяти. Решения — уменьшить -c, усилить квантование KV-кэша или взять более компактный тип квантования модели.
Итого
Локальный запуск 27B-модели на одной карте с 24 ГБ памяти сводится к четырём шагам: собрать llama.cpp под свою архитектуру GPU, скачать веса, сконвертировать их в GGUF-мастер F16, ужать в Q4_K_M. После этого llama-server поднимает и веб-чат, и OpenAI-совместимый API, который дальше можно использовать как безлимитный локальный бэкенд для своих инструментов.