Prise en main rapide du sélecteur de modèles llama.swap pour les LLM locaux compatibles avec OpenAI
Remplacement à chaud des LLM locaux sans modifier les clients.
Bientôt, vous jonglerez avec vLLM, llama.cpp et bien plus encore — chaque pile fonctionnant sur son propre port. Tout le reste de votre infrastructure souhaite toujours une URL de base unique /v1 ; sinon, vous finissez par réorganiser constamment les ports, les profils et les scripts ponctuels. llama-swap est le proxy /v1 qui précède ces piles.
llama-swap offre une porte d’entrée unique compatible OpenAI et Anthropic, avec un fichier YAML qui associe chaque nom de model à la commande qui lance l’amont approprié. Demandez un modèle et le proxy le démarre ou commute vers celui-ci ; configurez les TTL et les groupes lorsque la VRAM est limitée ou que plusieurs modèles doivent coexister. Ce guide couvre les chemins d’installation, une config.yaml pratique, la surface HTTP et les modes de défaillance qui apparaissent une fois que le streaming et les proxies inverses entrent en jeu.
Pour une comparaison plus large des options d’hébergement de LLM, consultez LLM Hosting in 2026: Local, Self-Hosted & Cloud Infrastructure Compared
Vue d’ensemble du sélecteur de modèles llama-swap pour les API LLM locales compatibles OpenAI
llama-swap est un serveur proxy léger construit autour d’un modèle opérationnel simple : un binaire, un fichier de configuration YAML, aucune dépendance. Il est écrit en Go, ce qui signifie un binaire statique unique à côté du reste de la pile — pas besoin de runtime Python ni d’application de bureau. Il se place devant n’importe quel amont compatible OpenAI et Anthropic en tant que couche de commutation de modèles.
Conceptuellement, cela répond à une question très pratique qui surgit dans les piles LLM locales :
Comment changer de modèle avec un client compatible OpenAI ?
Avec llama-swap, vous continuez à utiliser les requêtes normales /v1/..., mais vous changez le model que vous demandez. llama-swap lit cette valeur model, charge la configuration du serveur correspondante, et si le mauvais amont est en cours d’exécution, il le remplace par le bon.
Quelques détails de conception importent pour les configurations proches de la production :
llama-swap est sous licence MIT avec aucune télémétrie — cela vaut toujours la peine de le confirmer pour tout hôte qui voit de vraies prompts.
Il est conçu pour le chargement à la demande de backends comme llama.cpp, vLLM, Whisper et stable-diffusion.cpp, et non pour vous enfermer dans un moteur d’inférence unique.
Par défaut (sans regroupement spécial), il exécute un modèle à la fois : demandez un model différent et il arrête l’amont actuel pour démarrer le bon. Pour plus d’un modèle résident ou un contrôle plus fin de la coexistence, configurez des groups.
Voici le modèle mental que la plupart des développeurs trouvent utile :
flowchart LR
C[Votre app ou SDK\nClient compatible OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[Proxy llama-swap\npoint d'entrée unique]
LS -->|démarre ou route vers| U1[Serveur amont A\nllama-server]
LS -->|démarre ou route vers| U2[Serveur amont B\nserveur OpenAI vLLM]
LS --> M[Points d'extrémité de gestion\nrunning, unload, events, metrics]
C’est aussi pourquoi un proxy de commutation de modèle est différent de « lancer simplement un modèle » : c’est une orchestration et un routage au-dessus d’un ou plusieurs serveurs d’inférence.
llama-swap vs Ollama vs LM Studio vs serveur llama.cpp
Les quatre options peuvent vous offrir une « API LLM locale », mais elles optimisent des flux de travail différents. Le moyen le plus rapide de choisir est de décider si vous voulez un runtime (téléchargement de modèle + exécution) ou un routeur/proxy (commutation + orchestration entre les runtimes).
llama-swap
llama-swap se concentre sur le rôle de proxy transparent qui prend en charge les points d’extrémité compatibles OpenAI (y compris /v1/chat/completions, /v1/completions, /v1/embeddings et /v1/models) et route les requêtes vers l’amont correct en fonction du modèle demandé. Il fournit également des points d’extrémité opérationnels non liés à l’inférence tels que /running, /logs/stream et une interface Web à /ui.
Ollama
Ollama expose sa propre API HTTP (POST /api/chat, POST /api/generate, et le port local par défaut 11434).
keep_alive contrôle la durée pendant laquelle un modèle reste chargé, y compris 0 pour un déchargement immédiat.
Il convient aux utilisateurs qui veulent télécharger un modèle et discuter avec un câblage minimal. llama-swap convient aux commandes par modèle, aux backends mixtes et à une URL unique en forme OpenAI pour chaque client — orchestrer vLLM à côté de llama-server avec des drapeaux différents par modèle sort du cadre visé par Ollama.
LM Studio
LM Studio est une application de bureau avec un serveur API local depuis l’onglet Developer (localhost ou LAN), y compris les modes compatibles OpenAI et compatibles Anthropic, plus lms server start depuis le terminal.
Il convient à une boucle d’abord GUI : parcourir les modèles, cliquer, tester. llama-swap convient à un rôle de style serveur : YAML, supervision de processus, amonts mixtes, pas de session de bureau.
serveur llama.cpp
llama-server expose /v1/completions, /v1/chat/completions, /v1/responses, et le schéma habituel consiste à pointer un client OpenAI vers lui via base_url.
llama.cpp fournit également un mode routeur : exécutez llama-server en tant que routeur, --models-dir, puis POST /models/load et POST /models/unload pour jongler avec les modèles GGUF sans proxy séparé.
Si chaque modèle se trouve sous un seul routeur llama.cpp, un proxy supplémentaire est souvent inutile. Lorsque llama.cpp doit s’asseoir à côté de vLLM ou d’autres serveurs en forme OpenAI, llama-swap fournit une surface unique /v1 et plusieurs processus derrière elle.
Pour des solutions d’hébergement compatibles OpenAI similaires, consultez LocalAI QuickStart: Run OpenAI-Compatible LLMs Locally or SGLang QuickStart: Install, Configure, and Serve LLMs via OpenAI API
Installer le sélecteur de modèles llama-swap avec Docker, Homebrew, WinGet ou des binaires
Linux, macOS et Windows sont tous de première classe : Docker, Homebrew, WinGet, binaires GitHub ou compilation depuis le source. Choix courants : Docker sur les serveurs headless, Homebrew ou WinGet sur les postes de travail, binaires autonomes lorsque l’empreinte d’installation doit rester minimale.
Installation Docker
Téléchargez une image qui correspond à votre matériel. Les images suivent de près les amonts (builds nocturnes) et couvrent CUDA, Vulkan, Intel, MUSA et CPU — choisissez celle qui correspond à la façon dont vous accélérez réellement, pas « latest » par habitude.
# Exemples de téléchargements de plateforme
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
Privilégiez les variantes d’images non-root quand vous le pouvez : moins de regrets si la frontière du conteneur est jamais incorrecte.
Installation Homebrew
Sur macOS et Linux, utilisez le tap et installez :
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
Installation WinGet
Sur Windows :
winget install llama-swap
winget upgrade llama-swap
Binaires pré-construits et versions
GitHub Releases fournit des binaires Linux, macOS, Windows et FreeBSD si vous ne voulez pas de gestionnaire de paquets.
Les numéros de version évoluent rapidement (par exemple v198, v197 vers le début 2026) — verrouillez une version dans l’automatisation plutôt que de flotter « ce qui était là hier ».
Configurer llama-swap avec config.yaml pour la commutation de modèles, TTL et groupes
Tout dans llama-swap est piloté par la configuration. La configuration viable minimale est simplement un dictionnaire models: et une cmd pour chaque modèle, lançant souvent llama-server avec ${PORT} substitué par modèle.
Le système de configuration va beaucoup plus loin que « démarrer un processus », et quelques options méritent d’être comprises tôt car elles répondent directement à des problèmes courants de style FAQ (déchargement automatique, sécurité et clients qui s’appuient sur /v1/models).
Paramètres globaux que vous utiliserez réellement
healthCheckTimeout est la durée pendant laquelle llama-swap attend qu’un modèle devienne sain après le démarrage (par défaut 120s, minimum 15s). Pour des chargements multi-Go sur des disques lents, augmentez ceci avant de blâmer le proxy.
globalTTL est les secondes d’inactivité avant le déchargement automatique ; par défaut 0 signifie « ne jamais décharger » à moins que vous ne le définissiez — choisissez explicitement des TTL pour tout au-delà d’une configuration de jouet afin que la VRAM ne se remplisse pas de modèles oubliés.
startPort ensemence la macro ${PORT} (par défaut 5800) ; l’assignation est déterministe par ID de modèle alphabétique, ce qui est une fonctionnalité quand vous déboguez « qui a pris quel port » et un piège si vous renommez les modèles négligemment.
includeAliasesInList décide si les alias apparaissent comme des lignes séparées dans /v1/models ; activez-le si votre UI n’offre que des modèles énumérés.
apiKeys verrouille tout ce qui est accessible hors localhost : Basic, Bearer ou x-api-key. llama-swap supprime ces en-têtes avant de transférer afin que les logs amont soient moins susceptibles de conserver des secrets de client.
Paramètres au niveau du modèle qui débloquent l’ergonomie de production
Par modèle, cmd est le seul champ requis.
proxy est par défaut http://localhost:${PORT} — c’est la cible de transfert pour l’amont de ce modèle.
checkEndpoint est par défaut /health ; définissez "none" lorsque le backend n’a pas de route de santé ou que le démarrage à froid dépasse ce que vous êtes prêt à attendre — ne laissez pas un /health cassé et vous demandez pourquoi rien n’atteint ready.
ttl : -1 hérite globalTTL, 0 ne décharge jamais, N > 0 décharge après N secondes d’inactivité — utilisez des TTL par modèle lorsqu’un modèle doit persister et un autre disparaître rapidement.
aliases et useModelName maintiennent des noms stables visibles par le client tout en satisfaisant les amonts qui nécessitent un identifiant spécifique.
cmdStop est non optionnel pour les conteneurs : mappez-le sur docker stop (ou équivalent) ; sans cela, vous obtenez un SIGTERM POSIX / taskkill Windows contre n’importe quel PID que llama-swap a démarré — acceptable pour un binaire nu, incorrect pour un nom de conteneur.
concurrencyLimit limite les requêtes parallèles par modèle avec HTTP 429 lorsqu’elles sont dépassées — définissez-le lorsque vous préféreriez rejeter la charge plutôt que de mettre en file d’attente indéfiniment.
groups couvrent la coexistence (swap, exclusive) et les modèles toujours actifs (persistent). Les hooks peuvent précharger au démarrage ; si vous préchargez plusieurs modèles à la fois sans un groupe, attendez-vous à ce qu’ils se battent — définissez un groupe en premier afin que le préchargement corresponde à la façon dont vous voulez que les modèles partagent le GPU.
Exemple minimal de config.yaml pour llama.cpp et vLLM
Cet exemple vise à être « juste assez » pour illustrer les molettes de bonnes pratiques : un TTL par défaut, une vérification de santé explicite, des alias stables et un groupe qui garde un petit modèle « toujours actif » en cours d’exécution pendant que les grands modèles de chat commutent.
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 minutes d'inactivité puis déchargement
includeAliasesInList: true
startPort: 5800
# Optionnel mais recommandé pour tout au-delà du développement 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"
# Utilise les valeurs par défaut :
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (hériter globalTTL)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# Schéma illustratif : gérer un serveur compatible OpenAI conteneurisé
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 # jamais de déchargement automatique (ex. garder sur GPU)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
Rien de tout cela n’est décoratif : cmd pilote le processus, proxy/checkEndpoint/ttl contrôlent le routage et le cycle de vie, cmdStop est ce qui fait que les amonts basés sur Docker s’arrêtent réellement, et groups est ce qui sépare « un gros modèle à la fois » de « ces deux modèles de chat peuvent coexister pendant que le serveur d’embedding reste verrouillé ».
Exécuter et commuter les modèles via des points d’extrémité compatibles OpenAI
Une fois que llama-swap est en cours d’exécution, vous interagissez avec lui comme avec n’importe quel autre point d’extrémité compatible OpenAI. La surface de l’API inclut des points d’extrémité principaux tels que /v1/chat/completions, /v1/completions, /v1/embeddings et /v1/models, et llama-swap utilise le model demandé pour décider quel amont exécuter et router.
Un flux de démarrage rapide pratique :
# 1) Démarrer llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Découvrir les modèles disponibles
curl http://localhost:8080/v1/models
La liste des modèles est une fonctionnalité de gestion de premier ordre et inclut des comportements comme le tri par ID, l’exclusion des modèles unlisted et l’inclusion optionnelle des alias.
# 3) Faire une requête de complétion de chat pour un modèle spécifique
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":"Write a TypeScript function that retries fetch with backoff."}]
}'
Si vous répétez maintenant l’appel avec "model": "llama-chat", llama-swap commutera les processus amont (sauf si votre configuration de groupe leur permet de coexister) car il extrait le modèle demandé de la requête et charge la configuration du serveur appropriée.
Si vous utilisez un SDK, pointez le client vers http://localhost:8080/v1 — même astuce que viser la bibliothèque Python OpenAI vers llama-server, sauf que l’URL stable est maintenant llama-swap et le champ model choisit l’amont.
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": "Explain the difference between mutexes and semaphores."}],
)
print(resp.choices[0].message.content)
Pour réchauffer un modèle avant la première vraie requête (masquer la latence de démarrage à froid), utilisez /upstream/<model> — il se charge automatiquement si nécessaire et transfère directement vers cet amont. Façon simple de s’assurer que les poids sont résidents avant un benchmark ou un test scripté.
Contrôler et surveiller llama-swap via les points d’extrémité de l’API de gestion et les événements SSE
llama-swap n’est pas juste « un proxy » ; il expose également des points d’extrémité de contrôle opérationnel qui vous permettent de créer des outils autour du cycle de vie des modèles et de l’observabilité.
Vérifier ce qui est en cours d’exécution
GET /running retourne l’état d’exécution pour les modèles chargés, y compris des valeurs d’état comme ready, starting, stopping, stopped et shutdown.
curl http://localhost:8080/running
Décharger les modèles pour libérer la VRAM
Pour tout décharger immédiatement, utilisez le point d’extrémité versionné API POST /api/models/unload. Pour décharger un seul modèle (par ID ou alias), utilisez POST /api/models/unload/<model>. Un GET /unload legacy existe pour la compatibilité ascendante.
# décharger tout
curl -X POST http://localhost:8080/api/models/unload
# décharger un modèle
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
Utilisez ces points d’extrémité lorsque la VRAM est nécessaire maintenant au lieu d’attendre le TTL — benchmarks, changements rapides de modèle, ou après avoir chargé un checkpoint beaucoup plus grand que prévu.
Streamer les événements en direct via SSE
GET /api/events établit un flux Server-Sent Events et est conçu pour des mises à jour en temps réel qui incluent des changements d’état de modèle, des logs, des métriques et des comptages de requêtes en vol.
curl -N http://localhost:8080/api/events
Le SSE et le streaming de jetons échouent si une boîte intermédiaire tamponne — désactivez le tamponnement sur nginx (ou votre équivalent) pour /api/events et /v1/chat/completions. llama-swap définit X-Accel-Buffering: no sur SSE ; désactivez le tamponnement dans le proxy également — les en-têtes ne sont pas un substitut à une configuration de proxy correcte.
Métriques et captures de requêtes
GET /api/metrics retourne des métriques d’utilisation de jetons, avec une rétention en mémoire contrôlée par metricsMaxInMemory (par défaut 1000).
GET /api/captures/<id> peut récupérer des captures complètes de requête/réponse, mais seulement lorsque captureBuffer > 0 est configuré.
Logs et interface Web
llama-swap expose /ui pour une interface web, et des points d’extrémité de logs opérationnels tels que /logs et /logs/stream pour une surveillance en temps réel.

Si vous activez apiKeys, supposez une défense en profondeur : /health et des morceaux de /ui restent accessibles sans clé — acceptable pour les limites de confiance locales, pas acceptable si l’hôte est sur un réseau partagé. Mettez llama-swap derrière quelque chose qui applique votre politique réelle ; l’authentification intégrée est pour garder les clients occasionnels honnêtes, pas pour une API multi-locataire publique.
Dépannage de la commutation de modèles llama-swap en production
La plupart des problèmes llama-swap tombent dans un petit ensemble de catégories opérationnelles : streaming à travers un proxy inversé, vérifications de santé pendant les démarrages à froid, ports et cycle de vie des processus, et authentification.
Le streaming se brise derrière nginx ou un autre proxy inversé
nginx tamponnera avec plaisir vos SSE et complétions streamées. Désactivez proxy_buffering (et proxy_cache) pour /api/events et /v1/chat/completions. llama-swap émet X-Accel-Buffering: no sur SSE, ce qui aide — réparez le proxy quand même.
Un modèle ne devient jamais prêt
Par défaut, checkEndpoint par modèle est /health et doit retourner HTTP 200 pour que le processus soit considéré comme prêt. Vous pouvez définir checkEndpoint sur un autre chemin ou sur "none" pour désactiver complètement les vérifications de santé.
Si les grands modèles prennent plus de temps à charger, augmentez healthCheckTimeout (par défaut 120s), ou utilisez des vérifications de santé adaptées à votre amont spécifique.
Changer de modèle laisse un ancien conteneur en cours d’exécution
Si l’amont est Docker ou Podman, définissez cmdStop — sinon, llama-swap arrête le processus enveloppe pendant que le conteneur continue de consommer la VRAM en arrière-plan.
Je reçois des réponses 401 après avoir activé la sécurité
Lorsque apiKeys est configuré, llama-swap nécessite une clé valide et accepte trois méthodes (auth Basic, token Bearer, x-api-key). Il supprime également les en-têtes d’authentification avant de transférer vers l’amont.
Je reçois 429 Trop de requêtes
concurrencyLimit retourne 429 lorsqu’il est dépassé — par conception. Augmentez la limite si vous l’avez sous-dimensionnée, ou baissez la limite si vous n’aviez pas l’intention d’étrangler le trafic.
Conflits de ports ou problèmes de routage étranges
Évitez les ports codés en dur dans cmd ; utilisez ${PORT} et déplacez startPort si 5800+ entre en collision avec autre chose. Rappelez-vous que les ports sont assignés dans l’ordre alphabétique par ID de modèle — renommer un modèle et la cartographie des ports change.
Checklist de débogage opérationnel
/running pour la vérité, /logs/stream quand le démarrage est opaque, POST /api/models/unload quand la VRAM est nécessaire maintenant. Ce trio couvre la plupart des sessions « pourquoi le GPU est plein ».