Inference Server

Deploy fine-tuned models as an OpenAI-compatible API server.

Transformers Backend

bash
pip install "soup-cli[serve]"
soup serve --model ./output --port 8000

Simple HTTP API using HuggingFace Transformers. Good for testing and low-traffic use.

vLLM Backend (2-4x Faster)

Install [serve-fast] in a different environment from [train]. Their resolutions are genuinely incompatible today: pip install vllm into a training environment silently downgrades torch and pushes transformers past the <5.0.0 cap Soup's own metadata declares, producing an environment Soup calls unsupported with no warning at any point. Since v0.73.3, soup env check catches that after the fact, exit 3, without needing a lock file. Not creating it is cheaper.

bash
pip install "soup-cli[serve-fast]"
soup serve --model ./output --backend vllm

# Multi-GPU with tensor parallelism
soup serve --model ./output --backend vllm --tensor-parallel 2

# Control GPU memory usage
soup serve --model ./output --backend vllm --gpu-memory 0.8

Recommended for production. Uses PagedAttention for high throughput.

KV-cache type

The KV cache is usually the second-largest thing in VRAM while serving, after the weights, and it grows with context length rather than with model size.

bash
soup serve --model ./output --kv-cache-type bf16   # or f16, q8_0, fp8
  • bf16 and f16 set the cache dtype and need no extra dependency.
  • q8_0 is 8-bit quantized and needs hqq or optimum-quanto. Without one the command exits 2 with the install hint rather than falling back quietly.
  • fp8 is Hopper-only and rejected below SM 9.0.

Transformers backend only. Routing this flag through vLLM and SGLang is still open upstream, so do not assume it applies when you switch backend.

SGLang Backend

bash
pip install "soup-cli[sglang]"
soup serve --model ./output --backend sglang

# Multi-GPU
soup serve --model ./output --backend sglang --tensor-parallel 2

Alternative high-throughput backend with RadixAttention.

Speculative decoding

bash
# Transformers backend
soup serve --model ./output --speculative-decoding small-draft-model --num-speculative-tokens 5

# vLLM backend
soup serve --model ./output --backend vllm --speculative-decoding small-draft-model

A smaller draft model proposes tokens the target verifies in one pass, keeping the target's exact output. Whether that is actually faster depends on the pair, so measure it rather than assume: soup draft measure reports the real acceptance rate and plain-vs-assisted throughput, and on the pair we validated it came out at 0.55 to 0.64x, a net slowdown.

Multi-Adapter Serving (v0.22.0+)

Serve multiple LoRA adapters on a single base model:

bash
soup serve --model ./base --adapters chat=./adapters/chat --adapters code=./adapters/code

Switch adapters per request via the model field:

json
{"model": "chat", "messages": [{"role": "user", "content": "Hello!"}]}

API Endpoints

All backends expose the same OpenAI-compatible API:

  • POST /v1/chat/completions — chat completions (streaming supported)
  • GET /v1/models — list available models
  • GET /health — health check
bash
curl http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "output",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Compatible with OpenAI SDK:

python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="unused")
response = client.chat.completions.create(
    model="output",
    messages=[{"role": "user", "content": "Hello!"}],
)

Note: max_tokens is capped at 16,384 per request. Error details are never exposed in HTTP responses.

Soup is free and Apache-2.0. If it saved you a training run, starring the repo costs nothing and helps most. You can also fund the GPU time behind the work a 4 GB laptop cannot reach.