llama-swap

mostlygeekMIT活跃维护

本地大模型推理服务的模型热切换代理,按需自动加载和卸载不同模型,让单个服务端同时对外提供多个 LLM,省去手动重启。

Reliable model swapping for any local AI server. Chosen by thousands of users. Batteries included. If we don't have it, you probably don't need it.

v271发布于 2026-11-08 05:26 UTC6,230star +25 / 7 天544fork同步于 2026-11-10 17:35 UTC

怎么上手

由 README 提炼,执行前请确认
docker pull ghcr.io/mostlygeek/llama-swap:unified-cuda13
winget install llama-swap
硬件要求按 README 说明

README 未给出统一显存要求,取决于所挂载的推理后端;Docker 统一镜像按 GPU 分 CUDA 12、CUDA 13 和 Vulkan 版本,CUDA 13 覆盖 NVIDIA Turing 至 Blackwell(RTX 20xx、GTX 16xx、A100、RTX 30xx 等)。

支持 Apple Silicon需要 CUDA有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用单个二进制和一份配置在本地按需热切换多个 AI 模型的反向代理

本地大模型推理服务的模型热切换代理,按需自动加载和卸载不同模型,让单个服务端同时对外提供多个 LLM,省去手动重启。

核心能力

  • 按请求中的 model 值自动切换上游推理服务器
  • 兼容 OpenAI 与 Anthropic API 的多种端点
  • 支持 llama.cpp、vllm、ComfyUI 等本地推理后端
  • 用 matrix DSL 配置并发加载多个模型
  • 提供 Web UI 与实时日志流、模型手动装卸

容易踩的坑

