Учебник

Языковая модель на своём сервере без облачных платежей

У вас бизнес, каждый запрос к ChatGPT стоит денег, а данные утекают в облако. Вот как за вечер поднять свою локальную модель на любом железе: от MacBook до старого сервера. Никакого кода, только готовые бинарники и пара команд. Разбираем llama.cpp, GGUF, CUDA и Metal - на примере стройфирмы, которая автоматизирует ответы на типовые вопросы клиентов.

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

У ваших менеджеров уходит по 3-4 часа в день на однотипные вопросы от клиентов: «какой прайс на ремонт?», «когда приедет замерщик?», «есть ли скидка на материалы?». Вы платите за ChatGPT, но боитесь, что коммерческая информация утечёт в облако. А если внедрить свою локальную AI-модель - ни копейки за запрос, данные только у вас, и работает 24/7 без перерывов.

Разберём на примере стройфирмы, как за вечер поднять собственную модель на обычном ноутбуке или сервере. В этой статье - практический разбор llama.cpp, формата GGUF, флагов запуска и бенчмарков. Всё, что нужно, чтобы вы или ваш менеджер внедрили AI за 2-8 часов.

Что такое llama.cpp и зачем это вашему бизнесу

llama.cpp - это программа на C++, которая запускает языковые модели на любом железе: от MacBook M2 до сервера с восемью A100. Один и тот же исходник компилируется под CPU, CUDA (видеокарты NVIDIA) и Metal (Apple Silicon) - менять код между платформами не нужно. Для предпринимателя это значит: вы покупаете один бинарник и запускаете на том, что уже есть.

Зачем это бизнесу? Не нужно платить за каждый запрос в ChatGPT. Не нужно разбираться в Python или нейросетях. Просто скачали файл модели, запустили сервер, подключили к вашему CRM или сайту через API - и всё. Данные не уходят в облако, скорость контролируете сами.

Сборка из исходников для CUDA и macOS

Готовые бинарники из выпусков GitHub покрывают базовые сценарии. Но если у вас специфическое железо (например, старая видеокарта NVIDIA или MacBook на Intel), придётся собрать из исходников. Не пугайтесь - это пара команд, которые может выполнить любой менеджер с базовыми навыками работы в терминале.

CUDA на Linux (Ubuntu 22.04, CUDA 12.4) - для серверов с видеокартами NVIDIA:

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# Сборка с CUDA
cmake -B build \
 -DGGML_CUDA=ON \
 -DCMAKE_CUDA_ARCHITECTURES="80;86;89;90" # A100, RTX30, RTX40, H100
cmake --build build -j$(nproc)

Флаг CMAKE_CUDA_ARCHITECTURES важен: без него компилятор генерирует код для всех архитектур сразу - бинарник разрастается до 2-3 GB и медленнее стартует. 86 - RTX 3090/3080, 89 - RTX 4090/4080, 90 - H100. Если у вас RTX 3060 - поставьте 86.

macOS (Apple Silicon и Intel) - для MacBook ваших менеджеров:

cmake -B build -DGGML_METAL=ON
cmake --build build -j$(sysctl -n hw.ncpu)

На Apple Silicon DGGML_METAL=ON включён по умолчанию при обнаружении macOS ARM. Принудительно отключить Metal (для тестирования CPU-only): -DGGML_METAL=OFF.

Windows без Visual Studio - для офисных ПК:

# Через MSYS2 + MinGW
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc
cmake -B build -G "MinGW Makefiles"
cmake --build build -j4

DLL зависимости (libstdc++-6.dll, libwinpthread-1.dll) нужно скопировать рядом с бинарниками из папки MinGW bin.

Формат GGUF: структура файла и метаданные

GGUF (GGML Unified Format) - бинарный контейнер, введённый в августе 2023 вместо устаревшего GGML. Для бизнеса это значит: вы скачиваете один файл модели, в котором уже есть всё - и сама нейросеть, и словарь, и настройки. Никаких дополнительных файлов config.json или tokenizer.json.

Структура файла:

[Magic: 4 байта "GGUF"]
[Version: uint32]
[Tensor count: uint64]
[Metadata KV count: uint64]
[Metadata: ключ-значение пары]
 - general.architecture ("llama", "mistral", "qwen2"...)
 - llama.context_length
 - llama.attention.head_count
 - tokenizer.ggml.model
 - tokenizer.ggml.tokens (весь словарь)
[Tensor info: имя, тип, размеры, смещение]
[Выравнивание: padding]
[Тензорные данные]

Чем GGUF лучше GGML: метаданные содержат полную конфигурацию модели и токенизатор в одном файле. Не нужны отдельные config.json и tokenizer.json - llama.cpp читает всё из GGUF.

Типы квантования в имени файла: Q4_K_M - 4-bit, K-quant метод, Medium вариант. Q5_K_S - 5-bit, Small. Q8_0 - 8-bit без уточнений. K-quants (Q4_K_M, Q5_K_M) используют смешанную точность: более чувствительные слои (embedding, output) квантуются в 6-8 bit, остальные - в 4-5 bit. Для бизнеса это означает: модель занимает меньше места на диске и быстрее работает, при этом качество ответов почти не страдает.

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

