Guida rapida per llama.swap Model Switcher per modelli LLM locali compatibili con OpenAI
Sostituzione a caldo di LLM locali senza modificare i client.
Presto ti troverai a gestire vLLM, llama.cpp e altro ancora, ogni stack su una propria porta. Tutto il resto a valle si aspetta comunque un URL base unico /v1; altrimenti continuerai a spostare porte, profili e script monouso. llama-swap è il proxy /v1 che precede questi stack.
llama-swap fornisce un’unica porta d’accesso compatibile con OpenAI e Anthropic, con un file YAML che associa ogni nome model al comando necessario per avviare il backend corretto. Chiedi un modello e il proxy lo avvia o lo cambia; configura TTL e gruppi quando la VRAM è scarsa o quando più modelli devono coesistere. Questa guida copre i percorsi di installazione, un config.yaml pratico, la superficie HTTP e i modi di fallimento che emergono una volta che streaming e proxy inversi entrano in gioco.
Per un confronto più ampio delle opzioni di hosting LLM, vedi LLM Hosting in 2026: Local, Self-Hosted & Cloud Infrastructure Compared
Panoramica del cambio modello di llama-swap per API LLM locali compatibili con OpenAI
llama-swap è un server proxy leggero basato su un modello operativo semplice: un singolo binario, un file di configurazione YAML, nessuna dipendenza. È scritto in Go, il che significa un singolo binario statico accanto al resto dello stack: nessun runtime Python o applicazione desktop richiesti. Si colloca davanti a qualsiasi upstream compatibile con OpenAI e Anthropic come strato di cambio modello.
Concettualmente, questo risponde a una domanda molto pratica che sorge negli stack LLM locali:
Come cambio modello con un client compatibile con OpenAI?
Con llama-swap continui a usare le normali richieste /v1/..., ma cambi il model che richiedi. llama-swap legge quel valore model, carica la configurazione del server corrispondente e, se l’upstream “sbagliato” è in esecuzione, lo sostituisce con quello corretto.
Alcuni dettagli di progettazione sono importanti per configurazioni quasi di produzione:
llama-swap è con licenza MIT e non ha telemetria—vale comunque la pena confermarlo per qualsiasi host che veda prompt reali.
È costruito per il caricamento on-demand di backend come llama.cpp, vLLM, Whisper e stable-diffusion.cpp, non per bloccarti su un singolo motore di inferenza.
Di default (senza raggruppamento speciale), esegue un modello alla volta: richiedi un model diverso e arresta l’upstream attuale per avviare quello corretto. Per più modelli residenti o un controllo più fine sulla coesistenza, configura i groups.
Ecco il modello mentale che la maggior parte degli sviluppatori trova utile:
flowchart LR
C[La tua app o SDK\nClient compatibile OpenAI] -->|/v1/chat/completions\nmodel = qwen-coder| LS[proxy llama-swap\nsingolo endpoint]
LS -->|avvia o instrada verso| U1[Server upstream A\nllama-server]
LS -->|avvia o instrada verso| U2[Server upstream B\nvLLM OpenAI server]
LS --> M[Endpoint di gestione\nrunning, unload, events, metrics]
Questo è anche il motivo per cui un proxy di cambio modello è diverso da “eseguire semplicemente un modello”: è orchestrazione e instradamento sopra uno o più server di inferenza.
llama-swap vs Ollama vs LM Studio vs server llama.cpp
Tutte e quattro le opzioni possono fornirti un’API “LLM locale”, ma ottimizzano per flussi di lavoro diversi. Il modo più veloce per scegliere è decidere se vuoi un runtime (download modello + esecuzione) o un router/proxy (cambio + orchestrazione tra runtime).
llama-swap
llama-swap si concentra sull’essere un proxy trasparente che supporta endpoint compatibili con OpenAI (inclusi /v1/chat/completions, /v1/completions, /v1/embeddings e /v1/models) e instrada le richieste verso l’upstream corretto in base al modello richiesto. Fornisce anche endpoint operativi non di inferenza come /running, /logs/stream e un’interfaccia Web su /ui.
Ollama
Ollama espone la sua API HTTP (POST /api/chat, POST /api/generate e la porta locale di default 11434).
keep_alive controlla quanto tempo un modello rimane caricato, incluso 0 per scaricarlo immediatamente.
Si adatta agli utenti che vogliono scaricare un modello e chattare con la minima configurazione. llama-swap si adatta ai comandi per modello, backend misti e a un URL dalla forma OpenAI per ogni client: orchestrare vLLM accanto a llama-server con flag diversi per modello è fuori dallo scopo di Ollama.
LM Studio
LM Studio è un’app desktop con un server API locale dalla Developer tab (localhost o LAN), inclusi modi compatibili con OpenAI e compatibili con Anthropic, più lms server start dal terminale.
Si adatta a un ciclo GUI-first: sfoglia i modelli, clicca, testa. llama-swap si adatta a un ruolo di stile server: YAML, supervisione dei processi, upstream misti, nessuna sessione desktop.
llama.cpp server
llama-server espone /v1/completions, /v1/chat/completions, /v1/responses e il pattern usuale è puntare un client OpenAI verso di esso tramite base_url.
llama.cpp include anche una modalità router: esegui llama-server come router, --models-dir, poi POST /models/load e POST /models/unload per gestire i modelli GGUF senza un proxy separato.
Se ogni modello risiede sotto un router llama.cpp, un proxy aggiuntivo è spesso inutile. Quando llama.cpp deve stare accanto a vLLM o altri server dalla forma OpenAI, llama-swap fornisce una superficie /v1 unica e molti processi dietro di essa.
Per soluzioni di hosting compatibili con OpenAI simili, vedi LocalAI QuickStart: Run OpenAI-Compatible LLMs Locally or SGLang QuickStart: Install, Configure, and Serve LLMs via OpenAI API
Installa llama-swap model switcher con Docker, Homebrew, WinGet o binari
Linux, macOS e Windows sono tutti di prima classe: Docker, Homebrew, WinGet, binari GitHub o compilazione dal sorgente. Scelte comuni: Docker su server headless, Homebrew o WinGet su workstation, binari standalone quando l’impronta di installazione deve rimanere minima.
Installazione Docker
Scarica un’immagine che corrisponda al tuo hardware. Le immagini seguono da vicino gli upstream (build notturne) e coprono CUDA, Vulkan, Intel, MUSA e CPU: scegli quella che corrisponde a come acceleri effettivamente, non “latest” per abitudine.
# Esempi di pull per piattaforma
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
Preferisci le varianti non-root delle immagini quando possibile: meno rimpianti se il confine del container è mai sbagliato.
Installazione Homebrew
Su macOS e Linux, usa il tap e installa:
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
Installazione WinGet
Su Windows:
winget install llama-swap
winget upgrade llama-swap
Binari pre-compilati e release
GitHub Releases fornisce binari per Linux, macOS, Windows e FreeBSD se non vuoi un package manager.
I numeri di release si muovono velocemente (ad esempio v198, v197 intorno all’inizio del 2026): fissa una versione nell’automazione invece di galleggiare su “quello che c’era ieri”.
Configura llama-swap con config.yaml per cambio modello, TTL e gruppi
Tutto in llama-swap è guidato dalla configurazione. La configurazione minima vitale è semplicemente un dizionario models: e un cmd per ogni modello, spesso che lancia llama-server con ${PORT} sostituito per modello.
Il sistema di configurazione va molto oltre il semplice “avviare un processo”, e alcune opzioni vale la pena comprenderle presto perché rispondono direttamente a problemi di stile FAQ (scaricamento automatico, sicurezza e client che si basano su /v1/models).
Impostazioni globali che userai davvero
healthCheckTimeout è quanto tempo llama-swap aspetta che un modello diventi sano dopo l’avvio (default 120s, minimo 15s). Per caricamenti multi-GB su dischi lenti, aumenta questo prima di incolpare il proxy.
globalTTL sono i secondi di inattività prima dello scaricamento automatico; default 0 significa “non scaricare mai” a meno che tu non lo imposti—scegli esplicitamente i TTL per qualsiasi cosa oltre una configurazione giocosa così la VRAM non si riempi di modelli dimenticati.
startPort semina il macro ${PORT} (default 5800); l’assegnazione è deterministica per ID modello alfabetico, che è una funzione quando debugghi “chi ha preso quale porta” e un problema se rinomini modelli con disattenzione.
includeAliasesInList decide se gli alias appaiono come righe separate in /v1/models; attivalo se la tua UI offre solo modelli elencati.
apiKeys protegge tutto ciò che è raggiungibile fuori da localhost: Basic, Bearer o x-api-key. llama-swap rimuove quegli header prima di inoltrare così i log upstream hanno meno probabilità di conservare segreti del client.
Impostazioni a livello di modello che sbloccano l’ergonomia di produzione
Per modello, cmd è l’unico campo richiesto.
proxy predefinito è http://localhost:${PORT}—è il target di inoltro per l’upstream di quel modello.
checkEndpoint predefinito è /health; imposta "none" quando il backend non ha una rotta di salute o l’avvio a freddo supera ciò che sei disposto ad aspettare—non lasciare un /health rotto e chiederti perché nulla raggiunge ready.
ttl: -1 eredita globalTTL, 0 non scarica mai, N > 0 scarica dopo N secondi di inattività—usa TTL per modello quando un modello dovrebbe rimanere e un altro dovrebbe scomparire rapidamente.
aliases e useModelName mantengono nomi stabili visibili al client soddisfacendo gli upstream che richiedono un identificatore specifico.
cmdStop è non-opzionale per i container: mappalo a docker stop (o equivalente); senza di esso ottieni POSIX SIGTERM / Windows taskkill contro qualsiasi PID che llama-swap ha avviato—va bene per un binario nudo, sbagliato per un nome di container.
concurrencyLimit limita le richieste parallele per modello con HTTP 429 quando superato—impostalo se preferisci scartare il carico piuttosto che fare la coda per sempre.
groups coprono la coesistenza (swap, exclusive) e i modelli sempre attivi (persistent). Gli hook possono pre-caricare all’avvio; se precarichi più modelli contemporaneamente senza un gruppo, aspettati che si scontrino—definisci un gruppo prima così il pre-caricamento corrisponde a come vuoi che i modelli condividano la GPU.
Esempio minimo di config.yaml per llama.cpp e vLLM
Questo esempio mira a essere “quanto basta” per illustrare i migliori parametri: un TTL predefinito, controllo salute esplicito, alias stabili e un gruppo che mantiene un modello piccolo “sempre attivo” mentre i modelli di chat più grandi si alternano.
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 minuti inattivi poi scarica
includeAliasesInList: true
startPort: 5800
# Opzionale ma consigliato per tutto ciò che va oltre lo sviluppo 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"
# Usa i default:
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (eredita globalTTL)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# Pattern illustrativo: gestire un server OpenAI-compatible containerizzato
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 # non scaricare mai automaticamente (es. mantieni su GPU)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
Nessuna di queste cose è decorativa: cmd guida il processo, proxy/checkEndpoint/ttl controllano l’instradamento e il ciclo di vita, cmdStop è ciò che fa sì che gli upstream basati su Docker si fermino davvero, e groups sono ciò che separa “un grande modello alla volta” da “questi due modelli di chat possono coesistere mentre il server di embedding rimane fissato”.
Avvia e cambia modelli tramite endpoint compatibili con OpenAI
Una volta che llama-swap è in esecuzione, interagisci con esso come con qualsiasi altro endpoint compatibile con OpenAI. La superficie API include endpoint principali come /v1/chat/completions, /v1/completions, /v1/embeddings e /v1/models, e llama-swap usa il model richiesto per decidere quale upstream eseguire e instradare.
Un flusso pratico di avvio rapido:
# 1) Avvia llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Scopri i modelli disponibili
curl http://localhost:8080/v1/models
L’elenco dei modelli è una funzione di gestione di primo livello e include comportamenti come ordinamento per ID, esclusione di modelli unlisted e opzionalmente inclusi gli alias.
# 3) Esegui una richiesta di completamento chat per un modello specifico
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."}]
}'
Se ora ripeti la chiamata con "model": "llama-chat", llama-swap cambierà i processi upstream (a meno che la tua configurazione di gruppo non permetta loro di coesistere) perché estrae il modello richiesto dalla richiesta e carica la configurazione del server appropriata.
Se stai usando un SDK, punta il client a http://localhost:8080/v1—stesso trucco di puntare la libreria Python OpenAI a llama-server, tranne che l’URL stabile è ora llama-swap e il campo model sceglie l’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)
Per riscaldare un modello prima della prima richiesta reale (nascondere la latenza di avvio a freddo), usa /upstream/<model>—si auto-carica se necessario e inoltra direttamente a quell’upstream. Modo semplice per assicurarsi che i pesi siano residenti prima di un benchmark o test scriptato.
Controlla e monitora llama-swap tramite endpoint API di gestione e eventi SSE
llama-swap non è solo “un proxy”; espone anche endpoint di controllo operativo che ti permettono di costruire strumenti intorno al ciclo di vita del modello e all’osservabilità.
Verifica cosa è in esecuzione
GET /running restituisce lo stato runtime per i modelli caricati, inclusi valori di stato come ready, starting, stopping, stopped e shutdown.
curl http://localhost:8080/running
Scarica modelli per liberare VRAM
Per scaricare tutto immediatamente, usa l’endpoint versionato API POST /api/models/unload. Per scaricare un singolo modello (per ID o alias), usa POST /api/models/unload/<model>. Un legacy GET /unload esiste per la compatibilità retroattiva.
# scarica tutto
curl -X POST http://localhost:8080/api/models/unload
# scarica un modello
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
Usa questi endpoint quando la VRAM serve indietro ora invece di aspettare il TTL—benchmark, cambi rapidi di modello o dopo aver caricato un checkpoint molto più grande del previsto.
Streaming eventi live tramite SSE
GET /api/events stabilisce un flusso Server-Sent Events ed è progettato per aggiornamenti in tempo reale che includono cambiamenti di stato del modello, log, metriche e conteggi di richieste in volo.
curl -N http://localhost:8080/api/events
SSE e streaming token si rompono se qualsiasi box intermedio tampona—disabilita il buffering su nginx (o equivalente) per /api/events e /v1/chat/completions. llama-swap imposta X-Accel-Buffering: no su SSE; disabilita il buffering anche nel proxy—gli header non sono un sostituto per una configurazione proxy corretta.
Metriche e catture richieste
GET /api/metrics restituisce metriche di utilizzo token, con ritenzione in memoria controllata da metricsMaxInMemory (default 1000).
GET /api/captures/<id> può recuperare catture complete di richiesta/risposta, ma solo quando captureBuffer > 0 è configurato.
Log e interfaccia Web
llama-swap espone /ui per un’interfaccia web, e endpoint log operativi come /logs e /logs/stream per monitoraggio in tempo reale.

Se abiliti apiKeys, assumi difesa in profondità: /health e parti di /ui rimangono raggiungibili senza chiave—va bene per confini di fiducia locali, non va bene se l’host è su una rete condivisa. Metti llama-swap dietro qualcosa che applica la tua politica reale; l’autenticazione integrata è per mantenere onesti i client casuali, non per un’API multi-tenant pubblica.
Risoluzione dei problemi di cambio modello llama-swap in produzione
La maggior parte dei problemi di llama-swap rientra in un piccolo set di categorie operative: streaming attraverso un proxy inverso, controlli di salute durante l’avvio a freddo, porte e ciclo di vita del processo, e autenticazione.
Lo streaming si rompe dietro nginx o un altro proxy inverso
nginx tamponerà con piacere i tuoi SSE e completamenti streammati. Disabilita proxy_buffering (e proxy_cache) per /api/events e /v1/chat/completions. llama-swap emette X-Accel-Buffering: no su SSE, che aiuta—correggi comunque il proxy.
Un modello non diventa mai pronto
Di default, checkEndpoint per modello è /health e deve restituire HTTP 200 perché il processo sia considerato pronto. Puoi impostare checkEndpoint su un altro percorso o su "none" per disabilitare completamente i controlli di salute.
Se i modelli grandi impiegano più tempo a caricarsi, aumenta healthCheckTimeout (default 120s), o usa controlli di salute su misura per il tuo upstream specifico.
Cambiare modello lascia un container vecchio in esecuzione
Se l’upstream è Docker o Podman, imposta cmdStop—altrimenti llama-swap ferma il processo wrapper mentre il container continua a consumare VRAM in background.
Ottengo risposte 401 dopo aver abilitato la sicurezza
Quando apiKeys è configurato, llama-swap richiede una chiave valida e accetta tre metodi (autenticazione Basic, token Bearer, x-api-key). Rimuove anche gli header di autenticazione prima di inoltrare upstream.
Ottengo 429 Too Many Requests
concurrencyLimit restituisce 429 quando superato—progettato così. Aumenta il limite se lo hai sottodimensionato, o abbassa il limite se non intendevi limitare.
Conflitti di porta o problemi di instradamento strani
Evita porte hard-codate in cmd; usa ${PORT} e sposta startPort se 5800+ collisiona con qualcos’altro. Ricorda che le porte sono assegnate in ordine alfabetico per ID modello—rinomina un modello e la mappatura della porta cambia.
Checklist di debug operativo
/running per la verità, /logs/stream quando l’avvio è opaco, POST /api/models/unload quando la VRAM serve indietro ora. Questa terna copre la maggior parte delle sessioni “perché la GPU è piena”.