配置里 cmd 需自行指向本地模型文件与推理服务器可执行文件;nginx 反代需关闭 proxy_buffering,否则流式输出会失效;旧版 llama-server 需显式加 --jinja 才能让内置 Help 助手调用工具。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v271
  1. v271最新正式版2026-11-08 · 2026-11-08 05:26 UTC

    This release includes a some nice contributions form the community:

    • @cphlipot improved the sidebar on mobile
    • @candrews added model parsing from the websocket stream in v1/realtime
    • @heshiming added support for TensorFold metrics parsing

    On the backend there was lots of work to finetune LFM3-1.7B for the new help agent on llama-swap.ai. This includes the training scripts and data and the new docbot package that has the Help's mcp endpoints.

    • PR #1283 ui: dismiss mobile sidebar when user selects an item: closes the mobile sidebar overlay as soon as a nav item is tapped so the selected page comes into focus immediately, because the overlay previously stayed open and made switching pages (eg. activity -> playground) take two taps; no effect on desktop where the sidebar is always visible by @cphlipot
    • PR #1304 evals/docs-agent: update cases for current KB and tune the Docs Agent: adds 66 training and 29 holdout eval cases, fixes four wrong assertions, raises get_doc default output from 250 to 400 lines (it was cutting off the kubeswap gpu-budget example), corrects the cmdStop, ${PORT} macro and kubeswap docs, and points KB pages at the guides holding the answers, lifting gemma-4-12B-r9700's training score from 96.0% to 97.3% by @mostlygeek
    • PR #1308 evals/docs-agent: add fine-tuning pipeline for a small Docs Agent model: adds the scripts, recorded conversations and run notes used to fine-tune LFM3-1.7B on Docs Agent conversations (lfm3-v2 Q4_K_M scores 95.5% on training cases and 96.1% on the holdout at a 60 s per-question limit), with no weights included, as a reference for tuning future help-agent models by @mostlygeek
    • PR #1310 internal/server: route /v1/realtime by model in session.update: fixes 404s before the websocket upgrade for clients that follow OpenAI's documented /v1/realtime API and connect with ?intent=transcription but no ?model=, by having llama-swap complete the handshake itself, buffer events until a session.update names a model (session.model, then the transcription model keys), and replay them upstream through the normal model chain, reporting failures as OpenAI style error events by @candrews
    • PR #1312 docbot: new importable package: extracts MCP protocol handling into a stateless internal/mcpserver.Handler and adds a docbot package that serves llama-swap's docs (and optionally source) as MCP tools over any HTTP route with SystemPrompt() and Tools() helpers, a prerequisite for the help agent on llama-swap.ai by @mostlygeek
    • PR #1313 TensorFold support for pluggable usage handlers: adds a TensorFold usage and metrics extractor with simplified captured-metrics fixtures, rebuilt on the pluggable per-upstream usage handler standard from #1292 after that refactor left the original TensorFold support stale by @heshiming
    • dea1363 README.md: add tip for llama-swap.ai: adds a README tip pointing to the browser-based Chat agent powered by an LFM3-1.7B fine tuned on the docs by @mostlygeek
    • cef61b3 Revise Chat agent info in README: revises the Chat agent description and links to the fine-tuned model on Hugging Face by @mostlygeek
    • c805e62
  2. v2702026-11-05 · 2026-11-05 03:49 UTC
    查看更新说明

    Ohh, support for the v1/realtime API with LFM3 voice chat in the Playground! The Help agent has been updated with a guide on how to quickly get it set up and working.

    Also in this release are a few compatbility and quality improvements. Thanks to @noctrex, @SriRamanujam, and @ltjax for the contributions.

    • PR #1278 Feat/sidebar category submenus: adds category submenus to the left sidebar menu, mirroring the capability-derived categories recently added to the Models list by @noctrex and @mostlygeek
    • PR #1288 Configurable token rate sources: adds hints, docs and usage extraction for hipfire so token/s stats are captured correctly when running hipfire behind llama-swap, as part of the pluggable per-upstream usage parsing by @ltjax
    • PR #1291 cmd/kubeswap: Support defining annotations and service accounts: allows defining annotations on generated deployments and pods (rejecting the reserved kubeswap.io/model-id key) and setting .spec.template.spec.serviceAccountName on the Deployment, without managing the ServiceAccount itself by @SriRamanujam
    • PR #1297 fix(logmon): stop memory accumulating across config reloads: closes a process's dedicated log monitor when ProcessCommand.run returns so discarded router generations no longer leak memory, because each monitor's surviving broadcast goroutine kept its 100 KiB history buffer reachable after a hot reload (129 MiB retained after 100 router replacements in testing, now ~0) by @junmo-kim
    • PR #1298 makefile: use .stamp for UI dependency checks: uses a .stamp file to detect UI dependency changes, fixing a build error after pulling the latest version when UI dependencies changed by @mostlygeek
    • PR #1299 internal/server: add /v1/realtime proxying and a Realtime playground: proxies OpenAI Realtime API style websockets to the upstream named by the ?model= query and adds a Playground > Realtime tab for speech-to-speech models like LFM3 Audio through llama-server (push-to-talk or hands-free voice detection, streamed playback, replay/download per turn), records each session as one Activity row with reply, token, decode-rate and audio-second metrics, detects audio output from /v1/models output_modalities, and adds a KB guide with llama-server configuration examples by @mostlygeek
  3. v2692026-11-01 · 2026-11-01 01:06 UTC
    查看更新说明

    Happy Halloween!

    Lots of small and big treats in this release.

    • captures can now be persisted to disk and not lost on restart.
    • the metrics capture backend has been refactored to make it easy to add support for new inference servers.
    • the UI can show models sorted by categories, great if you have many different types configured!
    • metrics can be exported as a PNG to make sharing easier.
    • add support for the embedding model capability
    • small bug and UI improvements

    Details below:

    • PR #1274 go.mod,ui/package-lock.json: dependency updates: picks up security updates for node and moves shirou/gopsutil back to the main upstream repository by @mostlygeek
    • PR #1275 feat(config): add embeddings capability flag: adds capabilities.embeddings, mirroring the existing reranker flag and rendered into the /v1/models capabilities map, because capability discovery reads llama-server /props which reports nothing about embeddings, so a probed embed model surfaced as plain text->text and clients and the UI could only pick them out by name prefix by @noctrex
    • PR #1276 feat(ui): group Models list into capability-derived class sections: derives each model's class (Chat, Image, Video, Audio, Embeddings, Rerank) client-side from the capability flags and modality lists /v1/models already carries and renders one collapsible section per class with a status dot that aggregates its rows, because a long flat list is hard to scan once many models are configured; /api/events modelStatus now includes modalities: {in, out} from the same renderCapabilities call so the dashboard and the OpenAI listing cannot disagree by @noctrex
    • PR #1279 ui: move Models display options into a dropdown menu: moves the Categories and Show unlisted models switches into a "Display options" menu pinned to the right of the Models header (with the unlisted count shown in the item) and drops flex-wrap, because the header added in #1276 wrapped onto extra rows and made the page too tall; mobile layout improved too by @mostlygeek
    • PR #1280 Makefile: add native target for the host platform: makes native the default target so a bare make builds for the platform you are on instead of cross-compiling everything, and fixes make all to actually cover Windows and FreeBSD, with $(LDFLAGS) factored out and shared by every platform target by @mostlygeek
    • PR #1282 internal/capcompat: detect context length from yamz servers: reads max_context from /v1/models (tried after context_length) so yamz (kyojin) servers report their context length through the default prober by @mostlygeek
    • PR #1285 ui: export the activity table as a client-side PNG image: rasterizes the visible table in the browser with html-to-image (SVG foreignObject -> canvas) and adds Markdown / Screenshot tabs to the export dialog with clipboard copy, download and a background resolved from the nearest opaque ancestor, so exporting works without a new backend endpoint; Meta and Capture columns are excluded from the render (#1284) by @mostlygeek
    • PR #1287 ui: make markdown code highlighting theme aware in light mode: drives highlight.js token colors from --hljs-* custom properties (with a per-theme --link color and a lighter --muted for Midnight Commander) instead of one globally imported dark-only stylesheet, because code was measu
  4. v2682026-10-28 · 2026-10-28 03:32 UTC
    查看更新说明

    Many users run llama-swap on their gaming machines. The new Pause and Resume functionality unloads and pauses all inference, freeing up system resources for fun! Well llama-swap is fun too but you gotta be weird like me to prefer it over gaming.

    Also a small change to the CUDA 13 container to support Turing architectures, where the actual cut off is.

    • PR #1272 docker/unified: add compute capability 75 to cuda13 amd64 build: adds sm 75 to the default CMAKE_CUDA_ARCHITECTURES for the amd64 unified-cuda13 image, because it only compiled for sm 80 and up so Turing GPUs (Quadro T1000, RTX 20xx, GTX 16xx), which CUDA 13 still supports, failed at runtime with "no kernel image is available for execution on the device"; arm64 is unchanged (#1239) by @mostlygeek
    • 6c855da README: add turing architecture notes: lists Turing GPUs (RTX 20xx, GTX 16xx, Quadro T-series) as supported by the unified-cuda13 image by @mostlygeek
    • PR #1273 server: add pause/resume inference: adds /api/models/pause and /api/models/resume endpoints and UI controls that unload all local models and reject new requests until resumed, so system resources can be freed while llama-swap keeps running (#1268) by @mostlygeek
  5. v2672026-10-26 · 2026-10-26 04:52 UTC
    查看更新说明

    This is huge release with @JaredHatfield contributing a new capacity based router!

    Rather than defining which models fit with other models, the capacity router allows declaring pools of resources and how much of each resource a model needs. The new router will automatically evict models to free up enough capacity to load the new model. For use cases that have a big combinations of models that can run concurrently, the new router can eliminate a lot of manual configuration work.

    The other big feature is the Help Agent in the UI can now search llama-swap's source code as well as its knowledge base. Every release of llama-swap includes the source code it was built from (tests excluded). This is handy for answering questions about how llama-swap actually works and a knowledge base article does not exist. One step closer to the singularity!

    If you want to try out the new router ask the Help Agent to generate a configuration example using your existing configuration. Did you know, it can do that!? :)

    • PR #1242 router: add capacity-based model eviction: adds a capacity router where user-defined pools bound which models can be resident together and evict_cost picks what to unload when a model no longer fits, replacing the need to hand-maintain every valid combination in the matrix on systems with lots of unified memory (#1004) by @JaredHatfield
    • PR #1258 docs/kb: add guides/tools for the cmd/ programs: adds knowledge base articles for wol-proxy, fake-model and vllm-wrapper (and moves the kubeswap guide under guides/tools) so the Help chat can answer questions about the tools in the llama-swap ecosystem, plus a convention for keeping each tool's README and article in sync by @mostlygeek
    • PR #1259 internal/mcptools: add code search to Help agent: gives the Docs agent code__grep, code__read, code__find and code__ls so it can verify knowledge base articles against the code that implements them, adds helpagent.disable to hide Help and stop serving /api/mcp, and raises the agent loop's max iterations from 16 to 96 so the extra tool calls do not end the answer early by @mostlygeek
    • PR #1265 internal/mcptools: embed source for code tools instead of git: embeds the Go and TypeScript source (without tests) in the binary via the new embed_src build tag and reads it through fs.FS, because the runtime git checkout made the code tools fail on installs without the git command line tool; code__status and code__update are removed by @mostlygeek

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    llama-swap header image GitHub Downloads (all assets, all releases) GitHub Actions Workflow Status GitHub Repo stars

    llama-swap

    Run multiple generative AI models on your machine and hot-swap between them on demand. llama-swap works with any OpenAI and Anthropic API compatible server and is used by thousands of people to power their local AI workflows.

    Built in Go for performance and simplicity, llama-swap has zero dependencies and is incredibly easy to set up. Get started in minutes - just one binary and one configuration file.

    [!TIP] Got questions about configuring llama-swap? Try out the Chat agent on llama-swap.ai. It runs entirely in your browser and is powered by LFM3-1.7B fine tuned on the docs.

    Features:

    • ✅ Easy to deploy and configure: one binary, one configuration file. no external dependencies
    • ✅ On-demand model switching for many local AI servers (llama.cpp + forks, vllm, stable-diffusion.cpp, audio.cpp, ComfyUI, etc.)
      • future proof, upgrade your inference servers at any time.
    • ✅ OpenAI API supported endpoints:
      • v1/completions
      • v1/chat/completions
      • v1/responses
      • v1/embeddings
      • v1/models - list available models
      • v1/audio/speech (#36)
      • v1/audio/transcriptions (docs)
      • v1/audio/voices
      • v1/realtime - websocket, model from the ?model={model_id} query parameter or the first session.update event
      • v1/images/generations
      • v1/images/edits
    • ✅ Anthropic API supported endpoints:
      • v1/messages
      • v1/messages/count_tokens
    • ✅ llama-server (llama.cpp) supported endpoints
      • v1/rerank, v1/reranking, /rerank
      • /infill - for code infilling
      • /completion - for completion endpoint
      • /models - list available models. same behavior as v1/models
      • /props - requires ?model={model_id} query parameter to be provided. The autoload parameter is not supported and will be ignored.
    • ✅ SDAPI via stable-diffusion.cpp's server
      • /sdapi/v1/txt2img
      • /sdapi/v1/img2img
      • /sdapi/v1/loras - requires model in request body to fetch the correct loras
    • ✅ audio.cpp supported extra endpoints
      • /audioapi/v1/tasks/run
    • ✅ /audiocpp/ - audio.cpp UI endpoint, served by the audiocpp_auto model (#1221)
    • ✅ /comfyui/ - ComfyUI custom endpoint (#1001) for more reliable swapping
    • ✅ llama-swap API
      • /ui - web UI
      • /upstream/:model_id - direct access to upstream server (demo)
      • /running - list currently running models (#61)
      • POST /api/models/unload - manually unload all running models (#58)
      • POST /api/models/unload/:model_id - unload a specific model
      • POST /api/models/pause - unload all models and reject inference requests until resumed (#1268)
      • POST /api/models/resume - accept inference requests again
      • GET /api/profiles - list configured profiles and the active selection
      • PUT /api/profiles/active - activate a profile or select none
      • /logs - remote log monitoring
        • GET /logs returns buffered plain text logs.
          • If Accept: text/html is sent, /logs redirects to /ui/.
        • GET /logs/stream keeps the connection open for live log streaming.
          • Stream endpoints send buffered history first by default; add ?no-history to stream only new lines.
        • GET /logs/stream/proxy streams proxy logs only.
        • GET /logs/stream/upstream streams upstream process logs only.
        • GET /logs/stream/http streams the HTTP access log only.
        • GET /logs/stream/{model_id} streams logs for one model (including IDs with slashes, like author/model).
      • /health - just returns "OK"
      • /metrics - system and GPU metrics for prometheus
    • ✅ API Key support - define keys to restrict access to API endpoints
    • ✅ Customization
      • Switch model ID routing at runtime with profiles
      • Run concurrent models with a custom DSL swap matrix (#643)
      • Automatic unloading of models after timeout by setting a ttl
      • Docker and Podman support using cmd and cmdStop together
      • Preload models on startup with hooks (#235)
      • Apply filters to requests to control inference with stripParams, setParams and setParamsByID

    Web UI

    llama-swap includes a real time web interface with a playground for testing out all sorts of local models:

    View detailed token metrics:

    Inspect request and responses:

    Manually load and unload models:

    Real time log streaming:

    Installation

    llama-swap can be installed in multiple ways

    1. Docker
    2. Homebrew (macOS and Linux)
    3. MacPorts (macOS)
    4. WinGet
    5. From release binaries
    6. From source

    Docker Install (download images)

    Two types of container images are built nightly for llama-swap:

    1. A unified container with llama-server, ik-llama-server, stable-diffusion.cpp, whisper.cpp, audio.cpp and llama-swap all built from source. Available for CUDA 12, CUDA 13 and Vulkan. This one is recommended for use.
    2. A legacy image, which is llama.cpp's own llama-server container with llama-swap copied in. It carries only what that base image ships, so no image generation, speech or ik-llama-server.
    Unified container (Recommended)

    There are three unified images. Pick the one that matches your GPU:

    tagplatformsGPUs
    unified-cuda13amd64, arm64NVIDIA Turing through Blackwell: RTX 20xx, GTX 16xx, Quadro T-series, A100, RTX 30xx/40xx/50xx, H100, RTX PRO, and GB10 on DGX Spark. Built with CUDA 13.
    unified-cudaamd64NVIDIA Pascal through Ada: P40, P100, GTX 10xx, RTX 20xx/30xx/40xx. Built with CUDA 12, for cards CUDA 13 dropped.
    unified-vulkanamd64AMD and other Vulkan capable GPUs.

    unified-cuda13 is a multi-arch tag, so docker pull picks the right image for the host — including the aarch64 one a DGX Spark needs.

    $ docker pull ghcr.io/mostlygeek/llama-swap:unified-cuda13
    
    # run with a custom configuration and models directory
    $ docker run -it --rm --runtime nvidia -p 9292:8080 \
     -v /path/to/models:/models \
     -v /path/to/custom/config.yaml:/etc/llama-swap/config/config.yaml \
     ghcr.io/mostlygeek/llama-swap:unified-cuda13
    
    Configuring startup with environment variables

    The unified images can be configured with LLAMA_SWAP_* environment variables instead of command line flags, which is usually easier in a compose file or a Kubernetes manifest. Each one maps to a llama-swap flag:

    variableflagdefault in the image
    LLAMA_SWAP_CONFIG-config/etc/llama-swap/config/config.yaml
    LLAMA_SWAP_CONFIG_DIR-config-dir—
    LLAMA_SWAP_LISTEN-listen0.0.0.0:8080
    LLAMA_SWAP_TLS_CERT_FILE-tls-cert-file—
    LLAMA_SWAP_TLS_KEY_FILE-tls-key-file—
    LLAMA_SWAP_LISTEN_TAILCAT-listen-tailcat—
    LLAMA_SWAP_WATCH_CONFIG-watch-configtrue
    # configure startup with environment variables instead of flags
    $ docker run -it --rm --runtime nvidia -p 9292:8080 \
     -v /path/to/models:/models \
     -e LLAMA_SWAP_CONFIG=/models/llama-swap.yaml \
     -e LLAMA_SWAP_LISTEN=0.0.0.0:8080 \
     -e LLAMA_SWAP_WATCH_CONFIG=false \
     ghcr.io/mostlygeek/llama-swap:unified-cuda13
    
    services:
      llama-swap:
        image: ghcr.io/mostlygeek/llama-swap:unified-cuda13
        ports:
          - "9292:8080"
        volumes:
          - /path/to/models:/models
        environment:
          LLAMA_SWAP_CONFIG: /models/llama-swap.yaml
          LLAMA_SWAP_LISTEN: 0.0.0.0:8080
          LLAMA_SWAP_WATCH_CONFIG: "false"
    

    Keep LLAMA_SWAP_LISTEN on 0.0.0.0 whenever you publish a port. A container that binds its own loopback is not reachable through -p, so localhost:8080 there gives connection refused. Bind loopback only when the container shares the host's network, where it usefully limits llama-swap to the host itself:

    # reachable from the host only, not from the network
    $ docker run -it --rm --runtime nvidia --network host \
     -v /path/to/models:/models \
     -e LLAMA_SWAP_LISTEN=localhost:8080 \
     ghcr.io/mostlygeek/llama-swap:unified-cuda13
    

    An unset or empty variable contributes nothing and leaves llama-swap's own default. Booleans accept true/false, 1/0, yes/no or on/off in any case; anything else stops the container rather than being read as "off". -version is deliberately not mapped — use docker run <image> -version.

    Passing flags to the container still works and behaves exactly as it always has: arguments replace every default rather than adding to the variables above.

    # unchanged: runs `llama-swap -config /models/my.yaml`, nothing else added
    $ docker run ghcr.io/mostlygeek/llama-swap:unified-cuda13 -config /models/my.yaml
    

    See docker/unified/README.md for the details.

    Legacy container

    This image is llama.cpp's own llama-server container (ghcr.io/ggml-org/llama.cpp) with the llama-swap binary copied into it. It tracks llama.cpp's nightly server images closely, which is its only real advantage.

    Prefer the unified container. The legacy image inherits whatever the llama-server base ships and nothing else, so it has no stable-diffusion.cpp, whisper.cpp, audio.cpp or ik-llama-server, and no LLAMA_SWAP_* environment variable support. Use it only if staying on llama.cpp's exact server image matters to you.

    $ docker pull ghcr.io/mostlygeek/llama-swap:cuda
    
    # run with a custom configuration and models directory
    $ docker run -it --rm --runtime nvidia -p 9292:8080 \
     -v /path/to/models:/models \
     -v /path/to/custom/config.yaml:/app/config.yaml \
     ghcr.io/mostlygeek/llama-swap:cuda
    
    # pull latest images per platform
    docker pull ghcr.io/mostlygeek/llama-swap:cpu
    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
    
    # tagged llama-swap, platform and llama-server version images
    docker pull ghcr.io/mostlygeek/llama-swap:v166-cuda-b6795
    
    # non-root cuda
    docker pull ghcr.io/mostlygeek/llama-swap:cuda-non-root
    
    

    Homebrew Install (macOS/Linux)

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

    MacPorts (macOS)

    [!NOTE] Maintained by MacPorts community - llama-swap port. It is not an official part of llama-swap.

    sudo port install llama-swap
    llama-swap --config path/to/config.yaml --listen localhost:8080
    

    WinGet Install (Windows)

    [!NOTE] WinGet is maintained by community contributor Dvd-Znf (#327). It is not an official part of llama-swap.

    # install
    C:\> winget install llama-swap
    
    # upgrade
    C:\> winget upgrade llama-swap
    

    Pre-built Binaries

    Binaries are available on the release page for Linux, Mac, Windows and FreeBSD.

    Building from source

    1. Building requires Go and Node.js (for UI).
    2. git clone https://github.com/mostlygeek/llama-swap.git
    3. make clean then make to build a binary for the platform you are building on
      • make all builds macOS (arm64), Linux (arm64 + amd64), Windows (amd64) and FreeBSD (amd64) plus the test responder
      • make mac, make linux, make windows or make freebsd builds one OS, make darwin-arm64, make linux-amd64, make windows-amd64, ... builds one architecture
      • cross compile a single binary with make GOOS=linux GOARCH=arm64 native
      • Intel Mac binaries are not built here, get them from the release page
    4. look in the build/ subdirectory for the llama-swap binary

    Configuration

    # minimum viable config.yaml
    
    models:
      model1:
        cmd: llama-server --port ${PORT} --model /path/to/model.gguf
    

    That's all you need to get started:

    1. models - holds all model configurations
    2. model1 - the ID used in API calls
    3. cmd - the command to run to start the server.
    4. ${PORT} - an automatically assigned port number

    Almost all configuration settings are optional and can be added one step at a time:

    • Advanced features
      • matrix to run concurrent models with a custom swap logic DSL
      • hooks to run things on startup
      • macros reusable snippets
    • Model customization
      • ttl to automatically unload models
      • unloadTimeout to tune graceful unloads (manual, API and ttl expiry)
      • aliases to use familiar model names (e.g., "gpt-4o-mini")
      • env to pass custom environment variables to inference servers
      • cmdStop gracefully stop Docker/Podman containers
      • useModelName to override model names sent to upstream servers
      • ${PORT} automatic port variables for dynamic port assignment
      • filters rewrite parts of requests before sending to the upstream server

    See the configuration overview to get started, and the knowledge base for focused guides on the features people ask about most.

    You can also just ask. The Help page (in the sidebar) is an agent that calls llama-swap's own documentation tools and answers questions about your configuration using the real text of config.example.yaml and the knowledge base, running entirely on a local model. Pick a tool-capable model on the Help page and ask away — see Writing the cmd for a model if the model answers without calling anything (older llama-server builds need --jinja added explicitly).

    Those same tools are served as an MCP endpoint at /api/mcp, so any MCP client can ask about your configuration too. See Connecting an MCP client.

    How does llama-swap work?

    When a request is made to an OpenAI compatible endpoint, llama-swap will extract the model value and load the appropriate server configuration to serve it. If the wrong upstream server is running, it will be replaced with the correct one. This is where the "swap" part comes in. The upstream server is automatically swapped to handle the request correctly.

    In the most basic configuration llama-swap handles one model at a time. For more advanced use cases, using a matrix allows multiple models to be loaded at the same time. You have complete control over how your system resources are used.

    Reverse Proxy Configuration (nginx)

    If you deploy llama-swap behind nginx, disable response buffering for streaming endpoints. By default, nginx buffers responses which breaks Server‑Sent Events (SSE) and streaming chat completion. (#236)

    Recommended nginx configuration snippets:

    # SSE for UI events and logs (also covers /api/events/logs)
    location /api/events {
        proxy_pass http://your-llama-swap-backend;
        proxy_buffering off;
        proxy_cache off;
    }
    
    # Streaming chat completions (stream=true)
    location /v1/chat/completions {
        proxy_pass http://your-llama-swap-backend;
        proxy_buffering off;
        proxy_cache off;
    }
    

    As a safeguard, llama-swap also sets X-Accel-Buffering: no on SSE responses. However, explicitly disabling proxy_buffering at your reverse proxy is still recommended for reliable streaming behavior.

    Monitoring Logs on the CLI

    # sends up to the last 10KB of logs
    $ curl http://host/logs
    
    # streams combined logs
    curl -Ns http://host/logs/stream
    
    # stream llama-swap's proxy status logs
    curl -Ns http://host/logs/stream/proxy
    
    # stream logs from upstream processes that llama-swap loads
    curl -Ns http://host/logs/stream/upstream
    
    # stream the HTTP access log, one line per request
    curl -Ns http://host/logs/stream/http
    
    # stream logs only from a specific model
    curl -Ns http://host/logs/stream/{model_id}
    
    # stream and filter logs with linux pipes
    curl -Ns http://host/logs/stream | grep 'eval time'
    
    # appending ?no-history will disable sending buffered history first
    curl -Ns 'http://host/logs/stream?no-history'
    

    Do I need to use llama.cpp's server (llama-server)?

    Any OpenAI compatible server would work. llama-swap was originally designed for llama-server and it is the best supported.

    For Python based inference servers like vllm or tabbyAPI it is recommended to run them via podman or docker. This provides clean environment isolation as well as responding correctly to SIGTERM signals for proper shutdown.