llama.swap Modellumschalter: Schnelleinstieg für OpenAI-kompatible lokale LLMs
Lokale LLMs per Hot-Swap austauschen, ohne die Clients anzupassen.
Bald jonglierst du mit vLLM, llama.cpp und weiteren – jeder Stack auf seinem eigenen Port. Alles, was downstream liegt, erwartet weiterhin eine einzige /v1-Basis-URL; andernfalls musst du ständig Ports, Profile und Einmalskripte umstellen. llama-swap ist die /v1-Proxy-Schicht vor diesen Stacks.
llama-swap bietet eine einzige, OpenAI- und Anthropic-kompatible Fronttür, wobei eine YAML-Datei jedem model-Namen den Befehl zuordnet, der den richtigen Upstream startet. Fordere ein Modell an, und der Proxy startet es oder wechselt darauf. Konfiguriere TTLs und Gruppen, wenn VRAM knapp ist oder mehrere Modelle koexistieren müssen. Dieser Leitfaden behandelt Installationspfade, eine praktische config.yaml, die HTTP-Oberfläche und die Fehlermodi, die auftreten, wenn Streaming und Reverse Proxies ins Spiel kommen.
Für einen breiteren Vergleich von LLM-Hosting-Optionen, siehe LLM-Hosting in 2026: Lokal, Self-Hosted & Cloud-Infrastruktur im Vergleich
Überblick über den llama-swap-Modell-Umschalter für OpenAI-kompatible lokale LLM-APIs
llama-swap ist ein leichter Proxy-Server, der um ein einfaches Betriebsmodell herum aufgebaut ist: ein Binary, eine YAML-Konfigurationsdatei, keine Abhängigkeiten. Es ist in Go geschrieben, was ein einzelnes statisches Binary neben dem restlichen Stack bedeutet – ohne Python-Runtime oder Desktop-App. Es sitzt vor jedem OpenAI- und Anthropic-kompatiblen Upstream als die Modell-Umschalt-Schicht.
Konzeptionell beantwortet dies eine sehr praktische Frage, die in lokalen LLM-Stacks auftritt:
Wie wechsle ich Modelle mit einem OpenAI-kompatiblen Client?
Mit llama-swap verwendest du weiterhin normale /v1/...-Anfragen, änderst aber das model, das du anforderst. llama-swap liest diesen model-Wert, lädt die passende Serverkonfiguration und, wenn der „falsche“ Upstream läuft, tauscht er ihn gegen den richtigen aus.
Einige Design-Details sind für produktionsnahe Setups wichtig:
llama-swap ist MIT-lizenziert, ohne Telemetrie – es lohnt sich dennoch, dies für jeden Host zu überprüfen, der echte Prompts sieht.
Er ist für das bedarfsgesteuertes Laden von Backends wie llama.cpp, vLLM, Whisper und stable-diffusion.cpp entwickelt, um dich nicht an einen einzelnen Inferenz-Engine zu binden.
Standardmäßig (ohne spezielle Gruppierung) führt er ein Modell gleichzeitig aus: Fordere ein anderes model an, und er stoppt den aktuellen Upstream und startet den richtigen. Für mehr als ein residentes Modell oder feinere Kontrolle über die Koexistenz, konfiguriere groups.
Hier ist das mentale Modell, das die meisten Entwickler nützlich finden:
Deshalb ist ein Modell-Umschalter-Proxy etwas anderes als „nur ein Modell auszuführen": Es ist Orchestrierung und Routing auf der Grundlage von einem oder mehreren Inferenz-Servern.
llama-swap vs Ollama vs LM Studio vs llama.cpp Server
Alle vier Optionen können dir eine „lokale LLM-API" bieten, optimieren aber für unterschiedliche Workflows. Der schnellste Weg, eine Auswahl zu treffen, ist zu entscheiden, ob du eine Laufzeitumgebung (Modell-Download + Ausführung) oder einen Router/Proxy (Umschaltung + Orchestrierung über Laufzeitumgebungen hinweg) möchtest.
llama-swap
llama-swap konzentriert sich darauf, ein transparenter Proxy zu sein, der OpenAI-kompatible Endpunkte unterstützt (einschließlich /v1/chat/completions, /v1/completions, /v1/embeddings und /v1/models) und Anfragen basierend auf dem angeforderten Modell an den korrekten Upstream weiterleitet. Er bietet auch nicht-inferenzbezogene operative Endpunkte wie /running, /logs/stream und eine Web-UI unter /ui.
Ollama
Ollama stellt seine eigene HTTP-API bereit (POST /api/chat, POST /api/generate und die übliche lokale Standardinstanz auf Port 11434).
keep_alive steuert, wie lange ein Modell geladen bleibt, einschließlich 0 für sofortiges Entladen.
Es eignet sich für Benutzer, die ein Modell holen und chatten möchten, mit minimalem Aufwand. llama-swap eignet sich für modellspezifische Befehle, gemischte Backends und eine einzige OpenAI-artige URL für jeden Client – die Orchestrierung von vLLM neben llama-server mit unterschiedlichen Flags pro Modell liegt außerhalb dessen, was Ollama anstrebt.
LM Studio
LM Studio ist eine Desktop-App mit einem lokalen API-Server aus dem Entwickler-Tab (localhost oder LAN), einschließlich OpenAI-kompatibler und Anthropic-kompatibler Modi sowie lms server start aus dem Terminal.
Es eignet sich für einen GUI-first-Workflow: Modelle durchsuchen, anklicken, testen. llama-swap eignet sich für eine serverartige Rolle: YAML, Prozessüberwachung, gemischte Upstreams, keine Desktop-Sitzung.
llama.cpp Server
llama-server stellt /v1/completions, /v1/chat/completions, /v1/responses bereit, und das übliche Muster besteht darin, einen OpenAI-Client per base_url darauf zu zeigen. Die Installation dieses Servers und die Flags, die er tatsächlich unterstützt, werden im llama.cpp-Quickstart behandelt.
llama.cpp bietet auch einen Router-Modus an: Führe llama-server als Router aus, --models-dir, dann POST /models/load und POST /models/unload, um GGUF-Modelle ohne separaten Proxy zu jonglieren. Für einen vollständigen Einrichtungsguide siehe llama-server-Router-Modus: Dynamisches Modell-Umschalten ohne Neustarts.
Wenn jedes Modell unter einem llama.cpp-Router liegt, ist ein zusätzlicher Proxy oft unnötig. Wenn llama.cpp neben vLLM oder anderen OpenAI-artigen Servern laufen muss, bietet llama-swap eine /v1-Oberfläche und viele Prozesse dahinter.
Für ähnliche OpenAI-kompatible Hosting-Lösungen, siehe LocalAI QuickStart: OpenAI-kompatible LLMs lokal ausführen oder SGLang QuickStart: Installieren, Konfigurieren und Bereitstellen von LLMs über die OpenAI-API
llama-swap Modell-Umschalter mit Docker, Homebrew, WinGet oder Binaries installieren
Linux, macOS und Windows sind alle erste Klasse: Docker, Homebrew, WinGet, GitHub-Binaries oder aus Quellen bauen. Gängige Auswahlmöglichkeiten: Docker auf Headless-Servern, Homebrew oder WinGet auf Arbeitsplätzen, eigenständige Binaries, wenn der Installationsumfang minimal bleiben soll.
Docker-Installation
Ziehe ein Image, das zu deiner Hardware passt. Images tracken Upstreams eng (Nightly-Builds) und decken CUDA, Vulkan, Intel, MUSA und CPU ab – wähle das, das zu deiner tatsächlichen Beschleunigung passt, nicht aus Gewohnheit „latest".
# Beispiel-Plattform-Pulls
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
Bevorzuge die Non-Root-Image-Varianten, wenn möglich: Weniger zu bereuen, falls die Container-Grenze jemals falsch ist.
Homebrew-Installation
Auf macOS und Linux, nutze den Tap und installiere:
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
WinGet-Installation
Auf Windows:
winget install llama-swap
winget upgrade llama-swap
Vorgefertigte Binaries und Releases
GitHub Releases bietet Linux-, macOS-, Windows- und FreeBSD-Binaries an, falls du keinen Paketmanager möchtest.
Releases-Nummern bewegen sich schnell (zum Beispiel v198, v197 um Anfang 2026) – fixe eine Version in Automatisierungen, anstatt „was gestern da war" zu verwenden.
llama-swap mit config.yaml für Modell-Umschalten, TTL und Gruppen konfigurieren
Alles in llama-swap ist konfigurierungsgesteuert. Die minimal mögliche Konfiguration ist einfach ein models:-Dictionary und ein cmd für jedes Modell, das oft llama-server mit pro Modell ersetztem ${PORT} startet.
Das Konfigurationsystem geht viel weiter als nur „einen Prozess starten", und einige Optionen sind früh zu verstehen, weil sie gängige FAQ-artige Probleme direkt beantworten (automatisches Entladen, Sicherheit und Clients, die auf /v1/models angewiesen sind).
Globale Einstellungen, die du tatsächlich verwenden wirst
healthCheckTimeout ist die Zeit, die llama-swap wartet, bis ein Modell nach dem Start gesund ist (Standard 120s, Minimum 15s). Für mehr-GB-Ladevorgänge auf langsamen Festplatten, erhöhe dies, bevor du den Proxy beschuldigst.
globalTTL sind die Leerlauf-Sekunden vor dem automatischen Entladen; Standard 0 bedeutet „nie entladen", es sei denn, du setzt es – wähle TTLs explizit für alles, was über ein Spielzeug-Setup hinausgeht, damit VRAM nicht mit vergessenen Modellen voll wird.
startPort seedet das ${PORT}-Makro (Standard 5800); Zuweisung ist deterministisch nach alphabetischer Modell-ID, was eine Funktion ist, wenn du „wer hat welchen Port geholt" debuggst, und eine Falle, wenn du Modelle unachtsam umbenennst.
includeAliasesInList bestimmt, ob Aliase als separate Zeilen in /v1/models erscheinen; schalte es ein, wenn deine UI nur aufgeführte Modelle bietet.
apiKeys schließt alles, das außerhalb von localhost erreichbar ist, aus: Basic, Bearer oder x-api-key. llama-swap entfernt diese Header vor der Weiterleitung, damit Upstream-Logs weniger wahrscheinlich Client-Geheimnisse beibehalten.
Modellspezifische Einstellungen, die Produktivitäts-Ergonomie freischalten
Pro Modell ist cmd das einzige erforderliche Feld.
proxy Standard ist http://localhost:${PORT} – das ist das Weiterleitungsziel für den Upstream dieses Modells.
checkEndpoint Standard ist /health; setze "none", wenn das Backend keine Health-Route hat oder der kalte Start länger dauert, als du warten möchtest – lasse keinen kaputten /health und wundert dich nicht, warum nichts ready erreicht.
ttl: -1 erbt globalTTL, 0 entlädt nie, N > 0 entlädt nach N Sekunden Leerlauf – verwende modellspezifische TTLs, wenn ein Modell länger verweilen soll und ein anderes schnell verschwinden soll.
aliases und useModelName halten stabile client-seitige Namen, während sie Upstreams zufriedenstellen, die einen bestimmten Bezeichner erfordern.
cmdStop ist für Container nicht optional: mappe es auf docker stop (oder äquivalent); ohne es bekommst du POSIX SIGTERM / Windows taskkill gegen die PID, die llama-swap gestartet hat – gut für ein rohes Binary, falsch für einen Containernamen.
concurrencyLimit begrenzt parallele Anfragen pro Modell mit HTTP 429, wenn überschritten – setze es, wenn du Last lieber abschmeißen möchtest, als ewig zu warten.
groups decken Koexistenz (swap, exclusive) und Immer-An-Modelle (persistent) ab. Hooks können beim Start vorladen; wenn du mehrere Modelle gleichzeitig ohne Gruppe vorlädst, erwarte, dass sie kämpfen – definiere zuerst eine Gruppe, damit das Vorladen darauf passt, wie du möchtest, dass Modelle die GPU teilen.
Minimales config.yaml-Beispiel für llama.cpp und vLLM
Dieses Beispiel zielt darauf ab, „genug" zu sein, um Best-Practice-Knöpfe zu illustrieren: eine Standard-TTL, explizite Health-Checks, stabile Aliase und eine Gruppe, die ein kleines „Immer-An"-Modell laufen lässt, während größere Chat-Modelle umgeschaltet werden.
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 Minuten Leerlauf dann entladen
includeAliasesInList: true
startPort: 5800
# Optional, aber für alles empfohlen, was über localhost-Entwicklung hinausgeht
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"
# Verwendet Standards:
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (erbt globalTTL)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# Illustratives Muster: Verwaltet einen kontextbasierten OpenAI-kompatiblen Server
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 # nie automatisch entladen (z.B. auf GPU halten)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
Nichts davon ist dekorativ: cmd steuert den Prozess, proxy/checkEndpoint/ttl steuern Routing und Lebenszyklus, cmdStop ist das, was Docker-basierte Upstreams tatsächlich stoppen lässt, und groups sind das, was „ein großes Modell zur Zeit" von „diese beiden Chat-Modelle dürfen koexistieren, während der Embedding-Server fixiert bleibt" trennt.
Modelle über OpenAI-kompatible Endpunkte ausführen und umschalten
Sobald llama-swap läuft, interagierst du mit ihm wie mit jedem anderen OpenAI-kompatiblen Endpunkt. Die API-Oberfläche umfasst Kern-Endpunkte wie /v1/chat/completions, /v1/completions, /v1/embeddings und /v1/models, und llama-swap verwendet das angeforderte model, um zu entscheiden, welchen Upstream es ausführen und routen soll.
Ein praktischer Quickstart-Flow:
# 1) Starte llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Entdecke verfügbare Modelle
curl http://localhost:8080/v1/models
Das Modell-Listen ist eine erstklassige Verwaltungs-Funktion und enthält Verhaltensweisen wie Sortierung nach ID, Ausschluss von unlisted-Modellen und optionales Einbeziehen von Aliasen.
# 3) Stelle eine Chat-Completion-Anfrage für ein bestimmtes Modell
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."}]
}'
Wenn du den Aufruf nun mit "model": "llama-chat" wiederholst, wird llama-swap die Upstream-Prozesse umschalten (außer deine Gruppierungskonfiguration erlaubt ihnen zu koexistieren), da er das angeforderte Modell aus der Anfrage extrahiert und die entsprechende Serverkonfiguration lädt.
Wenn du ein SDK verwendest, zeige den Client auf http://localhost:8080/v1 – derselbe Trick wie das Zieln der OpenAI Python-Bibliothek auf llama-server, außer die stabile URL ist jetzt llama-swap und das model-Feld wählt den 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": "Explain the difference between mutexes and semaphores."}],
)
print(resp.choices[0].message.content)
Um ein Modell vor der ersten echten Anfrage aufzuwärmen (kalte Start-Latenz zu verbergen), verwende /upstream/<model> – es lädt bei Bedarf automatisch weiter und leitet direkt an diesen Upstream weiter. Eine geradlinige Methode, sicherzustellen, dass Gewichte resident sind, bevor ein Benchmark oder ein skriptgesteuerter Test stattfindet.
llama-swap über Verwaltungs-API-Endpunkte und SSE-Ereignisse steuern und überwachen
llama-swap ist nicht nur „ein Proxy"; er stellt auch operative Steuerungs-Endpunkte bereit, die es dir ermöglichen, Tools um den Modell-Lebenszyklus und Observability herum zu bauen.
Prüfe, was läuft
GET /running gibt den Laufzeitstatus für geladene Modelle zurück, einschließlich Statuswerte wie ready, starting, stopping, stopped und shutdown.
curl http://localhost:8080/running
Modelle entladen, um VRAM zu freigeben
Um alles sofort zu entladen, verwende den API-versionierten Endpunkt POST /api/models/unload. Um ein einzelnes Modell (nach ID oder Alias) zu entladen, verwende POST /api/models/unload/<model>. Ein Legacy-GET /unload existiert für Rückwärtskompatibilität.
# alles entladen
curl -X POST http://localhost:8080/api/models/unload
# ein Modell entladen
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
Verwende diese Endpunkte, wenn VRAM jetzt benötigt wird, anstatt auf TTL zu warten – Benchmarks, schnelle Modell-Umschaltungen oder nach dem Laden eines viel größeren Checkpoints als beabsichtigt.
Live-Ereignisse per SSE streamen
GET /api/events richtet einen Server-Sent Events-Stream ein und ist für Echtzeit-Updates konzipiert, die Modellstatusänderungen, Logs, Metriken und Anzahl der laufenden Anfragen enthalten.
curl -N http://localhost:8080/api/events
SSE und Token-Streaming brechen, wenn ein Zwischenkasten puffert – deaktiviere das Puffern in nginx (oder deinem Äquivalent) für /api/events und /v1/chat/completions. llama-swap setzt X-Accel-Buffering: no für SSE; deaktiviere das Puffern auch im Proxy – Header sind kein Ersatz für eine korrekte Proxy-Konfiguration.
Metriken und Anfrage-Aufnahmen
GET /api/metrics gibt Token-Nutzungs-Metriken zurück, mit In-Memory-Retention, die durch metricsMaxInMemory gesteuert wird (Standard 1000).
GET /api/captures/<id> kann vollständige Anfrage/Antwort-Aufnahmen abrufen, aber nur, wenn captureBuffer > 0 konfiguriert ist.
Logs und die Web-UI
llama-swap stellt /ui für eine Web-Oberfläche bereit und operative Log-Endpunkte wie /logs und /logs/stream für Echtzeit-Monitoring.

