Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → llama.cpp server: локальный инференс LLM

llama.cpp server: как поднять локальный LLM-сервер с OpenAI-совместимым API

llama-server: запуск GGUF-моделей, оффлоад слоёв на GPU, параметры контекста и батчинга, OpenAI-совместимый API и мониторинг нагрузки.

Прямой ответ

llama-server — компонент llama.cpp, который поднимает HTTP-сервер для GGUF-моделей и предоставляет API, совместимый с OpenAI (/v1/chat/completions). Это самый прямой путь запустить локальную модель без внешних сервисов: один бинарник, один файл модели, управляемые параметры контекста и параллелизма.

Базовый запуск:

./llama-server \
  -m ./models/qwen2.5-7b-instruct-q4_k_m.gguf \
  --host 0.0.0.0 --port 8080 \
  --ctx-size 8192 \
  --n-gpu-layers 35 \
  --threads 8 \
  --parallel 2

Ключевые параметры:

  • --ctx-size — размер контекстного окна в токенах. Память под KV-кэш растёт пропорционально, поэтому «поставить максимум» — плохая идея.
  • --n-gpu-layers — сколько слоёв модели выгрузить в видеопамять. При нехватке VRAM часть слоёв остаётся на CPU, и скорость определяется самым медленным звеном.
  • --parallel — число одновременных запросов; контекст делится между ними, поэтому --parallel 4 при --ctx-size 8192 даёт по 2048 токенов на запрос.
  • --threads — число потоков CPU. Больше не значит лучше: обычно оптимум равен числу физических ядер.

Отличия от Ollama: Ollama удобнее для быстрого старта и управления набором моделей, llama-server даёт больше контроля над параметрами инференса и удобен, когда нужна одна модель в продакшен-режиме с предсказуемым потреблением ресурсов.

Ограничения, которые стоит учесть:

  1. Одна модель на процесс. Для нескольких моделей нужен отдельный процесс (и отдельный порт) на каждую.
  2. Параллелизм ограничен контекстом. При высокой конкуренции запросы выстраиваются в очередь, поэтому для нагрузки с десятками одновременных пользователей лучше подходит движок с непрерывным батчингом — см. vLLM.
  3. Нет встроенной аутентификации уровня продакшена. Сервер нужно закрывать обратным прокси с TLS и авторизацией.

Практика: интеграция и эксплуатация

Запрос через OpenAI-совместимый API:

curl -s  \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-7b-instruct",
    "messages": [{"role": "user", "content": "Объясни, что такое KV-кэш, двумя предложениями."}],
    "temperature": 0.2,
    "max_tokens": 200
  }'

Проверка состояния и метрик:

curl -s       # состояние сервера
curl -s       # параметры модели и контекста
curl -s     # метрики в формате Prometheus

Метрики удобно отдавать в Prometheus: время генерации токена, размер очереди, использование контекста. Как снимать и называть метрики — в статье про инструментацию приложения.

Рекомендации:

  1. Подбирайте --n-gpu-layers эмпирически. Увеличивайте, пока VRAM не заполнен на 80–90 %, и следите, чтобы KV-кэш тоже помещался. Переполнение видеопамяти приводит к тихому падению скорости.
  2. Ограничивайте контекст по фактической необходимости. Если диалоги короткие, 4K вместо 16K освобождает память и ускоряет запуск.
  3. Добавьте healthcheck и graceful shutdown. Для контейнерной эксплуатации это обязательная практика — см. healthcheck и graceful shutdown.
  4. Фиксируйте версию модели и кванта. Смена файла модели меняет поведение; версионирование и откат должны быть такими же, как для кода.

Как понять, что упёрлись в память, а не в вычисления. Признак памяти: загрузка GPU низкая, а скорость генерации мала, при этом часть слоёв работает на CPU — в логе запуска видно распределение слоёв. Признак вычислений: GPU загружен полностью, скорость стабильна, но невелика. В первом случае помогает более агрессивный квант и сокращение контекста, во втором — только более быстрое железо или модель меньшего размера. Смешивать эти две причины опасно: можно потратить часы на настройку потоков, когда проблема в переполнении видеопамяти.

Как понять, что упёрлись в память, а не в вычисления. Признак памяти: загрузка GPU низкая, а скорость генерации мала, при этом часть слоёв работает на CPU — в логе запуска видно распределение слоёв. Признак вычислений: GPU загружен полностью, скорость стабильна, но невелика. В первом случае помогает более агрессивный квант и сокращение контекста, во втором — только более быстрое железо или модель меньшего размера. Смешивать эти две причины опасно: можно потратить часы на настройку потоков, когда проблема в переполнении видеопамяти.

Практический сценарий: сервер деградирует при двух одновременных запросах

Контекст: локальный сервис разбора инцидентов; один запрос работает за 3 секунды, два параллельных — за 25 секунд каждый.

  1. Диагностика. /props показывает --ctx-size 8192 и --parallel 4, то есть на запрос остаётся 2048 токенов. Запросы с длинным входом упираются в лимит и начинают обрезаться/тормозить.
  2. Проверка VRAM. nvidia-smi показывает 95 % занятой видеопамяти: часть слоёв вытеснена в системную память, обмен между CPU и GPU стал узким местом.
  3. Исправление. Уменьшаем --parallel до 2, поднимаем --ctx-size до 12288, снижаем --n-gpu-layers, чтобы KV-кэш гарантированно помещался в VRAM. Длинные входы урезаем на стороне приложения.
  4. Проверка. Два параллельных запроса выполняются за 5–6 секунд каждый; очередь не растёт. Добавляем алерт на длительность запроса p95 — подход к перцентилям описан в статье про гистограммы метрик.
  5. Планирование нагрузки. Оцениваем, сколько одновременных пользователей выдерживает конфигурация, и документируем предел; методика — в статье про capacity planning.

Результат: предсказуемая работа под небольшой конкуренцией. Вывод: в llama-server главный ресурс — контекстная память, а её делят между собой параллельные запросы; параметры нужно считать, а не ставить «с запасом».

FAQ

Можно ли использовать llama-server в продакшене? Да, для внутренней нагрузки с умеренным параллелизмом. Обязательны: обратный прокси с TLS и авторизацией, лимиты на размер запроса, мониторинг, резервный план при отказе модели. Для публичной нагрузки с десятками одновременных пользователей нужен движок с непрерывным батчингом.

Почему скорость генерации падает со временем работы? Чаще всего причина не в модели, а в росте контекста диалога: больше токенов — больше работы на каждый шаг. Вторая причина — тепловое троттлинг устройства. Третья — накопление запросов в очереди при недостаточном параллелизме.

Как выбрать между llama-server и Ollama? Ollama удобнее для разработки и нескольких моделей на одной машине. llama-server предпочтителен, когда нужна одна модель, точный контроль параметров и метрики Prometheus. Оба используют GGUF, поэтому модель можно переносить без конвертации.

Что делать, если модель не помещается целиком? Три варианта: взять модель меньшего размера, выбрать более агрессивный квант, либо оставить часть слоёв на CPU и принять снижение скорости. Комбинация «меньше модель + Q4» почти всегда быстрее, чем «большая модель + CPU-оффлоад».

Источники: llama.cpp server (GitHub), llama.cpp, Ollama — ссылки в шапке.