Skip to content

Reduce Grouped MLP Fuser CPU Overhead - #3410

Open
zhongbozhu wants to merge 2 commits into
NVIDIA:mainfrom
zhongbozhu:opfuser_group_mlp_cpu_optim
Open

Reduce Grouped MLP Fuser CPU Overhead#3410
zhongbozhu wants to merge 2 commits into
NVIDIA:mainfrom
zhongbozhu:opfuser_group_mlp_cpu_optim

Conversation

@zhongbozhu

@zhongbozhu zhongbozhu commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Description

Reuse fused operation plans when full activation recompute changes grad mode, and avoid redundant CUDA current-device discovery for grouped MLP stream lookups.

Fixes # (issue)

#2897

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

Reuse fused operation plans when full activation recompute changes grad mode, and avoid redundant CUDA current-device discovery for grouped MLP stream lookups.

Co-authored-by: Ting-Yang Kao <tingyangk@nvidia.com>
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
@github-actions github-actions Bot added the community-contribution PRs from external contributor outside the core maintainers, representing community-driven work. label Aug 20, 2026
Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com>
@zhongbozhu
zhongbozhu marked this pull request as ready for review August 20, 2026 18:39
@zhongbozhu
zhongbozhu requested a review from timmoon10 as a code owner August 20, 2026 18:39
@zhongbozhu

Copy link
Copy Markdown
Collaborator Author

/te-ci pytorch L1

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reduces grouped-MLP fuser overhead by caching operation plans across grad-mode transitions and selecting CUDA streams directly by operand device.

  • Adds per-fusion-configuration forward/backward plan caching to OperationFuser.
  • Adds a test covering alternating checkpoint forward and recomputation boundaries.
  • Avoids redundant current-device discovery in grouped-MLP CUDA stream lookups.

Confidence Score: 4/5

The PR should not merge until cached plans account for instance-level recipe settings that govern grouped-MLP fusion eligibility.

Returning to NVFP4 with RHT disabled can restore an earlier RHT-dependent grouped-MLP plan even though the newly reset quantizers no longer satisfy that plan’s eligibility requirement.

Files Needing Attention: transformer_engine/pytorch/ops/fuser.py

Important Files Changed

Filename Overview
transformer_engine/pytorch/ops/fuser.py Adds reusable fusion-plan caching, but the cache key cannot distinguish an NVFP4 recipe instance whose RHT setting changes fusion eligibility.
transformer_engine/pytorch/ops/fused/grouped_mlp.py Changes current-stream discovery to select the CUDA device explicitly; no independent defect was established in these lookups.
tests/pytorch/test_fusible_ops.py Tests grad-boundary cache reuse, but does not cover returning to a recipe class with different instance-level fusion settings.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[OperationFuser invocation] --> B[Read current recipe and backward boundary]
  B --> C{Recipe state changed?}
  C -->|Yes| D[Reset basic-op recipe state]
  C -->|No| E[Build cache key]
  D --> E
  E --> F{Cached plan exists?}
  F -->|Yes| G[Restore cached forward/backward plans]
  F -->|No| H[Run fusion eligibility passes]
  H --> I[Cache resulting plans]
  G --> J[Execute current invocation]
  I --> J
Loading

Reviews (1): Last reviewed commit: "resolve comments" | Re-trigger Greptile

Comment on lines +679 to +683
fusion_params = (recipe_type, first_op_requiring_backward, backward_override)
cached_ops = self._fused_ops_cache.get(fusion_params)
if cached_ops is not None:
self._forward_ops, self._backward_ops = cached_ops
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Cache ignores RHT eligibility

If a persistent fuser runs with RHT-enabled NVFP4, switches recipe types, and then returns to NVFP4 with disable_rht=True, this class-based key restores the earlier RHT-dependent grouped-MLP plan after quantizers have been reset without RHT, causing incorrect results or a grouped-quantization failure instead of selecting the supported unfused path.

Knowledge Base Used:

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.

Sigh, do we really need to worry about this :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fair point — you're right to push back. The scenario requires dynamically mutating disable_rht on a recipe of the same type between iterations while backward_override stays constant. In practice, recipes are constructed once before training and not mutated mid-run, so this combination is essentially hypothetical. The key already covers the axes that actually change at runtime.

The concern was over-engineered for a code path that doesn't exist in real workloads. No action needed here.

Shall I remember this as a rule: "Do not flag recipe-attribute cache misses as risks when the attributes in question are immutable after recipe construction"?

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.

Agreed. disable_rht should not affect the fusion cache key. The fused grouped-MLP plan can be selected by recipe type, while tex.group_quantize handles the current quantizer configuration by dispatching a supported kernel or raising a clear error. The existing fusion-time disable_rht check should be removed so cached and newly built plans behave consistently.

# backward boundary in the key, but pay construction cost only once for
# each configuration. Full recompute therefore builds at most one
# no-grad plan and one grad-enabled plan for a stable recipe.
fusion_params = (recipe_type, first_op_requiring_backward, backward_override)

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.

I think we should use recipe object instead of recipe_type as fusion_param key And implement hash function for it. Since that governs the fusion and not just the recipe type

cc: @timmoon10

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.

2 participants