Repository navigation
flashnext cuda: a shared round's attention in one launch a kernel - #1739
Conversation
|
@ashhart this is updated on current main, with #1741 and #1763 in, and merges cleanly. It stays opt-in, and the workflows are waiting for your approval. Same build with
All 540 reply comparisons are equal, and replies match between the two settings. |
|
Thanks @optimisme. Our GB10 run on Qwen3.8 Flash Next MLX 4-bit ( |
…LASHNEXT_ATTN_LANES (ashhart#1739) Squashed from ashhart#1739's branch, which merges main in; its eight commits replayed onto main conflicted where the merge had already resolved them. The tree is the PR merged with current main.
9b77402 to
f9d8146
Compare
|
Thank you @optimisme. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes. |
#1739 moved fn_attn_merge's loop into fn_attn_merge_body, which the kernel calls; the Qwen4 CUDA attention host instrument extracted only the kernel, so test-qwen4-host, test-qwen4-gdn-host and test-qwen4-projection-bodies stopped compiling. Extract the body too, as inline host code.
…attention runs in one launch With TF_FLASHNEXT_ATTN_LANES=1 (ashhart#1739) a shared round may take the one-launch attention or the per-lane one; the graph captured for one must not replay for the other, so SharedKey carries cuda_batch_lanes.useAttn's answer.
|
Thanks @optimisme! This is in TensorFold 1.2.2, out now: https://github.com/ashhart/TensorFold/releases/tag/v1.2.2 |
Part of #1737. Opt-in: off by default, and this is not proposed as a default. Merged with main at
1ce45264, which has #1741 and #1763. Numbers and every cell are in the receipt.A shared decode round launches each attention kernel once per stream. With
TF_FLASHNEXT_ATTN_LANES=1it launches each once for the round: every row finds its stream's caches and position in a table uploaded once a round.It applies to two to 32 streams of up to 16 rows each, text on contiguous caches, on our own glue. Page-table KV, media, captured sets and prompt rows keep today's path. So do one stream and a round with no rows: the kernels handle both, but the runtime does not send them here.
Kernels (one GB10, nvcc 13.3)
tf_nemo_router_tileson sm_89, which this does not touch. The new kernels' records are current on all five SM targets.lean_check: 0 new over main.Tokens: with the switch on, 4,616 comparisons across main and all three branches were equal and none unequal: concurrent against alone and alone against
"draft": false, at 1, 4, 8 and 16 streams, greedy and sampled. Resumed equals fresh on a 2,571-token prompt.bench_cache.py --require-reusereports unqualified, on main too, because the first repeat is cold.Speed, main against this branch, alternating fresh servers:
On current main: retested after #1763 brought in pending DeltaNet rows and the shared expert on a side stream, both on by default. Same build with the switch unset and on, a fresh server each, 1, 4 and 16 streams, greedy and sampled, short contexts: 540 comparisons equal, none unequal, replies equal between the two settings. 16 streams +1.6 to +2.7%, 4 streams +1.0 to +1.6%, 1 stream within 0.4%.
flashnext-attn-lanesgives 29 passes and 0 failures.test-cuda-hostpasses 4,188 of 4,207 with 17 skipped and the same 2drama_voice_toolcleanup failures. The full kernel contractSUMMARYabove is from before these merges and was not rerun. The last main commit, one file incore, came in after the tests.Not checked: a long-context run with the prompt cache off, which would remove most of that noise. HIP and Metal do not use this path.