Skip to content

[Pytorch] Add support for row-wise quanted input for grouped gemm#3244

Open
YangFei1990 wants to merge 6 commits into
NVIDIA:mainfrom
YangFei1990:mxfp8_input_groupedgemm
Open

[Pytorch] Add support for row-wise quanted input for grouped gemm#3244
YangFei1990 wants to merge 6 commits into
NVIDIA:mainfrom
YangFei1990:mxfp8_input_groupedgemm

Conversation

@YangFei1990

@YangFei1990 YangFei1990 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Description

To support the NCCL EP FP8 dispatch, this PR introduce a capability to allow grouped gemm to take input that is already quantized in row-wise.

  • For forward, we directly pass the row-wise quantized for forward grouped gemm and dequant + requant with col-wise to save for backward.
  • For backward, we pass the row-wise quantized for dgrad computation and dequant + requant with col-wise for wgrad

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

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

Signed-off-by: YangFei1990 <feiw@nvidia.com>
@YangFei1990
YangFei1990 requested a review from phu0ngng July 23, 2026 18:28
Comment on lines +1309 to +1310
and isinstance(input_quantizers[0], MXFP8Quantizer)
and isinstance(input_.quantizer, MXFP8Quantizer)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should we also assert input_quantizers[0] == input_.quantizer?

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.

I think == comparison is too strict. It will compare all value fields, I think things like columnwise_usage or optimize_for_gemm could mismatch? Maybe we should explicit assert dype to be E4M3? But let me know if the dispatch output tensor's quantizer can match all value fields.

with_columnwise: bool,
tensor_offsets: Optional[torch.Tensor] = None,
) -> None:
"""Prepare a rowwise-only MXFP8 grouped input for grouped GEMM (in place).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like this helper actually "prepares" colwise besides rowwise. I think we should make the function name and docstring clearer and more consistent.

format; they are converted to the GEMM-swizzled layout afterwards.
TODO: optimize and fuse the round-trips requant
"""
if grouped_x.rowwise_data is None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should we validate grouped_x.rowwise_scale as well?

raise ValueError("Pre-quantized MXFP8 grouped input is missing rowwise data.")
if grouped_x._with_gemm_swizzled_scales:
raise NotImplementedError(
"Pre-quantized MXFP8 grouped input must have scales in compact format."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

compact -> unswizzled.

Comment on lines +175 to +178
scale_shape = (
round_up_to_nearest_multiple(total_tokens, 128),
round_up_to_nearest_multiple(cols // 32, 4),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need to do this while we already have 128 per-expert-alignment in Dispatch? The total tokens should already be divisible by 128.

For hidden size, there will be an assertion in Dispatch to expect % 512 = 0.

Here, I think we can add assertions instead.

@phu0ngng
phu0ngng requested a review from vthumbe1503 July 23, 2026 20:42

def prepare_prequantized_mxfp8_grouped_input(
grouped_x: GroupedTensorStorage,
quantizer: MXFP8Quantizer,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Actually, is there a GroupedQuantizer in TE/PyT? If so, we probably need to use it instead.

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.

I do not see a GroupedQuantizer in Pytorch. I see what used is tex.group_quantize. Let me know if I missed it. Also can you help me understand the benefit of GroupedQuantizer and how it compared with current Pytorch approach?

Signed-off-by: YangFei1990 <feiw@nvidia.com>
Signed-off-by: YangFei1990 <feiw@nvidia.com>
@YangFei1990
YangFei1990 marked this pull request as ready for review July 26, 2026 04:37
@YangFei1990
YangFei1990 requested a review from timmoon10 as a code owner July 26, 2026 04:37
@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds row-wise prequantized MXFP8 support to grouped GEMM paths.

  • Repackages grouped tensors into saveable storage and manufactures columnwise data by dequantizing and requantizing when wgrad needs it.
  • Reuses row-wise data for forward and dgrad GEMMs while supporting ordinary and scaled-bias gradient reductions.
  • Extends grouped linear and fused grouped MLP tests for prequantized inputs and gradients.

Confidence Score: 3/5

The PR is not yet safe to merge because fused grouped MLP still aborts with frozen expert weights when input or routing gradients are required.

The basic grouped-linear fixes now supply dequantized gradients for scaled bias and directly reduce ordinary dbias without a wgrad stage, but the fused forward still omits columnwise activation data when weights are frozen and then asserts that this data exists while saving tensors, preventing the targeted frozen-expert backward flow from running.

Files Needing Attention: transformer_engine/pytorch/ops/fused/grouped_mlp.py, transformer_engine/pytorch/utils.py, tests/pytorch/test_grouped_mlp.py

Important Files Changed

Filename Overview
transformer_engine/pytorch/ops/_common.py Adds shared conversion and preparation helpers for row-wise prequantized MXFP8 grouped tensors, including columnwise requantization and direct dbias reduction.
transformer_engine/pytorch/ops/basic/grouped_linear.py Integrates prequantized MXFP8 grouped inputs and gradients into basic grouped-linear forward and backward paths.
transformer_engine/pytorch/ops/fused/grouped_mlp.py Integrates the same prequantized flow into fused grouped MLP, but its existing activation-saving invariant still blocks the frozen-weight configuration targeted by the prior scaled-bias report.
tests/pytorch/test_grouped_mlp.py Adds numerical coverage for row-wise prequantized grouped inputs and gradients, while explicitly skipping fused backward with frozen weights.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Row-wise MXFP8 GroupedTensor] --> B[Repack as GroupedTensorStorage]
  B --> C[Swizzle row-wise scales]
  B --> D{Columnwise copy needed?}
  D -->|Yes| E[Dequantize]
  E --> F[Columnwise-only requantize]
  C --> G[Forward or dgrad grouped GEMM]
  F --> H[Wgrad grouped GEMM]
  E --> I[Bias and routing-scale reductions]
Loading

Reviews (4): Last reviewed commit: "allow bias + frozen weight path in prequ..." | Re-trigger Greptile

Comment thread transformer_engine/pytorch/ops/basic/grouped_linear.py Outdated
Signed-off-by: YangFei1990 <feiw@nvidia.com>
Signed-off-by: YangFei1990 <feiw@nvidia.com>
Comment thread transformer_engine/pytorch/ops/basic/grouped_linear.py
Signed-off-by: YangFei1990 <feiw@nvidia.com>
@YangFei1990

Copy link
Copy Markdown
Collaborator Author

/te-ci pytorch

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants