Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Optional extras, combined as `pip install "decisionformer[serve,qlora]"`:
|---|---|
| `serve` | the `/v1/systemone` API server (FastAPI, uvicorn) |
| `qlora` | bitsandbytes, for QLoRA |
| `vllm` | the vLLM serving backend (a vLLM build from 2026-10-15 or later) |
| `vllm` | vLLM, for the vLLM serving backend; Decision 3.0 models need its nightly build (see [Serve as an API](#serve-as-an-api)) |
| `fla` | fast Gated DeltaNet kernels for Qwen3.5 backbones |
| `data` | datasets, for Hub datasets (`hf:` inputs) and the example converters |

Expand Down Expand Up @@ -126,10 +126,13 @@ schemas are at `/docs`. Over-long requests are refused with HTTP 422, never trun
runs at once; requests that arrive while it is busy are answered together, up to `--max-batch` (16) at a time.

For code-readout checkpoints on Qwen3.5 (the Decision 3.0 layout), vLLM can run the model behind the same API.
Other checkpoints fail with a clear error that points to the default backend:
This needs a vLLM nightly build from 2026-10-15 or later (vLLM 0.32.0 on PyPI predates its decision-model support)
and a CUDA GPU, Ampere or newer for non-causal checkpoints such as `vllm-sr/d3-edge`. Other checkpoints fail with a
clear error that points to the default backend:

```bash
pip install "decisionformer[vllm]"
pip install "decisionformer[serve]"
pip install -U vllm --pre --extra-index-url https://wheels.vllm.ai/nightly
decisionformer serve vllm-sr/d3-edge --backend vllm
```

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Dataset = "https://huggingface.co/datasets/FrontiersMind/deciformer-15k"
[project.optional-dependencies]
qlora = ["bitsandbytes>=0.45"]
serve = ["fastapi>=0.110", "uvicorn>=0.29"]
vllm = ["fastapi>=0.110", "uvicorn>=0.29", "vllm>=0.12"] # decision-model support: vLLM nightly from 2026-10-15
vllm = ["fastapi>=0.110", "uvicorn>=0.29", "vllm>=0.12"] # Decision 3.0 models need a vLLM nightly from 2026-10-15 (0.32.0 predates it)
fla = ["flash-linear-attention>=0.5"] # fast Gated DeltaNet kernels for Qwen3.5/3.8 backbones
data = ["datasets>=3"]
dev = ["pytest>=8", "ruff>=0.6", "mypy>=1.11", "fastapi>=0.110", "uvicorn>=0.29", "httpx>=0.27"]
Expand Down
2 changes: 1 addition & 1 deletion src/decisionformer/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def build_parser() -> argparse.ArgumentParser:
serve.add_argument("--host", default="127.0.0.1")
serve.add_argument("--port", type=int, default=8000)
serve.add_argument("--backend", choices=("transformers", "vllm"), default="transformers",
help="vllm: vLLM computes the readout (Qwen3.5/3.8 code-readout checkpoints only)")
help="vllm: vLLM computes the readout (Qwen3.5 code-readout checkpoints; needs a vLLM nightly)")
serve.add_argument("--max-batch", type=int, default=16,
help="requests arriving together are answered in one batch of up to this many")
serve.add_argument("--api-key-env", default="DECISIONFORMER_API_KEY",
Expand Down
8 changes: 4 additions & 4 deletions src/decisionformer/vllm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

vLLM computes the answer-code logits; decisionformer renders the prompt (byte-identical to the transformers
backend) and turns logits into answers with the checkpoint's per-type temperatures, so both backends answer the
same way. vLLM's decision-model support covers code-readout checkpoints whose backbone is a bare Qwen3.5/3.8 model
same way. vLLM's decision-model support covers code-readout checkpoints whose backbone is a bare Qwen3.5 model
(`Qwen3_5Model` plus `decision_config.json` and `readout.safetensors`): decisionformer exports on those bases,
Decision 3.0 (`vllm-sr/d3*`) and AutoJev-format exports such as FrontiersMind/Lumma-fev-27B. Anything else raises
`UnsupportedBackend`; serve it with the default transformers backend. Needs a vLLM build with decision-model
support (`pip install decisionformer[vllm]`, vLLM nightly from 2026-10-15 on) and a CUDA or ROCm GPU.
`UnsupportedBackend`; serve it with the default transformers backend. Needs a vLLM nightly from 2026-10-15
on (vLLM 0.32.0 on PyPI predates its decision-model support) and a CUDA or ROCm GPU.
"""

from __future__ import annotations
Expand Down Expand Up @@ -34,7 +34,7 @@ def check_vllm_support(root: Path, config: dict[str, Any]) -> None:
"""Raise UnsupportedBackend unless vLLM's decision-model path can load this checkpoint as it is."""
def refuse(reason: str) -> None:
raise UnsupportedBackend(f"vLLM cannot serve {root}: {reason}. vLLM serves code-readout decision checkpoints "
"with a bare Qwen3.5/3.8 backbone (Qwen3_5Model). Use the transformers backend "
"with a bare Qwen3.5 backbone (Qwen3_5Model). Use the transformers backend "
"(the default) for this model.")

if not (root / READOUT).is_file() or (root / HEADS).is_file():
Expand Down
Loading