Skip to content

feat(flops): register Qwen3.8-Flash-Next formula so BenchmarkingRecipe can run - #3963

Open
Agoniii wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
Agoniii:Agoniii/feat/qwen3-8-flash-next-flops
Open

Agoniii wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
Agoniii:Agoniii/feat/qwen3-8-flash-next-flops

Conversation

@Agoniii

@Agoniii Agoniii commented Sep 21, 2026

Copy link
Copy Markdown

What does this PR do ?

Register a FLOPs formula for Qwen3.8-Flash-Next so BenchmarkingRecipeForNextTokenPrediction can start and report MFU, and so the finetune recipe's TFLOPS metric uses the right architecture.

get_flops_formula_for_hf_config had no entry for Qwen3_8_FlashNextConfig / Qwen3_8_FlashNextTextConfig (or the pre-rename qwen4_exp aliases), so it fell back to transformer_flops, which reads config.hidden_size on the multimodal wrapper and raises AttributeError in BenchmarkingRecipe.setup() — the same failure mode #3955 fixed for DeepSeek-V4.1.

Changelog

  • Add qwen3_8_flash_next_flops to nemo_automodel/components/utils/flops_utils.py, mirroring the components/models/qwen3_8_flash_next module shapes:
    • GatedDeltaNet layers via the shared _gdn_attention_per_layer_flops term;
    • QSA layers: gated q_proj / k_proj / v_proj / o_proj, plus sparse GQA BMMs where query t attends to ratio * min(indexer_budget/ratio, floor((t+1)/ratio)) routed tokens and its (t+1) mod ratio causal tail (closed form, new _sum_mod helper);
    • frozen QSA indexer (requires_grad_(False)) counted forward-only (2x MACs);
    • MoE router, num_experts_per_tok routed + 1 shared expert, shared-expert gate;
    • two HyperConnection mixers per layer (down / up / inject) plus the final read mixer;
    • Engram PLE key_proj / value_proj and depthwise causal convolution on ple_layer_ids;
    • untied LM head. The checkpoint's MTP head is not loaded and not counted.
  • Register Qwen3_8_FlashNextConfig, Qwen3_8_FlashNextTextConfig, Qwen3_8_FlashNextLegacyConfig, Qwen3_8_FlashNextLegacyTextConfig in the class → formula map.
  • Add tests/unit_tests/utils/test_qwen3_8_flash_next_flops.py (8 CPU tests): registration of all four config classes, wrapper → text_config unwrapping, model-card parameter checks, _sum_mod vs brute force, per-layer QSA + indexer accounting vs brute-force sums, PLE projection counting, linearity in gbs, sparse-attention saturation with sequence length.

Sanity numbers on the released configuration:

Quantity Formula Reference
Active GEMM params / token (excl. LM head) 6.14B model card: 6B activated
Implied backbone params (excl. 51.2B Engram table) 125.8B model card: 125B
FLOPs / token at 4096 tokens 42.0 GFLOPs 1.034x 6 x active
32K vs 4K FLOPs / token +1.05% sparse attention saturates past the 2048-token budget

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation? (docstring on the new formula; no user-facing docs change)

ruff format / ruff check clean. pytest tests/unit_tests/utils/test_qwen3_8_flash_next_flops.py tests/unit_tests/utils/test_deepseek_v41_flops.py → 16 passed (CPU).

Additional Information

🤖 Generated with Claude Code

…e can run

`get_flops_formula_for_hf_config` had no entry for `Qwen3_8_FlashNextConfig`
or its text / legacy `qwen4_exp` aliases, so `BenchmarkingRecipe.setup()`
fell back to `transformer_flops`, which reads `config.hidden_size` on the
multimodal wrapper and raises `AttributeError` before the first iteration.
Any Qwen3.8-Flash-Next benchmark yaml therefore could not start, and the
finetune recipe's TFLOPS metric was computed with the wrong formula.

Add `qwen3_8_flash_next_flops`, mirroring the `qwen3_8_flash_next` module
shapes: GatedDeltaNet layers via the shared `_gdn_attention_per_layer_flops`
term, QSA gated q/k/v/o projections plus sparse GQA BMMs over the routed
compressed blocks and causal tail (closed form per query position), the
frozen indexer counted forward-only, the MoE router / routed + shared
experts / shared-expert gate, two HyperConnection mixers per layer plus the
final read mixer, the Engram PLE key/value projections and depthwise
convolution, and the untied LM head. The unloaded MTP head is not counted.

On the released configuration the formula counts 6.14B active GEMM
parameters per token excluding the LM head (model card: 6B activated) and
implies a 125.8B backbone excluding the 51.2B Engram table (model card:
125B); 4096-token training costs 42.0 GFLOPs/token, 1.034x `6 x active`.
Map all four config classes to it and add CPU unit tests (registration,
wrapper unwrapping, model-card parameter checks, closed-form tail sum
against brute force, per-layer QSA/indexer/PLE accounting, gbs linearity,
sparse-attention saturation).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Agoniii <815244047@qq.com>
@Agoniii
Agoniii requested a review from a team as a code owner September 21, 2026 14:08
@copy-pr-bot

copy-pr-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant