Быстрый старт переключателя моделей llama.swap для локальных LLM, совместимых с OpenAI
Горячая замена локальных LLM без изменения клиентов.
Вот вы скоро балансируете между vLLM, llama.cpp и прочим стеком — каждый на своем порту. Все downstream-системы все еще ожидают единый базовый URL /v1; иначе вы будете постоянно менять порты, профили и разовые скрипты. llama-swap — это прокси для /v1, стоящее перед этими стеками.
llama-swap предоставляет единый вход, совместимый с OpenAI и Anthropic, с YAML-файлом, который сопоставляет каждое имя model с командой для запуска соответствующего upstream-сервера. Запросите модель, и прокси запустит или переключится на нее; настройте TTL и группы, когда VRAM ограничена или несколько моделей должны сосуществовать. Это руководство охватывает пути установки, практический config.yaml, HTTP-интерфейс и режимы отказов, которые возникают при включении потоковой передачи и обратных прокси.
Для более широкого сравнения вариантов хостинга LLM см. Хостинг LLM в 2026 году: локальный, self-hosted и облачная инфраструктура
Обзор переключателя моделей llama-swap для локальных LLM-API, совместимых с OpenAI
llama-swap — это легковесный прокси-сервер, построенный вокруг простой операционной модели: один бинарный файл, один YAML-файл конфигурации, без зависимостей. Он написан на Go, что означает единый статический бинарный файл рядом с остальным стеком — без необходимости в runtime Python или десктопном приложении. Он стоит перед любым совместимым с OpenAI и Anthropic upstream-сервером в качестве слоя переключения моделей.
Концептуально это отвечает на очень практичный вопрос, возникающий в локальных стеках LLM:
Как переключать модели с клиентом, совместимым с OpenAI?
С llama-swap вы продолжаете использовать обычные запросы /v1/..., но меняете запрашиваемую model. llama-swap считывает значение этой model, загружает соответствующую конфигурацию сервера, и если запущен «неправильный» upstream, он заменяет его на правильный.
Несколько деталей дизайна важны для продвинутых настроек:
llama-swap имеет лицензию MIT и не содержит телеметрии — все же стоит убедиться в этом для любого хоста, который видит реальные промпты.
Он создан для загрузки бэкендов по требованию, таких как llama.cpp, vLLM, Whisper и stable-diffusion.cpp, а не для привязки к одному движению инференса.
По умолчанию (без специальной группировки) он запускает одну модель за раз: запросите другую model, и он остановит текущий upstream и запустит правильный. Для более чем одной резидентной модели или более тонкого контроля над сосуществованием настройте groups.
Вот ментальная модель, которую большинство разработчиков находят полезной:
flowchart LR
C[Ваше приложение или SDK\nКлиент, совместимый с OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[llama-swap прокси\nединая точка входа]
LS -->|запускает или маршрутизирует на| U1[Upstream сервер A\nllama-server]
LS -->|запускает или маршрутизирует на| U2[Upstream сервер B\nvLLM OpenAI server]
LS --> M[Точки управления\nrunning, unload, events, metrics]
Вот почему прокси-переключатель моделей отличается от «просто запуска модели»: это оркестрация и маршрутизация поверх одного или нескольких серверов инференса.
llama-swap vs Ollama vs LM Studio vs сервер llama.cpp
Все четыре варианта могут дать вам «локальный LLM-API», но они оптимизированы для разных рабочих процессов. Самый быстрый способ выбрать — решить, хотите ли вы runtime (загрузка модели + выполнение) или маршрутизатор/прокси (переключение и оркестрация между runtime).
llama-swap
llama-swap фокусируется на том, чтобы быть прозрачным прокси, который поддерживает совместимые с OpenAI конечные точки (включая /v1/chat/completions, /v1/completions, /v1/embeddings и /v1/models) и маршрутизирует запросы на правильный upstream на основе запрошенной модели. Он также предоставляет операционные конечные точки, не связанные с инференсом, такие как /running, /logs/stream и веб-интерфейс на /ui.
Ollama
Ollama предоставляет свой собственный HTTP-API (POST /api/chat, POST /api/generate и обычный локальный порт по умолчанию 11434).
keep_alive контролирует, как долго модель остается загруженной, включая 0 для немедленной разгрузки.
Он подходит пользователям, которые хотят скачать модель и пообщаться с минимальными настройками. llama-swap подходит для команд по модели, смешанных бэкендов и одного URL в стиле OpenAI для каждого клиента — оркестрация vLLM рядом с llama-server с разными флагами для каждой модели выходит за рамки того, на что нацелен Ollama.
LM Studio
LM Studio — это десктопное приложение с локальным API-сервером из вкладки Developer (localhost или LAN), включая режимы совместимые с OpenAI и Anthropic, а также команду lms server start из терминала.
Он подходит для цикла, ориентированного на GUI: просмотр моделей, клик, тест. llama-swap подходит для роли серверного стиля: YAML, надзор за процессами, смешанные upstream, без сеанса десктопа.
Сервер llama.cpp
llama-server предоставляет /v1/completions, /v1/chat/completions, /v1/responses, и обычный паттерн — указывать на него OpenAI-клиент через base_url.
llama.cpp также поставляется с режимом маршрутизатора: запустите llama-server как маршрутизатор, --models-dir, затем POST /models/load и POST /models/unload, чтобы управлять моделями GGUF без отдельного прокси.
Если каждая модель находится под одним маршрутизатором llama.cpp, дополнительный прокси часто не нужен. Когда llama.cpp должен стоять рядом с vLLM или другими серверами в стиле OpenAI, llama-swap предоставляет одну поверхность /v1 и много процессов за ней.
Для аналогичных решений хостинга, совместимых с OpenAI, см. LocalAI QuickStart: Запуск совместимых с OpenAI LLM локально или SGLang QuickStart: Установка, настройка и обслуживание LLM через OpenAI API
Установка переключателя моделей llama-swap с Docker, Homebrew, WinGet или бинарниками
Linux, macOS и Windows имеют первый класс поддержки: Docker, Homebrew, WinGet, бинарники GitHub или сборка из исходного кода. Обычные варианты: Docker для серверов без графического интерфейса, Homebrew или WinGet для рабочих станций, автономные бинарники, когда след установки должен быть минимальным.
Установка Docker
Загрузите образ, соответствующий вашему оборудованию. Образы тесно следят за upstream (ночные сборки) и охватывают CUDA, Vulkan, Intel, MUSA и CPU — выберите тот, который соответствует тому, как вы действительно ускоряете, а не «последний» из привычки.
# Примеры загрузки платформ
docker pull ghcr.io/mostlygeek/llama-swap:cuda
docker pull ghcr.io/mostlygeek/llama-swap:vulkan
docker pull ghcr.io/mostlygeek/llama-swap:intel
docker pull ghcr.io/mostlygeek/llama-swap:musa
docker pull ghcr.io/mostlygeek/llama-swap:cpu
Предпочитайте варианты образов не root, когда это возможно: меньше сожалений, если граница контейнера когда-нибудь окажется неверной.
Установка Homebrew
На macOS и Linux используйте tap и установите:
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
Установка WinGet
На Windows:
winget install llama-swap
winget upgrade llama-swap
Готовые бинарники и релизы
GitHub Releases предоставляет бинарники для Linux, macOS, Windows и FreeBSD, если вы не хотите использовать менеджер пакетов.
Номера релизов меняются быстро (например v198, v197 в начале 2026 года) — закрепите версию в автоматизации, а не плавьте «то, что было вчера».
Настройка llama-swap с config.yaml для переключения моделей, TTL и групп
Всё в llama-swap управляется конфигурацией. Минимальная жизнеспособная конфигурация — это просто словарь models: и cmd для каждой модели, часто запускающая llama-server с подстановкой ${PORT} для каждой модели.
Система конфигурации выходит далеко за рамки «просто запустить процесс», и несколько опций стоит понять заранее, потому что они напрямую отвечают на проблемы в стиле FAQ (авто-разгрузка, безопасность и клиенты, полагающиеся на /v1/models).
Глобальные настройки, которые вы действительно будете использовать
healthCheckTimeout — это время, которое llama-swap ждет, пока модель станет здоровой после запуска (по умолчанию 120с, минимум 15с). Для загрузки моделей в несколько ГБ на медленных дисках увеличьте это значение, прежде чем винить прокси.
globalTTL — это секунды простоя перед авто-разгрузкой; по умолчанию 0 означает «никогда не разгружать», если вы не установите это — явно выбирайте TTL для всего, что выходит за рамки детской настройки, чтобы VRAM не заполнялась забытыми моделями.
startPort — это начальное значение для макроса ${PORT} (по умолчанию 5800); назначение детерминировано по алфавитному ID модели, что является особенностью при отладке «кто занял какой порт» и ловушкой, если вы небрежно переименуете модели.
includeAliasesInList решает, будут ли алиасы отображаться как отдельные строки в /v1/models; включите это, если ваш интерфейс предлагает только перечисленные модели.
apiKeys защищает всё, что доступно вне localhost: Basic, Bearer или x-api-key. llama-swap удаляет эти заголовки перед пересылкой, чтобы upstream-логи с меньшей вероятностью хранили секреты клиента.
Настройки уровня модели, которые открывают производственную эргономику
Для каждой модели cmd — единственное обязательное поле.
proxy по умолчанию http://localhost:${PORT} — это цель пересылки для upstream этой модели.
checkEndpoint по умолчанию /health; установите "none", когда у бэкенда нет маршрута здоровья или холодный запуск превышает то, что вы готовы ждать — не оставляйте сломанный /health и удивляйтесь, почему ничего не достигает состояния ready.
ttl: -1 наследует globalTTL, 0 никогда не разгружает, N > 0 разгружает после N секунд простоя — используйте TTL для модели, когда одна модель должна оставаться, а другая должна исчезнуть быстро.
aliases и useModelName сохраняют стабильные имена для клиента, удовлетворяя upstream, требующий конкретного идентификатора.
cmdStop не опционален для контейнеров: сопоставьте его с docker stop (или аналогом); без него вы получаете POSIX SIGTERM / Windows taskkill против любого PID, который запустил llama-swap — нормально для голого бинарника, но неправильно для имени контейнера.
concurrencyLimit ограничивает параллельные запросы для модели с HTTP 429 при превышении — установите это, если вы предпочитаете сбрасывать нагрузку, а не ждать в очереди вечно.
groups покрывают сосуществование (swap, exclusive) и модели всегда включенные (persistent). Хуки могут предзагружать при запуске; если вы предзагружаете несколько моделей одновременно без группы, ожидайте, что они будут бороться — сначала определите группу, чтобы предзагрузка соответствовала тому, как вы хотите, чтобы модели делили GPU.
Минимальный пример config.yaml для llama.cpp и vLLM
Этот пример направлен на то, чтобы быть «достаточным», чтобы проиллюстрировать лучшие практики: TTL по умолчанию, явная проверка здоровья, стабильные алиасы и группа, которая держит маленькую модель «всегда включенной», в то время как большие чат-модели переключаются.
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 минут простоя, затем разгрузка
includeAliasesInList: true
startPort: 5800
# Опционально, но рекомендуется для всего, что выходит за рамки разработки на localhost
apiKeys:
- "${env.LLAMASWAP_API_KEY}"
models:
llama-chat:
cmd: |
llama-server --port ${PORT} --model /models/llama-chat.gguf
--ctx-size 8192
aliases:
- "llama-chat-latest"
# Использует значения по умолчанию:
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (наследует globalTTL)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# Иллюстративный паттерн: управление контейнеризированным сервером, совместимым с OpenAI
proxy: "http://127.0.0.1:${PORT}"
cmd: |
docker run --name ${MODEL_ID} --init --rm -p ${PORT}:8000 vllm/vllm-openai:latest
cmdStop: docker stop ${MODEL_ID}
checkEndpoint: "none"
ttl: 0 # никогда не разгружать автоматически (например, держать на GPU)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
Ничто из этого не декоративно: cmd управляет процессом, proxy/checkEndpoint/ttl контролируют маршрутизацию и жизненный цикл, cmdStop — это то, что заставляет upstream на базе Docker действительно останавливаться, а groups — это то, что отделяет «одну большую модель за раз» от «эти две чат-модели могут сосуществовать, пока сервер эмбеддингов остается закрепленным».
Запуск и переключение моделей через совместимые с OpenAI конечные точки
Как только llama-swap запущен, вы взаимодействуете с ним как с любым другим совместимым с OpenAI конечной точкой. Поверхность API включает основные конечные точки, такие как /v1/chat/completions, /v1/completions, /v1/embeddings и /v1/models, и llama-swap использует запрошенную model, чтобы решить, какой upstream запустить и на него маршрутизировать.
Практический поток быстрого старта:
# 1) Запустить llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Обнаружить доступные модели
curl http://localhost:8080/v1/models
Перечисление моделей — это функция управления первого класса и включает поведение, такое как сортировка по ID, исключение моделей unlisted и опциональное включение алиасов.
# 3) Сделать запрос на завершение чата для конкретной модели
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${LLAMASWAP_API_KEY}" \
-d '{
"model": "qwen-coder",
"messages": [{"role":"user","content":"Напишите функцию TypeScript, которая повторяет fetch с экспоненциальной задержкой."}]
}'
Если вы теперь повторите вызов с "model": "llama-chat", llama-swap переключит upstream-процессы (если ваша конфигурация группы не позволяет им сосуществовать), потому что он извлекает запрошенную модель из запроса и загружает соответствующую конфигурацию сервера.
Если вы используете SDK, укажите клиента на http://localhost:8080/v1 — тот же трюк, что и при направлении библиотеки OpenAI Python на llama-server, за исключением того, что стабильный URL теперь llama-swap, а поле model выбирает upstream.
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="sk-your-llamaswap-key"
)
resp = client.chat.completions.create(
model="qwen-coder",
messages=[{"role": "user", "content": "Объясните разницу между мьютексами и семафорами."}],
)
print(resp.choices[0].message.content)
Чтобы прогреть модель перед первым реальным запросом (скрыть задержку холодного старта), используйте /upstream/<model> — это автоматически загрузит, если нужно, и пересылает напрямую на этот upstream. Прямой способ убедиться, что веса находятся в памяти перед бенчмарком или скриптованным тестом.
Управление и мониторинг llama-swap через конечные точки управления API и события SSE
llama-swap — это не просто «прокси»; он также предоставляет операционные конечные точки управления, которые позволяют создать инструментарий вокруг жизненного цикла модели и наблюдаемости.
Проверить, что запущено
GET /running возвращает состояние runtime для загруженных моделей, включая значения состояния, такие как ready, starting, stopping, stopped и shutdown.
curl http://localhost:8080/running
Разгрузить модели для освобождения VRAM
Чтобы разгрузить всё немедленно, используйте API-версионную конечную точку POST /api/models/unload. Чтобы разгрузить одну модель (по ID или алиасу), используйте POST /api/models/unload/<model>. Легаси GET /unload существует для обратной совместимости.
# разгрузить все
curl -X POST http://localhost:8080/api/models/unload
# разгрузить одну модель
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
Используйте эти конечные точки, когда VRAM нужна сейчас, вместо ожидания TTL — бенчмарки, быстрые переключения моделей или после загрузки контрольной точки, намного большей, чем предполагалось.
Потоковая передача живых событий через SSE
GET /api/events устанавливает поток событий, отправляемых сервером (SSE), и предназначен для обновлений в реальном времени, которые включают изменения статуса модели, логи, метрики и количество запросов в полете.
curl -N http://localhost:8080/api/events
SSE и потоковая передача токенов ломаются, если любой промежуточный буфер — отключите буферизацию на nginx (или вашем аналоге) для /api/events и /v1/chat/completions. llama-swap устанавливает X-Accel-Buffering: no на SSE; отключите буферизацию в прокси также — заголовки не заменяют правильную конфигурацию прокси.
Метрики и перехват запросов
GET /api/metrics возвращает метрики использования токенов, с удержанием в памяти, контролируемым metricsMaxInMemory (по умолчанию 1000).
GET /api/captures/<id> может извлекать полные перехваты запроса/ответа, но только когда captureBuffer > 0 настроен.
Логи и веб-интерфейс
llama-swap предоставляет /ui для веб-интерфейса и операционные конечные точки логов, такие как /logs и /logs/stream, для мониторинга в реальном времени.

