llama.swap: szybki start z przełącznikiem modeli dla lokalnych LLM zgodnych z OpenAI
Gorąca wymiana lokalnych LLMów bez zmian w klientach.
Wkrótce będziesz jugglingiem w vLLM, llama.cpp i wielu innych — każdy stack na własnym porcie. Wszystkie komponenty dół wciąż wymagają jednego /v1 bazowego adresu URL; inaczej będziesz w nieskończoność przesuwać porty, profile i jednorazowe skrypty. llama-swap to /v1 proxy umieszczane przed tymi stackami.
llama-swap dostarcza jedną zgodną z OpenAI i Anthropic bramę wejściową, z plikiem YAML, który mapuje każdą nazwę model do polecenia uruchamiającego odpowiedni upstream. Żądanie modelu sprawia, że proxy uruchamia go lub przełącza na niego; konfigurowanie TTL-i i grup jest przydatne, gdy VRAM jest ograniczony lub gdy wiele modeli musi współistnieć. Ten przewodnik obejmuje ścieżki instalacji, praktyczny config.yaml, powierzchnię HTTP oraz tryby awaryjne, które pojawiają się, gdy w grę wchodzą streaming i proxy odwrotne.
Szersze porównanie opcji hostingu LLM znajdziesz w artykule Hosting LLM w 2026: Lokalne, Self-Hosted i Chmura — Porównanie
Przegląd przełącznika modeli llama-swap dla lokalnych API LLM zgodnych z OpenAI
llama-swap to lekki serwer proxy zbudowany wokół prostego modelu operacyjnego: jeden binary, jeden plik konfiguracyjny YAML, brak zależności. Jest napisany w Go, co oznacza pojedynczy statyczny binary obok reszty stacku — nie wymaga runtime’u Python ani aplikacji desktopowej. Działa przed dowolnym zgodnym z OpenAI i Anthropic upstreamem jako warstwa przełączania modeli.
Pojęciowo odpowiada to bardzo praktycznemu pytaniu, które pojawia się w lokalnych stackach LLM:
Jak przełączać modele z klientem zgodnym z OpenAI?
W przypadku llama-swap nadal używasz zwykłych żądań /v1/..., ale zmieniasz żądany model. llama-swap odczytuje wartość model, ładuje dopasowaną konfigurację serwera i, jeśli działa „zły" upstream, zamienia go na poprawny.
Kilka szczegółów projektowych ma znaczenie w środowiskach produkcyjnych:
llama-swap jest licencjonowany na MIT i nie zbiera telemetrii — warto to potwierdzić dla każdego hosta, który przetwarza prawdziwe prompty.
Został stworzony do uruchamiania backendsów takich jak llama.cpp, vLLM, Whisper i stable-diffusion.cpp na żądanie, a nie do zamykania cię w jednym silniku inferencji.
W konfiguracji domyślnej (bez specjalnego grupowania) działa jeden model naraz: żądasz innego model, a on zatrzymuje bieżący upstream i uruchamia odpowiedni. W przypadku więcej niż jednego rezydualnego modelu lub finer control nad współistnieniem, skonfiguruj groups.
Oto model mentalny, który większość developerów uważa za przydatny:
Dlatego też proxy przełącznika modeli różni się od „po prostu uruchomienia modelu": to orkiestracja i routing na wierzchu jednego lub więcej serwerów inferencji.
llama-swap vs Ollama vs LM Studio vs serwer llama.cpp
Wszystkie cztery opcje mogą dać ci „lokalne API LLM", ale optymalizują różne workflow. Najszybszy sposób na wybór to zdecydowanie, czy chcesz runtime (pobranie modelu + wykonanie) czy ruter/proxy (przełączanie + orkiestracja między runtime’ami).
llama-swap
llama-swap koncentruje się na byciu transparentnym proxy, które obsługuje endpointy zgodne z OpenAI (w tym /v1/chat/completions, /v1/completions, /v1/embeddings i /v1/models) i routuje żądania do poprawnego upstreamu na podstawie żądanego modelu. Dostarcza również nie-inferencyjne endpointy operacyjne, takie jak /running, /logs/stream oraz interfejs webowy pod /ui.
Ollama
Ollama wystawia własne API HTTP (POST /api/chat, POST /api/generate i zwykły lokalny domyślny port 11434).
keep_alive kontroluje, jak długo model pozostaje załadowany, w tym 0 do natychmiastowego wyładowania.
Pasuje do użytkowników, którzy chcą pobrać model i czatować przy minimalnym okablowaniu. llama-swap pasuje do polecenia per model, mieszanych backendów i jednego adresu URL w kształcie OpenAI dla każdego klienta — orkiestrowanie vLLM obok llama-server z różnymi flagami per model wykracza poza to, na co Ollama jest celowany.
LM Studio
LM Studio to aplikacja desktopowa z lokalnym serwerem API z zakładki Developer (localhost lub LAN), w tym tryby zgodne z OpenAI i zgodne z Anthropic, a także lms server start z terminala.
Pasuje do pętli GUI-first: przeglądaj modele, klikaj, testuj. llama-swap pasuje do roli serwerowej: YAML, nadzór procesów, mieszane upstreamy, brak sesji desktopowej.
Serwer llama.cpp
llama-server wystawia /v1/completions, /v1/chat/completions, /v1/responses, a zwykłym wzorcem jest wskazanie na niego klienta OpenAI przez base_url. Instalację tego serwera i flag, które faktycznie honoruje, omówiono w Szybki start llama.cpp.
llama.cpp dostarcza również tryb routera: uruchom llama-server jako router, --models-dir, a następnie POST /models/load i POST /models/unload, aby jugglingować modele GGUF bez osobnego proxy. Pełny przewodnik konfiguracji znajdziesz w Tryb routera llama-server: dynamiczne przełączanie modeli bez restartu.
Jeśli każdy model znajduje się pod jednym routerem llama.cpp, dodatkowe proxy często nie jest konieczne. Gdy llama.cpp musi istnieć obok vLLM lub innych serwerów w kształcie OpenAI, llama-swap dostarcza jedną powierzchnię /v1 i wiele procesów za nią.
Dla podobnych rozwiązań hostingu zgodnych z OpenAI zobacz Szybki start LocalAI: Uruchamianie LLM zgodnych z OpenAI lokalnie lub Szybki start SGLang: Instalacja, konfiguracja i serwowanie LLM przez API OpenAI
Instalacja przełącznika modeli llama-swap za pomocą Docker, Homebrew, WinGet lub binariów
Linux, macOS i Windows są wspierane w pierwszej klasie: Docker, Homebrew, WinGet, binariów z GitHub lub budowanie ze źródła. Częste wybory: Docker na serwerach headless, Homebrew lub WinGet na stacjach roboczych, samodzielne binariów, gdy stopa instalacji powinna pozostać minimalna.
Instalacja Docker
Pobierz obraz zgodny z Twoim sprzętem. Obrazy śledzą ciasno upstream (budowy nocne) i obejmują CUDA, Vulkan, Intel, MUSA oraz CPU — wybierz ten, który odpowiada temu, jak faktycznie przyspieszasz, a nie „najnowszy" z przyzwyczajenia.
# Przykładowe pobieranie platform
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
Gdy to możliwe, preferuj warianty obrazów non-root: mniej powodów do żalu, jeśli granica kontenera będzie kiedyś błędna.
Instalacja Homebrew
Na macOS i Linuxie użyj tap i zainstaluj:
brew tap mostlygeek/llama-swap
brew install llama-swap
llama-swap --config path/to/config.yaml --listen localhost:8080
Instalacja WinGet
Na Windowsie:
winget install llama-swap
winget upgrade llama-swap
Zbudowane binariów i wydania
GitHub Releases dostarcza binariów dla Linuxa, macOS, Windowsa i FreeBSD, jeśli nie chcesz menedżera pakietów.
Numery wydań zmieniają się szybko (na przykład v198, v197 w okolicach początku 2026) — przypnij wersję w automatyzacji, zamiast płynąć w „czymkolwiek, co było wczoraj".
Konfiguracja llama-swap za pomocą config.yaml do przełączania modeli, TTL-i i grup
Wszystko w llama-swap jest sterowane konfiguracją. Minimalna działająca konfiguracja to po prostu słownik models: i cmd dla każdego modelu, często uruchamiający llama-server z substytucją ${PORT} per model.
System konfiguracyjny sięga znacznie dalej niż „uruchomienie procesu", a kilka opcji warto zrozumieć wcześnie, ponieważ bezpośrednio odpowiadają na częste pytania FAQ (automatyczne wyładowanie, bezpieczeństwo i klienci polegający na /v1/models).
Globalne ustawienia, których faktycznie użyjesz
healthCheckTimeout to czas, przez jaki llama-swap czeka, aż model stanie się zdrowy po starcie (domyślnie 120s, minimum 15s). W przypadku wielu multi‑GB ładunków na wolnych dyskach, podnieś to, zanim obwinisz proxy.
globalTTL to sekundy bezczynności przed automatycznym wyładowaniem; domyślne 0 oznacza „nigdy nie wyładowuj”, chyba że to ustawisz — świadomie wybieraj TTL-e dla czegokolwiek poza zabawowym setupem, aby VRAM nie zapełnił się zapomnianymi modelami.
startPort zasiewa makro ${PORT} (domyślnie 5800); przydział jest deterministyczny według alfabetycznego ID modelu, co jest cechą przy debugowaniu „kto złapał który port” i pułapką, jeśli bezmyślnie zmienisz nazwy modeli.
includeAliasesInList decyduje, czy aliasy pojawiają się jako osobne wiersze w /v1/models; włącz to, jeśli Twój UI oferuje tylko wyliczone modele.
apiKeys blokuje wszystko osiągalne z localhost: Basic, Bearer lub x-api-key. llama-swap usuwa te nagłówki przed przesyłaniem, aby logi upstreamu rzadziej zatrzymywały sekrety klientów.
Ustawienia na poziomie modelu, które odblokowują ergonomię produkcyjną
Per model, cmd jest jedynym wymaganym polem.
proxy domyślnie http://localhost:${PORT} — to cel przesyłania dla upstreamu tego modelu.
checkEndpoint domyślnie /health; ustaw "none", gdy backend nie ma trasy zdrowotnej lub zimny start przekracza to, na co jesteś gotów czekać — nie zostawiaj zepsutego /health i nie dziw się, dlaczego nic nie osiąga ready.
ttl: -1 dziedziczy globalTTL, 0 nigdy nie wyładowuje, N > 0 wyładowuje po N sekundach bezczynności — używaj per-model TTL, gdy jeden model powinien zostać dłużej, a inny zniknąć szybko.
aliases i useModelName utrzymują stabilne nazwy dla klientów, jednocześnie zaspokajając upstreamy wymagające konkretnego identyfikatora.
cmdStop jest nieopcjonalne dla kontenerów: zmapuj to do docker stop (lub równoważnika); bez tego otrzymasz POSIX SIGTERM / Windows taskkill dla dowolnego PID uruchomionego przez llama-swap — dobrze dla binaria bez owijania, źle dla nazwy kontenera.
concurrencyLimit ogranicza równoległe żądania per model z HTTP 429 przy przekroczeniu — ustaw to, gdy wolisz odrzucać obciążenie niż kolejkować w nieskończoność.
groups obejmują współistnienie (swap, exclusive) i modele zawsze aktywne (persistent). Hooki mogą wstępnie załadować przy starcie; jeśli wstępnie załadujesz kilka modeli naraz bez grupy, spodziewaj się, że będą walczyć — zdefiniuj grupę wcześniej, aby wstępne ładowanie odpowiadało temu, jak chcesz, aby modele dzieliły GPU.
Minimalny przykład config.yaml dla llama.cpp i vLLM
Ten przykład ma na celu być „wystarczającym” do zilustrowania najlepszych praktyk: domyślny TTL, jawne sprawdzanie zdrowia, stabilne aliasy i grupa, która utrzymuje mały „zawsze aktywny” model podczas przełączania większych modeli czatu.
# config.yaml
healthCheckTimeout: 180
globalTTL: 900 # 15 minut bezczynności, potem wyładuj
includeAliasesInList: true
startPort: 5800
# Opcjonalne, ale zalecane dla czegokolwiek poza rozwojem na 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"
# Używa domyślnych:
# proxy: http://localhost:${PORT}
# checkEndpoint: /health
# ttl: -1 (dziedziczy globalTTL)
qwen-coder:
cmd: |
llama-server --port ${PORT} --model /models/qwen-coder.gguf
--ctx-size 8192
aliases:
- "qwen-coder-latest"
vllm-coder:
# Ilustracyjny wzorzec: zarządzanie kontenerowym serwerem zgodnym z OpenAI
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 # nigdy nie wyładuj automatycznie (np. zostaw na GPU)
groups:
chat-models:
swap: true
exclusive: true
members: ["llama-chat", "qwen-coder"]
always-on:
persistent: true
swap: false
exclusive: false
members: ["vllm-coder"]
Żadna z tych rzeczy nie jest dekoracyjna: cmd steruje procesem, proxy/checkEndpoint/ttl kontrolują routing i cykl życia, cmdStop sprawia, że upstreamy oparte na Dockerze faktycznie się zatrzymują, a groups to to, co oddziela „jeden duży model naraz” od „te dwa modele czatu mogą współistnieć, podczas gdy serwer embeddingów pozostaje przypięty”.
Uruchamianie i przełączanie modeli przez endpointy zgodne z OpenAI
Gdy llama-swap działa, interagujesz z nim jak z dowolnym innym endpointem zgodnym z OpenAI. Powierzchnia API obejmuje kluczowe endpointy, takie jak /v1/chat/completions, /v1/completions, /v1/embeddings i /v1/models, a llama-swap używa żądanego model, aby zdecydować, który upstream uruchomić i do niego routować.
Praktyczny szybki start:
# 1) Uruchom llama-swap
llama-swap --config ./config.yaml --listen localhost:8080
# 2) Odkryj dostępne modele
curl http://localhost:8080/v1/models
Wypisywanie modeli to funkcja zarządzania pierwszej klasy i obejmuje zachowania, takie jak sortowanie po ID, wykluczanie modeli unlisted i opcjonalne włączanie aliasów.
# 3) Wykonaj żądanie uzupełnienia czatu dla konkretnego modelu
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."}]
}'
Jeśli teraz powtórisz wywołanie z "model": "llama-chat", llama-swap zamieni procesy upstream (chyba że Twoja konfiguracja grup pozwala im na współistnienie), ponieważ wyciąga żądany model z żądania i ładuje odpowiednią konfigurację serwera.
Jeśli używasz SDK, wskazaj klienta na http://localhost:8080/v1 — ten sam trick co wskazanie biblioteki OpenAI Python na llama-server, z wyjątkiem tego, że stabilny adres URL to teraz llama-swap, a pole model wybiera 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)
Aby przegrzać model przed pierwszym prawdziwym żądaniem (ukryj opóźnienie zimnego startu), użyj /upstream/<model> — automatycznie ładuje, jeśli to potrzebne, i przesyła wprost do tego upstreamu. Prosty sposób, aby upewnić się, że wagii są rezydualne przed benchmarkiem lub skryptowanym testem.
Kontrola i monitorowanie llama-swap przez endpointy API zarządzania i zdarzenia SSE
llama-swap to nie tylko „proxy”; wystawia również endpointy kontroli operacyjnej, które pozwalają budować narzędzia wokół cyklu życia modeli i obserwowalności.
Sprawdź, co działa
GET /running zwraca stan runtime załadowanych modeli, w tym wartości stanów takie jak ready, starting, stopping, stopped i shutdown.
curl http://localhost:8080/running
Wyładuj modele, aby uwolnić VRAM
Aby natychmiast wyładować wszystko, użyj endpointu wersjonowanego API POST /api/models/unload. Aby wyładować pojedynczy model (po ID lub aliasie), użyj POST /api/models/unload/<model>. Istnieje legacy GET /unload dla kompatybilności wstecznej.
# wyładuj wszystko
curl -X POST http://localhost:8080/api/models/unload
# wyładuj jeden model
curl -X POST http://localhost:8080/api/models/unload/qwen-coder
Używaj tych endpointów, gdy VRAM jest potrzebne z powrotem teraz, zamiast czekać na TTL — benchmarki, szybkie przełączanie modeli lub po załadowaniu znacznie większego checkpointu, niż zamierzałeś.
Streamowanie żywych zdarzeń przez SSE
GET /api/events nawiązuje strumień Server-Sent Events i jest zaprojektowany do aktualizacji w czasie rzeczywistym, które obejmują zmiany statusu modeli, logi, metryki i liczbę żądań w toku.
curl -N http://localhost:8080/api/events
SSE i streaming tokenów się psują, gdy dowolna skrzynka pośrednia buforuje — wyłącz buforowanie na nginx (lub równoważniku) dla /api/events i /v1/chat/completions. llama-swap ustawia X-Accel-Buffering: no na SSE; wyłącz buforowanie również w proxy — nagłówki nie są zamiennikiem poprawnej konfiguracji proxy.
Metryki i przechwytywania żądań
GET /api/metrics zwraca metryki użycia tokenów, z retencją w pamięci kontrolowaną przez metricsMaxInMemory (domyślnie 1000).
GET /api/captures/<id> może pobrać pełne przechwytywania żądania/odpowiedzi, ale tylko gdy skonfigurowano captureBuffer > 0.
Logi i interfejs webowy
llama-swap wystawia /ui dla interfejsu webowego oraz operacyjne endpointy logów, takie jak /logs i /logs/stream, do monitorowania w czasie rzeczywistym.

