Skip to content

Improve device-init grouped linear module with single grouped weight support #3224

Open
zhongbozhu wants to merge 16 commits into
NVIDIA:mainfrom
zhongbozhu:improve_device_grouped_linear
Open

Improve device-init grouped linear module with single grouped weight support #3224
zhongbozhu wants to merge 16 commits into
NVIDIA:mainfrom
zhongbozhu:improve_device_grouped_linear

Conversation

@zhongbozhu

@zhongbozhu zhongbozhu commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes numerical issues when using single weight for TE module grouped linear. Limit the single weight feature to the grouped tensor API instead of the legacy path.

TODO: test E2E convergence, unit test directly from Mcore.

Note: needs to pay extra attention to whether bias grad and weight grad are generated properly.

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

@github-actions github-actions Bot added the community-contribution PRs from external contributor outside the core maintainers, representing community-driven work. label Jul 20, 2026
@zhongbozhu
zhongbozhu force-pushed the improve_device_grouped_linear branch from aa3b9d1 to 47ba66a Compare July 20, 2026 22:36
Comment thread transformer_engine/pytorch/module/grouped_linear.py Outdated
@zhongbozhu
zhongbozhu force-pushed the improve_device_grouped_linear branch from ff7eee2 to a43f70f Compare July 20, 2026 22:53
Comment thread transformer_engine/pytorch/module/grouped_linear.py Outdated
is_grad_enabled = torch.is_grad_enabled()
num_gemms = self.num_gemms

if FP8GlobalStateManager.fp8_graph_capturing():

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.

Note: this code block was deleted because it was duplicated

@zhongbozhu
zhongbozhu marked this pull request as ready for review July 23, 2026 10:52
@zhongbozhu

Copy link
Copy Markdown
Collaborator Author

/te-ci pytorch

@greptile-apps

greptile-apps Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a single_grouped_weight / single_grouped_bias experimental feature to both the module-level and op-fuser GroupedLinear paths. Instead of N separate per-GEMM weight{i} parameters, a single GroupedTensor parameter is registered, reducing optimizer state and checkpoint size. The PR also refactors the grouped-tensor path predicate into exported is_op_fuser_grouped_tensor_path_supported / is_module_grouped_tensor_path_supported helpers and extends group_quantize with output-reuse and noop_flag support.

  • Single-param layout: New make_grouped_weights() / _make_grouped_biases() methods build a GroupedTensor from a packed storage tensor; checkpoint compatibility is maintained via _remap_grouped_weight_state_dict_keys.
  • C++ extension: group_quantize gains an output parameter for in-place workspace reuse across iterations, plus noop_flag threading into the FP8 block-scaling kernel.
  • CUDA kernel fix: group_quantize_mxfp8.cuh corrects per-member scale-base computation for SAME_BOTH_DIMS shape representation.

Confidence Score: 3/5

Do not merge until the two P1 issues are resolved: meta-device AttributeError on construction and the missing skip guard in test_single_grouped_weight_rejects_host_m_splits.

Two confirmed P1 defects — one causes an AttributeError at module construction time on meta device with specific flags, and one causes a test to fail with the wrong exception type on pre-Hopper hardware. Both are straightforward one-line fixes but block correctness on non-Hopper CI runners.

Files Needing Attention: transformer_engine/pytorch/ops/basic/grouped_linear.py (lines 289-297) and tests/pytorch/test_grouped_linear.py (lines 48-63)

Important Files Changed

Filename Overview
transformer_engine/pytorch/module/grouped_linear.py Adds single_grouped_weight/bias support, make_grouped_weights(), state-dict remapping, and grouped-tensor forward/backward paths; logic is correct but early return in make_grouped_weights() for float8_current_scaling silently skips weight registration
transformer_engine/pytorch/ops/basic/grouped_linear.py Refactors grouped-tensor predicate and adds single-param support; P1 bug: _apply_delay_wgrad_param_hooks accesses self.weight before registration on meta device
transformer_engine/pytorch/csrc/extensions/cast.cpp Extends group_quantize with output reuse and noop_flag; identity/shape pre-checks are correct, noop_flag threading into FP8 block-scaling looks sound
transformer_engine/common/cast/mxfp8/group_quantize_mxfp8.cuh Fixes per-member scale-base for SAME_BOTH_DIMS; integer division is used without remainder assertion — benign if callers enforce divisibility
tests/pytorch/test_grouped_linear.py 538-line test suite for new single-param feature; test_single_grouped_weight_rejects_host_m_splits is missing _require_native_grouped_tensor_gemm() skip guard (P1)
tests/pytorch/test_grouped_mlp.py Replaces manual capability checks with is_op_fuser_grouped_tensor_path_supported; adds single_grouped_bias storage test; looks correct
transformer_engine/pytorch/ops/fused/grouped_mlp.py Minor fix: replaces _get_bias_tensors+stack with _get_packed_bias_tensor to support single_grouped_bias; correct

