Back to Vllm

vllm-frontend-rs

rust/README.md

0.28.05.0 KB
Original Source

vllm-frontend-rs

This is a Rust drop-in alternative frontend for vLLM. The current goal is to rebuild the northbound serving layer in Rust while still talking to the core Python vLLM engine process(es) via ZMQ over the existing engine boundary.

It should still be considered experimental, and is not feature-complete. We are working to add more functionality from the python front-end.

See https://github.com/Inferact/vllm-frontend-rs for the original commit history before it was moved into the main vllm repo.

Architecture

The component is organized as a Cargo workspace with several crates, layered bottom-up:

text
┌─────────────────────────────────┐
│  vllm-cmd / vllm-rs             │  CLI entrypoint:
│                                 │  Python vLLM frontend subprocess
│                                 │  Rust managed-engine serve mode
│                                 │  Engine-free render mode
├─────────────────────────────────┤
│  vllm-server                    │  OpenAI-compatible HTTP API (axum)
├─────────────────────────────────┤
│  vllm-chat                      │  Chat completions: template rendering,
│                                 │  structured assistant events,
│                                 │  reasoning & tool parsing
├─────────────────────────────────┤
│  vllm-text                      │  Tokenizer & incremental detokenizer
├─────────────────────────────────┤
│  vllm-llm                       │  Thin token-in/token-out facade over
│                                 │  the engine client
├─────────────────────────────────┤
│  vllm-engine-core-client        │  ZMQ transport + MessagePack protocol
│                                 │  for the headless vLLM engine
└─────────────────────────────────┘

vllm-rs integrates into Python vllm as a Rust frontend subprocess. Python owns process startup and launches the Rust API server as a Python-supervised worker, while passing the inherited listening socket and transport addresses into vllm-rs.

For example:

bash
VLLM_USE_RUST_FRONTEND=1 vllm serve Qwen/Qwen3-0.6B

External Engine

vllm-rs serve can be run standalone with --data-parallel-size-local 0 when the Python engines are started elsewhere and this node should run only the Rust frontend. The frontend still uses the global --data-parallel-size to determine how many engines it expects to join the shared handshake.

bash
vllm serve Qwen/Qwen3-0.6B \
  --headless \
  --data-parallel-address 127.0.0.1 \
  --data-parallel-rpc-port 62100 \
  --data-parallel-size 1 \
  --data-parallel-size-local 1

Then start the Rust frontend-only server:

bash
vllm-rs serve Qwen/Qwen3-0.6B \
  --data-parallel-address 127.0.0.1 \
  --data-parallel-rpc-port 62100 \
  --data-parallel-size 1 \
  --data-parallel-size-local 0

To build the vllm-rs in isolation:

bash
# from the local checkout
./build_rust.sh

Engine-free renderer

vllm-rs render serves text-only request preprocessing without starting or connecting to a Python inference engine:

bash
cargo run --manifest-path rust/Cargo.toml -p vllm-cmd --release -- \
  render Qwen/Qwen3-32B \
  --host 127.0.0.1 --max-model-len 32768

It exposes /v1/chat/completions/render and /v1/completions/render. Only tokenizer and model configuration files are loaded; model weights, PyTorch, and vLLM kernels are not required.

The render endpoints return the public token-in GenerateRequest consumed by the Rust /inference/v1/generate endpoint. A chat render response, or one item from a completion render response, can be submitted to that endpoint without changing its fields.

The render and inference paths use the same vllm-chat and vllm-text request-preparation logic; render mode stops before engine submission. Tool-call and reasoning parsers use model-based auto-detection by default. Use --tool-call-parser and --reasoning-parser to override either selection; unified parsers require the same selection for both options.

bash
curl http://127.0.0.1:8000/v1/chat/completions/render \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-32B",
    "messages": [{"role": "user", "content": "Hello"}],
    "max_completion_tokens": 16
  }'

Example Request

After either full-frontend startup path, you can use any OpenAI-compatible client against the inference endpoints:

bash
curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen/Qwen3-0.6B",
    "messages": [{"role": "user", "content": "What is the capital of France?"}],
    "stream": true
  }'