Skip to content

feat(bench): add GDN routines to flashinfer_benchmark.py - #3572

Merged
bkryu merged 4 commits into
flashinfer-ai:mainfrom
bkryu:gdn_microbench
Jun 10, 2026
Merged

bkryu merged 4 commits into
flashinfer-ai:mainfrom
bkryu:gdn_microbench

Conversation

@bkryu

@bkryu bkryu commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

📌 Description

Adds Gated Delta Net (GDN) support to flashinfer_benchmark.py as a new gdn routine category:

Added Routines:

  • gated_delta_rule_decode — T=1 decode; --state_layout {pretranspose,nontranspose}, --state_dtype {float32,bfloat16} (bf16 state kernels), --pool_mode {single,split}
  • gated_delta_rule_mtp — T>=2 multi-token processing with state pool + indices
  • chunk_gated_delta_rule — varlen chunked prefill

Bug fixes in the standalone benches

  • bench_gdn_decode.py: all-layouts mode called the BF16-state kernel without pool indices (column was always N/A); bytes model counted intermediate-state traffic for T>1 even with caching disabled, inflating reported TB/s
  • bench_gdn_prefill.py: fed log-space g to the FlashInfer kernel, which takes a linear-space alpha — outputs/state were NaN; FLA is now optional instead of a hard exit

🔍 Related Issues

🚀 Pull Request Checklist

Thank you for contributing to FlashInfer! Before we review your pull request, please make sure the following items are complete.

✅ Pre-commit Checks

  • I have installed pre-commit by running pip install pre-commit (or used your preferred method).
  • I have installed the hooks with pre-commit install.
  • I have run the hooks manually with pre-commit run --all-files and fixed any reported issues.

If you are unsure about how to set up pre-commit, see the pre-commit documentation.

🧪 Tests

  • Tests have been added or updated as needed.
  • All tests are passing (unittest, etc.).

Reviewer Notes

Summary by CodeRabbit

  • New Features

    • Added GDN (Gated Delta Net) benchmark family: decode, multi-token (MTP), and chunked prefill with multi-backend support and performance metrics that account for optional intermediate-state caching.
    • Added Triton-backed reference kernels and optional Triton routing for GDN workloads.
  • Bug Fixes

    • Prefill baseline is no longer fatal when optional baseline kernel is missing; reporting and columns adjust accordingly.
    • Corrected gate generation to avoid out-of-domain values.
  • Documentation

    • Updated docs and sample test lists with GDN routines, flags, backend matrix, and usage notes.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds GDN (Gated Delta Rule) benchmarking: Triton reference kernels, CLI wiring, a new GDN routine module with FLOPs/bytes estimators and tests, benchmark script updates (caching/accounting and optional FLA), docs, and sample invocations.

Changes

GDN Benchmarking Support

Layer / File(s) Summary
Documentation and samples
benchmarks/README.md, benchmarks/samples/sample_testlist.txt
Adds GDN to README (flags, backend legend, per-CC support) and appends GDN sample invocations to sample_testlist.txt.
Bench script updates and FLA handling
benchmarks/bench_gdn_decode.py, benchmarks/bench_gdn_prefill.py
Refactors decode script to import Triton wrappers, adds cache_intermediate_states accounting and BF16 state-index fixes; updates prefill to use linear-space forget gate, warn (not abort) when FLA missing, and conditionalize FLA columns/calls.
Benchmarking metadata and CLI dispatch
benchmarks/routines/flashinfer_benchmark_utils.py, benchmarks/flashinfer_benchmark.py
Registers gdn routine group and output columns, extends --routine choices, defines per-CC backend allowlists for GDN APIs, and wires parse_gdn_args / run_gdn_test into the main runner.
Triton reference decode and MTP kernels
benchmarks/gdn_triton_reference.py
New Triton module providing fused decode (non-pretranspose and pretranspose) and MTP kernels with optional intermediate-state caching and disable-state-update; includes Python wrappers triton_gdn_decode, triton_gdn_decode_pretranspose, and triton_gdn_mtp.
GDN benchmark routine implementation
benchmarks/routines/gdn.py
Adds CLI parsing/validation, analytical FLOPs/bytes estimators, and routines testGatedDeltaRuleDecode, testGatedDeltaRuleMtp, and testChunkGatedDeltaRule that generate inputs, run FlashInfer/Triton/optional FLA, perform optional reference checks, and report TFLOPs/TB/s.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

benchmark, op: misc

Suggested reviewers

  • yzh119
  • cyx-6
  • sricketts
  • jimmyzho
  • aleozlx
  • nv-yunzheq
  • samuellees
  • kahyunnam

Poem

🐰 In gates that gently nudge the flow,

Deltas hop where hidden states grow,
Triton hums and FlashInfer sings,
Benchmarks count the bytes and flops they bring,
A rabbit cheers: GDN leaps and shows.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(bench): add GDN routines to flashinfer_benchmark.py' accurately summarizes the main change—adding GDN support to the benchmark tool.
Docstring Coverage ✅ Passed Docstring coverage is 88.46% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description covers objectives, added routines, and bug fixes with clear details, and checklist items are addressed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds Gated Delta Net (GDN) linear attention benchmarking support (decode, MTP, and prefill) to the FlashInfer benchmark suite, extracting Triton reference kernels into a shared module and updating the benchmark infrastructure. Feedback on the changes highlights two critical issues: first, importing Triton reference functions will raise an ImportError on systems without Triton installed, breaking non-Triton benchmarks; second, BF16 state decode benchmarking will fail at runtime when pool_split is False because it incorrectly falls through to a non-pool path instead of routing to the pool-only path required by BF16 state kernels.

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.

BV=BV,
)

return output, initial_state

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If triton is not installed, importing triton_gdn_decode, triton_gdn_decode_pretranspose, or triton_gdn_mtp from gdn_triton_reference will raise an ImportError because these names are only defined inside the if TRITON_AVAILABLE: block. Since other scripts (like bench_gdn_decode.py and routines/gdn.py) import these functions at the top level, this completely breaks benchmarking on systems without Triton, even when only benchmarking the flashinfer backend.

Please add an else block at the end of the file to define these functions as None when Triton is not available.

Suggested change
return output, initial_state
return output, initial_state
else:
triton_gdn_decode = None
triton_gdn_decode_pretranspose = None
triton_gdn_mtp = None

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Adding the else-block None fallbacks in gdn_triton_reference.py in next commit

Comment thread benchmarks/routines/gdn.py Outdated
return gated_delta_rule_decode(
q, k, v, state, A_log, a, dt_bias, b, scale, output, use_qk_l2norm
)[0]
if pool_split:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The BF16 state decode/MTP kernels are pool-only and do not support the standard in-place non-pool path (where state is passed as the 4th positional argument).

When is_mtp is False (decode T=1), use_bf16_state is True, and pool_split is False (i.e., pool_mode is single), the code currently falls through to the non-pool path on line 623. This will cause a runtime failure when benchmarking the BF16 state decode kernel.

To fix this, we should route the call to the pool-only path whenever use_bf16_state is True, even if pool_split is False.

Suggested change
if pool_split:
if pool_split or use_bf16_state:

@bkryu bkryu self-assigned this Jun 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
benchmarks/README.md (1)

80-83: 💤 Low value

Optional: Clarify SM90+ support scope.

The description states "SM90+" which correctly indicates the minimum compute capability, but the support matrix (lines 548-550) shows FlashInfer backend support is limited to SM 9.0–10.3, with only Triton reference available for SM 11.0+ (and no prefill support for SM 11.0+). Consider adding a brief note like:

-- GDN (Gated Delta Net linear attention, SM90+):
+- GDN (Gated Delta Net linear attention, SM90+ minimum; FlashInfer kernels available on SM90–SM10.3):

This would set clearer expectations for users on newer architectures (SM 11.0–12.1) who will only have Triton reference kernels for decode/MTP.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@benchmarks/README.md` around lines 80 - 83, Add a brief clarification in the
GDN section explaining the SM90+ support scope: state that while the header uses
"SM90+" as the minimum compute capability, FlashInfer backend support is limited
to SM 9.0–10.3 (including prefill/preftransposed kernels), whereas for SM 11.0+
only the Triton reference kernels are available (no FlashInfer prefill support
for SM 11.0+), and note that BF16 state kernels or pretranspose variants
(referenced by gated_delta_rule_decode, gated_delta_rule_decode_pretranspose,
gated_delta_rule_mtp, and chunk_gated_delta_rule) may therefore be
backend-limited (flashinfer vs triton vs fla) on newer architectures to set
clear expectations for users.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@benchmarks/README.md`:
- Around line 80-83: Add a brief clarification in the GDN section explaining the
SM90+ support scope: state that while the header uses "SM90+" as the minimum
compute capability, FlashInfer backend support is limited to SM 9.0–10.3
(including prefill/preftransposed kernels), whereas for SM 11.0+ only the Triton
reference kernels are available (no FlashInfer prefill support for SM 11.0+),
and note that BF16 state kernels or pretranspose variants (referenced by
gated_delta_rule_decode, gated_delta_rule_decode_pretranspose,
gated_delta_rule_mtp, and chunk_gated_delta_rule) may therefore be
backend-limited (flashinfer vs triton vs fla) on newer architectures to set
clear expectations for users.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cbc113f9-07de-452b-bd34-77750657e7be

📥 Commits

Reviewing files that changed from the base of the PR and between 9e6a280 and 71fcd1a.

📒 Files selected for processing (8)
  • benchmarks/README.md
  • benchmarks/bench_gdn_decode.py
  • benchmarks/bench_gdn_prefill.py
  • benchmarks/flashinfer_benchmark.py
  • benchmarks/gdn_triton_reference.py
  • benchmarks/routines/flashinfer_benchmark_utils.py
  • benchmarks/routines/gdn.py
  • benchmarks/samples/sample_testlist.txt

@bkryu bkryu added run-ci benchmark Pertains to performance benchmarking labels Jun 10, 2026
@bkryu
bkryu merged commit a0cb4e7 into flashinfer-ai:main Jun 10, 2026
22 of 46 checks passed
@bkryu
bkryu deleted the gdn_microbench branch July 7, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmark Pertains to performance benchmarking run-ci

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants