Skip to content

Commit 064b770

Browse files
authored
[ckpt] fix: Honor retention for MSC checkpoints (#5559)
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
1 parent f6ee62a commit 064b770

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,12 @@ def cleanup_old_non_persistent_checkpoint(
16681668
"""
16691669
if torch.distributed.is_initialized() and torch.distributed.get_rank() != 0:
16701670
return
1671-
save_dir = Path(save_dir)
1671+
if MultiStorageClientFeature.is_enabled():
1672+
msc = MultiStorageClientFeature.import_package()
1673+
save_dir = msc.Path(save_dir)
1674+
else:
1675+
msc = None
1676+
save_dir = Path(save_dir)
16721677

16731678
iter_prefix = "iter_"
16741679
iter_ckpts = save_dir.glob(f"{iter_prefix}*")
@@ -1694,7 +1699,10 @@ def remove_iter_ckpts(_iter_ckpts):
16941699
with _CHECKPOINT_CLEANUP_LOCK:
16951700
for ckpt in _iter_ckpts:
16961701
if ckpt.exists():
1697-
shutil.rmtree(ckpt)
1702+
if msc is not None:
1703+
msc.delete(str(ckpt), recursive=True)
1704+
else:
1705+
shutil.rmtree(ckpt)
16981706

16991707
if do_async:
17001708
threading.Thread(target=remove_iter_ckpts, args=(rm_iter_ckpts,)).start()

‎tests/unit_tests/training/test_checkpointing.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,20 @@ def test_cleanup_old_non_persistent_checkpoint(self, mock_rmtree, mock_get_rank,
19011901
# Should remove the two older checkpoints
19021902
assert mock_rmtree.call_count == 2
19031903

1904+
@patch("torch.distributed.is_initialized", return_value=False)
1905+
def test_cleanup_old_non_persistent_checkpoint_with_msc_url(self, mock_dist_init, tmp_path):
1906+
"""Retention removes old checkpoints from an MSC-backed root."""
1907+
MultiStorageClientFeature.enable()
1908+
msc = MultiStorageClientFeature.import_package()
1909+
save_dir = f"msc://default{tmp_path}/checkpoints"
1910+
for name in ("iter_0001000", "iter_0002000", "iter_0003000"):
1911+
msc.os.makedirs(os.path.join(save_dir, name), exist_ok=True)
1912+
1913+
cleanup_old_non_persistent_checkpoint(save_dir, leave_ckpt_num=1, do_async=False)
1914+
1915+
retained_checkpoints = sorted(checkpoint.name for checkpoint in msc.Path(save_dir).glob("iter_*"))
1916+
assert retained_checkpoints == ["iter_0003000"]
1917+
19041918
@patch("torch.distributed.is_initialized")
19051919
@patch("torch.distributed.get_rank")
19061920
def test_cleanup_old_non_persistent_checkpoint_non_rank0(self, mock_get_rank, mock_dist_init):

0 commit comments

Comments
 (0)