feat(BACKEND-TENSTORRENT-HOST-FREE-FORWARD): capture the Qwen3 decode graph and advance cur_pos on device (#1105) - #1053
Conversation
b0737f7 to
a83f11b
Compare
|
Holding this for one change, and it's not the build break. First the easy part: The reason we are holding is It triggers on a new request, a batch-size change, or a block-boundary crossing that grows We could have added a guard ourselves, but you have the Blackhole silicon and we do not -- Two things only you can close: there is no GitHub issue for this work (policy wants it The specs are unusually good, and the measured 5.8x replay result is real. #694 we are |
9554184 to
67fbe9b
Compare
0b3d682 to
c63a938
Compare
|
Re-reviewed at
Both code blockers are still open, though. Checked on 1. The link break —
|
|
Correction — I was wrong about the link break, and I apologise. You did fix I grepped
That chain is sound: the header pulls only I also want to retract a scare before it reaches you: we checked whether this What is still open is the one blocker: the frozen Two smaller things worth your attention, and then an offer.
And the commit currently contradicts itself: The offer: everything except the Say the word and we will push those; the |
9075e70 to
9eacffe
Compare
9eacffe to
786d498
Compare
… graph and advance cur_pos on device (mudler#1105) The Tenstorrent decode path hung after about 38 replays because each step copied cur_pos and update_idxs into the live trace. This change captures the Qwen3 dense decode graph and advances cur_pos on-device with ttnn::plus_one, matching the upstream executor.py pattern. A P150 run of Qwen3-0.6B "Hello" at 80 tokens completed 79 replays with no hang, 5.8x vs eager, and 22/22 argmax vs the per-step-copy baseline. The path is inert unless VT_TT_HOST_FREE_DECODE is set. A new batch size after the first capture is refused rather than freezing cur_pos. CPU and Vulkan builds link via header no-ops. MSVC accepts the MoE refuse path. VT_TT_DUMP_KV is paid only on kTENSTORRENT. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:grok-4.6 [Grok]
…the probe was dead Three review repairs on top of the host-free decode work. No behavior change. The three new `VT_CHECK`s each told the operator to "Recapture, or seed DecodePos per cache entry (mudler#1105)". Recapture does not clear the refusal. `GraphCapturesCounter` is only ever `fetch_add`ed (`tenstorrent_ops.cpp:3225`, from `:3297`), nothing resets it, and `DestroyGraph` does not — so `VT_TT_RECAPTURE_EVERY` leaves the counter above zero, the missing `DecodePos` entry uncreated, and the refusal standing. Worse, that path lags `cur_pos` by one per recapture cycle, because the recapture-triggered eager step re-seeds nothing and skips every `copy_to_device`, and the next capture step then captures a position one behind. The messages now say to seed per cache entry and state plainly that recapture does not clear it. `examples/test_sdpa_minimal.cpp` is deleted rather than disclosed. It is in no `add_executable`, so it never compiled and nothing detected it rotting, and it includes `vt/backend.h` plus six raw `ttnn/`/`tt-metalium/` headers — examples are clients of `include/vllm.h` only. It was excused by a `scripts/example-abi-allowlist.txt` row whose own text conceded it "is not a CMake example"; that row goes with it. Deleting a dead isolation probe is cheaper than carrying a staged-slice exception for it. Two hazards found during review are recorded under `## Owed` rather than fixed here, because both are mudler#1105's scope: `DecodePosCache` is keyed on bare `num_reqs` with no engine identity and is never cleared, so two engines in one process at the same padded batch size share one `cur_pos` device tensor — silently, not as a refusal, and a candidate explanation for the `test_qwen3_paged_engine` timeout; and the recapture lag above, which the eager PA consistency check at `:2410-2412` cannot detect because it compares `e.cp_host[0]` against the same `seq_lens` that just rewrote `e.cp_host`, validating the host mirror against itself. `docs/ENVIRONMENT.md` gains a clause on the flag's own row saying a second concurrent request refuses rather than returning wrong tokens, since that is where an operator looks. FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: ClaudeCode:claude-opus-5 [ClaudeCode]
786d498 to
eecff93
Compare
feat(BACKEND-TENSTORRENT-HOST-FREE-FORWARD): capture the Qwen3 decode graph and advance cur_pos on device (#1105)
The Tenstorrent decode path hung after about 38 replays because each
step copied cur_pos and update_idxs into the live trace. This change
captures the Qwen3 dense decode graph and advances cur_pos on-device
with ttnn::plus_one, matching the upstream executor.py pattern.
A P150 run of Qwen3-0.6B "Hello" at 80 tokens completed 79 replays
with no hang, 5.8x vs eager, and 22/22 argmax vs the per-step-copy
baseline. The path is inert unless VT_TT_HOST_FREE_DECODE is set.
A new batch size after the first capture is refused rather than
freezing cur_pos. CPU and Vulkan builds link via header no-ops.
MSVC accepts the MoE refuse path. VT_TT_DUMP_KV is paid only on
kTENSTORRENT.
FOLLOWING_AGENTS_PROTOCOL
Following-Agents-Protocol: true
AI-Assisted: true
Assisted-by: AGENT:grok-4.6 [Grok]