Skip to content

[PyTorch] Quantize distributed BF16 weights in the fused grouped MLP - #3695

Open
xrennvidia wants to merge 3 commits into
NVIDIA:mainfrom
xrennvidia:xren/fused_grouped_mlp_gtp_bf16_weight_requant
Open

xrennvidia wants to merge 3 commits into
NVIDIA:mainfrom
xrennvidia:xren/fused_grouped_mlp_gtp_bf16_weight_requant

Conversation

@xrennvidia

Copy link
Copy Markdown
Collaborator

A distributed (e.g. GTP) weight whose shards are not natively quantized is re-gathered as BF16. The fused grouped-MLP op assumed gathered weights were already quantized: forward quantized the shards before the gather, and backward read _columnwise_data / the NVFP4 amax straight off the gathered tensor, which fails for a module whose per-module recipe (e.g. MXFP8 experts under a global NVFP4 recipe) does not create native-quantized params.

Gather first, then quantize whatever is still unquantized with the op's per-expert weight quantizers, mirroring module/linear.py's handling of a re-gathered BF16 distributed weight. Native-quantized shards gather as quantized tensors and pass through unchanged. The FC2 backward re-gather moves ahead of the NVFP4 global-scale computation so that path no longer reads un-gathered shards.

Description

Please include a brief summary of the changes, relevant motivation and context.

Fixes # (issue)

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

Please list the changes introduced in this PR:

  • Change A
  • Change B

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@xrennvidia
xrennvidia requested a review from timmoon10 as a code owner October 16, 2026 06:17
@github-actions github-actions Bot added the community-contribution PRs from external contributor outside the core maintainers, representing community-driven work. label Oct 16, 2026
@greptile-apps

greptile-apps Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge, with the requested regression coverage now present.

Summary

The PR gathers distributed weights before quantizing BF16 results with each layer’s own quantizers.

  • The fused grouped MLP quantizes distributed BF16 weights after gathering them.

Review checks were limited to source inspection; tests were not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Distributed weights] --> B[Gather weights]
  B --> C{Already quantized?}
  C -->|Yes| D[Use gathered weights unchanged]
  C -->|No| E[Quantize with layer quantizers]
  D --> F[Forward or backward GEMM]
  E --> F
Loading

Reviews (3) · Last reviewed commit: "[pre-commit.ci] auto fixes from pre-comm..." · Reviewed by Greptile

Comment thread transformer_engine/pytorch/ops/fused/grouped_mlp.py
A distributed (e.g. GTP) weight whose shards are not natively quantized is
re-gathered as BF16. The fused grouped-MLP op assumed gathered weights were
already quantized: forward quantized the shards before the gather, and backward
read _columnwise_data / the NVFP4 amax straight off the gathered tensor, which
fails for a module whose per-module recipe (e.g. MXFP8 experts under a global
NVFP4 recipe) does not create native-quantized params.

Gather first, then quantize whatever is still unquantized with the op's
per-expert weight quantizers, mirroring module/linear.py's handling of a
re-gathered BF16 distributed weight. Native-quantized shards gather as quantized
tensors and pass through unchanged. The FC2 backward re-gather moves ahead of
the NVFP4 global-scale computation so that path no longer reads un-gathered
shards.

Ported from the nemotron4 branch (te-nt4 f404cd6b); this tree's file has since
diverged, so the three backward/forward hunks were re-applied by hand.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Xiaowei Ren <xren@nvidia.com>
@xrennvidia
xrennvidia force-pushed the xren/fused_grouped_mlp_gtp_bf16_weight_requant branch from 98959c9 to e071ec7 Compare October 16, 2026 06:25
xrennvidia and others added 2 commits October 15, 2026 23:35
Regression test for the gather-then-quantize fix: a fake routed-expert
DistributedWeight group whose materialize hooks return BF16 tensors (or
MXFP8 tensors for the native-quantized case) drives the CuTeDSL fused grouped
MLP under per-module MXFP8, optionally inside a global NVFP4 autocast.
Distinct power-of-two scales in the forward/backward hooks make the gathered
weights observable: output, dgrad and the main_grad wgrads must match a plain
reference bit-exactly up to those scales. A unit check confirms already
quantized gathered weights pass through the helper unchanged.

Fails on the unpatched op with AttributeError on _columnwise_data in backward;
passes with the fix.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Xiaowei Ren <xren@nvidia.com>

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

Labels

community-contribution PRs from external contributor outside the core maintainers, representing community-driven work.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant