Skip to content

[ops] fix: stop NPU GDN Triton kernels recompiling per batch length - #1264

Merged
Coach257 merged 1 commit into
ByteDance-Seed:mainfrom
Estrellajer:fix/npu-gdn-triton-recompile
Oct 17, 2026
Merged

Coach257 merged 1 commit into
ByteDance-Seed:mainfrom
Estrellajer:fix/npu-gdn-triton-recompile

Conversation

@Estrellajer

@Estrellajer Estrellajer commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Four of the vendored NPU GatedDeltaNet Triton kernels take a length-derived value as tl.constexpr:
NT, the chunk count of the whole packed batch, in chunk_gated_delta_rule_fwd_kernel_h and both
wy_fast kernels, and N, the sequence count, in chunk_fwd_kernel_o. Both change with every
micro-batch, so varlen training recompiles the whole set each time it meets a total length it has not
seen — about 9–11 s per GDN forward+backward on a 910B2C.

A warm cache hides this completely, which is why it is easy to read as "the first step is slow". It is
not: with cu_seqlens packing, every step is a new total length. This PR passes the two values as
runtime arguments and adds them to do_not_specialize, which changes Triton's recompilation
granularity and nothing else.

Checklist Before Starting

Test

Ascend 910B2C, CANN 9.1.1, torch 2.10.0, torch_npu 2.10.0.post2, triton-ascend 3.2.2. Each variant run
with its own empty TRITON_CACHE_DIR over eight packed layouts with different total lengths, forward
and backward:

over eight packed layouts before after
layouts that triggered a compile 8 of 8 1 of the 7 new lengths
time per newly seen length 9.1–11.4 s 1.2 s, or a cache hit
steady-state time, first layout 12.1 ms 10.7 ms

Outputs and all gradients are bit-identical to the unpatched kernels across the eight layouts
(max abs diff 0.0), which is the check that matters: the change is meant to be a no-op numerically.

End to end, a GRPO run on Qwen3.5-4B over 8×910B2C with variable-length DocQA data goes from 57–65 s
per step to 48–54 s. Any variable-length run gains from this: it is overhead removed from every step,
not a win specific to one workload.

API and Usage Example

No API change. Nothing to configure; the kernels are selected as before.

Design & Code Changes

veomni/ops/kernels/gated_delta_rule/_ascend/triton/:

  • chunk_delta_h.py, wy_fast.py (two kernels), chunk_o.py: drop : tl.constexpr from the NT /
    N parameter and add the name to the kernel's do_not_specialize list. These parameters are only
    loop bounds and index arithmetic inside the kernel bodies; nothing specialises on their value.
  • chunk_scaled_dot_kkt.py: NT / B / TOTAL_TASKS were already runtime arguments but were not
    listed in do_not_specialize, so Triton still re-specialised them by divisibility. Listed now, for
    the same reason.

This bug class is known: fla-org/flash-linear-attention#1207 (2026-09-03) fixed the same thing in
fla's own triton_ascend backend by the same technique, reporting Triton cache misses dropping from
2647 to 203 over 20 steps. That patch does not transfer file-by-file — that backend is a rewritten
lineage with a different set of offending symbols — so the fix is applied here directly.

Checklist Before Submitting

  • Read the Contribute Guide
  • Applied pre-commit checks (ruff check, ruff format)
  • Added documentation: not needed, no user-visible surface
  • No tasks/ training scripts moved or renamed
  • Tests: none added. What changes is compile-cache granularity, not behaviour; the existing GDN
    tests cover correctness and the outputs are bit-identical.

Summary by CodeRabbit

  • Improvements
    • Gated delta rule operations now process sequence-, batch-, and task-related dimensions as runtime values rather than requiring them to be fixed during compilation. This supports a broader range of workload shapes and input configurations. Compilation behavior may differ; no user-facing functional changes were reported.

chunk_gated_delta_rule_fwd_kernel_h, prepare_wy_repr_bwd_kernel and
recompute_w_u_fwd_kernel took NT (total chunk count of the packed batch) as a
tl.constexpr, and chunk_fwd_kernel_o took N (sequence count) as one. Both
change with every packed batch, so each new total length compiled a fresh set
of kernels: ~10 s per GDN forward+backward on 910B2C. Warm caches hide it; a
training run on varlen data sees new lengths every step.

Pass them as runtime ints and add them, with the kkt kernel's NT/B/
TOTAL_TASKS, to do_not_specialize. Outputs and gradients are bit-identical to
before over eight layouts; with a fresh cache, seven of eight new lengths then
run without compiling. A 154-step GRPO run on DocQA-RL goes from 57-65 s to
48-54 s per step.

Same bug class and same technique as fla-org/flash-linear-attention#1207,
which fixed it in fla's own triton_ascend backend; these kernels came from
MindSpeed-MM 39775d87 before that and carry a different set of offending
constexprs, so the fix is reproduced here rather than ported.
@CLAassistant

CLAassistant commented Oct 5, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added ascend everything about Ascend support fix labels Oct 5, 2026
@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (3)
.agents/knowledge/constraints.md — configured
AGENTS.md — configured
CONTRIBUTING.md — configured

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: ByteDance-Seed/VeOmni/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 211d33a4-5889-44bd-9b7e-2241fc8a8554
📥 Commits

Reviewing files that changed from the base of the PR and between 0fbf546 and 64167fe.

📒 Files selected for processing (3)
  • veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_delta_h.py
  • veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_scaled_dot_kkt.py
  • veomni/ops/kernels/gated_delta_rule/_ascend/triton/wy_fast.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

Several Ascend gated delta rule Triton kernels update which arguments are excluded from specialization. Selected NT and N parameters are declared as runtime arguments.

Changes

Ascend kernel argument specialization

Layer / File(s) Summary
Triton runtime shape arguments
veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_delta_h.py, veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_o.py, veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_scaled_dot_kkt.py, veomni/ops/kernels/gated_delta_rule/_ascend/triton/wy_fast.py
The kernels update their Triton specialization exclusions. NT and N are runtime arguments in the affected kernels.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 64167

The changed kernels retain aligned runtime arguments and compile-time tile sizes. No actionable merge-blocking regression is evident.

Architecture Summary

Architecture risk: 🔵 Low · up to 64167

The change affects 1 system.

Changed systems: veomni

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — veomni (service) was modified; 4 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_o.py: chunk_fwd_kernel_o now excludes both T and N from specialization; previously only T was excluded.
  • observed — Modified behavior in veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_o.py: N is now a runtime argument instead of a tl.constexpr compile-time argument.
  • observed — Modified behavior in veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_delta_h.py: The kernel’s JIT decorator now prevents specialization on both T and NT; previously only T was excluded.
  • observed — Modified behavior in veomni/ops/kernels/gated_delta_rule/_ascend/triton/chunk_delta_h.py: NT is now a runtime parameter instead of a constexpr parameter.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: preventing Ascend GDN Triton kernels from recompiling for different batch lengths.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@Coach257
Coach257 merged commit 9251d15 into ByteDance-Seed:main Oct 17, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ascend everything about Ascend support fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants