Korte handleiding voor de llama.swap-modelwisselaar voor lokaal openai-compatibele LLM's

Wissel lokale LLM's heet uit zonder de clients te wijzigen.

Inhoud

Binnenkort balanceren vLLM, llama.cpp en meer—elk stack op zijn eigen poort. Alles downstream wil nog steeds één /v1 basis-URL; anders blijf je met poorten, profielen en eenmalige scripts shuffelen. llama-swap is de /v1 proxy voor die stacks.

llama-swap biedt één OpenAI- en Anthropic-compatibele ingang, met een YAML-bestand dat elke model-naam koppelt aan het commando dat de juiste upstream start. Vraag een model aan en de proxy start of schakelt ermee; configureer TTL’s en groepen als VRAM beperkt is of meerdere modellen moeten co-existeren. Deze gids behandelt installatiepaden, een praktisch config.yaml, het HTTP-oppervlak en de failure modes die tevoorschijn komen zodra streaming en reverse proxies de ingang nemen.

llama swap llm infographic Voor een bredere vergelijking van LLM-hostingopties, zie LLM Hosting in 2026: Lokaal, Self-Hosted & Cloud Infrastructuur vergeleken

Overzicht van llama-swap model switcher voor OpenAI-compatibele lokale LLM-API’s

llama-swap is een lichtgewicht proxyserver gebouwd rond een eenvoudig operationeel model: één binaire bestand, één YAML-configuratiebestand, geen afhankelijkheden. Het is geschreven in Go, wat betekent dat er naast de rest van de stack één statisch binaire bestand is—geen Python-runtime of desktop-app vereist. Het zit voor elke OpenAI- en Anthropic-compatibele upstream als de model-switching laag.

Conceptueel beantwoordt dit een zeer praktische vraag die in lokale LLM-stacks opduikt:

Hoe schakel ik modellen met een OpenAI-compatibele client?
Met llama-swap blijf je normale /v1/...-aanvragen gebruiken, maar je verandert het model dat je aanvraagt. llama-swap leest die model-waarde, laadt de overeenkomstige serverconfiguratie op en als de “foute” upstream draait, verwisselt het deze voor de juiste.

Enkele ontwerpdetails zijn belangrijk voor productie-achtige setup’s:

llama-swap is MIT-gelicentieerd met geen telemetrie—het is nog steeds de moeite waard om te bevestigen voor elke host die echte prompts ziet.
Het is gebouwd voor on-demand laden van backends zoals llama.cpp, vLLM, Whisper en stable-diffusion.cpp, niet om je te blokkeren aan één inference-engine.
Standaard (zonder speciale groepering) draait het één model tegelijk: vraag een ander model aan en het stopt de huidige upstream en start de juiste. Voor meer dan één residente model of fijnere controle over co-existentie, configureer groups.

Hier is het mentale model dat de meeste developers nuttig vinden:

flowchart LR
  C[Je app of SDK\nOpenAI-compatibele client] -->|/v1/chat/completions\nmodel = qwen-coder| LS[llama-swap proxy\néén eindpunt]
  LS -->|start of routeert naar| U1[Upstream server A\nllama-server]
  LS -->|start of routeert naar| U2[Upstream server B\nvLLM OpenAI server]
  LS --> M[Beheer-eindpunten\nrunning, unload, events, metrics]

Dit is ook waarom een model switcher proxy anders is dan “gewoon een model draaien”: het is orchestratie en routing bovenop één of meer inference-servers.

llama-swap vs Ollama vs LM Studio vs llama.cpp server

Alle vier opties kunnen je een “lokale LLM-API” geven, maar ze optimaliseren voor verschillende workflows. De snelste manier om te kiezen is te beslissen of je een runtime wilt (model downloaden + uitvoeren) of een router/proxy (schakelen + orchestratie over runtimes).

llama-swap
llama-swap focust op het zijn van een transparante proxy die OpenAI-compatibele eindpunten ondersteunt (inclusief /v1/chat/completions, /v1/completions, /v1/embeddings en /v1/models) en aanvragen routeert naar de juiste upstream op basis van het aangevraagde model. Het biedt ook niet-inference operationele eindpunten zoals /running, /logs/stream en een Web-UI op /ui.

Ollama
Ollama exposeert zijn eigen HTTP-API (POST /api/chat, POST /api/generate en de gebruikelijke lokale standaard op poort 11434).
keep_alive bepaalt hoe lang een model geladen blijft, inclusief 0 om direct te ontladen.
Het past bij gebruikers die een model willen trekken en chatten met minimale bedrading. llama-swap past bij per-model commando’s, gemengde backends en één OpenAI-achtige URL voor elke client—het orkestreren van vLLM naast llama-server met verschillende vlaggen per model valt buiten wat Ollama nastreeft.

