Skip to content

Commit f97d4cd

Browse files
authored
fix(recipe): partition GLM-4.5 pipeline layers (#5551)
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
1 parent 5e554f1 commit f97d4cd

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎src/megatron/bridge/recipes/glm/h100/glm45.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def glm45_355b_pretrain_128gpu_h100_bf16_config() -> ConfigContainer:
4848
cfg.model.tensor_model_parallel_size = 2
4949
cfg.model.pipeline_model_parallel_size = 8
5050
cfg.model.pipeline_model_parallel_layout = None
51+
cfg.model.num_layers_in_first_pipeline_stage = 10
52+
cfg.model.num_layers_in_last_pipeline_stage = 10
5153
cfg.model.pipeline_dtype = None
5254
cfg.model.virtual_pipeline_model_parallel_size = None
5355
cfg.model.context_parallel_size = 1
@@ -179,6 +181,8 @@ def glm45_air_106b_pretrain_32gpu_h100_bf16_config() -> ConfigContainer:
179181
cfg.model.tensor_model_parallel_size = 1
180182
cfg.model.pipeline_model_parallel_size = 4
181183
cfg.model.pipeline_model_parallel_layout = None
184+
cfg.model.num_layers_in_first_pipeline_stage = 11
185+
cfg.model.num_layers_in_last_pipeline_stage = 11
182186
cfg.model.pipeline_dtype = None
183187
cfg.model.virtual_pipeline_model_parallel_size = None
184188
cfg.model.context_parallel_size = 1
@@ -314,6 +318,8 @@ def glm45_355b_sft_128gpu_h100_bf16_config() -> ConfigContainer:
314318
cfg.model.pipeline_model_parallel_layout = None
315319
cfg.model.tensor_model_parallel_size = 2
316320
cfg.model.pipeline_model_parallel_size = 8
321+
cfg.model.num_layers_in_first_pipeline_stage = 10
322+
cfg.model.num_layers_in_last_pipeline_stage = 10
317323
cfg.model.pipeline_dtype = None
318324
cfg.model.virtual_pipeline_model_parallel_size = None
319325
cfg.model.context_parallel_size = 1
@@ -449,6 +455,8 @@ def glm45_air_106b_sft_32gpu_h100_bf16_config() -> ConfigContainer:
449455
cfg.model.pipeline_model_parallel_layout = None
450456
cfg.model.tensor_model_parallel_size = 1
451457
cfg.model.pipeline_model_parallel_size = 4
458+
cfg.model.num_layers_in_first_pipeline_stage = 11
459+
cfg.model.num_layers_in_last_pipeline_stage = 11
452460
cfg.model.pipeline_dtype = None
453461
cfg.model.virtual_pipeline_model_parallel_size = None
454462
cfg.model.context_parallel_size = 1

‎tests/unit_tests/recipes/test_glm45_recipes.py‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,11 @@ def __init__(self):
5454
# Set default attributes that recipes might set
5555
self.tensor_model_parallel_size = 1
5656
self.pipeline_model_parallel_size = 1
57+
self.pipeline_model_parallel_layout = None
5758
self.pipeline_dtype = None
5859
self.virtual_pipeline_model_parallel_size = None
60+
self.num_layers_in_first_pipeline_stage = None
61+
self.num_layers_in_last_pipeline_stage = None
5962
self.context_parallel_size = 1
6063
self.expert_model_parallel_size = 1
6164
self.expert_tensor_parallel_size = None
@@ -103,6 +106,23 @@ def from_hf_pretrained(hf_path: str, **kwargs):
103106
return _FakeBridge()
104107

105108

109+
class _RealDepthFakeBridge(_FakeBridge):
110+
"""Fake AutoBridge that preserves the selected GLM-4.5 model depth."""
111+
112+
def __init__(self, num_layers: int):
113+
self.num_layers = num_layers
114+
115+
def to_megatron_provider(self, load_weights: bool = False):
116+
model = _FakeModelCfg()
117+
model.num_layers = self.num_layers
118+
return model
119+
120+
@staticmethod
121+
def from_hf_pretrained(hf_path: str, **kwargs):
122+
num_layers = 46 if hf_path.endswith("Air") else 92
123+
return _RealDepthFakeBridge(num_layers)
124+
125+
106126
class _FakeTokenizer:
107127
"""Fake HuggingFace tokenizer for testing."""
108128

@@ -439,6 +459,35 @@ def test_glm45_air_106b_pretrain_defaults(monkeypatch: pytest.MonkeyPatch):
439459
assert hasattr(cfg.model, "mtp_loss_scaling_factor")
440460

441461

462+
@pytest.mark.parametrize(
463+
"recipe_name,num_layers",
464+
[
465+
("glm45_355b_pretrain_config", 92),
466+
("glm45_355b_sft_config", 92),
467+
("glm45_air_106b_pretrain_config", 46),
468+
("glm45_air_106b_sft_config", 46),
469+
],
470+
)
471+
def test_glm45_pipeline_partition_covers_real_model_depth(
472+
recipe_name: str,
473+
num_layers: int,
474+
monkeypatch: pytest.MonkeyPatch,
475+
):
476+
"""GLM-4.5 recipe defaults should partition every real decoder layer."""
477+
from megatron.core.transformer.transformer_block import get_num_layers_to_build
478+
479+
recipe_func = getattr(_glm_module, recipe_name)
480+
patch_recipe_module_global(monkeypatch, recipe_func, "AutoBridge", _RealDepthFakeBridge)
481+
482+
cfg = recipe_func()
483+
layers_per_stage = [
484+
get_num_layers_to_build(cfg.model, pp_rank=pp_rank)
485+
for pp_rank in range(cfg.model.pipeline_model_parallel_size)
486+
]
487+
488+
assert sum(layers_per_stage) == num_layers
489+
490+
442491
def test_glm45_sft_offline_packing_is_disabled(monkeypatch: pytest.MonkeyPatch):
443492
"""Test that unsupported offline packing remains disabled for GLM-4.5."""
444493
from megatron.bridge.recipes.glm import glm45_355b_sft_config

0 commit comments

Comments
 (0)