Старый скрипт convert.py устарел и удалён. Актуальный инструмент - convert_hf_to_gguf.py:

# Скачать модель локально
pip install huggingface_hub
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.3 \
 --local-dir ./mistral-7b-hf

# Конвертировать в GGUF (F16)
python convert_hf_to_gguf.py \
 --model ./mistral-7b-hf \
 --outfile ./mistral-7b-f16.gguf

# Квантовать в Q4_K_M
./build/bin/llama-quantize \
 ./mistral-7b-f16.gguf \
 ./mistral-7b-q4_k_m.gguf \
 Q4_K_M

Процесс конвертации требует RAM равной размеру модели в FP16: для Mistral-7B - около 14 GB. Квантование в Q4_K_M уменьшает файл с 14 GB до 4.1 GB. Для стройфирмы это значит: модель на 7 миллиардов параметров поместится на обычный ноутбук с 8 GB RAM и будет отвечать на вопросы по прайсу за секунды.

Модели с архитектурами вне стандартного набора (некоторые MoE, новые Qwen3) могут требовать обновлённой версии скрипта из git main.

Флаги запуска: -n-gpu-layers, -threads, -ctx-size, -flash-attn

Основная программа для инференса - llama-cli. Четыре ключевых флага, которые нужно знать:

./build/bin/llama-cli \
 -m ./mistral-7b-q4_k_m.gguf \
 --n-gpu-layers 32 \
 --threads 8 \
 --ctx-size 8192 \
 --flash-attn \
 -p "Write a haiku about GGUF"

--n-gpu-layers N: выгрузить N слоёв на GPU. Mistral-7B имеет 32 трансформерных слоя. Если поставить 99 или больше реального числа слоёв - модель полностью уйдёт на GPU (embedding и output тоже). Частичная выгрузка: 16 слоёв на GPU + 16 на CPU с offload через системную RAM. Скорость падает из-за трансферов PCIe, но 13B модель помещается на 8GB VRAM при 24 слоях на GPU.

--threads N: CPU-потоки для слоёв не на GPU. Оптимум - количество физических ядер (не HT). На Ryzen 9 5950X (16 ядер / 32 потока) - ставить 16, не 32.

--ctx-size N: размер контекстного окна в токенах. Влияет на VRAM/RAM: каждые 8192 токенов для Mistral-7B добавляют ~2 GB к KV-cache. Больше контекст - больше память, меньше скорость генерации. Для чат-бота стройфирмы хватит 4096 - это примерно 3000 русских слов.

--flash-attn: Flash Attention 2 через llama.cpp реализацию. Снижает VRAM для KV-cache на 20-40% и ускоряет prefill на 15-25%. Поддерживается на CUDA и Metal. Рекомендуется включать всегда при >= 4096 токенов контекста.

Metal на Apple Silicon: KV-cache квантование

Металловый бэкенд llama.cpp использует Metal Performance Shaders для matrix multiplication и кастомные шейдеры для остальных операций.

KV-cache квантование - специфичная для Metal оптимизация:

./build/bin/llama-cli \
 -m ./llama-3.2-3b-q8_0.gguf \
 --n-gpu-layers 99 \
 --cache-type-k q8_0 \
 --cache-type-v q8_0 \
 --ctx-size 32768

Квантование KV-cache в q8_0 сокращает его размер вдвое при минимальной потере качества. На M2 Pro 16GB это позволяет держать контекст 32K для 7B модели вместо 16K в f16.

Flash Attention на Metal реализован через фьюзионные Metal-шейдеры - llama.cpp не использует MFA (Metal Flash Attention) от Apple напрямую, а имеет собственную реализацию. Включается тем же --flash-attn.

Унифицированная память Apple Silicon - основное преимущество: нет трансферов CPU-GPU. Для бизнеса это значит: MacBook с M-чипом может запускать модели быстрее, чем ПК с дискретной видеокартой при том же объёме памяти.

Бенчмарк через llama-bench

./build/bin/llama-bench \
 -m ./mistral-7b-q4_k_m.gguf \
 -n 512 \
 -ngl 32 \
 -fa 1

Вывод включает два показателя:

  • pp (prompt processing): токены/сек при обработке входного промпта
  • tg (token generation): токены/сек при генерации

Типичные показатели Q4_K_M Mistral-7B:

  • RTX 4090 (CUDA): pp ~3500 tok/s, tg ~130 tok/s
  • M3 Pro 18GB (Metal): pp ~800 tok/s, tg ~65 tok/s
  • M2 Ultra 96GB (Metal): pp ~2200 tok/s, tg ~80 tok/s
  • Ryzen 9 5950X CPU-only: pp ~120 tok/s, tg ~18 tok/s

Generation (tg) ограничена bandwidth памяти, а не CUDA-ядрами. RTX 3090 (936 GB/s) быстрее RTX 4080 (717 GB/s) на генерации при одинаковом размере модели, несмотря на меньшее число CUDA-ядер.

