From 9fc0431531ceedd9b3dd68cda399359018ea79e1 Mon Sep 17 00:00:00 2001 From: Benson Wong Date: Sun, 19 Oct 2025 14:53:13 -0700 Subject: [PATCH] Clean up and Documentation (#347) [skip ci] * cmd,misc: move misc binaries to cmd/ * docs: add docs and move examples/ there * misc: remove unused misc/assets dir * docs: add configuration.md * update README with better structure Updates: #334 --- Makefile | 8 +- README.md | 291 +++++++------ .../misc}/benchmark-chatcompletion/main.go | 0 {misc => cmd/misc}/process-cmd-test/main.go | 0 {misc => cmd/misc}/test-rerank/README.md | 0 .../misc}/test-rerank/reranker-test.json | 0 .../simple-responder/simple-responder.go | 0 docs/configuration.md | 386 ++++++++++++++++++ {examples => docs/examples}/README.md | 0 .../examples}/aider-qwq-coder/README.md | 0 .../aider.model.settings.dualgpu.yml | 0 .../aider-qwq-coder/aider.model.settings.yml | 0 .../examples}/aider-qwq-coder/llama-swap.yaml | 0 .../examples}/benchmark-snakegame/README.md | 0 .../benchmark-snakegame/run-benchmark.sh | 0 .../restart-on-config-change/README.md | 0 .../examples}/speculative-decoding/README.md | 0 misc/assets/favicon-raw.png | Bin 52428 -> 0 bytes 18 files changed, 529 insertions(+), 156 deletions(-) rename {misc => cmd/misc}/benchmark-chatcompletion/main.go (100%) rename {misc => cmd/misc}/process-cmd-test/main.go (100%) rename {misc => cmd/misc}/test-rerank/README.md (100%) rename {misc => cmd/misc}/test-rerank/reranker-test.json (100%) rename {misc => cmd}/simple-responder/simple-responder.go (100%) create mode 100644 docs/configuration.md rename {examples => docs/examples}/README.md (100%) rename {examples => docs/examples}/aider-qwq-coder/README.md (100%) rename {examples => docs/examples}/aider-qwq-coder/aider.model.settings.dualgpu.yml (100%) rename {examples => docs/examples}/aider-qwq-coder/aider.model.settings.yml (100%) rename {examples => docs/examples}/aider-qwq-coder/llama-swap.yaml (100%) rename {examples => docs/examples}/benchmark-snakegame/README.md (100%) rename {examples => docs/examples}/benchmark-snakegame/run-benchmark.sh (100%) rename {examples => docs/examples}/restart-on-config-change/README.md (100%) rename {examples => docs/examples}/speculative-decoding/README.md (100%) delete mode 100644 misc/assets/favicon-raw.png diff --git a/Makefile b/Makefile index 0c00b0a..00dc1d0 100644 --- a/Makefile +++ b/Makefile @@ -61,12 +61,12 @@ windows: ui # for testing proxy.Process simple-responder: @echo "Building simple responder" - GOOS=darwin GOARCH=arm64 go build -o $(BUILD_DIR)/simple-responder_darwin_arm64 misc/simple-responder/simple-responder.go - GOOS=linux GOARCH=amd64 go build -o $(BUILD_DIR)/simple-responder_linux_amd64 misc/simple-responder/simple-responder.go + GOOS=darwin GOARCH=arm64 go build -o $(BUILD_DIR)/simple-responder_darwin_arm64 cmd/simple-responder/simple-responder.go + GOOS=linux GOARCH=amd64 go build -o $(BUILD_DIR)/simple-responder_linux_amd64 cmd/simple-responder/simple-responder.go simple-responder-windows: @echo "Building simple responder for windows" - GOOS=windows GOARCH=amd64 go build -o $(BUILD_DIR)/simple-responder.exe misc/simple-responder/simple-responder.go + GOOS=windows GOARCH=amd64 go build -o $(BUILD_DIR)/simple-responder.exe cmd/simple-responder/simple-responder.go # Ensure build directory exists $(BUILD_DIR): @@ -87,4 +87,4 @@ release: git tag "$$new_tag"; # Phony targets -.PHONY: all clean ui mac linux windows simple-responder test test-all test-dev +.PHONY: all clean ui mac linux windows simple-responder simple-responder-windows test test-all test-dev diff --git a/README.md b/README.md index 8ea52ca..fc2ea9c 100644 --- a/README.md +++ b/README.md @@ -5,74 +5,165 @@ # llama-swap -llama-swap is a light weight, transparent proxy server that provides automatic model swapping to llama.cpp's server. +Run multiple LLM models on your machine and hot-swap between them as needed. llama-swap works with any OpenAI API-compatible server, giving you the flexibility to switch models without restarting your applications. -Written in golang, it is very easy to install (single binary with no dependencies) and configure (single yaml file). To get started, download a pre-built binary, a provided docker images or Homebrew. +Built in Go for performance and simplicity, llama-swap has zero dependencies and is incredibly easy to set up. Get started in minutes - just install and configure. ## Features: -- ✅ Easy to deploy: single binary with no dependencies -- ✅ Easy to config: single yaml file +- ✅ Easy to deploy and configure: one binary, one configuration file. no external dependencies - ✅ On-demand model switching +- ✅ Use any local OpenAI compatible server (llama.cpp, vllm, tabbyAPI, etc) + - future proof, upgrade your inference servers at any time. - ✅ OpenAI API supported endpoints: - `v1/completions` - `v1/chat/completions` - `v1/embeddings` - `v1/audio/speech` ([#36](https://github.com/mostlygeek/llama-swap/issues/36)) - `v1/audio/transcriptions` ([docs](https://github.com/mostlygeek/llama-swap/issues/41#issuecomment-2722637867)) -- ✅ llama-server (llama.cpp) supported endpoints: +- ✅ llama-server (llama.cpp) supported endpoints - `v1/rerank`, `v1/reranking`, `/rerank` - `/infill` - for code infilling - `/completion` - for completion endpoint -- ✅ llama-swap custom API endpoints +- ✅ llama-swap API - `/ui` - web UI - - `/log` - remote log monitoring - - `/upstream/:model_id` - direct access to upstream HTTP server ([demo](https://github.com/mostlygeek/llama-swap/pull/31)) - - `/unload` - manually unload running models ([#58](https://github.com/mostlygeek/llama-swap/issues/58)) + - `/upstream/:model_id` - direct access to upstream server ([demo](https://github.com/mostlygeek/llama-swap/pull/31)) + - `/models/unload` - manually unload running models ([#58](https://github.com/mostlygeek/llama-swap/issues/58)) - `/running` - list currently running models ([#61](https://github.com/mostlygeek/llama-swap/issues/61)) + - `/log` - remote log monitoring - `/health` - just returns "OK" -- ✅ Run multiple models at once with `Groups` ([#107](https://github.com/mostlygeek/llama-swap/issues/107)) -- ✅ Automatic unloading of models after timeout by setting a `ttl` -- ✅ Use any local OpenAI compatible server (llama.cpp, vllm, tabbyAPI, etc) -- ✅ Reliable Docker and Podman support using `cmd` and `cmdStop` together -- ✅ Full control over server settings per model -- ✅ Preload models on startup with `hooks` ([#235](https://github.com/mostlygeek/llama-swap/pull/235)) +- ✅ Customizable + - Run multiple models at once with `Groups` ([#107](https://github.com/mostlygeek/llama-swap/issues/107)) + - Automatic unloading of models after timeout by setting a `ttl` + - Reliable Docker and Podman support using `cmd` and `cmdStop` together + - Preload models on startup with `hooks` ([#235](https://github.com/mostlygeek/llama-swap/pull/235)) + +### Web UI + +llama-swap includes a real time web interface for monitoring logs and controlling models: + +image + +The Activity Page shows recent requests: + +image + +## Installation + +llama-swap can be installed in multiple ways + +1. Docker +2. Homebrew (OSX and Linux) +3. WinGet +4. From release binaries +5. From source + +### Docker Install ([download images](https://github.com/mostlygeek/llama-swap/pkgs/container/llama-swap)) + +Nightly container images with llama-swap and llama-server are built for multiple platforms (cuda, vulkan, intel, etc). + +```shell +$ 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 +``` + +
+ +more examples + + +```shell +# 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 + +``` + +
+ +### Homebrew Install (macOS/Linux) + +```shell +brew tap mostlygeek/llama-swap +brew 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](https://github.com/Dvd-Znf) ([#327](https://github.com/mostlygeek/llama-swap/issues/327)). It is not an official part of llama-swap. + +```shell +# install +C:\> winget install llama-swap + +# upgrade +C:\> winget upgrade llama-swap +``` + +### Pre-built Binaries + +Binaries are available on the [release](https://github.com/mostlygeek/llama-swap/releases) page for Linux, Mac, Windows and FreeBSD. + +### Building from source + +1. Building requires Go and Node.js (for UI). +1. `git clone https://github.com/mostlygeek/llama-swap.git` +1. `make clean all` +1. look in the `build/` subdirectory for the llama-swap binary + +## Configuration + +```yaml +# 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 + - `groups` to run multiple models at once + - `hooks` to run things on startup + - `macros` reusable snippets +- Model customization + - `ttl` to automatically unload models + - `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 documentation](docs/configuration.md) for all options. ## 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 the correct one to serve the request. +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, the `groups` feature allows multiple models to be loaded at the same time. You have complete control over how your system resources are used. -## config.yaml - -llama-swap is managed entirely through a yaml configuration file. - -It can be very minimal to start: - -```yaml -models: - "qwen2.5": - cmd: | - /path/to/llama-server - -hf bartowski/Qwen2.5-0.5B-Instruct-GGUF:Q4_K_M - --port ${PORT} -``` - -However, there are many more capabilities that llama-swap supports: - -- `groups` to run multiple models at once -- `ttl` to automatically unload models -- `macros` for reusable snippets -- `aliases` to use familiar model names (e.g., "gpt-4o-mini") -- `env` to pass custom environment variables to inference servers -- `cmdStop` for to gracefully stop Docker/Podman containers -- `useModelName` to override model names sent to upstream servers -- `healthCheckTimeout` to control model startup wait times -- `${PORT}` automatic port variables for dynamic port assignment - -See the [configuration documentation](https://github.com/mostlygeek/llama-swap/wiki/Configuration) in the wiki all options and examples. - ## 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](https://github.com/mostlygeek/llama-swap/issues/236)) @@ -97,111 +188,7 @@ location /v1/chat/completions { 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. -## Web UI - -llama-swap includes a real time web interface for monitoring logs and models: - -image - -The Activity Page shows recent requests: - -image - -## Installation - -llama-swap can be installed in multiple ways - -1. Docker -2. Homebrew (OSX and Linux) -3. From release binaries -4. From source - -### Docker Install ([download images](https://github.com/mostlygeek/llama-swap/pkgs/container/llama-swap)) - -Docker images with llama-swap and llama-server are built nightly. - -```shell -# use CPU inference comes with the example config above -$ docker run -it --rm -p 9292:8080 ghcr.io/mostlygeek/llama-swap:cpu - -# qwen2.5 0.5B -$ curl -s http://localhost:9292/v1/chat/completions \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer no-key" \ - -d '{"model":"qwen2.5","messages": [{"role": "user","content": "tell me a joke"}]}' | \ - jq -r '.choices[0].message.content' - -# SmolLM2 135M -$ curl -s http://localhost:9292/v1/chat/completions \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer no-key" \ - -d '{"model":"smollm2","messages": [{"role": "user","content": "tell me a joke"}]}' | \ - jq -r '.choices[0].message.content' -``` - -
-Docker images are built nightly with llama-server for cuda, intel, vulcan and musa. - -They include: - -- `ghcr.io/mostlygeek/llama-swap:cpu` -- `ghcr.io/mostlygeek/llama-swap:cuda` -- `ghcr.io/mostlygeek/llama-swap:intel` -- `ghcr.io/mostlygeek/llama-swap:vulkan` -- ROCm disabled until fixed in llama.cpp container - -Specific versions are also available and are tagged with the llama-swap, architecture and llama.cpp versions. For example: `ghcr.io/mostlygeek/llama-swap:v89-cuda-b4716` - -Beyond the demo you will likely want to run the containers with your downloaded models and custom configuration. - -```shell -$ 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 -``` - -
- -### Homebrew Install (macOS/Linux) - -The latest release of `llama-swap` can be installed via [Homebrew](https://brew.sh). - -```shell -# Set up tap and install formula -brew tap mostlygeek/llama-swap -brew install llama-swap -# Run llama-swap -llama-swap --config path/to/config.yaml --listen localhost:8080 -``` - -This will install the `llama-swap` binary and make it available in your path. See the [configuration documentation](https://github.com/mostlygeek/llama-swap/wiki/Configuration) - -### Pre-built Binaries ([download](https://github.com/mostlygeek/llama-swap/releases)) - -Binaries are available for Linux, Mac, Windows and FreeBSD. These are automatically published and are likely a few hours ahead of the docker releases. The binary install works with any OpenAI compatible server, not just llama-server. - -1. Download a [release](https://github.com/mostlygeek/llama-swap/releases) appropriate for your OS and architecture. -1. Create a configuration file, see the [configuration documentation](https://github.com/mostlygeek/llama-swap/wiki/Configuration). -1. Run the binary with `llama-swap --config path/to/config.yaml --listen localhost:8080`. - Available flags: - - `--config`: Path to the configuration file (default: `config.yaml`). - - `--listen`: Address and port to listen on (default: `:8080`). - - `--version`: Show version information and exit. - - `--watch-config`: Automatically reload the configuration file when it changes. This will wait for in-flight requests to complete then stop all running models (default: `false`). - -### Building from source - -1. Build requires golang and nodejs for the user interface. -1. `git clone https://github.com/mostlygeek/llama-swap.git` -1. `make clean all` -1. Binaries will be in `build/` subdirectory - -## Monitoring Logs - -Open the `http://:/` with your browser to get a web interface with streaming logs. - -CLI access is also supported: +## Monitoring Logs on the CLI ```shell # sends up to the last 10KB of logs @@ -227,11 +214,11 @@ curl -Ns 'http://host/logs/stream?no-history' 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 to shutdown. +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. ## Star History > [!NOTE] -> ⭐️ Star this project to help others discover it! +> ⭐️ Star this project to help others discover it! [![Star History Chart](https://api.star-history.com/svg?repos=mostlygeek/llama-swap&type=Date)](https://www.star-history.com/#mostlygeek/llama-swap&Date) diff --git a/misc/benchmark-chatcompletion/main.go b/cmd/misc/benchmark-chatcompletion/main.go similarity index 100% rename from misc/benchmark-chatcompletion/main.go rename to cmd/misc/benchmark-chatcompletion/main.go diff --git a/misc/process-cmd-test/main.go b/cmd/misc/process-cmd-test/main.go similarity index 100% rename from misc/process-cmd-test/main.go rename to cmd/misc/process-cmd-test/main.go diff --git a/misc/test-rerank/README.md b/cmd/misc/test-rerank/README.md similarity index 100% rename from misc/test-rerank/README.md rename to cmd/misc/test-rerank/README.md diff --git a/misc/test-rerank/reranker-test.json b/cmd/misc/test-rerank/reranker-test.json similarity index 100% rename from misc/test-rerank/reranker-test.json rename to cmd/misc/test-rerank/reranker-test.json diff --git a/misc/simple-responder/simple-responder.go b/cmd/simple-responder/simple-responder.go similarity index 100% rename from misc/simple-responder/simple-responder.go rename to cmd/simple-responder/simple-responder.go diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..c253d40 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,386 @@ +# config.yaml + +llama-swap is designed to be very simple: one binary, one configuration file. + +## minimal viable config + +```yaml +models: + model1: + cmd: llama-server --port ${PORT} --model /path/to/model.gguf +``` + +This is enough to launch `llama-server` to serve `model1`. Of course, llama-swap is about making it possible to serve many models: + +```yaml +models: + model1: + cmd: llama-server --port ${PORT} -m /path/to/model.gguf + model2: + cmd: llama-server --port ${PORT} -m /path/to/another_model.gguf + model3: + cmd: llama-server --port ${PORT} -m /path/to/third_model.gguf +``` + +With this configuration models will be hot swapped and loaded on demand. The special `${PORT}` macro provides a unique port per model. Useful if you want to run multiple models at the same time with the `groups` feature. + +## Advanced control with `cmd` + +llama-swap is also about customizability. You can use any CLI flag available: + +```yaml +models: + model1: + cmd: | # support for multi-line + llama-server --PORT ${PORT} -m /path/to/model.gguf + --ctx-size 8192 + --jinja + --cache-type-k q8_0 + --cache-type-v q8_0 +``` + +## Support for any OpenAI API compatible server + +llama-swap supports any OpenAI API compatible server. If you can run it on the CLI llama-swap will be able to manage it. Even if it's run in Docker or Podman containers. + +```yaml +models: + "Q3-30B-CODER-VLLM": + name: "Qwen3 30B Coder vllm AWQ (Q3-30B-CODER-VLLM)" + # cmdStop provides a reliable way to stop containers + cmdStop: docker stop vllm-coder + cmd: | + docker run --init --rm --name vllm-coder + --runtime=nvidia --gpus '"device=2,3"' + --shm-size=16g + -v /mnt/nvme/vllm-cache:/root/.cache + -v /mnt/ssd-extra/models:/models -p ${PORT}:8000 + vllm/vllm-openai:v0.10.0 + --model "/models/cpatonn/Qwen3-Coder-30B-A3B-Instruct-AWQ" + --served-model-name "Q3-30B-CODER-VLLM" + --enable-expert-parallel + --swap-space 16 + --max-num-seqs 512 + --max-model-len 65536 + --max-seq-len-to-capture 65536 + --gpu-memory-utilization 0.9 + --tensor-parallel-size 2 + --trust-remote-code +``` + +## Many more features.. + +llama-swap supports many more features to customize how you want to manage your environment. + +| Feature | Description | +| --------- | ---------------------------------------------- | +| `ttl` | automatic unloading of models after a timeout | +| `macros` | reusable snippets to use in configurations | +| `groups` | run multiple models at a time | +| `hooks` | event driven functionality | +| `env` | define environment variables per model | +| `aliases` | serve a model with different names | +| `filters` | modify requests before sending to the upstream | +| `...` | And many more tweaks | + +## Full Configuration Example + +> [!NOTE] +> This is a copy of `config.example.yaml`. Always check that for the most up to date examples. + +```yaml +# llama-swap YAML configuration example +# ------------------------------------- +# +# 💡 Tip - Use an LLM with this file! +# ==================================== +# This example configuration is written to be LLM friendly. Try +# copying this file into an LLM and asking it to explain or generate +# sections for you. +# ==================================== + +# Usage notes: +# - Below are all the available configuration options for llama-swap. +# - Settings noted as "required" must be in your configuration file +# - Settings noted as "optional" can be omitted + +# healthCheckTimeout: number of seconds to wait for a model to be ready to serve requests +# - optional, default: 120 +# - minimum value is 15 seconds, anything less will be set to this value +healthCheckTimeout: 500 + +# logLevel: sets the logging value +# - optional, default: info +# - Valid log levels: debug, info, warn, error +logLevel: info + +# metricsMaxInMemory: maximum number of metrics to keep in memory +# - optional, default: 1000 +# - controls how many metrics are stored in memory before older ones are discarded +# - useful for limiting memory usage when processing large volumes of metrics +metricsMaxInMemory: 1000 + +# startPort: sets the starting port number for the automatic ${PORT} macro. +# - optional, default: 5800 +# - the ${PORT} macro can be used in model.cmd and model.proxy settings +# - it is automatically incremented for every model that uses it +startPort: 10001 + +# macros: a dictionary of string substitutions +# - optional, default: empty dictionary +# - macros are reusable snippets +# - used in a model's cmd, cmdStop, proxy, checkEndpoint, filters.stripParams +# - useful for reducing common configuration settings +# - macro names are strings and must be less than 64 characters +# - macro names must match the regex ^[a-zA-Z0-9_-]+$ +# - macro names must not be a reserved name: PORT or MODEL_ID +# - macro values can be numbers, bools, or strings +# - macros can contain other macros, but they must be defined before they are used +macros: + # Example of a multi-line macro + "latest-llama": > + /path/to/llama-server/llama-server-ec9e0301 + --port ${PORT} + + "default_ctx": 4096 + + # Example of macro-in-macro usage. macros can contain other macros + # but they must be previously declared. + "default_args": "--ctx-size ${default_ctx}" + +# models: a dictionary of model configurations +# - required +# - each key is the model's ID, used in API requests +# - model settings have default values that are used if they are not defined here +# - the model's ID is available in the ${MODEL_ID} macro, also available in macros defined above +# - below are examples of the all the settings a model can have +models: + # keys are the model names used in API requests + "llama": + # macros: a dictionary of string substitutions specific to this model + # - optional, default: empty dictionary + # - macros defined here override macros defined in the global macros section + # - model level macros follow the same rules as global macros + macros: + "default_ctx": 16384 + "temp": 0.7 + + # cmd: the command to run to start the inference server. + # - required + # - it is just a string, similar to what you would run on the CLI + # - using `|` allows for comments in the command, these will be parsed out + # - macros can be used within cmd + cmd: | + # ${latest-llama} is a macro that is defined above + ${latest-llama} + --model path/to/llama-8B-Q4_K_M.gguf + --ctx-size ${default_ctx} + --temperature ${temp} + + # name: a display name for the model + # - optional, default: empty string + # - if set, it will be used in the v1/models API response + # - if not set, it will be omitted in the JSON model record + name: "llama 3.1 8B" + + # description: a description for the model + # - optional, default: empty string + # - if set, it will be used in the v1/models API response + # - if not set, it will be omitted in the JSON model record + description: "A small but capable model used for quick testing" + + # env: define an array of environment variables to inject into cmd's environment + # - optional, default: empty array + # - each value is a single string + # - in the format: ENV_NAME=value + env: + - "CUDA_VISIBLE_DEVICES=0,1,2" + + # proxy: the URL where llama-swap routes API requests + # - optional, default: http://localhost:${PORT} + # - if you used ${PORT} in cmd this can be omitted + # - if you use a custom port in cmd this *must* be set + proxy: http://127.0.0.1:8999 + + # aliases: alternative model names that this model configuration is used for + # - optional, default: empty array + # - aliases must be unique globally + # - useful for impersonating a specific model + aliases: + - "gpt-4o-mini" + - "gpt-3.5-turbo" + + # checkEndpoint: URL path to check if the server is ready + # - optional, default: /health + # - endpoint is expected to return an HTTP 200 response + # - all requests wait until the endpoint is ready or fails + # - use "none" to skip endpoint health checking + checkEndpoint: /custom-endpoint + + # ttl: automatically unload the model after ttl seconds + # - optional, default: 0 + # - ttl values must be a value greater than 0 + # - a value of 0 disables automatic unloading of the model + ttl: 60 + + # useModelName: override the model name that is sent to upstream server + # - optional, default: "" + # - useful for when the upstream server expects a specific model name that + # is different from the model's ID + useModelName: "qwen:qwq" + + # filters: a dictionary of filter settings + # - optional, default: empty dictionary + # - only stripParams is currently supported + filters: + # stripParams: a comma separated list of parameters to remove from the request + # - optional, default: "" + # - useful for server side enforcement of sampling parameters + # - the `model` parameter can never be removed + # - can be any JSON key in the request body + # - recommended to stick to sampling parameters + stripParams: "temperature, top_p, top_k" + + # metadata: a dictionary of arbitrary values that are included in /v1/models + # - optional, default: empty dictionary + # - while metadata can contains complex types it is recommended to keep it simple + # - metadata is only passed through in /v1/models responses + metadata: + # port will remain an integer + port: ${PORT} + + # the ${temp} macro will remain a float + temperature: ${temp} + note: "The ${MODEL_ID} is running on port ${PORT} temp=${temp}, context=${default_ctx}" + + a_list: + - 1 + - 1.23 + - "macros are OK in list and dictionary types: ${MODEL_ID}" + + an_obj: + a: "1" + b: 2 + # objects can contain complex types with macro substitution + # becomes: c: [0.7, false, "model: llama"] + c: ["${temp}", false, "model: ${MODEL_ID}"] + + # concurrencyLimit: overrides the allowed number of active parallel requests to a model + # - optional, default: 0 + # - useful for limiting the number of active parallel requests a model can process + # - must be set per model + # - any number greater than 0 will override the internal default value of 10 + # - any requests that exceeds the limit will receive an HTTP 429 Too Many Requests response + # - recommended to be omitted and the default used + concurrencyLimit: 0 + + # Unlisted model example: + "qwen-unlisted": + # unlisted: boolean, true or false + # - optional, default: false + # - unlisted models do not show up in /v1/models api requests + # - can be requested as normal through all apis + unlisted: true + cmd: llama-server --port ${PORT} -m Llama-3.2-1B-Instruct-Q4_K_M.gguf -ngl 0 + + # Docker example: + # container runtimes like Docker and Podman can be used reliably with + # a combination of cmd, cmdStop, and ${MODEL_ID} + "docker-llama": + proxy: "http://127.0.0.1:${PORT}" + cmd: | + docker run --name ${MODEL_ID} + --init --rm -p ${PORT}:8080 -v /mnt/nvme/models:/models + ghcr.io/ggml-org/llama.cpp:server + --model '/models/Qwen2.5-Coder-0.5B-Instruct-Q4_K_M.gguf' + + # cmdStop: command to run to stop the model gracefully + # - optional, default: "" + # - useful for stopping commands managed by another system + # - the upstream's process id is available in the ${PID} macro + # + # When empty, llama-swap has this default behaviour: + # - on POSIX systems: a SIGTERM signal is sent + # - on Windows, calls taskkill to stop the process + # - processes have 5 seconds to shutdown until forceful termination is attempted + cmdStop: docker stop ${MODEL_ID} + +# groups: a dictionary of group settings +# - optional, default: empty dictionary +# - provides advanced controls over model swapping behaviour +# - using groups some models can be kept loaded indefinitely, while others are swapped out +# - model IDs must be defined in the Models section +# - a model can only be a member of one group +# - group behaviour is controlled via the `swap`, `exclusive` and `persistent` fields +# - see issue #109 for details +# +# NOTE: the example below uses model names that are not defined above for demonstration purposes +groups: + # group1 works the same as the default behaviour of llama-swap where only one model is allowed + # to run a time across the whole llama-swap instance + "group1": + # swap: controls the model swapping behaviour in within the group + # - optional, default: true + # - true : only one model is allowed to run at a time + # - false: all models can run together, no swapping + swap: true + + # exclusive: controls how the group affects other groups + # - optional, default: true + # - true: causes all other groups to unload when this group runs a model + # - false: does not affect other groups + exclusive: true + + # members references the models defined above + # required + members: + - "llama" + - "qwen-unlisted" + + # Example: + # - in group2 all models can run at the same time + # - when a different group is loaded it causes all running models in this group to unload + "group2": + swap: false + + # exclusive: false does not unload other groups when a model in group2 is requested + # - the models in group2 will be loaded but will not unload any other groups + exclusive: false + members: + - "docker-llama" + - "modelA" + - "modelB" + + # Example: + # - a persistent group, prevents other groups from unloading it + "forever": + # persistent: prevents over groups from unloading the models in this group + # - optional, default: false + # - does not affect individual model behaviour + persistent: true + + # set swap/exclusive to false to prevent swapping inside the group + # and the unloading of other groups + swap: false + exclusive: false + members: + - "forever-modelA" + - "forever-modelB" + - "forever-modelc" + +# hooks: a dictionary of event triggers and actions +# - optional, default: empty dictionary +# - the only supported hook is on_startup +hooks: + # on_startup: a dictionary of actions to perform on startup + # - optional, default: empty dictionary + # - the only supported action is preload + on_startup: + # preload: a list of model ids to load on startup + # - optional, default: empty list + # - model names must match keys in the models sections + # - when preloading multiple models at once, define a group + # otherwise models will be loaded and swapped out + preload: + - "llama" +``` diff --git a/examples/README.md b/docs/examples/README.md similarity index 100% rename from examples/README.md rename to docs/examples/README.md diff --git a/examples/aider-qwq-coder/README.md b/docs/examples/aider-qwq-coder/README.md similarity index 100% rename from examples/aider-qwq-coder/README.md rename to docs/examples/aider-qwq-coder/README.md diff --git a/examples/aider-qwq-coder/aider.model.settings.dualgpu.yml b/docs/examples/aider-qwq-coder/aider.model.settings.dualgpu.yml similarity index 100% rename from examples/aider-qwq-coder/aider.model.settings.dualgpu.yml rename to docs/examples/aider-qwq-coder/aider.model.settings.dualgpu.yml diff --git a/examples/aider-qwq-coder/aider.model.settings.yml b/docs/examples/aider-qwq-coder/aider.model.settings.yml similarity index 100% rename from examples/aider-qwq-coder/aider.model.settings.yml rename to docs/examples/aider-qwq-coder/aider.model.settings.yml diff --git a/examples/aider-qwq-coder/llama-swap.yaml b/docs/examples/aider-qwq-coder/llama-swap.yaml similarity index 100% rename from examples/aider-qwq-coder/llama-swap.yaml rename to docs/examples/aider-qwq-coder/llama-swap.yaml diff --git a/examples/benchmark-snakegame/README.md b/docs/examples/benchmark-snakegame/README.md similarity index 100% rename from examples/benchmark-snakegame/README.md rename to docs/examples/benchmark-snakegame/README.md diff --git a/examples/benchmark-snakegame/run-benchmark.sh b/docs/examples/benchmark-snakegame/run-benchmark.sh similarity index 100% rename from examples/benchmark-snakegame/run-benchmark.sh rename to docs/examples/benchmark-snakegame/run-benchmark.sh diff --git a/examples/restart-on-config-change/README.md b/docs/examples/restart-on-config-change/README.md similarity index 100% rename from examples/restart-on-config-change/README.md rename to docs/examples/restart-on-config-change/README.md diff --git a/examples/speculative-decoding/README.md b/docs/examples/speculative-decoding/README.md similarity index 100% rename from examples/speculative-decoding/README.md rename to docs/examples/speculative-decoding/README.md diff --git a/misc/assets/favicon-raw.png b/misc/assets/favicon-raw.png deleted file mode 100644 index 191c37cdce94d02f8194f5d0e6653ceb9f6bfd70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52428 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 KMNUMnLSTX)1z)oO