Llama.swap Modellväxlar – Snabbstart för lokala, OpenAI-kompatibla LLM:ar

Byt lokala LLM:ar utan att ändra klienterna.

Sidinnehåll

Snart kastar du mellan vLLM, llama.cpp och mer – varje stack på sin egen port. Allt nedströms vill fortfarande ha en enda bas-URL /v1; annars fortsätter du att shuffla med portar, profiler och skript för enskilda fall. llama-swap är /v1-proxyn som ligger framför dessa stackar.

llama-swap ger en enda OpenAI- och Anthropic-kompatibel ingångsport, med en YAML-fil som mappar varje model-namn till kommandot som startar rätt uppströms-tjänst. Begär en modell så startar proxyn den eller byter till den; konfigurera TTL och grupper när VRAM är knappt eller flera modeller måste samexistera. Denna guide täcker installationsvägar, en praktisk config.yaml, HTTP-gränssnittet och de fel som dyker upp när streaming och omvända proxyer kommer in i bilden.

llama swap llm infographic För en bredare jämförelse av alternativ för LLM-hosting, se LLM-hosting 2026: Lokalt, self-hostat och molninfrastruktur jämfört.

Översikt över modellväxlaren llama-swap för lokala LLM-API:er kompatibla med OpenAI

llama-swap är en lättviktig proxyserver byggd kring en enkel operativ modell: en binär fil, en YAML-konfigurationsfil, inga beroenden. Den är skriven i Go, vilket innebär en enda statisk binär fil bredvid resten av stacken – ingen Python-runtime eller skrivbordsapp krävs. Den sitter framför vilken OpenAI- och Anthropic-kompatibel uppströms-tjänst som helst som modellväxlingslagret.

Konceptuellt svarar detta på en mycket praktisk fråga som dyker upp i lokala LLM-stackar:

Hur byter jag modeller med en OpenAI-kompatibel klient?
Med llama-swap fortsätter du använda normala /v1/...-förfrågan, men du ändrar model du begär. llama-swap läser det model-värdet, laddar den matchande serverkonfigurationen och om “fel” uppströms-tjänst är igång byter den ut den mot rätt en.

Några design detaljer är viktiga för produktionsliknande uppsättningar:

llama-swap är MIT-licensierat med ingen telemetri – fortfarande värt att bekräfta för alla värdar som ser verkliga prompts.
Det är byggt för on-demand-laddning av backendar som llama.cpp, vLLM, Whisper och stable-diffusion.cpp, inte för att låsa dig till en enda inferensmotor.
Utan att konfigurera något särskilt (inga grupper) kör det en modell i taget: begär en annan model och det stoppar den nuvarande uppströms-tjänsten och startar rätt en. För mer än en bosatt modell eller finare kontroll över samexistering, konfigurerar du groups.

Här är den mentala modellen som de flesta utvecklare hittar användbar:

flowchart LR
  C[Din app eller SDK\nOpenAI-kompatibel klient] -->|/v1/chat/completions\nmodel = qwen-coder| LS[llama-swap proxy\nenda ändpunkt]
  LS -->|startar eller styr till| U1[Uppströms server A\nllama-server]
  LS -->|startar eller styr till| U2[Uppströms server B\nvLLM OpenAI server]
  LS --> M[Hanteringsändpunkter\nrunning, unload, events, metrics]

Detta är också varför en modellväxlingsproxy skiljer sig från “bara att köra en modell”: det är orkestrering och styrning ovanpå en eller flera inferensservrar.

llama-swap jämfört med Ollama, LM Studio och llama.cpp-servern

Alla fyra alternativen kan ge dig en “lokal LLM-API”, men de optimerar för olika arbetsflöden. Det snabbaste sättet att välja är att bestämma om du vill ha en runtime (modellnedladdning + exekvering) eller en router/proxy (växling + orkestrering över runtimear).

llama-swap
llama-swap fokuserar på att vara en transparent proxy som stöder OpenAI-kompatibla ändpunkter (inklusive /v1/chat/completions, /v1/completions, /v1/embeddings och /v1/models) och styr förfrågan till rätt uppströms-tjänst baserat på den begärd modellen. Den ger också icke-inferens operativa ändpunkter som /running, /logs/stream och en webbgränssnitt på /ui.

Ollama
Ollama exponerar sin egen HTTP-API (POST /api/chat, POST /api/generate och den vanliga lokala standardport 11434).
keep_alive styr hur länge en modell förblir laddad, inklusive 0 för att omedelbart avladda.
Det passar användare som vill hämta en modell och chatta med minimal konfiguration. llama-swap passar kommandon per modell, blandade backendar och en OpenAI-formad URL för varje klient – att orkestrera vLLM bredvid llama-server med olika flaggor per modell ligger utanför vad Ollama är avsett för.

