Гайды

llama.cpp: сборка запуск и параметры без магии

Сборка под CUDA, Metal и CPU, запуск модели и разбор флагов, которые реально меняют скорость в разы: -ngl, -c, -t, -fa — с методикой замера эффекта каждого.

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 локально.

Хотите ИИ, который помнит вас?

Persona держит контекст между чатами и работает на вашем железе — если развернуть её у себя и подключить локальную модель.

Создать аккаунт