Wenn du apiKeys aktivierst, geh von Verteidigung in der Tiefe aus: /health und Teile von /ui bleiben ohne Schlüssel erreichbar – gut für lokale Vertrauensgrenzen, nicht gut, wenn der Host in einem gemeinsamen Netzwerk ist. Stelle llama-swap hinter etwas, das deine echte Politik durchsetzt; die eingebaute Authentifizierung ist dafür, zufällige Clients ehrlich zu halten, nicht für eine öffentliche Multi-Tenant-API.
Fehlersuche bei llama-swap-Modell-Umschaltung in der Produktion
Die meisten llama-swap-Problem fallen in eine kleine Reihe operativer Kategorien: Streaming durch einen Reverse Proxy, Health-Checks während kalter Starts, Ports und Prozess-Lebenszyklus sowie Authentifizierung.
Streaming bricht hinter nginx oder einem anderen Reverse Proxy
nginx puffert gerne dein SSE und gestreamte Completions weg. Deaktiviere proxy_buffering (und proxy_cache) für /api/events und /v1/chat/completions. llama-swap emittiert X-Accel-Buffering: no für SSE, was hilft – repariere den Proxy trotzdem.
Ein Modell wird nie bereit
Standardmäßig ist der modellspezifische checkEndpoint /health und muss HTTP 200 zurückgeben, damit der Prozess als bereit angesehen wird. Du kannst checkEndpoint auf einen anderen Pfad oder auf "none" setzen, um Health-Checks vollständig zu deaktivieren.
Wenn große Modelle länger zum Laden brauchen, erhöhe healthCheckTimeout (Standard 120s) oder verwende maßgeschneiderte Health-Checks für deinen spezifischen Upstream.
Modell-Umschalten lässt einen alten Container laufen
Wenn der Upstream Docker oder Podman ist, setze cmdStop – andernfalls stoppt llama-swap den Wrapper-Prozess, während der Container im Hintergrund weiter VRAM konsumiert.
Ich erhalte 401-Antworten nach der Aktivierung der Sicherheit
Wenn apiKeys konfiguriert ist, verlangt llama-swap einen gültigen Schlüssel und akzeptiert drei Methoden (Basic-Auth, Bearer-Token, x-api-key). Es entfernt auch Authentifizierungs-Header vor der Weiterleitung an den Upstream.
Ich erhalte 429 Too Many Requests
concurrencyLimit gibt 429 zurück, wenn überschritten – per Design. Erhöhe die Grenze, wenn du sie zu niedrig angesetzt hast, oder senke die Grenze, wenn du nicht drosseln wolltest.
Port-Konflikte oder seltsame Routing-Problem
Vermeide hartkodierte Ports in cmd; verwende ${PORT} und verschiebe startPort, wenn 5800+ mit etwas anderem kollidiert. Denke daran, dass Ports in alphabetischer Reihenfolge nach Modell-ID zugewiesen werden – benenne ein Modell um, und die Port-Zuordnung verschiebt sich.
Operative Debugging-Checkliste
/running für die Wahrheit, /logs/stream, wenn Start undurchsichtig ist, POST /api/models/unload, wenn VRAM jetzt benötigt wird. Dieses Trio deckt die meisten „warum ist die GPU voll"-Situationen ab.