Если вы включите apiKeys, предполагайте защиту в глубину: /health и части /ui остаются доступными без ключа — это нормально для локальных границ доверия, но не нормально, если хост находится в общей сети. Поставьте llama-swap за что-то, что обеспечивает вашу реальную политику; встроенная аутентификация предназначена для того, чтобы держать случайных клиентов честными, а не для публичного многопользовательского API.
Устранение неполадок переключения моделей llama-swap в продакшене
Большинство проблем llama-swap попадают в небольшой набор операционных категорий: потоковая передача через обратный прокси, проверки здоровья во время холодного старта, порты и жизненный цикл процесса, а также аутентификация.
Потоковая передача ломается за nginx или другим обратным прокси
nginx с радостью буферизует ваши SSE и потоковые завершения. Отключите proxy_buffering (и proxy_cache) для /api/events и /v1/chat/completions. llama-swap излучает X-Accel-Buffering: no на SSE, что помогает — все же исправьте прокси.
Модель никогда не становится готовой
По умолчанию checkEndpoint для каждой модели — /health, и он должен вернуть HTTP 200, чтобы процесс считался готовым. Вы можете установить checkEndpoint на другой путь или на "none", чтобы полностью отключить проверки здоровья.
Если большие модели загружаются дольше, увеличьте healthCheckTimeout (по умолчанию 120с) или используйте адаптированные проверки здоровья для вашего конкретного upstream.
Переключение моделей оставляет старый контейнер запущенным
Если upstream — Docker или Podman, установите cmdStop — в противном случае llama-swap остановит процесс-обертку, а контейнер продолжит пожирать VRAM на заднем плане.
Я получаю ответы 401 после включения безопасности
Когда apiKeys настроен, llama-swap требует валидный ключ и принимает три метода (Basic auth, Bearer token, x-api-key). Он также удаляет заголовки аутентификации перед пересылкой upstream.
Я получаю 429 Too Many Requests
concurrencyLimit возвращает 429 при превышении — по дизайну. Увеличьте лимит, если вы недообеспечили его, или уменьшите лимит, если вы не планировали ограничивать скорость.
Конфликты портов или странные проблемы маршрутизации
Избегайте жестко закодированных портов в cmd; используйте ${PORT} и переместите startPort, если 5800+ конфликтует с чем-то еще. Помните, что порты назначаются в алфавитном порядке по ID модели — переименуйте модель, и маппинг портов изменится.
Чек-лист операционной отладки
/running для истины, /logs/stream, когда запуск непрозрачен, POST /api/models/unload, когда VRAM нужна сейчас. Эта тройка покрывает большинство сессий «почему GPU полна».