Режим маршрутизации Llama-Server: динамическое переключение моделей без перезапуска

Запуск и замена LLM без перезагрузки

Содержимое страницы

Долгое время у llama.cpp была очевидная limitation:
вы могли обслуживать только одну модель в процессе, а переключение требовало перезапуска.

Эта эпоха закончилась.

Недавние обновления добавили режим маршрутизатора (router mode) в llama-server, приблизив функциональность к тому, что люди ожидают от современных локальных сред выполнения LLM:

  • динамическая загрузка моделей
  • выгрузка по требованию
  • переключение на уровне запроса
  • без перезапуска процесса

llm router on the table

Другими словами: поведение, похожее на Ollama, но без «треног».

Если вы все еще выбираете между локальными средами выполнения, облачными API и собственным хостингом, обзор Хостинг LLM является хорошей отправной точкой.


Предварительные требования

Для режима маршрутизатора требуется свежая сборка llama-server — примерно после середины 2024 года. В старых сборках отсутствуют флаги --models-preset или --models-dir.

Варианты установки (менеджер пакетов, готовые бинарные файлы или полная сборка из исходников с поддержкой CUDA) описаны в быстром старте llama.cpp.

После получения llama-server убедитесь, что ваша сборка поддерживает режим маршрутизатора:

llama-server --help | grep -i models

Если вы видите --models-preset или --models-dir, значит все в порядке. Если их нет, обновите сборку.

Вывод справки, относящийся к моделям, в моей текущей версии:

-cl,   --cache-list                     show list of models in cache
                                        Prefix/Suffix/Middle) as some models prefer this. (default: disabled)
                                        models with dynamic resolution (default: read from model)
                                        models with dynamic resolution (default: read from model)
                                        embedding models (default: disabled)
--models-dir PATH                       directory containing models for the router server (default: disabled)
                                        (env: LLAMA_ARG_MODELS_DIR)
--models-preset PATH                    path to INI file containing model presets for the router server
                                        (env: LLAMA_ARG_MODELS_PRESET)
--models-max N                          for router server, maximum number of models to load simultaneously
                                        (env: LLAMA_ARG_MODELS_MAX)
