You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
qwen27 CUDA: the AOT capture harness never records a multi-stream _shared, so captured sets refuse multi-stream rounds #793
The AOT capture harness for the qwen27 CUDA family (zig/tests/cuda/qwen27/capture.py, carried by #608 and #726) records Triton launches through two paths: eng.generate (single-stream serial decode) and a teacher-forced trace (tree_forward, one token a row). Neither exercises multi_tree_forward, which is the path a serving engine uses for multi-stream rounds.
_shared (e.g. zig/src/families/qwen27/cuda/triton.zig:108 on #726) fires for every attention round with plan.n_items > 0, and its runtime argument W is the round's window width. In everything the capture produces, W is 1 and Triton folds it into a constant, so a set captured this way holds a single _shared variant with W = 1 among its constants. A server packs several streams' rows into one shared round — W = 2 for --parallel 2 — and then no captured variant can match:
error: no captured Triton variant of _shared for this launch:
Q: *bf16 … KC … VC … OFF: *i64 … STREAM: *i32 … ITEMS: *i32 … PO/PM/PL: *fp32 … W: i32 2
On a GB10 (sm_121) serving real chat traffic, every 500 we chased traced to this — e.g. ended chatcmpl-… reason=error (MissingTritonVariant) prompt=75187 tokens=1 after=6.60s while a shorter prompt on the same engine served — and a two-user parallel test failed both requests. The set covers the shapes the harness happens to produce, not the round widths a running engine asks for.
capture_windows.py does drive multi_tree_forward, but it is the window-verification oracle: the set is packed from recordings made for verification, not from a serving-shaped run, so its shared rounds are only the hand-picked layouts it verifies. No capture this project can currently produce covers the multi-stream _shared.
Our workaround is a small out-of-tree script that launches _shared, _tail and _merge directly with W = 2..N and the pointer alignment the engine passes, through the manifest recorder; packed into the same aot.json, those variants give multi-stream rounds something to match. It lives outside the tree because it imports the Python engine (the 10 Oct rule, see #726), so the coverage does not reach anyone else.
Would a multi-stream phase in the in-tree capture — a companion to capture_windows.py, or a few lines in capture.py that run representative shared rounds through the recorder — be acceptable? That would make a capture this project can produce cover the rounds a serving engine actually launches.
Thank you for the missing-variant trace, including the W: i32 2 line and the two-user failure.
That harness is not on main. zig/tests/cuda/qwen27/capture.py is absent, and the qwen27 family here is the Metal engine. The CUDA registry serves Nemotron only (zig/src/native/cuda.zig:13). The capture you describe lives on #608 and #726.
A multi-stream phase in that harness, recording _shared at W of 2 through N with the alignment the server passes, is the fix for that branch. A PR there, beside capture_windows.py, would make a capture this project can produce cover a serving round. The out-of-tree script that imports the Python engine stays off the native build.
Thank you, @zweck, for tracing every 500 back to the missing W: i32 2 variant, and for the two-user test that showed it.
That harness lived on #608 and #726, and we have closed both in favour of #836 as the one Qwen CUDA base. #836 builds its own kernels and refuses an external captured set (zig/src/families/qwen3_5/cuda_native.zig:36), capturing CUDA graphs of its own launches for every row bucket up to --parallel, so this missing-variant failure has no path there. Its gates run concurrent streams against solo, the case you hit.
If you see anything like it on #836, please open a new issue.
Activity
ashhart commentedon Oct 14, 2026
Hello @zweck,
Thank you for the missing-variant trace, including the W: i32 2 line and the two-user failure.
That harness is not on main. zig/tests/cuda/qwen27/capture.py is absent, and the qwen27 family here is the Metal engine. The CUDA registry serves Nemotron only (zig/src/native/cuda.zig:13). The capture you describe lives on #608 and #726.
A multi-stream phase in that harness, recording _shared at W of 2 through N with the alignment the server passes, is the fix for that branch. A PR there, beside capture_windows.py, would make a capture this project can produce cover a serving round. The out-of-tree script that imports the Python engine stays off the native build.
Thank you again.
ashhart commentedon Oct 15, 2026
Thank you, @zweck, for tracing every 500 back to the missing
W: i32 2variant, and for the two-user test that showed it.That harness lived on #608 and #726, and we have closed both in favour of #836 as the one Qwen CUDA base. #836 builds its own kernels and refuses an external captured set (
zig/src/families/qwen3_5/cuda_native.zig:36), capturing CUDA graphs of its own launches for every row bucket up to--parallel, so this missing-variant failure has no path there. Its gates run concurrent streams against solo, the case you hit.If you see anything like it on #836, please open a new issue.
Posted by Ash's AI Assistant Synthena