LM Studio
LM Studio är en skrivbordsapp med en lokal API-server från Developer-fliken (localhost eller LAN), inklusive OpenAI-kompatibel och Anthropic-kompatibel läge, plus lms server start från terminalen.
Det passar ett GUI-först flöde: bläddra modeller, klicka, testa. llama-swap passar en server-stil roll: YAML, processövervakning, blandade uppströms-tjänster, ingen skrivbordssession.

llama.cpp-servern
llama-server exponerar /v1/completions, /v1/chat/completions, /v1/responses och det vanliga mönstret är att peka en OpenAI-klient mot den via base_url.
llama.cpp levereras också med ett router-läge: kör llama-server som router, --models-dir, sedan POST /models/load och POST /models/unload för att jonglera GGUF-modeller utan en separat proxy. För en full installationsguide se llama-server router-läge: dynamisk modellväxling utan omstartar.
Om varje modell sitter under en llama.cpp-router är en extra proxy ofta onödig. När llama.cpp måste sitta bredvid vLLM eller andra OpenAI-formade servrar ger llama-swap en enda /v1-yta och många processer bakom den.

För liknande OpenAI-kompatibla hostinglösningar, se LocalAI QuickStart: Kör OpenAI-kompatibla LLM:er lokalt eller SGLang QuickStart: Installera, konfigurera och servera LLM:er via OpenAI-API.

Installera modellväxlaren llama-swap med Docker, Homebrew, WinGet eller binärer

Linux, macOS och Windows är alla förstahandsalternativ: Docker, Homebrew, WinGet, GitHub-binärer eller bygg från källkod. Vanliga val: Docker på headless-servrar, Homebrew eller WinGet på arbetsstationer, fristående binärer när installationsfotavtrycket ska hållas minimalt.

Docker-installation

Hämta en bild som matchar din hårdvara. Bilder följer uppströms-tjänster tätt (nattbyggen) och täcker CUDA, Vulkan, Intel, MUSA och CPU – välj den som matchar hur du faktiskt accelererar, inte “latest” av vana.

# Exempel på plattforms-hämtningar
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

Föredra icke-root-bildsvarianter om du kan: mindre att ångra om containergränsen någonsin är fel.

Homebrew-installation

På macOS och Linux, använd tap och installera:

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

WinGet-installation

På Windows:

winget install llama-swap
winget upgrade llama-swap

Förberedda binärer och utgåvor

GitHub Releases levererar Linux, macOS, Windows och FreeBSD-binärer om du inte vill ha en paketförvaltare.
Utgåversioner rör sig snabbt (till exempel v198, v197 i början av 2026) – lås en version i automatisering istället för att flyta “vad som fanns igår”.

Konfigurera llama-swap med config.yaml för modellväxling, TTL och grupper

Allt i llama-swap är konfigurationsdrivet. Den minsta möjliga konfigurationen är helt enkelt en models:-dikt och en cmd för varje modell, som ofta startar llama-server med ${PORT} substituerad per modell.

Konfigurationssystemet går mycket längre än bara “starta en process”, och några alternativ är värt att förstå tidigt eftersom de direkt svarar på vanliga FAQ-stilproblem (automatisk avladdning, säkerhet och klienter som förlitar sig på /v1/models).

Globala inställningar du faktiskt kommer använda

healthCheckTimeout är hur länge llama-swap väntar för att en modell ska bli frisk efter start (standard 120s, minimum 15s). För multi-GB-laddningar på långsamma diskar, öka detta innan du anklagar proxyn.
globalTTL är idle-sekunder innan automatisk avladdning; standard 0 betyder “aldrig avladda” om du inte ställer in det – välj explicit TTL för allt utöver ett lekuppsättning så att VRAM inte fylls med glömda modeller.
startPort sår ${PORT}-makron (standard 5800); tilldelning är deterministisk per alfabetisk modell-ID, vilket är en funktion när du debuggar “vem tog vilken port” och en fälla om du döper om modeller slarvigt.
includeAliasesInList bestämmer om alias syns som separata rader i /v1/models; slå det om ditt gränssnitt bara erbjuder uppräknade modeller.
apiKeys skyddar allt som är nåbart från localhost: Basic, Bearer eller x-api-key. llama-swap tar bort dessa huvudfält innan vidarebefordring så att uppströms-loggar är mindre benägna att behålla klienthemligheter.

Modellinställningar på modellnivå som låser upp produktionsergonomi

