Skip to content

Commit b0d07f4

Browse files
kamran-nvidiaclaude
andcommitted
test(recipe): give the offline Nemotron 3 Ultra provider its layer pattern
The 384-GPU H100 SFT recipe splits Nemotron 3 Ultra's hybrid_layer_pattern into pipeline stages, so the shared offline provider used by test_all_recipe_factories.py needs that model's pattern, as it already has for GLM-5.x and DeepSeek-V4. Define the 108-layer pattern once in recipe_test_utils.py and reuse it in the two Ultra recipe test files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kamran Jafari <kjafarisadeg@nvidia.com>
1 parent 358b5b7 commit b0d07f4

3 files changed

Lines changed: 19 additions & 13 deletions

File tree

‎tests/unit_tests/recipes/nemotronh/test_nemotron_3_ultra.py‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,9 @@
3636
nemotron_3_ultra_pretrain_config,
3737
nemotron_3_ultra_sft_openmathinstruct2_packed_config,
3838
)
39-
from tests.unit_tests.recipes.recipe_test_utils import patch_recipe_module_global
40-
41-
42-
# Nemotron 3 Ultra's 108-layer decoder pattern from the Hugging Face config.
43-
ULTRA_HYBRID_LAYER_PATTERN = (
44-
"MEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEME"
39+
from tests.unit_tests.recipes.recipe_test_utils import (
40+
NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN,
41+
patch_recipe_module_global,
4542
)
4643

4744

@@ -50,7 +47,7 @@ class _FakeUltraProvider:
5047

5148
def __init__(self) -> None:
5249
self.vocab_size = 256
53-
self.hybrid_layer_pattern = ULTRA_HYBRID_LAYER_PATTERN
50+
self.hybrid_layer_pattern = NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN
5451

5552
def finalize(self) -> None:
5653
return None
@@ -254,7 +251,7 @@ def test_openmath_sft_uses_48_node_layout() -> None:
254251
assert cfg.model.recompute_modules == ["moe", "core_attn", "moe_act"]
255252
stages = cfg.model.hybrid_layer_pattern.split("|")
256253
assert [len(stage) for stage in stages] == [9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 11, 5]
257-
assert "".join(stages) == ULTRA_HYBRID_LAYER_PATTERN
254+
assert "".join(stages) == NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN
258255
# A recomputed TE norm as a stage's first backward op fails on TE >= 2.18 (invalid device context).
259256
assert "layernorm" not in cfg.model.recompute_modules
260257
assert cfg.dist.distributed_timeout_minutes == 90

‎tests/unit_tests/recipes/recipe_test_utils.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ def exported_recipe_factory_keys(module: ModuleType) -> set[tuple[str, str]]:
117117
}
118118

119119

120+
# Nemotron 3 Ultra's 108-layer decoder pattern from the Hugging Face config.
121+
NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN = (
122+
"MEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEME"
123+
)
124+
125+
120126
class _OfflineModelProvider:
121127
"""Mutable provider with the fields HF-backed recipes read before writing.
122128
@@ -195,6 +201,9 @@ def to_megatron_provider(self, *args: object, **kwargs: object) -> _OfflineModel
195201
if model_id in {"zai-org/glm-5.2", "zai-org/glm-5.3"}:
196202
provider.dsa_indexer_topk_freq = 4
197203
provider.dsa_indexer_skip_topk_offset = 3
204+
if model_id == "nvidia/nvidia-nemotron-3-ultra-550b-a55b-bf16":
205+
provider.hybrid_layer_pattern = NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN
206+
provider.num_layers = len(provider.hybrid_layer_pattern)
198207
if "deepseek-v4-" in model_id:
199208
logical_layers = 61 if "deepseek-v4-pro" in model_id else 43
200209
provider.hybrid_layer_pattern = "WEWE" + "".join(

‎tests/unit_tests/recipes/test_nemotronh_recipes.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
import torch
2828

2929
from megatron.bridge.training.utils.omegaconf_utils import OverridesError, process_config_with_overrides
30-
from tests.unit_tests.recipes.recipe_test_utils import patch_recipe_module_global
30+
from tests.unit_tests.recipes.recipe_test_utils import (
31+
NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN,
32+
patch_recipe_module_global,
33+
)
3134

3235

3336
_nemotronh_module = importlib.import_module("megatron.bridge.recipes.nemotronh")
@@ -77,10 +80,7 @@ class _FakeUltraModelProvider(_FakeModelProvider):
7780

7881
def __init__(self) -> None:
7982
super().__init__()
80-
self.hybrid_layer_pattern = (
81-
"MEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEME"
82-
"MEM*EMEMEM*EMEMEMEM*EMEMEMEM*EMEMEM*EMEMEMEM*EMEMEMEME"
83-
)
83+
self.hybrid_layer_pattern = NEMOTRON_3_ULTRA_HYBRID_LAYER_PATTERN
8484

8585

8686
class _FakeUltraAutoBridge(_FakeAutoBridge):

0 commit comments

Comments
 (0)