--models-autoload, --no-models-autoload
                                        for router server, whether to automatically load models (default:
                                        (env: LLAMA_ARG_MODELS_AUTOLOAD)

Что на самом деле делает режим маршрутизатора

Режим маршрутизатора превращает llama-server в диспетчер моделей.

Вместо привязки к одной модели через флаг -m, сервер:

  • запускается без загруженных моделей
  • получает запрос с указанием имени модели
  • загружает эту модель, если она еще не находится в памяти
  • выполняет инференс (вывод)
  • по желанию выгружает модель после ответа или держит ее «теплой» для следующего запроса

Основная идея

Вы больше не запускаете:

./llama-server -m model.gguf

Вы запускаете:

./llama-server --models-preset models.ini --port 8080

И позволяете серверу решать, что загружать и когда, на основе того, что фактически запрашивает клиент.

Это важно, потому что означает, что один постоянный процесс может обслуживать целый парк моделей, а клиенты выбирают подходящую для каждой задачи — модель для кода, модель для чата, модель для суммаризации — без дополнительных накладных расходов на координацию с вашей стороны.


Конфигурация: определение моделей

Здесь все еще есть некоторые шероховатости.

Единого стабильного официального формата еще нет, но текущие сборки поддерживают определения моделей в стиле INI через конфигурационный файл.

Пример models.ini

[llama3]
model = /opt/models/llama-3-8b-instruct.Q5_K_M.gguf
ctx-size = 8192
ngl = 35
threads = 8

[mistral]
model = /opt/models/mistral-7b-instruct-v0.3.Q4_K_M.gguf
ctx-size = 4096
ngl = 20
threads = 8

[qwen]
model = /opt/models/qwen2.5-coder-7b-instruct.Q5_K_M.gguf
ctx-size = 16384
ngl = 35
threads = 8

Имя каждого раздела становится идентификатором модели, который клиенты используют в поле "model" своих API-запросов.

Ключевые параметры конфигурации

Параметр Что он контролирует
model Абсолютный путь к файлу GGUF
ctx-size Размер контекстного окна в токенах. Большие значения используют больше VRAM.
ngl Количество слоев GPU, загруженных на видеокарту. Установите 0 для работы только на CPU; увеличивайте, пока не достигнете лимитов VRAM.
threads Потоки CPU для слоев, оставшихся на процессоре.

Выбор правильного значения ngl зависит от доступного VRAM вашей видеокарты — для выбора GPU и оценки аппаратных расходов полезен руководство по вычислительному оборудованию. Чтобы следить за потреблением VRAM в реальном времени во время настройки, см. инструменты мониторинга GPU для Linux.

Запуск сервера с конфигурацией

./llama-server --models-preset /opt/llama.cpp/models.ini --port 8080

Убедитесь, что сервер запустился корректно:

curl http://localhost:8080/v1/models | jq '.data[].id'

Вы должны увидеть каждый раздел из вашего models.ini в списке идентификаторов моделей.

Примечание по стабильности

Интерфейс конфигурации INI все еще развивается:

  • флаги могут меняться между коммитами
  • некоторые параметры распознаются только определенными конфигурациями сборки
  • документация отстает от реализации

Если вам нужна воспроизводимость при перезапусках, привяжите конкретный коммит llama.cpp.


Использование API: переключение моделей по запросу

После запуска сервера переключение моделей происходит через стандартный OpenAI-совместимый API. Вам просто нужно установить поле "model".

Список зарегистрированных моделей

curl http://localhost:8080/v1/models

Запрос на завершение — первая модель

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama3",
    "messages": [
      {"role": "user", "content": "Explain router mode in one paragraph"}
    ]
  }'

Переключение на другую модель — тот же конечный пункт, тот же порт

curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen",
    "messages": [
      {"role": "user", "content": "Write a Python function that reads a CSV file"}
    ]
  }'

Сервер прозрачно обрабатывает цикл выгрузки/загрузки. Ваш клиентский код не меняется — меняется только поле model.

Пример на Python

Если вы используете клиент openai для Python:

from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")

# Use the coding model
response = client.chat.completions.create(
    model="qwen",
    messages=[{"role": "user", "content": "Write a Go HTTP handler"}],
)
print(response.choices[0].message.content)

# Switch to the chat model — same client, different model name
response = client.chat.completions.create(
    model="llama3",
    messages=[{"role": "user", "content": "What is the capital of Australia?"}],
)
print(response.choices[0].message.content)

Что происходит внутри

Когда поступает запрос для qwen, а llama3 в данный момент загружена:

  1. llama3 выгружается из VRAM
  2. веса qwen считываются с диска и загружаются в VRAM
  3. выполняется инференс
  4. следующий запрос определяет, оставить ли qwen загруженной или снова выполнить обмен

Это напрямую отвечает на распространенный вопрос:

Как локальный сервер LLM может переключать модели без перезапуска

Загружая модели динамически для каждого запроса, а не привязывая их при запуске.


Системная служба Systemd: готовая к производству настройка

Создание отдельного пользователя и директорий

sudo useradd --system --shell /usr/sbin/nologin --home-dir /opt/llama.cpp llm
sudo mkdir -p /opt/llama.cpp/models
sudo chown -R llm:llm /opt/llama.cpp

Скопируйте бинарный файл и конфигурацию моделей на место:

sudo cp build/bin/llama-server /opt/llama.cpp/
sudo cp models.ini /opt/llama.cpp/

/etc/systemd/system/llama-server.service

[Unit]
Description=Llama.cpp Router Server
After=network.target

[Service]
Type=simple
User=llm
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/llama-server --models-preset /opt/llama.cpp/models.ini --port 8080
Restart=always
RestartSec=5

Environment=LLAMA_LOG_LEVEL=info

[Install]
WantedBy=multi-user.target

Включение и запуск

sudo systemctl daemon-reload
sudo systemctl enable llama-server
sudo systemctl start llama-server

Проверка и просмотр журналов

sudo systemctl status llama-server
journalctl -u llama-server -f

При успешном запуске вы увидите строки, указывающие, что сервер слушает порт и реестр моделей загружен. Быстрая проверка:

curl -s http://localhost:8080/v1/models | jq '.data[].id'

Теперь у вас есть постоянная служба с автоматическим перезапуском и централизованным переключением моделей — без ручного управления процессами. Если вы хотите применить тот же шаблон к другим бинарным файлам, руководство Хостинг любого исполняемого файла как службы Linux описывает общий подход.

Флаг llama-server --metrics открывает конечный пункт, совместимый с Prometheus. Для дашбордов, специфичных для llama.cpp, запросов PromQL и правил оповещений см. руководство по мониторингу инференса LLM. Для более широкой настройки наблюдаемости руководство наблюдаемость охватывает полный стек.


Ограничения, которые необходимо понимать

Режим маршрутизатора действительно полезен, но он имеет компромиссы, о которых вы должны быть ясны, прежде чем полагаться на него в производстве.

Только одна модель в памяти одновременно

Несмотря на то, что в models.ini определено несколько моделей, в любой момент времени в VRAM на одного рабочего процесса resides только одна. Переключение означает полный цикл выгрузки и перезагрузки.

  • переключение означает перезагрузку
  • всплеск задержки неизбежен
  • для типичной модели 7B в квантовании Q5 перезагрузка может занять 3–10 секунд в зависимости от скорости диска и пропускной способности VRAM

Это отвечает на еще один ключевой вопрос:

Поддерживает ли llama.cpp обслуживание нескольких моделей одновременно

Не совсем. Он поддерживает несколько определений, но не одновременное размещение в памяти. Если вам нужно, чтобы две модели действительно были загружены параллельно, вам нужны два процесса на двух отдельных GPU.

Измеренное потребление VRAM и токены в секунду для разных размеров моделей описаны в бенчмарках производительности LLM. Для чисел, специфичных для llama.cpp на GPU с 16 ГБ памяти — плотные и MoE модели при разных размерах контекста — см. бенчмарки llama.cpp для VRAM 16 ГБ.

Отсутствие интеллектуального кэширования

В отличие от Ollama, который поддерживает теплый пул и выгружает модели на основе недавности использования:

  • нет автоматической стратегии выгрузки моделей
  • нет фонового предварительного прогрева
  • нет очереди приоритетов для часто используемых моделей

Если вы отправляете чередующиеся запросы для llama3 и mistral, каждый отдельный запрос вызывает перезагрузку. Это фундаментальная цена за близость к «железу».

Задержка непредсказуема для смешанных рабочих нагрузок

Хорошо себя ведущая рабочая нагрузка, использующая одну модель постоянно, будет быстрой. Рабочая нагрузка, которая чередует несколько моделей, будет медленной. Планируйте логику маршрутизации клиента соответственно — группируйте запросы по моделям, где это возможно.

Конфигурация нестабильна

Поддержка INI существует и работает в большинстве последних сборок, но она не полностью стандартизирована. Флаги и имена параметров менялись между версиями. Если вы обновляете llama-server, протестируйте ваш models.ini против новой сборки перед развертыванием.


Llama.cpp против Ollama: честное сравнение

Характеристика маршрутизатор llama.cpp Ollama
Динамическая загрузка Да Да
Переключение моделей Да Да
Встроенный реестр Частичный (INI) Да (на основе pull)
Управление памятью Базовое Продвинутое
Выгрузка моделей Нет На основе TTL
Пользовательский опыт Низкий Высокий
Совместимость с OpenAI API Да Да
Контроль Максимальный Мнение (Opinionated)
Стабильность конфигурации Экспериментальный Стабильный

Субъективное мнение

Выбирайте режим маршрутизатора llama.cpp, если вам нужно:

  • максимальный контроль над параметрами выполнения для каждой модели
  • минимальные накладные расходы на процесс
  • прямой доступ к флагам llama.cpp без слоев абстракции
  • базовая платформа для создания пользовательских инструментов

Выбирайте Ollama, если вам нужно:

  • стабильный, отполированный опыт
  • автоматическое скачивание моделей и управление версиями
  • умное удержание и выгрузка без конфигурации
  • все включено с первого дня

Ни тот, ни другой не является неправильным. Выбор зависит от того, насколько много вы хотите управлять самостоятельно.

Если вы выберете Ollama, шпаргалка по CLI Ollama охватывает повседневные команды. Для более широкого сравнения, которое также включает vLLM, LM Studio и LocalAI, см. как сравниваются разные локальные среды выполнения в 2026 году.


Llama.cpp против llama-swap

llama-swap — это внешний оркестратор, который располагается перед одним или несколькими экземплярами llama-server:

  • он перехватывает запросы и проверяет поле model
  • он запускает соответствующий процесс llama-server для этой модели
  • он останавливает неактивные экземпляры после настраиваемого тайм-аута
  • он проксирует запрос после того, как модель готова

Для практической настройки см. быстрый старт llama-swap.

Ключевое различие

Аспект режим маршрутизатора llama-swap
Встроенный Да Нет (отдельный бинарный файл)
Зрелость Экспериментальный Более стабильный
Гибкость Ограниченная Высокая
Слой управления Внутренний Внешний прокси
Конфигурация на модель Файл INI Файл YAML
Модель процессов Один процесс Один процесс на модель

Когда использовать llama-swap

llama-swap обеспечивает изоляцию на уровне процесса для каждой модели, что означает, что сбой в одном экземпляре модели не влияет на другие. Он также позволяет каждой модели работать с полностью независимыми флагами llama-server.

Используйте его, если вам нужно:

  • лучший контроль жизненного цикла и изоляция
  • более умная логика переключения с настраиваемыми тайм-аутами простоя
  • более предсказуемая задержка (каждая модель имеет «теплый» процесс после первой загрузки)
  • стабильность производства сегодня, а не в будущем

Когда нативного режима маршрутизатора достаточно

Используйте встроенный маршрутизатор, если вам нужно:

  • нулевая зависимость от внешних компонентов
  • один процесс для управления
  • более простое развертывание (один бинарный файл, один файл конфигурации)
  • минимальный стек для разработки или конфигураций на одного пользователя

Финальные мысли

Режим маршрутизатора — значительный шаг вперед для llama-server.

Он отвечает на давний запрос:

Что такое режим маршрутизатора в сервере llama.cpp

Это недостающий слой, который превращает статический бинарный файл в динамическую службу инференса — один процесс, который может обрабатывать запросы для всего каталога моделей.

Но он еще не завершен.

Сегодня он:

  • достаточно мощный для реальных рабочих нагрузок
  • перспективен как основа для более сложной маршрутизации
  • немного шероховат в плане конфигурации и стабильности

Если ваша рабочая нагрузка предсказуема и вы можете группировать запросы по моделям, режим маршрутизатора хорошо работает сегодня. Если вам нужна надежность уровня производства и изоляция на уровне моделей, обратитесь к llama-swap, пока нативная реализация созревает.

Когда вам нужно освободить VRAM без перезапуска — для запуска бенчмарка, окна обслуживания или чистой перезагрузки разработки — скриптуемый подход заключается в том, чтобы перечислить загруженные модели и вызвать конечный пункт выгрузки для каждой из них. Полный паттерн с использованием curl и jq описан в Выгрузка всех моделей маршрутизатора llama.cpp без перезапуска.

В любом случае, вы получаете поведение, похожее на Ollama, не скрывая механизмы.

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.