Per modell är cmd det enda obligatoriska fältet.
proxy är standardinställt till http://localhost:${PORT} – det är mottagaren för vidarebefordring för den modellens uppströms-tjänst.
checkEndpoint är standardinställt till /health; ställ in "none" när backenden inte har en hälsorutt eller kallstart överstiger vad du är villig att vänta på – gör inte att du lämnar en trasig /health och undrar varför ingenting når ready.
ttl: -1 ärvt globalTTL, 0 avladdar aldrig, N > 0 avladdar efter N sekunder idle – använd per-modell TTL när en modell ska ligga kvar och en annan ska försvinna snabbt.
aliases och useModelName behåller stabila klientförliga namn samtidigt som de tillgodoser uppströms-tjänster som kräver en specifik identifierare.
cmdStop är icke-valfritt för containrar: mappa det till docker stop (eller motsvarighet); utan det får du POSIX SIGTERM / Windows taskkill mot vilken PID llama-swap startade – bra för en ren binär, fel för ett containernamn.
concurrencyLimit sätter tak på parallella förfrågan per modell med HTTP 429 när gränsen överskrids – ställ in det när du hellre slänger last än att köa för evigt.

groups täcker samexistering (swap, exclusive) och alltid-på-modeller (persistent). Hooks kan förhandsladda vid start; om du förhandsladdar flera modeller samtidigt utan en grupp, förvänta dig att de ska strida – definiera en grupp först så att förhandsladdning matchar hur du vill att modeller ska dela GPU:n.

Minimal config.yaml-exempel för llama.cpp och vLLM

Detta exempel siktar på att vara “precis tillräckligt” för att illustrera bästa-praktik-knappar: en standard-TTL, explicit hälsokontroll, stabila alias och en grupp som håller en liten “alltid-på”-modell igång medan större chattmodeller växlar.

# config.yaml
healthCheckTimeout: 180
globalTTL: 900            # 15 minuter idle sedan avladda
includeAliasesInList: true
startPort: 5800

# Valfritt men rekommenderat för allt utöver localhost-utveckling
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"
    # Använder standardvärden:
    # proxy: http://localhost:${PORT}
    # checkEndpoint: /health
    # ttl: -1 (arv globalTTL)

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

  vllm-coder:
    # Illustrativt mönster: hantera en containeriserad OpenAI-kompatibel 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                 # avladda aldrig automatiskt (t.ex. behåll på GPU)

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

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

Inget av detta är dekorativt: cmd driver processen, proxy/checkEndpoint/ttl styr styrning och livscykel, cmdStop är det som får Docker-baserade uppströms-tjänster att faktiskt stoppa, och groups är det som separerar “en stor modell i taget” från “dessa två chattmodeller kan samexistera medan inbäddningsservern stannar fast”.

Kör och växla modeller via OpenAI-kompatibla ändpunkter

När llama-swap är igång, interagerar du med det som vilken annan OpenAI-kompatibel ändpunkt som helst. API-ytan inkluderar kärnändpunkter som /v1/chat/completions, /v1/completions, /v1/embeddings och /v1/models, och llama-swap använder den begärda model för att bestämma vilken uppströms-tjänst som ska köras och styras till.

Ett praktiskt snabbspår:

# 1) Starta llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Upptäck tillgängliga modeller
curl http://localhost:8080/v1/models

Modelllistning är en förstahands-hanteringsfunktion och inkluderar beteende som sortering efter ID, exkludering av unlisted-modeller och valfritt inkludering av alias.

# 3) Gör en chattkompletteringsförfrågan för en specifik 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":"Skriv en TypeScript-funktion som försöker hämta med backoff."}]
  }'

Om du nu upprepar anropet med "model": "llama-chat", kommer llama-swap att byta uppströms-processer (om inte din gruppkonfiguration tillåter dem att samexistera) eftersom det extraherar den begärda modellen från förfrågan och laddar rätt serverkonfiguration.

Om du använder en SDK, peka klienten mot http://localhost:8080/v1 – samma trick som att sikta OpenAI-biblioteket för Python mot llama-server, förutom att den stabila URL:n nu är llama-swap och model-fältet plockar uppströms-tjänsten.

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": "Förklara skillnaden mellan mutex och semaforer."}],
)
print(resp.choices[0].message.content)

För att värma en modell innan den första verkliga förfrågan (dölja kallstartslatens), använd /upstream/<model> – det laddar automatiskt om det behövs och vidarebefordrar direkt till den uppströms-tjänsten. Ett rakt sätt att se till att vikter är bosatta innan en benchmark eller skriptad test.

Kontrollera och övervaka llama-swap via hanterings-API-ändpunkter och SSE-händelser

llama-swap är inte bara “en proxy”; den exponerar också operativa kontrolländpunkter som låter dig bygga verktyg kring modelllivscykel och observabilitet.

