Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .agents/NOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Working head: `row/backend-rocm-w0` (#41). Prior: benchmark checkpoint
| Supported-models list | **LANDED**: FEATURES arch table CI-bound (33 archs) | — |
| `/v1/videos` OpenAI shape | **MERGED** (#71): Sora `model`/`size`/`seconds` + `GET /{id}/content` | `row/SERVE-VIDEOS-REFS` PR open: reference conditioning |
| `BACKEND-ROCM` W0 | Skeleton in; **HIP never compiled** (no AMD HW) | #41 contributors build it; a compile error IS the deliverable |
| Surface coverage (`ARCH-ONE-SURFACE`) | **ROW 2 LANDED (#123)**: H3 video on the surface (`vllm_video_*` v12, `/v1/videos` via the seam, both examples thin clients, ratchet 11→9); ROW 1 (#121) before it | GB10 re-verify residual; next fold row |
| Surface coverage (`ARCH-ONE-SURFACE`) | **ROW 8 IN REVIEW (`row/DEVICE-KNOB`)**: ABI v14 `device` knob (0=auto/1=cpu/2=cuda), absent-cuda fails loud, `--device` on server+cli, #123's 3 minors folded | Merge after review; rebased (#122); CUDA A/B residual |

In-flight (default-OFF, not pushed): `laguna-fp4proj-prod`, laguna
bf16/legacy/pipeline-gemv, `ds4-hc-expand-fuse`.
Expand Down
2 changes: 1 addition & 1 deletion .agents/specs/one-surface-abi.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ONE SURFACE — every capability ships through the C ABI

Row: `ARCH-ONE-SURFACE`. Status: **AUDIT DONE; remediation IN PROGRESS — ROW 1 (Parakeet ASR / audio transcription) LANDED 2026-08-07: ABI v11 `vllm_transcribe`, live `/v1/audio/transcriptions`, registry refuse-by-task, example folded, ratchet 12 -> 11. ROW 2 (MiniMax-H3 video+audio generation) LANDED 2026-08-08 (`row/H3-VIDEO-ABI`, task #283): ABI v12 `vllm_video_engine_load`/`vllm_video_generate`/`vllm_video_result_free` + `vllm_video_mux_argv` over the `MiniMaxH3VideoEngine` library seam, `/v1/videos` routed through the SAME seam, both H3 examples rewritten as `vllm.h` clients byte-identical to the pre-fold binary, ratchet 11 -> 9. GB10 real-video re-verification is a NAMED RESIDUAL (box on the Kimi campaign).**
Row: `ARCH-ONE-SURFACE`. Status: **AUDIT DONE; remediation IN PROGRESS — ROW 1 (Parakeet ASR / audio transcription) LANDED 2026-08-07: ABI v11 `vllm_transcribe`, live `/v1/audio/transcriptions`, registry refuse-by-task, example folded, ratchet 12 -> 11. ROW 2 (MiniMax-H3 video+audio generation) LANDED 2026-08-08 (`row/H3-VIDEO-ABI`, task #283): ABI v12 `vllm_video_engine_load`/`vllm_video_generate`/`vllm_video_result_free` + `vllm_video_mux_argv` over the `MiniMaxH3VideoEngine` library seam, `/v1/videos` routed through the SAME seam, both H3 examples rewritten as `vllm.h` clients byte-identical to the pre-fold binary, ratchet 11 -> 9. GB10 real-video re-verification is a NAMED RESIDUAL (box on the Kimi campaign). ROW 8 (explicit device selection) LANDED 2026-08-08 (`row/DEVICE-KNOB`, task #284): ABI v14 `vllm_model_params.device` (0=auto/1=cpu/2=cuda, the vLLM `DeviceConfig.device` names) -> `EngineParams::device` -> `SelectQueue`; explicit cpu forces the CPU queue without probing, an explicitly named ABSENT device fails LOUD before any model I/O (the vllm/config/device.py:61-66 never-substitute mirror), `--device` on server + cli as pure field consumers; the #123 review's three MINOR findings closed in the same change (c_header_compile.c now references the v11+v12 surface + the v14 field; the v12 changelog block moved to chronological position; the fold fixture's flag list gained `--keep-quant`). CUDA-build A/B (auto->CUDA vs explicit-cpu->CPU on a GPU box) is a NAMED RESIDUAL — the CPU tier pins that half through the pure `ResolveExplicitDeviceType` matrix instead.**

## The defect

Expand Down
2 changes: 1 addition & 1 deletion .agents/specs/surface-coverage-2026-08-07.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ lanes are leaves of `ARCH-ONE-SURFACE` (do not open parallel rows).
| 5 | Kimi-Linear incremental | expose the incremental decode path through the runner/engine (the recompute forward already routes) | rewrite `kimi_linear_gen` | S–M | `KimiDecodeCache` on the runner |
| 6 | Embeddings/pooling | `vllm_embed`/pooling entry point + live `/v1/embeddings`; register a pooling arch (`is_pooling_model=true`); invoke `PoolingRunner` in the step | — | M | pooler live-wiring |
| 7 | Multimodal input | multimodal-content entry point on `vllm_chat`; run the vision/audio tower in the engine step (`mm_features`→`ModelForwardInput.mm`) | wire `chat_mm` seam into the ABI | L | `MM-SERVE-E2E` engine mm-forward residual |
| 8 | Device-selection knob | `device` field on `vllm_model_params` (absent today) → `EngineParams` → `SelectQueue`; `--device` on server + cli | additive | S | mirror vLLM `--device`/`DeviceConfig` |
| 8 | Device-selection knob | **DONE (ROW 8, 2026-08-08, `row/DEVICE-KNOB`)**: `vllm_model_params.device` (ABI v14: 0=auto/1=cpu/2=cuda, the vLLM `DeviceConfig.device` names, device.py:13) → `EngineParams::device` → `SelectQueue` explicit arms via `LoadedEngine::ResolveExplicitDeviceType`; explicit cpu never probes, explicit ABSENT cuda fails LOUD before any model I/O (device.py:61-66 never-substitute mirror); `--device` on server + cli | **DONE**: both thin clients consume the field; zero value byte-identical (auto probe) | S | mirror vLLM `--device`/`DeviceConfig` |
| 9 | Voxtral + audio chat seam | register `VoxtralForConditionalGeneration` + fold `VoxtralGenerateGreedy` into the registry forward; audio-capable chat fn + an engine consumer for `AudioKwargs` mm_features | rewrite tests→clients | M | mirror upstream `voxtral.py:309`, `SupportsTranscription` |
| 10 | Gemma-4 audio e2e | bf16 device audio forward + audio→text merge (residual `gemma4_audio.h:41`); USM log-mel front end | fold into the registered mm forward | M | `MM-SERVE-E2E` |
| 11 | Tokenizer/bench ABI + real-load gate | `vllm_tokenize`/`vllm_detokenize`; token-id/count fields on the stream callback for bench; **gate `vllm_engine_load` on a REAL tiny checkpoint at least once** (today bad-path only, `test_capi.cpp:474`) | rewrite `tokenize`/`bench` as clients | S-M | `/tokenize` route exists (`api_server.cpp:432`) |
Expand Down
81 changes: 81 additions & 0 deletions .agents/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -42368,3 +42368,84 @@ The full digits and file:line map live in spec §21; the binding facts:
capture pushed the unified pool below the floor at 00:25 — reproduces the §19 measured
box-safety violation; NOT retried per the safety mandate). Denominator stays the #111
recorded ~21 floor. Box recovered clean; worker auto-restored (--restart=always).

## 2026-08-08 — ARCH-ONE-SURFACE ROW 8: explicit device selection through the ONE surface (`row/DEVICE-KNOB`, task #284)
<!-- state: 2026-08-08T12:00 -->

**What.** The smallest fold row: an embedder can now ASK for a device instead
of inheriting the accelerator-first probe. Mirrors vLLM's `DeviceConfig.device`
names (`${VLLM_SOURCE}/vllm/config/device.py:13` `Device = Literal["auto",
"cuda", "cpu", ...]`; explicit assignment is VERBATIM, never substituted,
device.py:61-66; upstream's `--device` CLI flag itself was removed in v0.10,
`bc8a8ce5e`, so the ABI field mirrors the surviving config surface).

- W1 ABI: `vllm_model_params.device` appended (int32, 0=auto/1=cpu/2=cuda —
0 MUST be auto for the zero-value contract; cpu-before-cuda follows the v12
`vllm_video_model_params.device` precedent shifted by the auto slot).
`VLLM_ABI_VERSION` -> 14 per the operator's version-collision correction
(#122 Kimi `vllm_complete_tokens` reconciles to v13 at its landing; this
branch pre-rebase shows v12 -> v14 with the gap named in the changelog).
Floor pin advanced to `>= 14` (the #121 == lesson). New
`include/vllm/config/device.h` + `src/vllm/config/device.cpp`
(`vllm::Device`, `DeviceFromString`, `DeviceName`), ported from
vllm/config/device.py @ 555967922.
- W2 plumb: `EngineParams::device` -> `SelectQueue(architecture, device)`.
Explicit arms route through `LoadedEngine::ResolveExplicitDeviceType(device,
cuda_platform_registered)` — pure, so the CPU tier gates the full matrix
including "explicit cpu beats a REGISTERED accelerator". Explicit cpu never
consults the probe; explicit cuda requires the registered kCUDA platform
(cuda.cpp Registrar == usable GPU) and THROWS the pinned message otherwise;
queue-creation failure on the explicit arm PROPAGATES (no try/catch), unlike
the auto arm's byte-identical catch-and-fall-back. `FromModelDir` resolves
an explicit device BEFORE any path/config I/O (mirror of DeviceConfig
resolving at config time, arg_utils.py:1878), so the device error is never
masked by a path error — which is also what makes the capi plumb pinnable
with no loadable checkpoint. capi validates 0/1/2 (else
VLLM_ERR_INVALID_ARGUMENT) and refuses explicit cuda on the CPU-hosted
transcription stack instead of silently downgrading.
- W3 thin clients: `--device auto|cpu|cuda` on `vllm-cli` (ABI field only,
local name->int map) and `examples/server` (`vllm::DeviceFromString` ->
`EngineParams.device`; `--video-device` untouched — separate engine,
separate checkpoint, may legitimately differ).
- W5 (the #123 review's 3 MINORS, closed): c_header_compile.c now actually
references the v11 transcription + v12 video entry points + the v14 field
(its "references every ABI entry point" claim went stale at v10); the v12
changelog block moved to chronological position (after v11); the H3 fold
fixture's flag list gained `--keep-quant` (matches test:85 + the capture).

**Gates.** Full CPU build -Werror clean (fresh tree). test_capi 44 cases
(4 new v14 + floor >= 14) green; test_loaded_engine_dense +3 device cases
green; test_dlopen green; test_openai_api_server + the new explicit-cpu
serving smoke green; test_minimax_h3_video_fold green (vllm.h touched);
test_model_loader_gguf + test_platform green. check-surface-coverage green
(capability row added, ratchet UNTOUCHED — 8 after the #122 rebase below;
9 at first write). STATUS ratchet: paid for the
new line by removing a stale back-to-back merge DUPLICATE of the metrics
narrative (nothing lost), ratchet 279200 -> 279150 (measured 279108).

**Mutation kills (each RED then reverted).** M1 default device=2 ->
zero-contract 3 fails; M2 capi 0->kCUDA -> zero-contract bogus-path arm RED
(the auto arm must report the PATH, not a device); M3 range validation
dropped -> range test 6 fails; M4 capi drops the device=2 mapping -> plumb
pin RED; M5 FromModelDir early resolve removed -> capi plumb pin + the
device-before-path test both RED; M6 ctor passes kAuto -> EngineParams-seam
ctor-throw arm RED; M7 SelectQueue explicit arm catch-and-fallback -> same
test RED; M8 policy hands explicit-cpu to a registered accelerator -> matrix
RED; M9 DeviceFromString "cuda"->kCPU -> parse test RED; M10 ABI macro left
at 12 -> floor pin RED. Not uniquely killable (disclosed): the api_server
smoke (same seams as M6-M8), c_header_compile (a compile-time reference),
the two doc-only minors.

**Residuals (honest).** (1) CUDA-build A/B — auto->CUDA vs explicit-cpu->CPU
vs explicit-cuda->CUDA on a GPU box — not run (no dgx in scope); the CPU tier
pins that half via the pure matrix. (2) The 0-as-explicit-cpu vs 0-as-auto
distinction is behaviorally invisible on a CPU-only tier at the queue level;
pinned structurally (matrix + the bogus-path capi arm) and named for the
CUDA-build pass. (3) EXECUTED post-#122 (9f772cad): rebased onto main — v14 sits
on v13 (changelog now v10..v14 chronological, the minor-#2 v12 move kept),
c_header_compile composes main's `vllm_complete_tokens` reference with the
v14 field, floor pin stays >= 14, allowlist ratchet inherited at 8, keyed
records main-wholesale + these rows re-applied. (4) Explicit
names for xpu/vulkan/metal/rocm are additive later; auto reaches them today.
(5) The transcription stack refuses explicit cuda (CPU pipeline) — revisit
when an accelerated transcription path exists.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ add_library(vllm STATIC
src/vllm/sampling_params.cpp
src/vllm/lora/punica_cpu.cpp
src/vllm/config/scheduler.cpp
src/vllm/config/device.cpp
src/vllm/config/kv_transfer.cpp
src/vllm/config/speculative.cpp
src/vllm/outputs.cpp
Expand Down
2 changes: 1 addition & 1 deletion docs/BENCHMARKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ built on it rather than keeping the flattering one.

| Track | Status | Next gate |
|---|---|---|
| Surface coverage (`ARCH-ONE-SURFACE`) | **No number owed**: a CPU records/tooling change (the ONE SURFACE audit + `scripts/check-surface-coverage.py` guard, two axes, preflight + CI); no kernel or generation path touched | Fold-plan lanes carry their own gates; guard keeps CLI-only capabilities from landing untracked |
| Surface coverage (`ARCH-ONE-SURFACE`) | **No number owed**: CPU tooling/plumbing (guard; ROW 8 device knob, ABI v14 `device`, zero value = the probe, byte-identical); no kernel path touched | Fold lanes carry their own gates; ROW 8 CUDA-build A/B = named residual |
| 35B prefill TTFT | 0.93x to 0.98x at every concurrency (2026-08-05) | Attribute the residual, then close |
| 35B low-batch MoE decode | CLOSED at low batch (c1 0.975x, c4 wins); c16 0.93x. `VT_ASYNC_DEVICE_MIRROR` **default ON for correctness**. `VT_ASYNC_EXECUTOR` Option A (H2D out of capture) A/B'd speed-NEUTRAL | c16 lever is prefill glue (task #61), not the decode drain. `test_qwen36_async_serving` GREEN |
| CPU keep-quant MoE decode | **No number owed**: correctness-only P0. The grouped keep-quant GEMM read activations as f32 whatever their dtype, so CPU MoE decode emitted token-0 garbage from `b4f5610a` (2026-07-31) | Speed unmeasured and unclaimed; `test_ops_quant_dot` GREEN (150224 assertions) |
Expand Down
1 change: 1 addition & 0 deletions docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ Build with `-DVLLM_CPP_VULKAN=ON`; off by default.
| Embeddings / pooling | none | embedder-unreachable |
| Audio transcription (Parakeet ASR) | `vllm_transcribe`, `vllm_transcription_params_default`, `vllm_transcription_free` | reachable |
| Video+audio generation (MiniMax-H3) | `vllm_video_engine_load`, `vllm_video_generate`, `vllm_video_result_free`, `vllm_video_mux_argv` | reachable |
| Explicit device selection (auto/cpu/cuda) | `device` field on `vllm_model_params` (ABI v14; 0=auto keeps the probe, explicit absent device fails loud) | reachable |
| Multimodal input (image/audio/video) | none | embedder-unreachable | <!-- abi-capability-table:end -->

## Parallelism and scale-out
Expand Down
7 changes: 3 additions & 4 deletions docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,9 @@ runtime-verified yet.
lanes. Guard `scripts/check-surface-coverage.py` (two axes, preflight + CI):
every `examples/*` unit is a client of `include/vllm.h` or tracked to a fold
row; every `FEATURES.md` C-ABI capability names an entry point or is tracked.
Fold ROW 8: `vllm_model_params.device` (ABI v14, 0=auto/1=cpu/2=cuda);
explicit cpu forces CPU, an absent named device fails loud (never
substituted); `--device` on server+cli. CUDA-build A/B = named residual.
- **Automatic prefix caching (APC)** is on by default for dense models (hybrid /
GDN and attention-free default off, mirroring vLLM), and it now has an
end-to-end cache-ON gate on `Qwen/Qwen3-4B` (a shared common prefix reused
Expand Down Expand Up @@ -1594,10 +1597,6 @@ runtime-verified yet.
remaining work is the async production-serving path wiring, the chat/completion
response-body timing surface, and the config-gated metric families (speculative
decoding, KV connector, multimodal cache, LoRA).
matching vLLM's own mapping. A behavioural CPU gate drives the reference engine
for several steps and checks the values track the run. The remaining work is
the async production-serving path wiring and the config-gated metric families
(speculative decoding, KV connector, multimodal cache, LoRA).
- **SGLang RadixAttention behavior parity** — scoped 2026-07-27, W1+W2 flags now
IMPLEMENTED (CPU-gated). SGLang's radix-tree prefix cache is functionally
equivalent to our block-hash APC (both do automatic longest-prefix KV sharing
Expand Down
32 changes: 30 additions & 2 deletions examples/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// vllm_last_error().
//
// vllm-cli --model <dir> --prompt "<text>"
// [--tokenizer-config <path>]
// [--tokenizer-config <path>] [--device auto|cpu|cuda]
// [--max-tokens N] [--temperature T] [--top-p P] [--top-k K]
// [--seed S] [--stream]
//
Expand Down Expand Up @@ -36,13 +36,17 @@ struct Args {
bool have_seed = false;
bool stream = false;
std::string speculative_config; // vLLM --speculative-config JSON; "" => off.
// --device (ABI v14): "auto" (default probe), "cpu", or "cuda" — the names
// of vLLM's DeviceConfig.device this build serves. Mapped to the int the ABI
// takes (0/1/2) in ParseArgs; an unknown name is rejected there.
int32_t device = 0;
};

void Usage(const char* argv0, std::FILE* out) {
std::fprintf(
out,
"usage: %s --model <dir> --prompt \"<text>\"\n"
" [--tokenizer-config <path>]\n"
" [--tokenizer-config <path>] [--device auto|cpu|cuda]\n"
" [--max-tokens N] [--temperature T] [--top-p P] [--top-k K]\n"
" [--seed S] [--stream]\n"
" [--speculative-config '<json>']\n"
Expand Down Expand Up @@ -90,6 +94,26 @@ bool ParseArgs(int argc, char** argv, Args& a, int& exit_code) {
a.stream = true;
} else if (flag == "--speculative-config") {
a.speculative_config = NextArg(argc, argv, i);
} else if (flag == "--device") {
// The vLLM DeviceConfig.device names (auto/cpu/cuda) -> the ABI int
// (vllm_model_params.device: 0=auto, 1=cpu, 2=cuda). An unknown name is
// a usage error, mirroring vLLM rejecting a non-Literal device value.
const std::string device = NextArg(argc, argv, i);
if (device == "auto") {
a.device = 0;
} else if (device == "cpu") {
a.device = 1;
} else if (device == "cuda") {
a.device = 2;
} else {
std::fprintf(stderr,
"vllm-cli: unknown --device '%s' (expected auto, cpu, or "
"cuda)\n",
device.c_str());
Usage(argv[0], stderr);
exit_code = 2;
return false;
}
} else if (flag == "-h" || flag == "--help") {
Usage(argv[0], stdout);
exit_code = 0;
Expand Down Expand Up @@ -150,6 +174,10 @@ int main(int argc, char** argv) {
if (!args.speculative_config.empty()) {
mp.speculative_config = args.speculative_config.c_str();
}
// --device: explicit device selection (ABI v14). 0 (the default) keeps the
// accelerator-first probe; an explicitly named absent device fails the load
// below with the library's message (never a silent fallback).
mp.device = args.device;

vllm_engine* engine = nullptr;
std::fprintf(stderr, "vllm-cli: loading model from %s\n",
Expand Down
Loading
Loading