LM Studio
LM Studio is een desktop-app met een lokale API-server vanuit het Developer-tabblad (localhost of LAN), inclusief OpenAI-compatibele en Anthropic-compatibele modi, plus lms server start vanuit de terminal.
Het past bij een GUI-first lus: modellen browsen, klikken, testen. llama-swap past bij een server-achtige rol: YAML, procesbeheer, gemengde upstreams, geen desktopsessie.

llama.cpp server
llama-server exposeert /v1/completions, /v1/chat/completions, /v1/responses en het gebruikelijke patroon is om een OpenAI-client daarop te richten via base_url.
llama.cpp heeft ook een router-mode: draai llama-server als router, --models-dir, dan POST /models/load en POST /models/unload om GGUF-modellen te balanceren zonder een aparte proxy. Voor een volledige setupgids zie llama-server router mode: dynamisch wisselen van modellen zonder herstart.
Als elk model onder één llama.cpp-router zit, is een extra proxy vaak onnodig. Wanneer llama.cpp naast vLLM of andere OpenAI-achtige servers moet zitten, biedt llama-swap één /v1-oppervlak en vele processen daarachter.

Voor vergelijkbare OpenAI-compatibele hostingoplossingen, zie LocalAI QuickStart: Draai OpenAI-Compatibele LLM’s Lokaal of SGLang QuickStart: Installeer, Configureer en Serveer LLM’s via OpenAI API

Installeer llama-swap model switcher met Docker, Homebrew, WinGet of binaire bestanden

Linux, macOS en Windows zijn allen eerste klas: Docker, Homebrew, WinGet, GitHub binaire bestanden of build from source. Veelgebruikte keuzes: Docker op headless servers, Homebrew of WinGet op werkstations, standalone binaire bestanden als de installatievoetafdruk minimaal moet blijven.

Docker installatie

Pull een beeld dat bij je hardware past. Beelden volgen upstream nauw (nightly builds) en dekken CUDA, Vulkan, Intel, MUSA en CPU—kies degene die overeenkomt met hoe je echt accelereert, niet “latest” uit gewoonte.

# Voorbeeld platform 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

Voorkeur geven aan de non-root beeldvarianten als je kunt: minder spijt als de containergrens ooit fout is.

Homebrew installatie

Op macOS en Linux, gebruik de tap en installeer:

brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080

WinGet installatie

Op Windows:

winget install llama-swap
winget upgrade llama-swap

Vooraf gecompileerde binaire bestanden en releases

GitHub Releases biedt Linux, macOS, Windows en FreeBSD binaire bestanden als je geen package manager wilt.
Versienummers bewegen snel (bijvoorbeeld v198, v197 rond begin 2026)—pin een versie in automatisering in plaats van te drijven op “wat er gisteren was”.

Configureer llama-swap met config.yaml voor model wisselen, TTL en groepen

Alles in llama-swap is configuratie-gedreven. De minimale levensvatbare configuratie is simpelweg een models: dictionary en een cmd voor elk model, vaak het starten van llama-server met ${PORT} per model vervangen.

Het configuratiesysteem gaat veel verder dan alleen “een proces starten”, en enkele opties zijn vroeg begrijpen waard omdat ze direct antwoord geven op veelgestelde FAQ-stijl problemen (auto-unloaden, beveiliging en clients die afhankelijk zijn van /v1/models).

Globale instellingen die je daadwerkelijk zult gebruiken

healthCheckTimeout is hoe lang llama-swap wacht tot een model gezond wordt na opstart (standaard 120s, minimum 15s). Voor multi-GB laden op trage schijven, verhoog dit voordat je de proxy de schuld geeft.
globalTTL is de idle seconden voordat auto-unload; standaard 0 betekent “nooit unload” tenzij je het instelt—kies expliciet TTL’s voor alles buiten een speelsetup zodat VRAM niet vult met vergeten modellen.
startPort zaait de ${PORT} macro (standaard 5800); toewijzing is deterministisch per alfabetische model-ID, wat een functie is als je debugt “wie welke poort pakte” en een valkuil als je modellen onzorgvuldig hernoemt.
includeAliasesInList beslist of aliases als aparte rijen in /v1/models verschijnen; zet het aan als je UI alleen genummerde modellen aanbiedt.
apiKeys gatest alles bereikbaar vanaf localhost: Basic, Bearer of x-api-key. llama-swap verwijdert die headers voordat het doorstuurt zodat upstream logs minder kans hebben om client geheimen te behouden.

Model-level instellingen die productie ergonomica ontgrendelen

