Skip to content

flashnext cuda: a shared round's DeltaNet in one launch a kernel, behind TF_FLASHNEXT_GDN_LANES - #1740

Closed
optimisme wants to merge 26 commits into
ashhart:mainfrom
optimisme:fn-gdn-lanes
Closed

optimisme wants to merge 26 commits into
ashhart:mainfrom
optimisme:fn-gdn-lanes

Conversation

@optimisme

@optimisme optimisme commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1737. Stacked on #1739, which it contains; review that first. Opt-in: off by default, and this is not proposed as a default. Merged with main, including 1.2.0. Numbers are in the receipt.

With TF_FLASHNEXT_GDN_LANES=1 a shared decode round's DeltaNet runs each stream's rollback copies, window shifts and rows in one launch a kernel, from the table #1739 adds. It needs TF_FLASHNEXT_ATTN_LANES=1. One stream and a round with no rows keep today's path.

Kernels (one GB10, nvcc 13.3)

SUMMARY 463 kernels: 463 pass gates 1-4, 0 fail, 6 known findings; 324 controls: 324 red as planted, 0 missed; 223 limit problems; gates 2374019 ms, limits 2492302 ms
  • fn_shift_window_lanes, fn_gdn_keep_lanes, fn_gdn_front_lanes and fn_gdn_rows_lanes are registered as replacements of the per-stream launch and compared byte for byte from 2 to 32 lanes, plus one stream, a stream with zero rows, and streams at different context lengths.
  • Limit problems: as on flashnext cuda: a shared round's attention in one launch a kernel #1739. The new kernels' records are current on all five SM targets.
  • lean_check: 0 new over main.

Tokens: the same 4,616 comparisons as #1739, with both switches on in this branch's runs, all equal.

Speed, main against this branch, alternating fresh servers:

  • Short contexts: +2.0 to +5.8% from 4 streams up, one stream ties. No slower cell.
  • Long contexts (about 30k tokens): slower cells in one cycle, cause not established. Cycle 2 reads 5.23 and 5.40 tok/s at 16 streams against main's 6.79 and 7.39, about 25% down, with first tokens at 365 to 377 s against 265 to 290 s, and decode lower as well. Sampled at 4 and 8 streams it also reads 8.20 and 6.76 against 8.71 and 7.69. Cycle 1 shows 6.81 and 7.47 at 16 streams, level with main, though 7.05 against 8.73 at temp 0, 4 streams. Main itself varies by up to 17% between runs here because the prompt cache keeps three states and evicts, which may explain it, but I have not shown that.

So this does not meet "no cell is slower". It should stay opt-in until a long-context run with the prompt cache off settles it. HIP and Metal do not use this path. On the latest merge the stack builds; test-cuda-host passes 3,390 of 3,400 with 8 skipped and the same 2 drama_voice_tool cleanup failures seen on main in this setup; and a short served check with both switches on, 1, 4 and 16 streams, greedy and sampled, has every reply equal alone and to "draft": false. That was on main at 372af1ec. The kernel contracts passed on the merge before it (flashnext-attn-lanes and flashnext-gdn-lanes, 29 passes and 0 failures each) and were not rerun. The later main commits came in through a changelog-only conflict and were not built or tested here; they leave zig/src/families/flashnext alone, and the newest add grammar timing in the core lanes code.

Arminova added a commit to Arminova/TensorFold that referenced this pull request Oct 31, 2026
…ared expert on a side stream

Three changes to a shared pass's rounds on one GPU. Each keeps the bits of main and has its own switch:

- A partly kept window's DeltaNet rows stay pending in a per-stream log instead of being replayed; the next window's
  chain applies them first, so a rollback only moves the conv windows and the n-gram tail.
  TF_FLASHNEXT_KEEP_LATE=0 replays as before.
- A contiguous lane's fixed-size buffers are reused across streams instead of allocated for every request.
  TF_FLASHNEXT_LANE_PARTS=0 allocates them as before.
- A decode or verify pass's shared expert runs on a side stream beside the routed experts.
  TF_FLASHNEXT_SHARED_SIDE=0 keeps it in line.

Three new kernels (fn_gdn_front_log, fn_gdn_rows_late, and fn_late_roll for a rollback's windows in one launch), each
registered with the kernel contract as a bit-equal replacement of the kernels it stands for
(zig/tests/cuda/contract_flashnext_late.zig, contract_flashnext_roll.zig; one set in contract_flashnext_more.zig,
registered with the family sets).
One launch for all streams' DeltaNet steps is left to ashhart#1737 / ashhart#1740.

Off or refused with tensor parallelism. Code moved into new files where a file would pass 600 lines
(cuda_batch_late, cuda_batch_side, cuda_lane_parts, cuda_seq_parts, cuda_lanes_snap,
cuda_mtp_roll).
@optimisme
optimisme marked this pull request as ready for review October 31, 2026 22:28
ashhart pushed a commit to Arminova/TensorFold that referenced this pull request Nov 2, 2026
…ared expert on a side stream

Three changes to a shared pass's rounds on one GPU. Each keeps the bits of main and has its own switch:

- A partly kept window's DeltaNet rows stay pending in a per-stream log instead of being replayed; the next window's
  chain applies them first, so a rollback only moves the conv windows and the n-gram tail.
  TF_FLASHNEXT_KEEP_LATE=0 replays as before.
- A contiguous lane's fixed-size buffers are reused across streams instead of allocated for every request.
  TF_FLASHNEXT_LANE_PARTS=0 allocates them as before.
- A decode or verify pass's shared expert runs on a side stream beside the routed experts.
  TF_FLASHNEXT_SHARED_SIDE=0 keeps it in line.

Three new kernels (fn_gdn_front_log, fn_gdn_rows_late, and fn_late_roll for a rollback's windows in one launch), each
registered with the kernel contract as a bit-equal replacement of the kernels it stands for
(zig/tests/cuda/contract_flashnext_late.zig, contract_flashnext_roll.zig; one set in contract_flashnext_more.zig,
registered with the family sets).
One launch for all streams' DeltaNet steps is left to ashhart#1737 / ashhart#1740.

Off or refused with tensor parallelism. Code moved into new files where a file would pass 600 lines
(cuda_batch_late, cuda_batch_side, cuda_lane_parts, cuda_seq_parts, cuda_lanes_snap,
cuda_mtp_roll).
ashhart pushed a commit that referenced this pull request Nov 2, 2026
…ared expert on a side stream

Three changes to a shared pass's rounds on one GPU. Each keeps the bits of main and has its own switch:

- A partly kept window's DeltaNet rows stay pending in a per-stream log instead of being replayed; the next window's
  chain applies them first, so a rollback only moves the conv windows and the n-gram tail.
  TF_FLASHNEXT_KEEP_LATE=0 replays as before.
- A contiguous lane's fixed-size buffers are reused across streams instead of allocated for every request.
  TF_FLASHNEXT_LANE_PARTS=0 allocates them as before.
- A decode or verify pass's shared expert runs on a side stream beside the routed experts.
  TF_FLASHNEXT_SHARED_SIDE=0 keeps it in line.

Three new kernels (fn_gdn_front_log, fn_gdn_rows_late, and fn_late_roll for a rollback's windows in one launch), each
registered with the kernel contract as a bit-equal replacement of the kernels it stands for
(zig/tests/cuda/contract_flashnext_late.zig, contract_flashnext_roll.zig; one set in contract_flashnext_more.zig,
registered with the family sets).
One launch for all streams' DeltaNet steps is left to #1737 / #1740.

Off or refused with tensor parallelism. Code moved into new files where a file would pass 600 lines
(cuda_batch_late, cuda_batch_side, cuda_lane_parts, cuda_seq_parts, cuda_lanes_snap,
cuda_mtp_roll).
@optimisme

Copy link
Copy Markdown
Contributor Author

Closing this rather than adapting it to #1763, which changes the same DeltaNet steps. @Arminova, you mentioned you had batched these steps too, pending rows included, and held that back because of this PR, so please go ahead with your version. The fn-gdn-lanes branch stays on my fork if any of it is useful, and you're welcome to reuse it.

One thing to check if you continue: this stack had slower cells in one long-context cycle (about 30k tokens, 16 streams), and the cause was never established. Details are in the receipt. #1739 stays open and doesn't depend on this PR.

@optimisme optimisme closed this Nov 2, 2026
@Arminova

Arminova commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Thanks, @optimisme. I took the batched DeltaNet steps out of #1763 only so they wouldn't overlap #1740, so thank you for handing them back. I'll open them as a new PR, ported onto main with the pending rows, and run your long-context case (about 30K tokens, 16 streams, prompt cache off) in its receipt before opening it. Thanks for the offer of your branch too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants