Repository navigation
Enable inference CUDA graphs with Shortcut MoE and wide residuals #7772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
santhnm2
merged 17 commits into
NVIDIA:main
from
susavlsh10:nemotron4-inference-cuda-graphs
Oct 15, 2026
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
c4f5455
Enable Nemotron 4 Shortcut MoE inference CUDA graphs
susavlsh10 0d33120
Remove redundant inference RMSNorm dtype adaptation
susavlsh10 bddb884
Align checkpoint routing test with upstream MIMO detection
susavlsh10 74b714f
Handle SSM token padding independently of batch-invariant guards
susavlsh10 61c1d14
Prepare global-batch QB routing in shared inference configuration
susavlsh10 0b93ab0
Remove QB inference workaround in favor of native support
0631f92
Update residual recompute wide-residual graph guard expectation
susavlsh10 9eb096f
Mock checkpoint metadata in MIMO text detection test
susavlsh10 7738d1d
Merge branch 'main' into nemotron4-inference-cuda-graphs
susavlsh10 8113702
Merge branch 'main' into nemotron4-inference-cuda-graphs
balasaajay 8e455a2
Fix MIMO checkpoint detection test import
susavlsh10 29809c7
Merge branch 'main' into nemotron4-inference-cuda-graphs
santhnm2 95f9b94
Merge branch 'main' into nemotron4-inference-cuda-graphs
santhnm2 c436ba3
Merge with main
santhnm2 d66aacb
Clean up NVLS state after Shortcut MoE CUDA graph tests
susavlsh10 27c6495
Merge branch 'main' into nemotron4-inference-cuda-graphs
santhnm2 0c70a59
Merge branch 'main' into nemotron4-inference-cuda-graphs
balasaajay File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
tests/unit_tests/inference/engines/test_shortcut_moe_cuda_graph_e2e.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| # Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
|
|
||
| """Exercise Shortcut MoE and wide residuals through the inference graph manager.""" | ||
|
|
||
| import torch | ||
|
|
||
| from megatron.core import parallel_state | ||
| from megatron.core.activations import squared_relu | ||
| from megatron.core.inference.symmetric_memory import SymmetricMemoryManager | ||
| from megatron.core.models.hybrid.hybrid_layer_specs import ( | ||
| wide_residual_gated_delta_product_inference_stack_spec, | ||
| ) | ||
| from megatron.core.models.hybrid.hybrid_model import HybridModel | ||
| from megatron.core.models.hybrid.shortcut_block import ShortcutMoEBlock | ||
| from megatron.core.transformer.attention import Attention | ||
| from megatron.core.transformer.enums import AttnBackend | ||
| from megatron.core.transformer.moe.token_dispatcher_inference import NVLSAllGatherVDispatcher | ||
| from megatron.core.transformer.transformer_config import TransformerConfig | ||
| from megatron.core.transformer.wide_residual_config import WideResidualConfig | ||
| from tests.unit_tests.inference.engines.test_gdp_cuda_graph_e2e import ( | ||
| FLASH_ATTENTION_VERSION, | ||
| MAX_SEQ_LEN, | ||
| VOCAB_SIZE, | ||
| ) | ||
| from tests.unit_tests.inference.engines.test_gdp_cuda_graph_e2e import ( | ||
| TestGDPCudaGraphE2E as _GDPGraphTest, | ||
| ) | ||
| from tests.unit_tests.test_utilities import Utils | ||
|
|
||
|
|
||
| class TestShortcutMoECudaGraphE2E(_GDPGraphTest): | ||
| """Greedy tokens must match eager inference for a GDP/Shortcut-MoE pair.""" | ||
|
|
||
| @classmethod | ||
| def setup_class(cls): | ||
| Utils.initialize_distributed() | ||
| Utils.initialize_model_parallel( | ||
| expert_model_parallel_size=torch.distributed.get_world_size() | ||
| ) | ||
|
|
||
| @classmethod | ||
| def teardown_class(cls): | ||
| try: | ||
| NVLSAllGatherVDispatcher._delete_buffers() | ||
| SymmetricMemoryManager.destroy() | ||
| finally: | ||
| super().teardown_class() | ||
|
|
||
| def _create_model(self): | ||
| torch.manual_seed(1234) | ||
| config = TransformerConfig( | ||
| params_dtype=torch.bfloat16, | ||
| num_layers=3, | ||
| hidden_size=256, | ||
| num_attention_heads=16, | ||
| ffn_hidden_size=512, | ||
| activation_func=squared_relu, | ||
| mamba_num_heads=8, | ||
| mamba_head_dim=32, | ||
| mamba_num_groups=8, | ||
| mamba_state_dim=64, | ||
| gdp_num_householder=2, | ||
| num_moe_experts=8, | ||
| moe_router_topk=2, | ||
| moe_router_pre_softmax=True, | ||
| moe_router_dtype="fp32", | ||
| moe_token_dispatcher_type="alltoall", | ||
| moe_shortcut_connection=True, | ||
| moe_shared_expert_intermediate_size=512, | ||
| moe_shortcut_post_norm=True, | ||
| wide_residual=WideResidualConfig(num_streams=3), | ||
| use_cpu_initialization=True, | ||
| transformer_impl="inference_optimized", | ||
| normalization="RMSNorm", | ||
| cuda_graph_impl="local", | ||
| inference_cuda_graph_scope="block", | ||
| inference_rng_tracker=True, | ||
| tensor_model_parallel_size=1, | ||
| expert_model_parallel_size=parallel_state.get_expert_model_parallel_world_size(), | ||
| pipeline_model_parallel_size=1, | ||
| pipeline_dtype=torch.bfloat16, | ||
| add_bias_linear=False, | ||
| is_hybrid_model=True, | ||
| attention_dropout=0.0, | ||
| attention_backend=AttnBackend.flash, | ||
| flash_attention_version=FLASH_ATTENTION_VERSION, | ||
| ) | ||
| model = HybridModel( | ||
| config=config, | ||
| hybrid_stack_spec=wide_residual_gated_delta_product_inference_stack_spec, | ||
| vocab_size=VOCAB_SIZE, | ||
| max_sequence_length=MAX_SEQ_LEN, | ||
| parallel_output=True, | ||
| hybrid_layer_pattern="ME*", | ||
| pre_process=parallel_state.is_pipeline_first_stage(), | ||
| post_process=parallel_state.is_pipeline_last_stage(), | ||
| ).cuda() | ||
| assert any(isinstance(layer, ShortcutMoEBlock) for layer in model.decoder.layers) | ||
| for param in model.parameters(): | ||
| param.data = param.data.to(config.params_dtype) | ||
| model.eval() | ||
| for module in model.modules(): | ||
| if isinstance(module, Attention): | ||
| module.batch_invariant_mode = True | ||
| return model |
29 changes: 29 additions & 0 deletions
29
tests/unit_tests/inference/test_mimo_text_checkpoint_detection.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
|
|
||
| """MIMO checkpoints select the text backbone and its checkpoint prefix.""" | ||
|
|
||
| from argparse import Namespace | ||
|
|
||
| import pytest | ||
|
|
||
| from examples.inference.advanced import vlm_dynamic_inference | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("provider", ["nemotron-moe-vlm", "nemotron-moe-mistral-vit"]) | ||
| def test_mimo_text_detection_selects_text_backbone(monkeypatch, provider): | ||
| """Model detection selects the text backbone without constructing a VLM.""" | ||
| args = Namespace(model_provider="gpt") | ||
| saved = Namespace(model_provider=provider, mimo_llm_tp=1) | ||
| monkeypatch.setattr(vlm_dynamic_inference, "load_args_from_checkpoint", lambda _: (args, saved)) | ||
| # Detection also reads tensor metadata on newer main; keep this unit test independent of I/O. | ||
| monkeypatch.setattr( | ||
| vlm_dynamic_inference, | ||
| "_checkpoint_tensor_keys", | ||
| lambda _: [ | ||
| "language_model.module.module.decoder.layers.0.self_attention.linear_qkv.weight" | ||
| ], | ||
| raising=False, | ||
| ) | ||
| assert not vlm_dynamic_inference._detect_vlm_from_checkpoint(args) | ||
| assert args.model_provider == "hybrid" | ||
| assert args.checkpoint_model_prefix == "language_model.module.module." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.