Сборка и запуск llama.cpp на Linux-сервере
Опубликовано:
Используемые термины: llama.cpp, LLM, Linux.
В этой инструкции разберем, как собрать llama.cpp и запустить локальный OpenAI-совместимый API-сервер на Linux. Это практический гайд по llama cpp — от установки зависимостей до автозапуска сервиса через systemd.
Предварительная подготовка
Сборка из исходников
Если запускаем только на CPU
Если будет работать на видеокарте
Выбор и загрузка модели в GGUF
Запуск API-сервера
Обновление llama.cpp
Решение проблем
Сравнение с Ollama
Подготовка системы и зависимостей
Установка llama cpp начинается с системных зависимостей — компилятора, cmake, git и curl. В зависимости от типа Linux, команды будут немного отличаться.
а) для Deb (Debian / Ubuntu):
apt update
apt install -y build-essential cmake git curl
б) для RPM (Rocky Linux / AlmaLinux / Fedora):
dnf install -y gcc-c++ make cmake git curl
* где:
- build-essential / gcc-c++ make — компилятор и базовые инструменты сборки.
- cmake — система сборки проекта llama.cpp.
- git — клонирование репозитория.
- curl — скачивание модели GGUF и проверка API.
Клонирование и компиляция
Скачаем llama cpp с GitHub и соберем его. Дальше разберем два варианта: сборку только под CPU и сборку с поддержкой NVIDIA GPU (CUDA).
Вариант A: только CPU
Клонируем репозиторий и переходим в рабочий каталог:
git clone https://github.com/ggml-org/llama.cpp /opt/llama.cpp
cd /opt/llama.cpp
Для продакшн-сервера разумнее собирать не актуальный master, а фиксированный релиз. Переключимся на конкретный тег:
git checkout tags/<tag>
* <tag> — версия релиза со страницы github.com/ggml-org/llama.cpp/releases, например b4200. Для тестового стенда этот шаг можно пропустить и остаться на master.
Настроим сборку через cmake:
cmake -B build -DCMAKE_BUILD_TYPE=Release
* где:
- /opt/llama.cpp — каталог установки; дальше по статье все пути ведут сюда.
- -B build — каталог с файлами сборки.
- -DCMAKE_BUILD_TYPE=Release — оптимизированная сборка без отладочных символов.
Запускаем компиляцию:
cmake --build build --config Release -j $(nproc)
* -j $(nproc) — число параллельных потоков компиляции по количеству ядер CPU.
Вариант B: NVIDIA GPU (CUDA)
Для сборки с CUDA понадобятся NVIDIA CUDA Toolkit и драйверы видеокарты — без них сборка не пройдет. Точные команды установки зависят от дистрибутива и версии CUDA, поэтому берите их с официальной страницы developer.nvidia.com/cuda-downloads — там NVIDIA сама подбирает нужный репозиторий под вашу систему.
Клонируем репозиторий и переходим в рабочий каталог:
git clone https://github.com/ggml-org/llama.cpp /opt/llama.cpp
cd /opt/llama.cpp
Как и в варианте с CPU, для продакшена стоит зафиксировать релиз:
git checkout tags/<tag>
* <tag> — версия релиза со страницы github.com/ggml-org/llama.cpp/releases. Для тестового стенда шаг можно пропустить.
Настройка llama-cpp для GPU отличается одним флагом — включаем поддержку CUDA:
cmake -B build -DGGML_CUDA=ON -DCMAKE_BUILD_TYPE=Release
* где:
- /opt/llama.cpp — каталог установки; дальше по статье все пути ведут сюда.
- -DGGML_CUDA=ON — включает поддержку NVIDIA CUDA.
- -DCMAKE_BUILD_TYPE=Release — оптимизированная сборка.
Запускаем компиляцию:
cmake --build build --config Release -j $(nproc)
* -j $(nproc) — число параллельных потоков компиляции по количеству ядер CPU.
Выбор и загрузка модели в формате GGUF
Модели GGUF поставляются в разных квантах — это влияет на размер файла, скорость и качество ответов. Чем ниже число бит, тем меньше памяти нужно и тем быстрее инференс, но точность модели немного снижается.
- Q4_K_M — компромиссный вариант: подходит для большинства задач, занимает меньше всего памяти среди практичных квантов.
- Q5_K_M — точность выше, размер и потребление памяти тоже растут.
- Q8_0 — минимальные потери качества, но модель занимает почти столько же места, как в исходной точности.
Для сервера с ограниченной VRAM или RAM разумно начать с Q4_K_M, для продакшена с высокими требованиями к качеству — перейти на Q5 или Q8.
* модель 8B в кванте Q4_K_M весит около 5 ГБ на диске, и под нее нужно закладывать порядка 6-8 ГБ свободной RAM или VRAM с учетом контекстного окна и служебных буферов. Для Q5_K_M и Q8_0 запас увеличивайте пропорционально размеру файла модели.
Создадим каталог для хранения моделей:
mkdir -p /opt/llama.cpp/models
Скачаем модель с Hugging Face:
curl -L -o /opt/llama.cpp/models/llama-3-8b-instruct-q4_k_m.gguf https://huggingface.co/lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf
* где:
- -L — следовать редиректам Hugging Face.
- -o /opt/llama.cpp/models/llama-3-8b-instruct-q4_k_m.gguf — полный путь к локальному файлу модели.
Модель загружена, можно переходить к запуску сервера.
Запуск OpenAI-совместимого API-сервера
Разберем, как запустить llama cpp в режиме сервера.
Разовый запуск и проверка
Указываем путь к модели, размер контекста, адрес и порт:
/opt/llama.cpp/build/bin/llama-server -m /opt/llama.cpp/models/llama-3-8b-instruct-q4_k_m.gguf -c 4096 --host 0.0.0.0 --port 8080 -ngl 99
* где:
- -m — путь к файлу модели .gguf.
- -c 4096 — размер контекстного окна в токенах.
- --host 0.0.0.0 — слушать на всех сетевых интерфейсах.
- --port 8080 — порт API.
- -ngl 99 — число слоев модели на GPU; на CPU-only сборке флаг уберите.
* для тонкой настройки производительности к команде можно добавить --threads (число CPU-потоков инференса) и --batch-size (размер батча токенов за проход).
Сервер поднят и слушает порт 8080.
Проверим, как пользоваться llama-cpp через API-запрос, отправив тестовое сообщение в чат:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "Привет! Напиши одно короткое предложение про Linux."}
],
"temperature": 0.7
}'
* где:
- /v1/chat/completions — OpenAI-совместимый endpoint чата.
- temperature — креативность ответа (0 — детерминированно, ближе к 1 — разнообразнее).
Сразу после старта модель еще грузится в память, и сервер может вернуть:
{"error":{"message":"Loading model","type":"unavailable_error","code":503}}
* это нормальное поведение — ждем несколько секунд, пока модель полностью загрузится, и повторяем запрос.
Кроме /v1/chat/completions доступны /v1/completions для запросов без диалоговой обертки и /health — для проверки, что сервер жив и модель загружена.
Автозапуск через systemd
Настроим автозапуск llama-cpp через systemd, чтобы сервер поднимался сам после перезагрузки. Создадим unit-файл:
vi /etc/systemd/system/llama.service
[Unit]
Description=Llama.cpp API Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/build/bin/llama-server -m /opt/llama.cpp/models/llama-3-8b-instruct-q4_k_m.gguf -c 4096 --host 0.0.0.0 --port 8080 -ngl 99
Restart=always
RestartSec=5
Environment=LD_LIBRARY_PATH=/usr/local/cuda/lib64
[Install]
WantedBy=multi-user.target
* где:
- WorkingDirectory / ExecStart — те же пути /opt/llama.cpp, что использовались при клонировании и запуске вручную.
- Restart=always — перезапуск сервиса при падении.
- Environment=LD_LIBRARY_PATH=... — путь к библиотекам CUDA; строку и флаг -ngl 99 оставьте только для GPU, на CPU-only удалите.
* юнит запускает сервис от root для простоты. Для продакшена лучше завести отдельного пользователя (например, llama), дать ему права только на /opt/llama.cpp и указать в User. Логи по умолчанию уже пишутся в journal — при желании можно добавить SyslogIdentifier=llama-server, чтобы отделить их от других сервисов при поиске в journalctl.
Перечитаем конфигурацию systemd и запустим сервис:
systemctl daemon-reload
systemctl enable --now llama
systemctl status llama
* где:
- daemon-reload — перечитать unit-файлы после создания llama.service.
- enable --now — автозапуск после перезагрузки и старт сервиса сразу.
- status — проверить состояние и логи запуска.
Готово. Llama.cpp запущен как systemd-сервис и переживет перезагрузку сервера.
Ограничение доступа к API и настройка NGINX-прокси
Флаг --host 0.0.0.0 открывает порт 8080 наружу — без дополнительной защиты к серверу сможет обратиться кто угодно. Для внутреннего использования проще всего слушать только локальный интерфейс:
--host 127.0.0.1
* заменяем этот флаг в команде запуска и в ExecStart юнита, если внешний доступ не нужен.
Если доступ снаружи все же нужен, ставим перед llama-server реверс-прокси nginx с базовой авторизацией — так порт 8080 не торчит в интернет напрямую, а запросы проходят проверку логина и пароля.
Создадим файл с логином и паролем и укажем его в конфиге nginx:
htpasswd -c /etc/nginx/.htpasswd admin
server {
listen 80;
server_name llama.example.com;
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}
* llama.example.com замените на свой домен; после сохранения конфига перезапустите nginx командой systemctl reload nginx.
Обновление llama.cpp
Проект развивается быстро, поэтому имеет смысл периодически обновлять сборку. Переходим в каталог проекта и подтягиваем изменения:
cd /opt/llama.cpp && git pull
Пересобираем проект тем же способом, что и при первой установке:
cmake --build build --config Release -j $(nproc)
* после обновления перезапускаем сервис: systemctl restart llama.
Типичные проблемы
Рассмотрим несколько частовстречаемых проблем.
CUDA out of memory
Сервер падает при загрузке модели на GPU с ошибкой CUDA out of memory.
Причина: не хватает VRAM — модель в выбранном кванте вместе с контекстным окном не помещается в видеопамять.
Решение: уменьшаем значение -ngl, чтобы часть слоев осталась на CPU — это снизит нагрузку на VRAM ценой небольшого падения скорости. Либо берем модель с более легким квантом (например, Q4_K_M вместо Q5_K_M). Если проблема повторяется и на CPU — увеличиваем размер swap или выбираем модель меньшего размера.
Cmake не находит CUDA
cmake завершается с ошибкой при сборке варианта B — не находит CUDA.
Причина: либо NVIDIA CUDA Toolkit не установлен, либо переменная окружения PATH не указывает на его bin-каталог, где лежит nvcc.
Решение: проверяем, что CUDA Toolkit установлен (nvcc --version должен вернуть версию компилятора). Если команда не найдена — добавляем путь к bin-каталогу CUDA в PATH, например:
export PATH=/usr/local/cuda/bin:$PATH
После чего повторяем настройку и сборку.
Curl висит или возвращает 503
Сервер не отвечает на первый запрос — curl висит или возвращает 503.
Причина: это нормальное поведение для больших моделей — llama-server грузит веса в память при старте, и до завершения загрузки не обрабатывает запросы.
Решение: ждем несколько секунд (для моделей 8B — обычно до 10–30 секунд в зависимости от диска и CPU/GPU), затем повторяем запрос. Убедиться, что модель загружена, можно по логам сервиса:
journalctl -u llama -f
Строка о готовности к приему запросов появится в выводе.
Сравнение с Ollama
Llama.cpp часто сравнивают с Ollama — оба движка построены на одном и том же ядре инференса.
И так, llama.cpp в сравнении с Ollama:
- Дает больше контроля над флагами сборки и запуска.
- Не требует отдельного демона поверх системы — llama-server запускается как обычный процесс.
- Не скачивает и не версионирует модели автоматически — файлы GGUF нужно искать и подкладывать вручную.
- Не имеет встроенной командной обертки для смены моделей на лету.