Per model is cmd het enige verplichte veld.
proxy default naar http://localhost:${PORT}—dat is het doel voor dat model’s upstream.
checkEndpoint default naar /health; zet "none" als de backend geen health route heeft of de koude start langer duurt dan je wilt wachten—laat geen gebroken /health en vraag je af waarom niets ready wordt.
ttl: -1 erf globalTTL, 0 laadt nooit uit, N > 0 laadt uit na N seconden idle—gebruik per-model TTL wanneer één model moet blijven en een ander snel moet verdwijnen.
aliases en useModelName houden stabiele client-gerichte namen terwijl ze upstreams bevredigen die een specifieke identifier vereisen.
cmdStop is niet optioneel voor containers: map het naar docker stop (of equivalent); zonder het krijg je POSIX SIGTERM / Windows taskkill tegen wat voor PID dan ook dat llama-swap startte—fijn voor een bare binary, fout voor een container-naam.
concurrencyLimit limiet parallelle aanvragen per model met HTTP 429 bij overschrijding—zet het als je liever load werpt dan eeuwig te queue.

groups dekken co-existentie (swap, exclusive) en altijd-aan modellen (persistent). Hooks kunnen preloaden bij opstart; als je meerdere modellen tegelijk preloadt zonder een groep, verwacht ze om te vechten—definieer eerst een groep zodat preloading overeenkomt met hoe je wilt dat modellen de GPU delen.

Minimale config.yaml voorbeeld voor llama.cpp en vLLM

Dit voorbeeld streeft naar “net genoeg” om beste-praktijk knoppen te illustreren: een standaard TTL, expliciete health checking, stabiele aliases en een groep die een klein “altijd-aan” model draait terwijl grotere chat-modellen wisselen.

# config.yaml
healthCheckTimeout: 180
globalTTL: 900            # 15 minuten idle dan unload
includeAliasesInList: true
startPort: 5800

# Optioneel maar aanbevolen voor alles buiten localhost ontwikkeling
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"
    # Gebruikt defaults:
    # proxy: http://localhost:${PORT}
    # checkEndpoint: /health
    # ttl: -1 (erf globalTTL)

  qwen-coder:
    cmd: |
      llama-server --port ${PORT} --model /models/qwen-coder.gguf
      --ctx-size 8192      
    aliases:
      - "qwen-coder-latest"

  vllm-coder:
    # Illustratief patroon: beheer een containeriseerde OpenAI-compatibele 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                 # nooit auto-unload (bijv. houd op GPU)

groups:
  chat-models:
    swap: true
    exclusive: true
    members: ["llama-chat", "qwen-coder"]

  always-on:
    persistent: true
    swap: false
    exclusive: false
    members: ["vllm-coder"]

Dit is niet decoratief: cmd drijft het proces, proxy/checkEndpoint/ttl controleren routing en levenscyclus, cmdStop is wat Docker-based upstreams daadwerkelijk stopt, en groups scheiden “één groot model tegelijk” van “deze twee chat-modellen mogen co-existeren terwijl de embedding server vastgepind blijft”.

Draai en wissel modellen via OpenAI-compatibele eindpunten

Zodra llama-swap draait, interacteer je ermee als met elk ander OpenAI-compatibel eindpunt. Het API-oppervlak omvat kerneindpunten zoals /v1/chat/completions, /v1/completions, /v1/embeddings en /v1/models, en llama-swap gebruikt het aangevraagde model om te beslissen welke upstream te draaien en waar naartoe te routeren.

Een praktische quickstart flow:

# 1) Start llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Ontdek beschikbare modellen
curl http://localhost:8080/v1/models

Model listing is een eerste klas beheerfunctie en omvat gedrag zoals sorteren op ID, uitsluiten van unlisted modellen en optioneel inclusief aliases.

# 3) Maak een chat completion aanvraag voor een specifiek model
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":"Schrijf een TypeScript functie die fetch met backoff herbeproept."}]
  }'

Als je nu de oproep herhaalt met "model": "llama-chat", zal llama-swap upstream processen wisselen (tenzij je groepsconfiguratie ze toelaat te co-existeren) omdat het het aangevraagde model uit de aanvraag haalt en de passende serverconfiguratie laadt.

Als je een SDK gebruikt, wijs de client op http://localhost:8080/v1—dezelfde truc als de OpenAI Python library op llama-server richten, behalve dat de stabiele URL nu llama-swap is en het model veld de upstream kiest.

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": "Leg het verschil uit tussen mutexes en semafors."}],
)
print(resp.choices[0].message.content)

Om een model te warmen voordat de eerste echte aanvraag (om koude-start latentie te verbergen), gebruik /upstream/<model>—het laadt automatisch als nodig en stuurt direct door naar die upstream. Eenvoudige manier om te zorgen dat gewichten resident zijn voordat een benchmark of gescript test.

Controleer en monitor llama-swap via beheer-API eindpunten en SSE events

llama-swap is niet alleen “een proxy”; het exposeert ook operationele controle-eindpunten die je tooling laten bouwen rond model levenscyclus en observabiliteit.