Jeśli włączysz apiKeys, zakładaj głębię obrony: /health i elementy /ui pozostają osiągalne bez klucza — dobrze dla lokalnych granic zaufania, źle, jeśli host jest na wspólnej sieci. Umieść llama-swap za czymś, co wymusza Twoją rzeczywistą politykę; wbudowane uwierzytelnianie służy do trzymania casualnych klientów w ryzach, a nie do publicznego, wielonajemcy API.
Rozwiązywanie problemów z przełączaniem modeli llama-swap w produkcji
Większość problemów z llama-swap spada do małego zestawu kategorii operacyjnych: streaming przez proxy odwrotne, sprawdzanie zdrowia podczas zimnych startów, porty i cykl życia procesów oraz uwierzytelnianie.
Streaming psuje się za nginx lub innym proxy odwrotnym
nginx chętnie zbuforuje Twoje SSE i streamowane uzupełnienia. Wyłącz proxy_buffering (i proxy_cache) dla /api/events i /v1/chat/completions. llama-swap emituje X-Accel-Buffering: no na SSE, co pomaga — napraw proxy tak czy siak.
Model nigdy nie staje się gotowy
Domyślnie, per-model checkEndpoint to /health i musi zwracać HTTP 200, aby proces był uznawany za gotowy. Możesz ustawić checkEndpoint na inną ścieżkę lub na "none", aby całkowicie wyłączyć sprawdzanie zdrowia.
Jeśli duże modele potrzebują więcej czasu na ładowanie, zwiększ healthCheckTimeout (domyślnie 120s) lub użyj dostosowanych sprawdzania zdrowia dla Twojego konkretnego upstreamu.
Przełączanie modeli pozostawia stary kontener działający
Jeśli upstreamem jest Docker lub Podman, ustaw cmdStop — inaczej llama-swap zatrzyma proces wrappera, podczas gdy kontener nadal zjada VRAM w tle.
Otrzymuję odpowiedzi 401 po włączeniu bezpieczeństwa
Gdy skonfigurowano apiKeys, llama-swap wymaga ważnego klucza i akceptuje trzy metody (uwierzytelnianie Basic, token Bearer, x-api-key). Usuwa również nagłówki uwierzytelniania przed przesyłaniem do upstreamu.
Otrzymuję 429 Too Many Requests
concurrencyLimit zwraca 429 przy przekroczeniu — zgodnie z projektem. Podnieś limit, jeśli niedoinwestowałeś, lub obniż limit, jeśli nie zamierzałeś dławić.
Konflikty portów lub dziwne problemy routingu
Unikaj twardo zakodowanych portów w cmd; używaj ${PORT} i przesuń startPort, jeśli 5800+ koliduje z czymś innym. Pamiętaj, że porty są przydzielane w kolejności alfabetycznej według ID modelu — zmiana nazwy modelu przesunęła mapowanie portów.
Checklist do debugowania operacyjnego
/running dla prawdy, /logs/stream, gdy start jest niejasny, POST /api/models/unload, gdy VRAM jest potrzebne z powrotem teraz. Ta trójka obejmuje większość sesji „dlaczego GPU jest pełne”.