Repository navigation
Conversation
…er its lanes A shared verify or decode pass ran each DeltaNet step once per lane: the rollback copies, the front (or, with pending rows, the front into the stream's log), the chain, and the conv window's shift. Now each step is one launch over all the pass's lanes (fn_gdn_lanes_keep / _front / _chain / _shift), every lane running its lone launch's program on its own buffers, so the bits are the per-lane path's. On by default; TF_FLASHNEXT_GDN_LANES=0 loops the lanes as before. Falls back to the loop above 16 lanes, for a lane of 64 rows or more, for unaligned row blocks, and with tensor parallelism. New code in cuda_batch_gdn_lanes.zig. The four kernels are registered with the kernel contract as bit-equal replacements of the per-lane launches (zig/tests/cuda/contract_flashnext_lanes.zig, in the Flash Next family set): 1 to 16 lanes of 1 to 32 rows, mixing lanes with no rollback, with a rollback copy and with pending rows.
|
Thanks @Arminova. We reviewed this independently. The four batched kernels call the same inlined |
…t test of the rounds once() leaves to the loop The contract's served shapes add one lane (a single stream's round). cuda_batch_gdn_lanes_test.zig runs once() with a driver that counts launches: one, two and sixteen lanes launch three kernels (four with rollback copies); seventeen lanes, a 64-row lane, a misaligned projection or keep buffer, tensor parallelism and TF_FLASHNEXT_GDN_LANES=0 return false with nothing launched.
|
Thanks, Ash. Both are in
On the head: |
|
Thanks @Arminova. Here's our GB10 A/B of Exact: 0 of 20 prompt rows differ, and every concurrent stream equals its run alone. Both 64K long runs pass on both arms. Decode gains with more streams:
Prompt speed is unchanged everywhere (2K to 64K, all within ±0.3%). One stream is slightly slower, and steadily so:
That's inside our noise threshold, but one stream is the number we're pushing hardest, and we hold to "never slower" there. Could the merged launch fall back to the per-lane launches when a round has one lane? The kernels are already bit-equal to them, so it changes no bytes, and every stream count keeps its gain. Once that's in, I'll rerun the same cells and land it on a clean one-stream result. |
What this changes
A shared round (decode or verify) ran each DeltaNet step once per stream: the rollback copies, the front (or, with pending rows, the front into the stream's log), the chain, and the conv window's shift. Now each step is one launch over all the round's lanes, each lane running the lone launch's program on its own buffers, so the bits are
main's.On by default;
TF_FLASHNEXT_GDN_LANES=0loops the lanes as before. A round falls back to the loop above 16 lanes, for a lane of 64 rows or more (that chain takesfn_gdn_chain_tpr), or for buffers not 16-byte aligned. Off with tensor parallelism. New filecuda_batch_gdn_lanes.zig.Four new kernels (
fn_gdn_lanes_keep,fn_gdn_lanes_front,fn_gdn_lanes_chain,fn_gdn_lanes_shift), each registered with the kernel contract as a bit-equal replacement of the per-lane launches it stands for (zig/tests/cuda/contract_flashnext_lanes.zig, in the Flash Next family set): 1 to 16 lanes of 1 to 32 rows each, mixing lanes with no rollback, with a rollback copy, and with pending rows (none, at the store threshold, past it, the log wrapping).This is the batching we took out of #1763 for #1740, which optimisme has closed in its favour. It does not need #1739's lane table. Part of #1762.
Receipt
Environment: as flashnext cuda: pending DeltaNet rows, reused lane buffers and the shared expert on a side stream #1763 (GB10, driver 580.173.02, nvcc 13.3.73,
nvidia/Qwen3.8-Flash-Next-FP4-Localatb9ce18a6, a fresh server for every run), onmain088cfbd35. Base:main; this changefdb221871. The head574d965c6is that code with the four kernels' measured launch records and the lane loop'selsefolded into its condition (socuda_batch.zigstays within 600 lines next to flashnext cuda: a shared round's attention in one launch a kernel #1739), in one commit; served once more on the head: every reply equalsmain's at 1, 4 and 16 streams, alone and serial all equal. Mean of two alternated rounds (base, this change, this change, base).Exactness: every reply's
token_sha256equalsmain's in every cell below: 1, 4 and 16 streams, greedy and seeded sampled, code and chat, and each of the 16 long prompts.bench_concurrent --alone --serialat 1 and 4 streams (--context 262144 --parallel 3) and at 16 streams (--context 32768 --parallel 16): 336 of 336 concurrent replies equal their solo run and 216 of 216 equal"draft": false. An 8,192-token prompt sent twice on 4 streams: the 5 replies resumed from 8,191 cached tokens equal the 2 fresh ones.Speed, tok/s:
bench_concurrent, 256 tokens--context 32768 --parallel 16) code / chatOne stream takes the batched path too (a shared round of one lane) and ties.
Long contexts (flashnext cuda: a shared round's DeltaNet in one launch a kernel, behind TF_FLASHNEXT_GDN_LANES #1740's case, prompt cache off):
--context 45056 --parallel 16 --prompt-cache-gib 0, 16 distinct prompts of about 30K tokens,--tokens 128: prompts of 25,152 to 32,208 tokens,--levels 4,16, greedy and seeded sampled. End-to-end tok/s (every token over the whole run, prefill included): 4 streams 6.69 → 6.70 / 6.63 → 6.64; 16 streams 6.78 → 6.86 (all 16 done in 302.2 → 298.4 s) / 6.88 → 6.91 (297.7 → 296.2 s). No cell is slower, and every reply equalsmain's. (aggregate_tpsin these cells spans the first stream's first token to the last stream's last, so it mostly measures when the first of 16 staggered prefills ends; it moved 12.8 to 14.1 between runs of the same build.)Tests on the head
574d965c6:zig build test465 / 465 steps andtest-cuda-host285 / 285 steps, 0 failures;compile-cuda-testsbuilds.tools/zig/lean_check.py: 424 problems, the same asmain(0 new).Kernel contract (nvcc 13.3.73, GB10), on
a4e1c3c6e(the head differs only by that one line incuda_batch.zig): every gate line of the four kernels passes (sums: none declared).SUMMARY 534 kernels: 534 pass gates 1-4, 0 fail, 6 known findings; 344 controls: 344 red as planted, 0 missed; 229 limit problemskernel-contract-limitson fatbins for sm_80 / 86 / 89 / 120 / 121: none of the four kernels' records stale, no launch over a limit; the 274 stale records and the 229 limit problems aremain's own on this nvcc build. A planted mutation (fn_gdn_lanes_shiftmoving the window one row too far) fails gates 1 and 3 from byte 0.Not run: TP2 (one GB10; the change keeps today's path with tensor parallelism), Metal and HIP (CUDA-only change), CUDA chips other than GB10 (launch records only).
Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo.SUMMARYline is in the receipt.