Для стройфирмы: если у вас офисный ПК без видеокарты, скорость ~18 токенов в секунду - это примерно 15 русских слов в секунду. Для ответа на вопрос клиента достаточно. Если нужно быстрее - поставьте видеокарту или используйте MacBook.

llama-server: HTTP API и параметры контекста

./build/bin/llama-server \
 -m ./mistral-7b-q4_k_m.gguf \
 --n-gpu-layers 32 \
 --ctx-size 8192 \
 --port 8080 \
 --host 0.0.0.0 \
 --parallel 4

llama-server поднимает OpenAI-совместимый API на /v1/chat/completions и /v1/completions. Параметр --parallel N задаёт число одновременных слотов (независимых KV-cache контекстов). Каждый слот занимает отдельный блок VRAM. Для чат-бота стройфирмы достаточно --parallel 4 - четыре клиента могут одновременно задавать вопросы.

Дополнительные точки API:

  • GET /health - статус сервера
  • GET /metrics - Prometheus метрики (включить --metrics)
  • POST /tokenize - токенизация текста
  • GET /slots - состояние всех слотов

Для встроенного UI (чат в браузере) - открыть http://localhost:8080 без дополнительных настроек. Ваши менеджеры могут сразу начать тестировать.

Сравнение бэкендов: когда CUDA обгоняет Metal

На генерации (decode) ограничение - bandwidth памяти:

  • RTX 4090: 1008 GB/s
  • M2 Ultra: 800 GB/s
  • M3 Max: 400 GB/s
  • M4 Pro: 273 GB/s

На одном и том же размере модели RTX 4090 обгоняет M3 Max примерно в 2.5× на generation. Но M-серия выигрывает по энергоэффективности: M3 Max даёт ~65 tok/s при 30W, RTX 4090 - 130 tok/s при 450W.

CPU достаточно для: редкого использования (пара запросов в час), моделей до 7B Q4, интеграционного тестирования без GPU. При постоянной нагрузке CPU-only даже для 3B модели - неудобно медленно. Для стройфирмы с 10-20 запросами в день CPU-версии хватит.

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

Зачем собирать llama.cpp из исходников, если есть готовые бинарники?

Готовые бинарники из выпусков компилируются с консервативными настройками CUDA_ARCHITECTURES для широкой совместимости. Сборка под конкретный GPU (только arch=89 для RTX 4090) ускоряет старт и может дать 3-7% прирост скорости. Также сборка из исходников необходима для экспериментальных флагов (Vulkan бэкенд, SYCL для Intel Arc) и модификаций. Для бизнеса: если у вас типовое железо - берите готовые бинарники. Если хотите выжать максимум - соберите под себя.

Как узнать, сколько слоёв отдать на GPU через --n-gpu-layers?

Запустить с --n-gpu-layers 0 и посмотреть базовую скорость. Затем увеличивать на 4-8 слоёв и следить за VRAM через nvidia-smi или sudo powermetrics на Mac. Как только VRAM заканчивается - llama.cpp начнёт использовать системную RAM через cuda unified memory (медленно) или упадёт. Оптимум - максимум слоёв без выхода за 80-85% VRAM.

Почему convert.py устарел и что его заменяет?

Старый convert.py поддерживал ограниченный набор архитектур и не обновлялся под новые модели. Начиная с середины 2024 он удалён из репозитория. Замена - convert_hf_to_gguf.py, который поддерживает 40+ архитектур (Llama, Mistral, Qwen, Phi, Gemma, Command-R и другие) и правильно экспортирует токенизаторы в GGUF-формат.

Можно ли запустить llama.cpp на Windows без Visual Studio?

Да, через MinGW (MSYS2) или через CMake с компилятором Clang из LLVM Windows installer. CUDA на Windows требует MSVC или cl.exe - для CUDA-сборки. Без полной VS достаточно установить «Build Tools for Visual Studio» (бесплатно, только компилятор без IDE). CPU-only сборка через MinGW работает полностью без MSVC.

Чем llama.cpp отличается от llama-cpp-python - когда что использовать?

llama-cpp-python - Python биндинги к llama.cpp через ctypes. Предоставляет OpenAI-совместимый сервер через python -m llama_cpp.server и Python API для встраивания в приложения. Использовать llama-cpp-python когда нужна интеграция в Python-проект без отдельного HTTP-сервера. llama-server напрямую - когда нужна максимальная производительность без overhead Python интерпретатора. Для стройфирмы: если у вас нет программиста - используйте llama-server, он проще.

Что делать прямо сейчас

  1. Скачайте готовый бинарник llama.cpp для вашей ОС с GitHub (раздел Releases).
  2. Скачайте модель в GGUF, например Mistral-7B-Instruct Q4_K_M (4 GB).
  3. Запустите сервер командой из раздела «llama-server».
  4. Откройте в браузере http://localhost:8080 и проверьте, отвечает ли модель.
  5. Подключите API к вашему CRM или сайту через простой HTTP-запрос.

Весь процесс займёт 2-4 часа у вашего менеджера. Никакого программиста, никаких курсов. Просто скачали, запустили, пользуетесь.

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