Swap Laboratories is a fork of llama-swap focused on operating recipe-based inference clusters with a practical web control plane.
Current backend support in this fork is limited to:
vLLM(spark-vllm-docker)llama.cpp(spark-llama-cpp)
SGLang and TRT-LLM are planned for a later phase.
Upstream project: mostlygeek/llama-swap
This repository keeps the core model-swap proxy behavior and adds an operations layer tailored for multi-node recipe workflows:
- Backend selector in UI (
Backendpage) with persisted override and backend discovery fromswap-laboratories/backend/*(default active backend:~/swap-laboratories/backend/spark-vllm-docker). - Recipe Manager in UI (
Modelspage) to create/update/delete managed models from backend recipes. - Cluster diagnostics page (
Cluster) using backendautodiscover.sh+ SSH checks. - YAML Config Editor (
Editor) with CodeMirror syntax highlighting + validation on save. - llama-benchy integration in UI and API, including intelligence plugins.
- Extra backend actions from UI:
- Git sync (
git_pull,git_pull_rebase) - HF model download (
download_hf_modelviahf-download.sh) - vLLM builds (
build_vllm,build_mxfp4,build_vllm_12_0f) - NVIDIA image management (
pull_*_image,update_*_image) for current vLLM workflows - llama.cpp image build (
build_llamacpp)
- Git sync (
- Home-safe path rendering in UI (
~instead of hardcoded absolute home path in labels).
- OpenAI-compatible request proxy with model-based routing and hot swapping.
- Optional model groups for exclusive/swap behavior.
- Per-model lifecycle (
load,unload,ttl,cmdStop, health checks). - Unified activity/log stream in the UI via SSE (
/api/events).
- Go
1.24+ - Node.js + npm (for Svelte UI build)
- Linux environment recommended for cluster/backend operations
- Docker and SSH access for recipe backends (depends on your backend repo)
git clone https://github.com/vedcsolution/llama-swap.git
cd llama-swap
# Build UI assets
make ui
# Build binary
go build -o build/llama-swap .
# Start
./build/llama-swap --config ./config.yaml --watch-config --listen 0.0.0.0:8080Then open:
- UI:
http://127.0.0.1:8080/ui - API health:
http://127.0.0.1:8080/health
Scope note: this workflow currently targets vLLM and llama.cpp backends only.
Use the UI Backend tab or env var:
export LLAMA_SWAP_RECIPES_BACKEND_DIR="$HOME/swap-laboratories/backend/spark-vllm-docker"Backend selection precedence is:
- persisted override (
LLAMA_SWAP_RECIPES_BACKEND_OVERRIDE_FILE) LLAMA_SWAP_RECIPES_BACKEND_DIR- default
~/swap-laboratories/backend/spark-vllm-docker
A valid backend directory must contain:
run-recipe.shrecipes/
Use Models -> Recipe Manager to generate model entries in config.yaml.
Managed entries are written with metadata under:
metadata.recipe_ui.*
When saving from Recipe Manager, this fork also ensures macros required for portability:
user_homespark_rootrecipe_runnerllama_root
- Per-model load/unload from
Modelspage. Stop Clustertriggers immediate local unload + backendlaunch-cluster.sh stop.
Playground: chat/image/speech/transcription client against current API.Models: model states, load/unload, Recipe Manager, Benchy.Activity: request/token activity history.Logs: proxy + upstream logs.Cluster: autodiscovery + SSH/port 22 health matrix.Backend: backend selection + backend actions.Editor: liveconfig.yamlcode editor with validation.
This fork exposes benchy in UI and API:
POST /api/benchyGET /api/benchy/:idPOST /api/benchy/:id/cancel
Supported options include:
tokenizer,baseUrl,pp,tg,depth,concurrency,runs,latencyModenoCache,noWarmup,adaptPrompt,enablePrefixCaching,trustRemoteCode- Intelligence mode:
enableIntelligence,intelligencePlugins,allowCodeExec,datasetCacheDir,outputDir,maxConcurrent
Runner resolution order:
LLAMA_BENCHY_CMDuvx --from ... llama-benchyllama-benchy
Intelligence plugin source:
christopherowen/llama-benchy(@intelligence)
POST /api/models/unloadPOST /api/models/unload/:modelPOST /api/cluster/stopGET /api/cluster/statusPOST /api/cluster/dgx/updateGET /api/images/dockerPOST /api/images/docker/updatePOST /api/images/docker/deleteGET /api/config/editorPUT /api/config/editorGET /api/recipes/stateGET /api/recipes/backendPUT /api/recipes/backendGET /api/recipes/containersGET /api/recipes/selected-containerPUT /api/recipes/selected-containerPOST /api/recipes/backend/actionGET /api/recipes/backend/action-statusGET /api/recipes/backend/hf-modelsPUT /api/recipes/backend/hf-models/pathDELETE /api/recipes/backend/hf-modelsPOST /api/recipes/modelsDELETE /api/recipes/models/:idGET /api/recipes/sourcePUT /api/recipes/sourcePOST /api/recipes/source/createPOST /api/benchyGET /api/benchy/:idPOST /api/benchy/:id/cancelGET /api/eventsGET /api/metricsGET /api/versionGET /api/captures/:id
LLAMA_SWAP_RECIPES_BACKEND_DIR: active backend root.LLAMA_SWAP_RECIPES_BACKEND_OVERRIDE_FILE: file used to persist backend override.LLAMA_SWAP_RECIPES_DIR: explicit recipes catalog directory (when set, searched first).LLAMA_SWAP_LOCAL_RECIPES_DIR: extra local recipe directory.LLAMA_SWAP_CLUSTER_AUTODISCOVER_PATH: override autodiscover script path.LLAMA_SWAP_HF_DOWNLOAD_SCRIPT: overridehf-download.shpath used by backend actions.LLAMA_SWAP_HF_HUB_PATH: Hugging Face hub cache base path.LLAMA_SWAP_HF_HUB_PATH_OVERRIDE_FILE: file used to persist HF hub path override.LLAMA_SWAP_CONFIG_PATH: fallback config path if not started with--config.
LLAMA_BENCHY_CMD: explicit benchy runner command.LLAMA_BENCHY_DISABLE: disable benchy API (1/true).LLAMA_BENCHY_OUTPUT_DIR: default output directory.LLAMA_SWAP_BENCHY_PY_SHIM_DIR: optional py shim dir.LLAMA_SWAP_SWEBENCH_TEXT_COMPAT: SWE-bench text compatibility toggle.
- No SSH private keys are stored in this repository.
- Cluster operations use the system
sshclient and your local user credentials/agent. - Secrets should be passed via environment variables and macros (for example
${env.HF_TOKEN},${env.OPENROUTER_API_KEY}). - Avoid committing local
config.yamlvalues that include private hostnames, tokens, or internal topology details.
This fork includes:
scripts/build-vllm-marlin-sm12x.sh
It builds a custom vllm-node-marlin-sm12x image and can optionally copy it to nodes.
Example:
./scripts/build-vllm-marlin-sm12x.sh \
--tag vllm-node-marlin-sm12x \
--nodes "${VLLM_NODES}"By default, it resolves backend path from:
SPARK_VLLM_DOCKER_DIR- fallback:
../spark-vllm-docker
This fork includes starter scripts to harden NVMe-oF initiator connectivity and network tuning without changing current model paths:
scripts/nvmeof-initiator-canary.shscripts/net-tune-canary.shscripts/install-nvmeof-canary-units.sh
Systemd templates:
scripts/systemd/nvmeof-connect@.servicescripts/systemd/net-tune-canary.service
These help apply canary settings (keep-alive, ctrl-loss, reconnect delay, queue size, sysctl snapshot/rollback) and keep reconnect order at boot.
The Cluster UI now also shows a storage baseline matrix (per-node path presence) to highlight potential duplicated local caches and track optimization toward a shared read path.
Related pending plans:
- docs/pending/nvmeof-overlayfs-cache-strategy.md
- docs/pending/prefetch-sidecar-ttft-and-nvmeof-canary.md
Enable allow-code-exec when running EvalPlus / SWE-bench / Terminal-Bench plugins.
Fix permissions on existing cache (no new cache dir required):
sudo chown -R "$USER:$USER" ~/.cache/huggingface/datasetsThis usually comes from local tokenizer/tooling path in benchy subprocess; it does not necessarily mean your serving backend lacks PyTorch.
Set HF_TOKEN to avoid unauthenticated hub limits.
Comes from tokenizer config metadata in some models; verify actual server-side max context and tokenizer behavior for your recipe.
- Build UI only:
make ui - Run tests:
make test - Full proxy tests:
make test-all
Primary config references:
config.example.yamldocs/configuration.md
If you are looking for the original generic project README, see upstream: mostlygeek/llama-swap