[Perf][Linear-Attn] Add optimized Gated DeltaNet prefill op#1596
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements the Gated DeltaNet inference prefill operator (GatedDeltaNetPrefillFwdOp) and its corresponding kernel, along with associated tests, benchmarks, and performance formulas. Feedback on the changes highlights two critical issues: first, input tensors should be made contiguous in the operator's forward pass to prevent memory access errors or crashes; second, the optimized scan path condition (use_scan_h) in the prefill kernel needs an additional divisibility check on the sequence length to avoid silent correctness bugs on non-divisible lengths.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
58a4ea4 to
ec23c79
Compare
ec23c79 to
b617d52
Compare
b617d52 to
2170e25
Compare
2170e25 to
17bfa8b
Compare
Gabbering
left a comment
There was a problem hiding this comment.
goose review — 17bfa8b9
honk. Both inline thread comments were addressed by the master. The goose has re-read the conversation and confirmed the following:
-
Thread 1 (
tileops/ops/gated_deltanet.py:303): The master added.contiguous()calls for all five input tensors before validation and kernel dispatch, and wrote a test (test_gated_deltanet_prefill_bthd_layout_matches_bhtd) that passes non-contiguous permuted inputs through the BTHD path. The goose's contiguity concern is resolved. -
Thread 2 (
tileops/kernels/gated_deltanet/gated_deltanet_prefill.py:852): The master definedgroup_chunks = 64before theuse_scan_hguard and addedand seq_len % (chunk_size * group_chunks) == 0to the condition. Non-divisible long sequences now fall back to the standard recurrence path. The goose's scan-path divisibility concern is resolved.
Both fixes are present in the delta 17bfa8b9 and the goose sees no new issues introduced by this commit.
SILENT
Ibuki-wind
left a comment
There was a problem hiding this comment.
Overall
The new manifest-driven benchmark does not record an independent baseline, so the benchmark contract is not satisfied yet.
17bfa8b to
d09c8f2
Compare
Ibuki-wind
left a comment
There was a problem hiding this comment.
Overall
The benchmark baseline blocker is fixed, but the public BTHD layout contract is not represented in the manifest and the approval-gate authoring hygiene still needs cleanup. Update the manifest shape rules for layout, make the PR body follow the template with final verification facts including pre-commit/benchmark/test-node-delta, and edit author replies to outcome-only one-liners.
## Summary - update the GatedDeltaNetPrefillFwdOp spec-only manifest contract to allow chunk_size=None - add the layout parameter used by the implementation path - add an H16/S2K manifest workload row for the target prefill shape family ## Notes - This is a manifest-only precursor for PR #1596. - It intentionally keeps status: spec-only and leaves source paths null; the implementation PR should flip status/source/roofline once the kernel code lands. ## Validation - python scripts/validate_manifest.py --check-op GatedDeltaNetPrefillFwdOp
## Summary - encode the GatedDeltaNetPrefillFwdOp BHTD/BHSD and BTHD layout shape contracts in the manifest - add fixed-rank shape metadata for the manifest tensors - fill the planned roofline/source metadata while keeping the entry spec-only ## Notes - This is a manifest-only prerequisite for PR #1596. - The implementation PR should only flip status and keep any remaining manifest edit within the status-flip carve-out. ## Validation - python scripts/validate_manifest.py
0828ab6 to
067edc7
Compare
|
For the performance comparison, please include FlashQLA as a baseline/reference as well: https://github.com/QwenLM/FlashQLA It would be useful to compare on the same target hardware and representative GDN prefill shapes/dtypes so the remaining gap vs. the current public optimized implementation is explicit. |
1c4337e to
9d21d88
Compare
9d21d88 to
9282b2b
Compare
|
Thanks for the pointer. I added FlashQLA as an explicit baseline in the PR body, measured on the same H200/GPU4 setup with the TileOps benchmark/CUPTI timer and representative Qwen-style GDN prefill rows. The refreshed numbers show the TileOps path is faster than the public FlashQLA reference on these rows. The main reason is not just a different block/thread schedule tweak. The important change is the overall inference prefill path: the serving path materializes only I also kept FlashQLA attribution explicit in the PR body: Qwen FlashQLA is credited as the schedule-level reference for the h-state / corrected-segment-start CP-split part of long-context GDN prefill. The TileOps-specific work is the owned operator integration, BTHD/head-major API, blocked/Neumann-style A-producer integration, local replay/output implementation, dispatch/tuning, tests, benchmarks, and validation against the recorded references. |
…shqla-specialized # Conflicts: # tileops/kernels/gated_deltanet/gated_deltanet_fwd.py
zhen8838
left a comment
There was a problem hiding this comment.
Approved current head 7fb5f35. The earlier requested FlashQLA comparison is now in the PR body with H200/Qwen-style rows, the manifest now represents the BTHD public layout contract with layout-specific shape rules, and current GitHub checks are green including gpu-smoke, validate-manifest, benchmark-contract, pre-commit, actionlint, and gitleaks.
Ibuki-wind
left a comment
There was a problem hiding this comment.
Overall
Please fix the manifest roofline shape handling and rewrite the PR body into a commit-log-ready summary before merge.
Cross-cutting concerns
- The current PR body is too noisy to become the squash commit log: it mixes implementation history, temporary verification logs, artifact paths, long benchmark tables, and explanatory back-and-forth. Replace it with a concise final-state commit message: short summary, key implementation bullets, supported dispatch shape, final performance headline, and final verification commands/results only.
|
Thanks for the review. Fixed the manifest roofline blocker and rewrote the PR body into a final-state summary. What changed:
Verified:
|
|
Also re-verified with the TileOpsGov CI runner image from the new launcher docs:
Docker results:
I also added these docker results to the PR body. |
|
Thanks for raising this. I kept the original license headers because this path includes third-party MIT-licensed lineage, but I tightened the wording to avoid implying that TileOps directly wraps or copies the complete FlashQLA kernels. More specifically:
To make this explicit in-repo, I added |
Ibuki-wind
left a comment
There was a problem hiding this comment.
Clean on current head under a strict correctness/project-contract review.
The prior blockers I cared about are addressed: benchmark rows now record an independent FLA or torch-ref baseline, the manifest represents the BTHD public layout contract, and roofline decoding branches on layout so BTHD workloads produce nonzero FLOPs/bytes. I also rechecked the earlier correctness hazards: forward makes inputs contiguous before validation/dispatch, and the grouped scan path now requires divisibility by chunk_size * group_chunks before taking that path.
I treated the remaining third-party attribution threads as already answered by the clarified headers plus THIRD_PARTY_NOTICES.md; I do not see a code correctness blocker there. GitHub CI is green, including gpu-smoke, validate-manifest, benchmark-contract, and pre-commit. I did not run the GPU tests locally.
Closes #1595.
Summary
Adds
GatedDeltaNetPrefillFwdOp, an optimized zero-state inference prefill operator for Gated DeltaNet. The op returns(o, final_state)without training-only intermediates and provides a TileOps-owned serving path for long-context prefill.Implementation
layout="bthd",B=1,fp16,DK=DV=128,chunk=64, with an environment kill switch.[B, T, H, D]instead of[B, H, T, D].Third-party Attribution
This PR also adds
THIRD_PARTY_NOTICES.mdand clarifies source-file headers for the GDN prefill path. Qwen FlashQLA is the MIT-licensed schedule-level reference for the h-state / corrected-segment-start CP-split scheduling. The local utility file is adapted from FlashQLA's utility source and keeps its upstream copyright notice. TileOps-specific work includes the public op wrapper, BTHD/head-major API integration, shape-aware dispatch, blocked/Neumann-style A producer integration, local replay/output implementation, TileLang compatibility changes, manifest/roofline support, tests, benchmarks, and verification.Shape Contract
Primary BTHD path:
q, k:[B, T, H, DK]v, o:[B, T, H, DV]g, beta:[B, T, H]initial_state, final_state:[B, H, DK, DV]Head-major BHTD/BHSD layouts remain supported through the public op API, but the optimized long-context serving dispatch targets BTHD.
Performance Headline
H200/GPU4, BTHD, fp16,
B=1,DK=DV=128,chunk=64, TileOps benchmark timer/CUPTI path. FlashQLA is reported as a public TL0.1.8 anchor and should be read as a public-environment comparison, not a same-lowering attribution experiment. Qwen FlashQLA is credited as the reference for the CP-split schedule family.Verification
Host checks:
python -m pytest tests/perf/test_gated_deltanet_prefill_roofline.py -q:2 passedpython -m pytest tests/test_validate_manifest.py -q:223 passed, 3 warningspre-commit run --files tileops/perf/formulas.py tests/perf/test_gated_deltanet_prefill_roofline.py: passedPYTHONPYCACHEPREFIX=<tmp> python -m py_compile tileops/perf/formulas.py tests/perf/test_gated_deltanet_prefill_roofline.py: passedGatedDeltaNetPrefillFwdOp: all listed BTHD workloads now report nonzero FLOPs and bytes.TileOpsGov CI docker image
ghcr.io/tile-ai/tileops-runner:65dbc98-torch2.10(tilelang 0.1.11+cu129.git65dbc983,torch 2.10.0+cu129):python -m pytest tests/perf/test_gated_deltanet_prefill_roofline.py -q:2 passedGatedDeltaNetPrefillFwdOp: all listed BTHD workloads report nonzero FLOPs and bytes.python -m pytest tests/test_validate_manifest.py -q:223 passed, 15 warningstests/ops/test_gated_deltanet_prefill.py::test_gated_deltanet_prefill_bthd_layout_matches_bhtdand::test_gated_deltanet_prefill_bthd_blocksolve_path_matches_bhtd:2 passed, 14 warnings