llama.cpp нужна не всем. Если задача — «запустить модель и общаться», Ollama или графическое приложение сделают это быстрее и без компилятора. Прямая работа с llama.cpp окупается в трёх случаях: когда нужно выжать максимум скорости из конкретного железа, когда нужен параметр, которого обёртки не отдают, и когда нужно запустить файл GGUF, которого нет ни в одном каталоге.
Этот гайд про третью ситуацию и про флаги, которые действительно двигают стрелку. Их четыре, остальные — либо косметика, либо узкие случаи.
#Что понадобится
- Компилятор и CMake. На Linux —
build-essentialиcmake, на macOS — Xcode Command Line Tools, на Windows — Visual Studio Build Tools с компонентом C++ или сборка внутри WSL2. Сборка Makefile из проекта убрана, актуален только CMake. - CUDA Toolkit — если у вас NVIDIA и нужен GPU. Версия драйвера должна быть не ниже требуемой тулкитом.
- Файл модели в формате GGUF. Что внутри этого файла и как посмотреть его метаданные — в разборе формата GGUF.
- Свободное место: сама сборка занимает единицы гигабайт, модель — отдельно.
Флаги и имена целей сборки в проекте меняются между релизами чаще, чем в любом другом инструменте кластера. Всё, что ниже, верно на момент написания; перед сборкой имеет смысл заглянуть в docs/build.md репозитория и в вывод --help собранного бинарника.
#Шаг 1. Клонировать репозиторий
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
#Шаг 2. Собрать под свой бэкенд
Бэкенд выбирается на этапе конфигурации, и пересобрать под другой позже — значит сконфигурировать заново.
Только процессор:
cmake -B build
cmake --build build --config Release -j
NVIDIA (CUDA):
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j
Apple Silicon (Metal): отдельного флага не нужно, Metal включён по умолчанию на macOS:
cmake -B build
cmake --build build --config Release -j
AMD (ROCm/HIP):
cmake -B build -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx1100
cmake --build build --config Release -j
Значение AMDGPU_TARGETS — кодовое имя архитектуры вашей карты, его нужно подставить своё. Если ROCm вашу карту официально не поддерживает, остаётся вариант с Vulkan ниже.
Универсальный вариант через Vulkan — работает на AMD, Intel и NVIDIA, обычно медленнее родного бэкенда, но заводится там, где родной не собирается:
cmake -B build -DGGML_VULKAN=ON
cmake --build build --config Release -j
Сборка занимает от нескольких минут на процессоре до получаса с CUDA. Результат — набор бинарников в build/bin: llama-cli (диалог в терминале), llama-server (HTTP-сервер), llama-bench (замеры), llama-quantize (квантизация).
#Шаг 3. Первый запуск
./build/bin/llama-cli -m ~/models/qwen2.5-7b-instruct-q4_k_m.gguf -ngl 99 -c 8192 -cnv
Разбор: -m — путь к файлу, -ngl 99 — выгрузить на видеокарту все слои (99 — просто заведомо больше, чем есть), -c 8192 — размер контекста, -cnv — режим диалога вместо однократного продолжения текста.
На Windows путь к бинарнику будет build\bin\Release\llama-cli.exe, остальное совпадает.
#Шаг 4. Флаги, которые меняют скорость
Вот те, что действительно влияют на результат. Остальные параметры — сэмплинг, штрафы за повторы, seed — влияют на текст ответа, но не на производительность.
| Флаг | Что делает | Эффект |
|---|---|---|
-ngl N |
сколько слоёв считать на GPU | решающий: разница между 2 и 40 ток/с |
-c N |
размер контекста | больше контекст — больше памяти под KV-кэш |
-t N |
число потоков CPU | важен только при расчёте на процессоре |
-fa |
Flash Attention | меньше памяти под кэш, обычно быстрее |
-ctk / -ctv |
тип KV-кэша (f16, q8_0, q4_0) |
вдвое-вчетверо меньше памяти под контекст |
-b / -ub |
размер батча и микробатча обработки промпта | влияет на скорость чтения длинного запроса |
--no-mmap |
грузить веса в память целиком | дольше старт, иногда стабильнее на слабом диске |
-sm / -ts |
режим и пропорции разделения между GPU | только для нескольких карт |
Четыре из них заслуживают разбора.
-ngl — главный флаг. Каждый слой модели считается либо на видеокарте, либо на процессоре. Значение 99 означает «все». Если все не влезают, движок сообщит об ошибке памяти — тогда значение подбирается вниз. Разница между «все слои на GPU» и «половина» — не проценты, а разы. Подбирается значение сверху вниз: начните с 99, при ошибке памяти снижайте шагом в несколько слоёв.
-c — контекст, который вы реально получите. Модель может быть обучена на 128k, но памяти у вас на 8k. Флаг задаёт то, что будет выделено. Если не указать, возьмётся значение по умолчанию — которое между версиями менялось, так что указывайте явно.
-t — потоки. На чистом CPU-запуске оптимум обычно равен числу физических ядер, а не логических: гиперпоточность здесь чаще мешает. При полной выгрузке на GPU этот флаг почти ничего не меняет.
-fa — Flash Attention. Другой алгоритм расчёта внимания: меньше обращений к памяти, меньше расход под кэш. В свежих сборках флаг принимает значение (on, off, auto) — проверьте вывод --help своей версии. Вместе с квантизацией KV-кэша это самая дешёвая экономия памяти из доступных, разбор — в статье о Flash Attention и квантизации KV-кэша.
#Шаг 5. Что ещё лежит в build/bin
Сборка даёт не один бинарник, и половина ценности llama.cpp — в утилитах, аналогов которым в обёртках нет.
llama-bench— замеры. Принимает списки значений через запятую (-t 4,8,12) и прогоняет все комбинации, выдавая таблицу. Единственный корректный способ сравнить две настройки.llama-quantize— квантизация. Принимает GGUF в высокой точности и выдаёт нужный уровень:llama-quantize model-f16.gguf model-q4km.gguf Q4_K_M. Нужна, если вы дообучили свою модель или готового кванта нет.llama-perplexity— измерение перплексии на текстовом наборе. Это способ численно сравнить, насколько сильнее испортил модель более жёсткий квант, вместо оценки «на глаз».llama-gguf-split— разрезание и склейка больших файлов моделей на части.llama-server— HTTP-сервер с OpenAI-совместимым API.
Отдельно про несколько видеокарт. Флаг -sm выбирает режим разделения: layer раскладывает слои по картам (работает почти всегда), row делит тензоры (иногда быстрее, требовательнее к связи между картами). Флаг -ts 3,1 задаёт пропорции, если карты разного объёма, -mg указывает главную. Вторая карта в этом режиме даёт объём памяти, а не пропорциональный прирост скорости.
#Проверка результата
Гайд без критерия успеха бесполезен, поэтому три проверки подряд.
Проверка 1: все ли слои на видеокарте. В логе запуска ищите строку вида offloaded 29/29 layers to GPU. Если число слева меньше — часть слоёв осталась на процессоре, и это главная причина медленной работы.
Проверка 2: сколько занято видеопамяти. В отдельном терминале, пока модель загружена:
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
Если занято больше 95% — уменьшайте контекст или включайте квантизацию кэша, иначе драйвер начнёт вытеснять данные и скорость упадёт без сообщений об ошибке.
Проверка 3: реальная скорость. Не на глаз, а замером:
./build/bin/llama-bench -m ~/models/qwen2.5-7b-instruct-q4_k_m.gguf -ngl 99 -p 512 -n 128
llama-bench сам прогревает модель и повторяет прогон, выдавая отдельно скорость обработки промпта (pp) и скорость генерации (tg). Это те два числа, по которым имеет смысл сравнивать любые изменения настроек. Почему домашние замеры без прогрева обычно неверны — в материале о том, как измерить скорость локальной модели правильно.
Меняйте по одному флагу за раз и перезамеряйте. Одновременная смена кванта и контекста даёт результат, из которого нельзя сделать вывод.
#Что может пойти не так
CUDA error: out of memory при запуске. Не хватило памяти на веса плюс контекст. По порядку: уменьшите -c, добавьте -ctk q8_0 -ctv q8_0, уменьшите -ngl, и только потом меняйте модель.
Собралось, но GPU не используется. Типичная причина — конфигурация прошла без флага бэкенда, и собрался CPU-вариант. cmake -B build -DGGML_CUDA=ON в уже существующий каталог build может не подхватить изменение — удалите каталог и сконфигурируйте заново.
unknown model architecture. Файл модели новее вашей сборки. Обновите репозиторий (git pull) и пересоберите — поддержка каждой новой архитектуры добавляется отдельно.
Скорость упала после увеличения контекста. Ожидаемо: больший KV-кэш означает больше чтений из памяти на каждый токен. Если падение резкое — вероятно, вы перешли границу видеопамяти и часть данных ушла в оперативную.
Модель отвечает бессвязно или дописывает ваши реплики. Скорее всего, применяется неверный шаблон чата. Задайте его явно флагом --chat-template или проверьте, что лежит в метаданных файла.
На Windows сборка падает на этапе линковки. Чаще всего — несовместимость версий Visual Studio и CUDA Toolkit. Практичная альтернатива: собирать внутри WSL2, где сборка ведёт себя предсказуемее.
#Частые вопросы
#Нужна ли llama.cpp, если есть Ollama?
В большинстве бытовых сценариев — нет, Ollama использует тот же движок и делает разумные предположения за вас. Прямая работа окупается, когда нужен конкретный флаг, нестандартный файл модели или максимальная производительность. Разбор шести конкретных ситуаций — в сравнении Ollama против llama.cpp.
#Можно ли не собирать, а скачать готовые бинарники?
Да, проект публикует сборки под основные платформы в разделе релизов на GitHub. Это разумный путь, если вы не собираетесь ничего менять в коде. Минус — готовая сборка может быть собрана не под ваш бэкенд, и придётся выбирать подходящий архив.
#Что такое llama-server и зачем он нужен?
Это HTTP-сервер, поднимающий OpenAI-совместимый эндпоинт: к нему подключается любой клиент, умеющий работать с этим API. Команда запуска и пример запроса — в гайде о llama.cpp server как своём OpenAI-совместимом эндпоинте.
#Сколько потоков ставить в -t?
Начните с числа физических ядер. Больше логических потоков, чем физических ядер, обычно не ускоряет, а иногда замедляет. При полной выгрузке модели на видеокарту флаг почти не влияет — проверьте замером, а не предположением.
#Как понять, какие флаги поддерживает моя сборка?
Вывод ./build/bin/llama-cli --help — единственный надёжный источник. Флаги переименовывают и объединяют между релизами; статья, включая эту, устаревает быстрее, чем справка бинарника.
#Обязательно ли обновлять llama.cpp?
Не обязательно, если всё работает. Обновляться стоит по конкретному поводу: не читается новая модель, нужен новый флаг, вышло исправление под ваш бэкенд. Первый шаг локального запуска целиком — в руководстве по запуску LLM локально.