Skip to content

Commit 53cb923

Browse files
committed
[training] fix: validate final MegatronMIMO weights
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
1 parent 600d069 commit 53cb923

3 files changed

Lines changed: 84 additions & 3 deletions

File tree

‎src/megatron/bridge/training/pretrain_megatron_mimo.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import torch.distributed as dist
3131

3232
from megatron.bridge.training.config import ConfigContainer, megatron_mimo_runtime_config_update
33+
from megatron.bridge.training.eval import evaluate_and_print_results
3334
from megatron.bridge.training.pretrain import _maybe_destroy_process_group
3435
from megatron.bridge.training.setup_megatron_mimo import setup_megatron_mimo
3536
from megatron.bridge.training.state import GlobalState
@@ -99,6 +100,30 @@ def pretrain_megatron_mimo(
99100
module_to_grid_tuple=setup_output.module_to_grid_tuple,
100101
)
101102

103+
# Ensure the completed weights are validated when the final step was not
104+
# already covered by interval evaluation.
105+
eval_interval = cfg.validation.eval_interval
106+
if eval_interval is None:
107+
eval_interval = cfg.train.eval_interval
108+
iteration = setup_output.global_state.train_state.step
109+
if (
110+
setup_output.valid_data_iterator is not None
111+
and cfg.validation.eval_iters
112+
and (not eval_interval or iteration % eval_interval != 0)
113+
):
114+
evaluate_and_print_results(
115+
state=setup_output.global_state,
116+
prefix=f"iteration {iteration} on validation set",
117+
forward_step_func=forward_step_func,
118+
data_iterator=setup_output.valid_data_iterator,
119+
model=[setup_output.model],
120+
config=cfg,
121+
verbose=True,
122+
write_to_tensorboard=True,
123+
p2p_communicator=setup_output.multimodule_communicator,
124+
pg_collection=setup_output.multimodule_pg_collection,
125+
)
126+
102127
# Post-training cleanup: finalize async saves, shut down NVRx/FT, flush
103128
# loggers, destroy GlobalState (which calls destroy_model_parallel internally).
104129
_finish_train(setup_output.global_state, setup_output.checkpoint_manager)

‎tests/functional_tests/test_groups/megatron_mimo/test_pretrain_megatron_mimo.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,8 @@ class TestMegatronMIMOTraining:
510510
"""
511511

512512
@pytest.mark.run_only_on("GPU")
513-
def test_megatron_mimo_interval_validation(self):
514-
"""MegatronMIMO should run interval validation with its canonical provider config."""
513+
def test_megatron_mimo_terminal_validation(self):
514+
"""MegatronMIMO should validate final weights after an off-interval step."""
515515
from megatron.bridge.training.state import GlobalState
516516

517517
initialize_distributed()
@@ -542,7 +542,7 @@ def test_megatron_mimo_interval_validation(self):
542542
)
543543

544544
cfg = _build_config(par_cfg, train_iters=1)
545-
cfg.validation.eval_interval = 1
545+
cfg.validation.eval_interval = 2
546546
cfg.validation.eval_iters = 1
547547
cfg.validation.eval_global_batch_size = 1
548548
cfg.validation.eval_micro_batch_size = 1

‎tests/unit_tests/training/megatron_mimo/test_pretrain_megatron_mimo.py‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,62 @@ def test_pretrain_megatron_mimo_calls_setup_and_train(
258258
mock_finish.assert_called_once()
259259

260260

261+
def test_pretrain_megatron_mimo_evaluates_terminal_weights_off_interval():
262+
"""MegatronMIMO should validate final weights when the last step is off interval."""
263+
from megatron.bridge.training.pretrain_megatron_mimo import pretrain_megatron_mimo
264+
265+
cfg = _make_cfg()
266+
cfg.validation.eval_interval = 2
267+
cfg.validation.eval_iters = 1
268+
269+
setup_output = _make_setup_output(module_to_grid_map={"language": MagicMock()})
270+
setup_output.valid_data_iterator = iter([object()])
271+
forward_step_func = MagicMock()
272+
events = []
273+
274+
def run_training(**_kwargs):
275+
events.append("train")
276+
setup_output.global_state.train_state.step = 1
277+
278+
with (
279+
patch("megatron.bridge.training.pretrain_megatron_mimo.megatron_mimo_runtime_config_update"),
280+
patch("megatron.bridge.training.pretrain_megatron_mimo.setup_megatron_mimo", return_value=setup_output),
281+
patch("megatron.bridge.training.pretrain_megatron_mimo.train_megatron_mimo", side_effect=run_training),
282+
patch(
283+
"megatron.bridge.training.pretrain_megatron_mimo.evaluate_and_print_results", create=True
284+
) as mock_evaluate,
285+
patch(
286+
"megatron.bridge.training.pretrain_megatron_mimo._finish_train",
287+
side_effect=lambda *_args: events.append("finish"),
288+
),
289+
patch("megatron.bridge.training.pretrain_megatron_mimo.dist") as mock_dist,
290+
):
291+
mock_dist.get_rank.return_value = 0
292+
mock_dist.is_initialized.return_value = True
293+
mock_evaluate.side_effect = lambda **_kwargs: events.append("evaluate")
294+
295+
pretrain_megatron_mimo(
296+
cfg=cfg,
297+
forward_step_func=forward_step_func,
298+
build_data_iterators_fn=MagicMock(),
299+
global_state=setup_output.global_state,
300+
)
301+
302+
mock_evaluate.assert_called_once_with(
303+
state=setup_output.global_state,
304+
prefix="iteration 1 on validation set",
305+
forward_step_func=forward_step_func,
306+
data_iterator=setup_output.valid_data_iterator,
307+
model=[setup_output.model],
308+
config=cfg,
309+
verbose=True,
310+
write_to_tensorboard=True,
311+
p2p_communicator=setup_output.multimodule_communicator,
312+
pg_collection=setup_output.multimodule_pg_collection,
313+
)
314+
assert events == ["train", "evaluate", "finish"]
315+
316+
261317
def test_finish_train_calls_cleanup():
262318
"""_finish_train should finalize async saves, shut down NVRx/FT, and flush loggers."""
263319
from megatron.bridge.training.train import _finish_train

0 commit comments

Comments
 (0)