Controleer wat er draait
GET /running retourneert runtime status voor geladen modellen, inclusief statuswaarden zoals ready, starting, stopping, stopped en shutdown.

curl http://localhost:8080/running

Ontlaad modellen om VRAM vrij te maken
Om alles direct te ontladen, gebruik het API-versie-eindpunt POST /api/models/unload. Om één model (op ID of alias) te ontladen, gebruik POST /api/models/unload/<model>. Een legacy GET /unload bestaat voor achterwaartse compatibiliteit.

# laad alles uit
curl -X POST http://localhost:8080/api/models/unload

# laad één model uit
curl -X POST http://localhost:8080/api/models/unload/qwen-coder

Gebruik deze eindpunten als VRAM nu nodig is nu in plaats van te wachten op TTL—benchmarks, snelle modelwissels, of na het laden van een veel groter checkpoint dan beoogd.

Stream live events via SSE
GET /api/events stelt een Server-Sent Events stream in en is ontworpen voor real-time updates die model statusveranderingen, logs, metrics en in-flight aanvrageaantallen bevatten.

curl -N http://localhost:8080/api/events

SSE en token streaming breken als elke tussenbox buffer—schakel buffering uit op nginx (of je equivalent) voor /api/events en /v1/chat/completions. llama-swap zet X-Accel-Buffering: no op SSE; schakel buffering ook in de proxy uit—headers zijn geen vervanging voor een correcte proxy-configuratie.

Metrics en aanvraagopnames
GET /api/metrics retourneert token-gebruik metrics, met in-memory retentie beheerd door metricsMaxInMemory (standaard 1000).
GET /api/captures/<id> kan volledige aanvraag/respons opnames ophalen, maar alleen als captureBuffer > 0 is geconfigureerd.

Logs en de Web UI

llama-swap exposeert /ui voor een web-interface, en operationele log-eindpunten zoals /logs en /logs/stream voor real-time monitoring.

llama-swap web UI voor het wisselen van modellen

Als je apiKeys inschakelt, ga uit van defence in depth: /health en stukken van /ui blijven bereikbaar zonder een sleutel—fijn voor lokale vertrouwensgrenzen, niet fijn als de host op een gedeeld netwerk staat. Zet llama-swap achter iets dat je echte beleid afdwingt; de ingebouwde auth is voor het houden van casual clients eerlijk, niet voor een publieke multi-tenant API.

Probleemoplossing voor llama-swap model wisselen in productie

De meeste llama-swap problemen vallen in een klein set operationele categorieën: streaming door een reverse proxy, health checks tijdens koude starts, poorten en proceslevenscyclus, en authenticatie.

Streaming breekt achter nginx of een andere reverse proxy
nginx zal blijvend je SSE en gestreamde completions bufferen. Schakel proxy_buffering (en proxy_cache) uit voor /api/events en /v1/chat/completions. llama-swap emiteert X-Accel-Buffering: no op SSE, wat helpt—fix de proxy toch.

Een model wordt nooit ready
Standaard is per-model checkEndpoint /health en moet HTTP 200 retourneren voor het proces om als ready te worden beschouwd. Je kunt checkEndpoint op een ander pad of op "none" zetten om health checks volledig uit te schakelen.
Als grote modellen langer nodig hebben om te laden, verhoog healthCheckTimeout (standaard 120s), of gebruik aangepaste health checks voor je specifieke upstream.

Wisselen van modellen laat een oude container draaien
Als de upstream Docker of Podman is, zet cmdStop—anders stopt llama-swap het wrapper-proces terwijl de container in de achtergrond VRAM blijft kauwen.

Ik krijg 401 responses na het inschakelen van beveiliging
Wanneer apiKeys is geconfigureerd, vereist llama-swap een geldige sleutel en accepteert drie methoden (Basic auth, Bearer token, x-api-key). Het verwijdert ook authenticatie headers voordat het upstream stuurt.

Ik krijg 429 Too Many Requests
concurrencyLimit geeft 429 terug bij overschrijding—opzettelijk. Verhoog de limiet als je het onder-provisioneerde, of verlaag de limiet als je niet van plan was te throttlen.

Poortconflicten of vreemde routingproblemen
Vermijd hard-coded poorten in cmd; gebruik ${PORT} en verplaats startPort als 5800+ botst met iets anders. Onthoud dat poorten worden toegewezen in alfabetische volgorde per model-ID—hernoem een model en de poortmapping verschuift.

Operationele debug checklist
/running voor waarheid, /logs/stream als opstart ondoorzichtig is, POST /api/models/unload als VRAM nu nodig is nu. Dat trio dekt de meeste “waarom is de GPU vol” sessies.

Abonneren

Ontvang nieuwe berichten over systemen, infrastructuur en AI-engineering.