Skip to content
This repository was archived by the owner on Oct 6, 2026. It is now read-only.

NVFP4-CSF: expand_scales() for ahead-of-call scale expansion - #477

Merged
voipmonitor merged 2 commits into
integration/karmic-kraken-betafrom
perf/csf-scale-prefetch
Oct 4, 2026
Merged

voipmonitor merged 2 commits into
integration/karmic-kraken-betafrom
perf/csf-scale-prefetch

Conversation

@voipmonitor

Copy link
Copy Markdown
Contributor

NVFP4-CSF layers share one scale scratch. Every eager prefill call expands its experts' scales into it serially, right before the MoE. In a GLM-5.3-Flash glm53-tp2 A4 prefill trace, those expansions took 4.1% of the GPU time with no kernel on any other stream overlapping them.

This PR adds what an integration needs to move the expansion off the critical path:

  • fused_moe.expand_scales(experts) expands every expert's NVFP4-CSF scales into the experts' scratch on the current stream (Nvfp4CsfDecoder.decode_all). Long prefills already use this full expansion (mode 3), so the bytes are identical. It returns False and does nothing for experts without compressed scales.
  • bind(..., scales_expanded=True) makes the call skip its own expansion. The caller orders the streams: after the previous user of the scratch, before the bound call. Calls of the micro kernel, whose barrier reset is fused into the expansion, ignore the flag and expand as before.

vLLM (paired PR) expands the next layer's scales on a side stream while that layer's attention runs.

Evidence

glm53-tp2 (stored QAD CSF checkpoint, TP2/DCP2 MTP3, DMA all-reduce) on two RTX PRO 6000 Max-Q, side-stream prefetch off vs on (two runs each):

2K 8K 32K
A4 prefill, off 9,254 / 9,169 10,083 / 9,981 10,391 / 10,232
A4 prefill, on 9,234 / 9,300 10,298 / 10,209 10,690 / 10,549
A16 prefill, off 7,310 / 7,238 7,713 / 7,630 7,954 / 7,895
A16 prefill, on 7,311 / 7,245 7,811 / 7,715 8,129 / 7,987

Decode is unchanged (it runs from CUDA graphs and reads compressed scales per stage). Needle-checksum with the prefetch, 3 salted runs each: A4 495, 490, 492 (492, 492, 490 before); A16 498, 495, 497.

Tests

tests/moe/test_nvfp4_csf.py, tests/moe/test_w4a16_a4_prefill.py, tests/quantization/test_nvfp4_csf.py: 84 passed on an RTX PRO 6000. New test_prefetched_scales_replace_the_per_call_expansion:

  • A16: with poisoned scratch the flag changes the output, which shows the skip.
  • A side-stream expand_scales then restores the bit-exact native result.
  • A call without the flag still expands its own experts.
  • A4 micro calls ignore the flag.

🤖 Generated with Claude Code

expand_scales(experts) expands every expert's NVFP4-CSF scales into the
experts' scratch on the current stream (decode_all, the full expansion long
prefills already use), and bind(..., scales_expanded=True) skips the per-call
expansion. An integration whose layers share one scale scratch can expand the
next layer on a side stream while that layer's attention runs, instead of
serially before its MoE, where the expansion took 4% of a GLM-5.3 TP2 A4
prefill. Calls of the micro kernel, whose barrier reset is fused into the
expansion, ignore the flag and expand as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: local-inference-lab/b12x/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8557b0ba-b332-4560-b7b4-ae642a3a6a93

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • 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.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant