[ckpt] fix: Preserve async checkpoint logger iteration - #5738
Conversation
Signed-off-by: Yu Yao <yaoyu.094@gmail.com>
|
/ok to test b0157bf |
|
LGTM - clean, well-targeted bug fix. The change routes the async W&B / MLflow / Comet completion finalizers through the immutable checkpoint_step snapshot (captured at checkpoint_step = train_state.step, checkpointing.py:1149) instead of re-reading the mutable train_state.step when the queued save later completes. This matches the sibling async cleanup finalizers (max_iteration=checkpoint_step at lines 1603/1622/1644), which already used the snapshot, so the three logger finalizers were the last outliers. Correctly fixes the provenance mismatch where an in-flight iter_N artifact was tagged with a later iteration N+k. Verified:
Minor test-robustness note (non-blocking): test_async_checkpoint_loggers_use_scheduled_step asserts on the hardcoded path /checkpoints/iter_0001000, coupling the test to the fixture save dir and the iter naming convention. Deriving it from the fixture + get_checkpoint_name would be more resilient, but this is optional. Suggested test cases:
|
Problem
When a supported async distributed checkpoint remains in flight while training advances, its completion callbacks receive the fixed checkpoint path for iteration N but read the later mutable training step N+k.
This silently creates conflicting checkpoint provenance:
Root cause
The async logger finalizers close over TrainState and read train_state.step only when the queued save completes. The checkpoint path and an immutable checkpoint_step snapshot are created when the save is scheduled.
Fix
Pass the existing checkpoint_step snapshot to the W&B, MLflow, and Comet completion helpers. This is limited to checkpoint logger provenance; callback state and other checkpoint lifecycle behavior are unchanged.
Regression evidence
The focused regression schedules iter_0001000, advances TrainState.step to 1001, then executes the captured async finalizers.
Before the fix:
After the fix:
Result:
1 passed.Focused and adjacent validation:
Result:
34 passed.Additional checks:
git diff --check: passeduv run pre-commit run --all-files: passedThe regression ran on CPU against the exact audited Bridge revision and its pinned Megatron-Core source. No GPU or distributed runtime behavior was mocked away; the test controls only the async completion timing and external logger calls.