Быстрый старт: переключатель моделей 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, что означает наличие единого статического бинарного файла рядом с остальной частью стека — без необходимости в Python runtime или настольном приложении. Он располагается перед любым совместимым с 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 против Ollama против LM Studio против llama.cpp server
Все четыре варианта могут предоставить вам «локальный 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 server
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-server: динамическое переключение моделей без перезапусков.
Если каждая модель находится под одним роутером llama.cpp, дополнительный прокси часто не нужен. Когда llama.cpp должен сосуществовать с vLLM или другими серверами в стиле OpenAI, llama-swap предоставляет одну поверхность /v1 и множество процессов за ней.
Для аналогичных решений размещения, совместимых с OpenAI, см. LocalAI QuickStart: Запуск LLM, совместимых с OpenAI, локально или SGLang QuickStart: Установка, настройка и обслуживание LLM через OpenAI API
Установка переключателя моделей llama-swap с Docker, Homebrew, WinGet или бинарными файлами
Linux, macOS и Windows имеют равные права: Docker, Homebrew, WinGet, бинарные файлы GitHub или сборка из исходного кода. Обычные выборы: Docker на headless-серверах, Homebrew или WinGet на рабочих станциях, автономные бинарные файлы, когда размер установки должен быть минимальным.
Установка через Docker
Получите образ, соответствующий вашему оборудованию. Образы тесно следят за upstream (ночные сборки) и покрывают CUDA, Vulkan, Intel, MUSA и CPU — выберите тот, который соответствует тому, как вы действительно ускоряете работу, а не «latest» по привычке.
# Примеры получения платформ
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 на уровне модели, когда одна модель должна lingering, а другая должна исчезнуть быстро.
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
# Необязательно, но рекомендуется для всего, что выходит за рамки локальной разработки
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 с backoff."}]
}'
Если вы теперь повторите вызов с "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 возвращает состояние выполнения для загруженных моделей, включая значения состояния, такие как 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 устанавливает поток событий Server-Sent Events и предназначен для обновлений в реальном времени, которые включают изменения статуса модели, логи, метрики и количество запросов в полете.
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, x-api-key). Он также удаляет заголовки аутентификации перед пересылкой upstream.
Я получаю 429 Too Many Requests
concurrencyLimit возвращает 429 при превышении — по дизайну. Увеличьте лимит, если вы недооценили его, или уменьшите, если не планировали ограничивать.
Конфликты портов или странные проблемы маршрутизации
Избегайте жестко закодированных портов в cmd; используйте ${PORT} и измените startPort, если 5800+ конфликтует с чем-то еще. Помните, что порты назначаются в алфавитном порядке по ID модели — переименуйте модель, и маппинг портов сдвинется.
Чек-лист операционной отладки
/running для истины, /logs/stream, когда запуск неясен, POST /api/models/unload, когда VRAM нужна сейчас. Эта тройка покрывает большинство сессий «почему GPU полон».