Reviews (13): Last reviewed commit: "relax atol for bf16 sum errors" | Re-trigger Greptile

Comment thread transformer_engine/pytorch/module/grouped_linear.py
Comment thread tests/pytorch/test_grouped_linear.py
Comment thread tests/pytorch/test_grouped_mlp.py Outdated

@timmoon10 timmoon10 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The biggest change in this PR is that TE is abandoning any attempt to make single_grouped_weight=True a general feature. Things must be exactly right, or we crash. Given how delicate and experimental this feature has been, I'm not opposed.

The second change is that users must opt-in to access the grouped GEMM kernel. This is also reasonable, since it has alignment requirements for m_splits and it's helpful having a way for users to accept that stricter contract.

We are experiencing many test failures. Given that single_grouped_weight is no longer a general feature, I think it's reasonable we move the corresponding tests to test_grouped_linear.py and test_grouped_mlp.py.

Comment on lines +761 to +764
raise ValueError(
"The native grouped_tensor path requires CUDA m_splits. Pass a CUDA int64 "
"tensor, or select grouped_gemm_backend='legacy'."
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I get that the h2d memcpy is suboptimal, but it's trivially easy to handle. Erroring out seems excessively rigid.

Suggested change
raise ValueError(
"The native grouped_tensor path requires CUDA m_splits. Pass a CUDA int64 "
"tensor, or select grouped_gemm_backend='legacy'."
)
m_splits = m_splits.to(device=device)

We need to handle the d2h case anyways when the user has specified grouped_gemm_backend="grouped_tensor", but it's not supported and we fallback to split-quantize.

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.

But if the alignment is not provided in the first place, converting it to a device tensor also wouldn't work right, I am okay with another alignment check before adding this H2D copy.

EXPERIMENTAL and subject to change. Gated by the
``NVTE_GROUPED_LINEAR_SINGLE_PARAM`` environment variable: if the env var
is not set this argument is forced to ``False`` with a warning.
grouped_gemm_backend : {"legacy", "grouped_tensor"}, default = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These are misleading names.

  • Legacy implies we are deprecating it, but in fact it is the default backend and it is the fallback when the grouped tensor impl is not supported.
  • As mentioned in https://github.com/NVIDIA/TransformerEngine/pull/3224/changes#r3618050729, it's confusing that we might not actually perform the backend specified by the user. The user might put grouped_gemm_backend="grouped_tensor" and we'll actually do split-quantize because the cuBLAS version is old or something.

Really, this is not a backend config. It's a hint where the user promises to provide m_splits with a certain alignment. I'd suggest changing this to a bool like enable_grouped_tensor_backend. Alternatively if we want to generalize in case we add more backends in the future, we could have a string like enabled_backends (enabled_backends="grouped_tensor,future_backend").

@zhongbozhu zhongbozhu Jul 24, 2026

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.

and we'll actually do split-quantize because the cuBLAS version is old or something

Should we just raise error instead of silently doing this fallback? As a user, it's actually annoying to specify some optimization but it's not working because a fallback get triggered.

I am okay with changing the TE interface into a bool flag like enable_grouped_tensor_backend instead of a str.

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.

renamed

zhongbozhu and others added 9 commits July 24, 2026 11:36
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
@zhongbozhu
zhongbozhu force-pushed the improve_device_grouped_linear branch from 3d37fd3 to 69b906f Compare July 24, 2026 18:36
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
@zhongbozhu
zhongbozhu force-pushed the improve_device_grouped_linear branch from f95ae42 to e02f24d Compare July 24, 2026 23:47
zhongbozhu and others added 3 commits July 24, 2026 21:27
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
@zhongbozhu
zhongbozhu force-pushed the improve_device_grouped_linear branch from b6a9482 to 25314b8 Compare July 25, 2026 07:08
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
Signed-off-by: zhongboz <zhongboz@nvidia.com>
):
pytest.skip("Recipe is not supported by the module GroupedTensor path on this system.")
if fuse_wgrad_accumulation and fp8_recipe is not None and fp8_recipe.float8_block_scaling():
# TODO: Re-enable after resolving cuBLASLt grouped FP8 block-scaling support for

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.

TODO: I don't quite understand why this is the case, but without it, cublas will complain cannot find supported gemm. Unclear if it's related with TE integration or a cublas issue or if upgrading to the next cublas version can fix it.
cc @denera @timmoon10

Signed-off-by: zhongboz <zhongboz@nvidia.com>
@zhongbozhu

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

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.

3 participants