Skip to content

Commit 548fec1

Browse files
committed
fix(megatron_bridge): save TensorBoard logs by default
Set the default log directory to the saved run output so training reports can consume TensorBoard metrics while preserving user overrides. Signed-off-by: Ben Lugassi <blugassi@nvidia.com>
1 parent 0de6ca8 commit 548fec1

4 files changed

Lines changed: 31 additions & 2 deletions

File tree

src/cloudai/report_generator/training/parser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,16 @@ def get_model_name(self, tr: TestRun) -> str:
7474

7575
def can_parse(self, tr: TestRun) -> bool:
7676
"""Return True when the run produced the TB events and config artifact this parser needs."""
77+
name = type(self).__name__
7778
tb_dir = self.get_tb_dir(tr)
7879
if not (tb_dir.is_dir() and any(tb_dir.iterdir())):
80+
logging.warning(f"{name}: no TensorBoard events at '{tb_dir}'; skipping training report")
7981
return False
8082
config_path = self.get_config_path(tr)
81-
return config_path is not None and config_path.is_file()
83+
if config_path is None or not config_path.is_file():
84+
logging.warning(f"{name}: config artifact not found under '{tr.output_path}'; skipping training report")
85+
return False
86+
return True
8287

8388
def parse(self, tr: TestRun, system: System) -> TrainingResults:
8489
"""Read TB scalars + the config artifact and assemble TrainingResults."""

src/cloudai/workloads/megatron_bridge/slurm_command_gen_strategy.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ def _list_or_comma_str(self, val: str | list[str] | None) -> Optional[str]:
430430
def _add_extra_cmd_args(self, extra_cmd_args: dict[str, str]) -> list[str]:
431431
"""Hydra overrides: defaults merged with the user's extra_cmd_args, which take precedence."""
432432
overrides = {
433+
"logger.tensorboard_dir": "/nemo_run/tb_logs",
433434
"logger.log_timers_to_tensorboard": "true",
434435
"logger.log_throughput_to_tensorboard": "true",
435436
"logger.log_memory_to_tensorboard": "true",

tests/ref_data/megatron-bridge.sbatch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if [ "${WANDB_INSTALL_RC}" -ne 0 ]; then
1919
fi
2020

2121
LAUNCH_RC=0
22-
NEMORUN_HOME="__OUTPUT_DIR__/output" __INSTALL_DIR__/Run__main-venv/bin/python __INSTALL_DIR__/Megatron-Bridge__main/scripts/performance/setup_experiment.py -p main -t 00:20:00 -i __OUTPUT_DIR__/output/megatron_bridge_image.sqsh -hf dummy_token -ng 8 -gn 8 -cm __INSTALL_DIR__/Megatron-Bridge__main:/opt/Megatron-Bridge -cb 'export CUDA_VISIBLE_DEVICES=0,1,2,3' -cb 'export NCCL_DEBUG=INFO' -m qwen3 -mr 30b_a3b --detach false --save_config_filepath /nemo_run/configs/ConfigContainer.yaml --additional_slurm_params 'gpus-per-node=8;gres=gpu:8' logger.log_timers_to_tensorboard=true logger.log_throughput_to_tensorboard=true logger.log_memory_to_tensorboard=true >>"$LOG" 2>&1 || LAUNCH_RC=$?
22+
NEMORUN_HOME="__OUTPUT_DIR__/output" __INSTALL_DIR__/Run__main-venv/bin/python __INSTALL_DIR__/Megatron-Bridge__main/scripts/performance/setup_experiment.py -p main -t 00:20:00 -i __OUTPUT_DIR__/output/megatron_bridge_image.sqsh -hf dummy_token -ng 8 -gn 8 -cm __INSTALL_DIR__/Megatron-Bridge__main:/opt/Megatron-Bridge -cb 'export CUDA_VISIBLE_DEVICES=0,1,2,3' -cb 'export NCCL_DEBUG=INFO' -m qwen3 -mr 30b_a3b --detach false --save_config_filepath /nemo_run/configs/ConfigContainer.yaml --additional_slurm_params 'gpus-per-node=8;gres=gpu:8' logger.tensorboard_dir=/nemo_run/tb_logs logger.log_timers_to_tensorboard=true logger.log_throughput_to_tensorboard=true logger.log_memory_to_tensorboard=true >>"$LOG" 2>&1 || LAUNCH_RC=$?
2323

2424

2525
JOB_ID=""

tests/workloads/megatron_bridge/test_command_gen_strategy_slurm.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,29 @@ def test_defaults_not_emitted_when_not_set_in_toml(
185185
assert "--cuda_graph_impl" not in cmd
186186
assert " -ms " not in cmd
187187

188+
def test_tensorboard_dir_defaults_to_persisted_run_path(
189+
self, configured_slurm_system: SlurmSystem, make_test_run: Callable[..., TestRun]
190+
) -> None:
191+
tr = make_test_run(output_subdir="out_default_tensorboard")
192+
cmd_gen = MegatronBridgeSlurmCommandGenStrategy(configured_slurm_system, tr)
193+
194+
wrapper_content = self._wrapper_content(cmd_gen)
195+
196+
assert "logger.tensorboard_dir=/nemo_run/tb_logs" in wrapper_content
197+
198+
def test_tensorboard_dir_can_be_overridden(
199+
self, configured_slurm_system: SlurmSystem, make_test_run: Callable[..., TestRun]
200+
) -> None:
201+
tr = make_test_run(output_subdir="out_custom_tensorboard")
202+
tdef = cast(MegatronBridgeTestDefinition, tr.test)
203+
tdef.extra_cmd_args["logger.tensorboard_dir"] = "/nemo_run/custom_tb"
204+
cmd_gen = MegatronBridgeSlurmCommandGenStrategy(configured_slurm_system, tr)
205+
206+
wrapper_content = self._wrapper_content(cmd_gen)
207+
208+
assert "logger.tensorboard_dir=/nemo_run/custom_tb" in wrapper_content
209+
assert "logger.tensorboard_dir=/nemo_run/tb_logs" not in wrapper_content
210+
188211
def test_container_image_local_path_passed_verbatim(
189212
self, cmd_gen: MegatronBridgeSlurmCommandGenStrategy, test_run: TestRun
190213
) -> None:

0 commit comments

Comments
 (0)