Kolla vad som körs
GET /running returnerar körtillstånd för laddade modeller, inklusive tillståndsvärden som ready, starting, stopping, stopped och shutdown.

curl http://localhost:8080/running

Avladda modeller för att frigöra VRAM
För att avladda allt omedelbart, använd API-versionerad ändpunkt POST /api/models/unload. För att avladda en enskild modell (via ID eller alias), använd POST /api/models/unload/<model>. En legacy GET /unload finns för bakåtkompatibilitet.

# avladda allt
curl -X POST http://localhost:8080/api/models/unload

# avladda en modell
curl -X POST http://localhost:8080/api/models/unload/qwen-coder

Använd dessa ändpunkter när VRAM behövs tillbaka nu istället för att vänta på TTL – benchmarks, snabba modellbyten eller efter att ha laddat en mycket större checkpoint än avsett.

Strömma live-händelser via SSE
GET /api/events etablerar en Server-Sent Events-ström och är designad för realtidsuppdateringar som inkluderar modellstatusförändringar, loggar, metrik och antal pågående förfrågan.

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

SSE och token-strömning bryts när någon mellanliggande box buffrar – inaktivera buffring på nginx (eller din motsvarighet) för /api/events och /v1/chat/completions. llama-swap sätter X-Accel-Buffering: no på SSE; inaktivera buffring i proxyn också – huvudfält är ingen ersättning för en korrekt proxykonfiguration.

Metrik och fångade förfrågan
GET /api/metrics returnerar tokenanvändningsmetrik, med in-memory-retention kontrollerad av metricsMaxInMemory (standard 1000).
GET /api/captures/<id> kan hämta fullständiga förfrågan/svar-fångster, men bara när captureBuffer > 0 är konfigurerad.

Loggar och webbgränssnitt

llama-swap exponerar /ui för ett webbgränssnitt, och operativa loggändpunkter som /logs och /logs/stream för realtidsövervakning.

llama-swap web UI for switching models

Om du aktiverar apiKeys, anta försvar i djup: /health och delar av /ui förblir nåbara utan nyckel – bra för lokala tillitgränser, inte bra om värdaren är på ett delat nätverk. Sätt llama-swap bakom något som tillämpar din verkliga policy; den inbyggda autentiseringen är för att hålla slentrianmässiga klienter ärliga, inte för en offentlig multi-tenant-API.

Felsökning av modellväxling med llama-swap i produktion

De flesta llama-swap-problem faller in i en liten uppsättning operativa kategorier: strömning genom en omvänd proxy, hälsokontroller under kallstart, portar och processlivscykel, samt autentisering.

Strömning bryts bakom nginx eller en annan omvänd proxy
nginx kommer glatt att buffra bort din SSE och strömmade kompletteringar. Inaktivera proxy_buffering (och proxy_cache) för /api/events och /v1/chat/completions. llama-swap sänder X-Accel-Buffering: no på SSE, vilket hjälper – fixa proxyn ändå.

En modell blir aldrig redo
Som standard är per-modell checkEndpoint /health och måste returnera HTTP 200 för att processen ska anses redo. Du kan ställa in checkEndpoint till en annan sökväg eller till "none" för att helt inaktivera hälsokontroller.
Om stora modeller tar längre tid att ladda, öka healthCheckTimeout (standard 120s), eller använd skräddarsydda hälsokontroller för din specifika uppströms-tjänst.

Växling av modeller lämnar en gammal container igång
Om uppströms-tjänsten är Docker eller Podman, ställ in cmdStop – annars stoppar llama-swap wrapper-processen medan containern fortsätter att äta VRAM i bakgrunden.

Jag får 401-responser efter att ha aktiverat säkerhet
När apiKeys är konfigurerad kräver llama-swap en giltig nyckel och accepterar tre metoder (Basic auth, Bearer-token, x-api-key). Den tar också bort autentiseringshuvudfält innan vidarebefordring uppströms.

Jag får 429 Too Many Requests
concurrencyLimit returnerar 429 när gränsen överskrids – av design. Höj taket om du har underdimensionerat det, eller sänk gränsen om du inte menade att tvinga fram throttling.

Portkonflikter eller konstiga styrningsproblem
Undvik hårdkodade portar i cmd; använd ${PORT} och flytta startPort om 5800+ krockar med något annat. Kom ihåg att portar tilldelas i alfabetisk ordning per modell-ID – döpa om en modell och portmappningen skiftar.

Operativ felsökningschecklista
/running för sanning, /logs/stream när start är opålitlig, POST /api/models/unload när VRAM behövs tillbaka nu. Den triaden täcker de flesta “varför är GPU:n full”-sessioner.

Prenumerera

Få nya inlägg om system, infrastruktur och AI-ingenjörskonst.