Skip to content

Commit 132665a

Browse files
fix(ckpt): handle missing newer MLM checkpoint args (#5715)
Signed-off-by: caohch-1 <caohch2023@shanghaitech.edu.cn> Co-authored-by: Charlie Truong <chtruong@nvidia.com>
1 parent 9d8261b commit 132665a

2 files changed

Lines changed: 60 additions & 12 deletions

File tree

‎src/megatron/bridge/training/mlm_compat/arguments.py‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ def _transformer_config_from_args(
6969
args: argparse.Namespace, config_class: type[TransformerConfig] = TransformerConfig
7070
) -> TransformerConfig:
7171
"""Build a variant of TransformerConfig based on contents of the MLM argparse args object."""
72-
if args.multi_latent_attention:
72+
multi_latent_attention = getattr(args, "multi_latent_attention", False)
73+
if multi_latent_attention:
7374
config_class = MLATransformerConfig
7475

75-
if args.heterogeneous_layers_config_path is not None:
76-
assert not args.multi_latent_attention, "Multi latent attention with heterogeneous layers is not supported."
76+
heterogeneous_layers_config_path = getattr(args, "heterogeneous_layers_config_path", None)
77+
if heterogeneous_layers_config_path is not None:
78+
assert not multi_latent_attention, "Multi latent attention with heterogeneous layers is not supported."
7779
config_class = HeterogeneousTransformerConfig
7880

7981
# Translate args to core transformer configuration
@@ -90,10 +92,13 @@ def _transformer_config_from_args(
9092
kw_args["pipeline_dtype"] = args.params_dtype
9193
kw_args["batch_p2p_comm"] = not args.overlap_p2p_comm
9294
kw_args["num_moe_experts"] = args.num_experts
93-
kw_args["rotary_interleaved"] = args.rotary_interleaved
94-
kw_args["num_layers_in_first_pipeline_stage"] = args.decoder_first_pipeline_num_layers
95-
kw_args["num_layers_in_last_pipeline_stage"] = args.decoder_last_pipeline_num_layers
96-
kw_args["fp8_param"] = args.fp8_param_gather
95+
if hasattr(args, "decoder_first_pipeline_num_layers"):
96+
kw_args["num_layers_in_first_pipeline_stage"] = args.decoder_first_pipeline_num_layers
97+
if hasattr(args, "decoder_last_pipeline_num_layers"):
98+
kw_args["num_layers_in_last_pipeline_stage"] = args.decoder_last_pipeline_num_layers
99+
if hasattr(args, "fp8_param_gather"):
100+
kw_args["fp8_param"] = args.fp8_param_gather
101+
97102
if args.swiglu:
98103
kw_args["activation_func"] = F.silu
99104
kw_args["gated_linear_unit"] = True
@@ -109,12 +114,10 @@ def _transformer_config_from_args(
109114
kw_args["num_query_groups"] = args.num_query_groups
110115
else:
111116
kw_args["num_query_groups"] = None
112-
kw_args["config_logger_dir"] = args.config_logger_dir
113117

114-
if len(args.cp_comm_type) == 1:
115-
kw_args["cp_comm_type"] = args.cp_comm_type[0]
116-
if args.is_hybrid_model:
117-
kw_args["is_hybrid_model"] = args.is_hybrid_model
118+
cp_comm_type = getattr(args, "cp_comm_type", ["p2p"])
119+
if len(cp_comm_type) == 1:
120+
kw_args["cp_comm_type"] = cp_comm_type[0]
118121

119122
# handle quantization config
120123
# NOTE: Kitchen arguments are only added to the namespace when

‎tests/unit_tests/training/mlm_compat/test_arguments.py‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,51 @@ def basic_args(self):
173173

174174
return args
175175

176+
@pytest.mark.parametrize(
177+
("missing_arg", "config_attr", "expected"),
178+
[
179+
("multi_latent_attention", "multi_latent_attention", False),
180+
("rotary_interleaved", "rotary_interleaved", False),
181+
("fp8_param_gather", "fp8_param", False),
182+
("config_logger_dir", "config_logger_dir", ""),
183+
("cp_comm_type", "cp_comm_type", "p2p"),
184+
("is_hybrid_model", "is_hybrid_model", False),
185+
],
186+
)
187+
def test_missing_newer_arg_uses_legacy_default(self, basic_args, missing_arg, config_attr, expected):
188+
delattr(basic_args, missing_arg)
189+
190+
cfg = _transformer_config_from_args(basic_args)
191+
192+
assert getattr(cfg, config_attr) == expected
193+
194+
def test_missing_heterogeneous_layers_config_path_uses_default(self, basic_args):
195+
delattr(basic_args, "heterogeneous_layers_config_path")
196+
197+
cfg = _transformer_config_from_args(basic_args)
198+
199+
assert type(cfg) is TransformerConfig
200+
201+
def test_missing_uneven_pipeline_args_uses_legacy_defaults(self, basic_args):
202+
delattr(basic_args, "decoder_first_pipeline_num_layers")
203+
delattr(basic_args, "decoder_last_pipeline_num_layers")
204+
205+
cfg = _transformer_config_from_args(basic_args)
206+
207+
assert cfg.num_layers_in_first_pipeline_stage is None
208+
assert cfg.num_layers_in_last_pipeline_stage is None
209+
210+
def test_preserves_explicit_newer_args(self, basic_args):
211+
basic_args.rotary_interleaved = True
212+
basic_args.config_logger_dir = "/tmp/config-logger"
213+
basic_args.is_hybrid_model = True
214+
215+
cfg = _transformer_config_from_args(basic_args)
216+
217+
assert cfg.rotary_interleaved is True
218+
assert cfg.config_logger_dir == "/tmp/config-logger"
219+
assert cfg.is_hybrid_model is True
220+
176221
def test_basic_transformer_config(self, basic_args):
177222
"""Test basic transformer config creation."""
178223
cfg = _transformer_config_from_args(basic_args)

0 commit comments

Comments
 (0)