Skip to content

Commit e50e394

Browse files
angel-coreGoogle-ML-Automation
authored andcommitted
Use helper functions for CheckpointManager operations.
Refactors code to interact with the CheckpointManager through dedicated helper functions instead of direct method calls. This is necessary because: - The underlying CheckpointManager operations (`.wait_until_finished`, `.latest_step`, `.reached_preemption`) have different semantics in v1 compared to v0. - We need to ensure the v0 emergency checkpointer functionality remains intact. This abstraction layer isolates the core logic from the specific CheckpointManager version PiperOrigin-RevId: 953793325
1 parent 1d197d8 commit e50e394

20 files changed

Lines changed: 60 additions & 36 deletions

src/maxtext/checkpoint_conversion/reshard_checkpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def main(argv: Sequence[str]) -> None:
117117
save_ckpt_path = os.path.join(save_ckpt_directory, str(step_number), "items")
118118
max_logging.log(f"Saved checkpoint: {save_ckpt_path}")
119119
# Upon preemption, exit when and only when all ongoing saves are complete.
120-
checkpoint_manager.wait_until_finished()
120+
checkpointing.wait_until_finished(checkpoint_manager)
121121

122122
max_logging.log(f"Elapse for checkpoint save: {(time.time() - start) / 60:.2f} min")
123123
print_peak_memory()

src/maxtext/checkpoint_conversion/standalone_scripts/convert_gemma2_chkpt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ def astype_fn(x):
301301
if checkpointing.save_checkpoint(checkpoint_manager, 0, state_new):
302302
max_logging.log("saved a checkpoint at step 0")
303303
# Upon preemption, exit when and only when all ongoing saves are complete.
304-
if checkpoint_manager.reached_preemption(0):
305-
checkpoint_manager.wait_until_finished()
304+
if checkpointing.reached_preemption(checkpoint_manager, 0):
305+
checkpointing.wait_until_finished(checkpoint_manager)
306306
sys.exit()
307307

308308

src/maxtext/checkpoint_conversion/standalone_scripts/convert_gemma3_chkpt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ def astype_fn(x):
241241
max_logging.log("saved a checkpoint at step 0")
242242
max_logging.log(f"Checkpoint saved to: {args.maxtext_model_path}")
243243
# Upon preemption, exit when and only when all ongoing saves are complete.
244-
if checkpoint_manager.reached_preemption(0):
245-
checkpoint_manager.wait_until_finished()
244+
if checkpointing.reached_preemption(checkpoint_manager, 0):
245+
checkpointing.wait_until_finished(checkpoint_manager)
246246
sys.exit()
247247

248248

src/maxtext/checkpoint_conversion/standalone_scripts/convert_gemma_chkpt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ def astype_fn(x):
175175
if checkpointing.save_checkpoint(checkpoint_manager, 0, state_new):
176176
max_logging.log("saved a checkpoint at step 0")
177177
# Upon preemption, exit when and only when all ongoing saves are complete.
178-
if checkpoint_manager.reached_preemption(0):
179-
checkpoint_manager.wait_until_finished()
178+
if checkpointing.reached_preemption(checkpoint_manager, 0):
179+
checkpointing.wait_until_finished(checkpoint_manager)
180180
sys.exit()
181181

182182

src/maxtext/checkpoint_conversion/standalone_scripts/convert_gpt3_ckpt_from_paxml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,8 @@ def map_fn(key_path, value):
306306
if checkpointing.save_checkpoint(checkpoint_manager, step_value, converted_state):
307307
max_logging.log(f"saved a checkpoint at step {step_value}")
308308
# Upon preemption, exit when and only when all ongoing saves are complete.
309-
if checkpoint_manager.reached_preemption(step_value):
310-
checkpoint_manager.wait_until_finished()
309+
if checkpointing.reached_preemption(checkpoint_manager, step_value):
310+
checkpointing.wait_until_finished(checkpoint_manager)
311311
sys.exit()
312312

313313
max_logging.log(f"Peak cpu memory in a single process: {fmt_size(memory_metrics['max_cpu_bytes'])}")

src/maxtext/checkpoint_conversion/standalone_scripts/llama_ckpt_conversion_inference_only.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ def checkpoint_device_put(arr):
314314
if checkpointing.save_checkpoint(checkpoint_manager, step_number_to_save_new_ckpt, state_new):
315315
max_logging.log(f"saved a checkpoint at step {step_number_to_save_new_ckpt}")
316316
# Upon preemption, exit when and only when all ongoing saves are complete.
317-
if checkpoint_manager.reached_preemption(0):
318-
checkpoint_manager.wait_until_finished()
317+
if checkpointing.reached_preemption(checkpoint_manager, 0):
318+
checkpointing.wait_until_finished(checkpoint_manager)
319319
sys.exit()
320320

321321

src/maxtext/checkpoint_conversion/utils/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ def save_weights_to_checkpoint(
12461246
if checkpointing.save_checkpoint(checkpoint_manager, step_number_to_save_new_ckpt, state_new, config=config):
12471247
max_logging.log(f"saved a checkpoint at step {step_number_to_save_new_ckpt}")
12481248
# Upon preemption, exit when and only when all ongoing saves are complete.
1249-
checkpoint_manager.wait_until_finished()
1249+
checkpointing.wait_until_finished(checkpoint_manager)
12501250

12511251
max_logging.log(f"Elapse for checkpoint save: {(time.time() - start) / 60:.2f} min")
12521252

src/maxtext/common/checkpointing.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
from orbax.checkpoint._src.checkpoint_managers import preservation_policy as preservation_policy_lib
4444
from orbax.checkpoint._src.checkpoint_managers import save_decision_policy as save_decision_policy_lib
4545

46-
4746
CheckpointManagerOptions = ocp.CheckpointManagerOptions
4847
Composite = ocp.args.Composite
4948
PyTreeCheckpointHandler = ocp.PyTreeCheckpointHandler
@@ -394,6 +393,21 @@ def print_save_message(step, async_checkpointing):
394393
max_logging.log(f"Saved a checkpoint at step {step}.")
395394

396395

396+
def latest_step(checkpoint_manager):
397+
"""Latest saved step or None, across the v0 emergency manager and the v1 Checkpointer."""
398+
return checkpoint_manager.latest_step()
399+
400+
401+
def wait_until_finished(checkpoint_manager):
402+
"""Blocks until pending saves finish, across the v0 emergency manager and the v1 Checkpointer."""
403+
return checkpoint_manager.wait_until_finished()
404+
405+
406+
def reached_preemption(checkpoint_manager, step: int) -> bool:
407+
"""Whether a preemption sync point has been reached at `step`, across the v0 emergency manager and the v1 Checkpointer."""
408+
return checkpoint_manager.reached_preemption(step)
409+
410+
397411
def load_state_if_possible(
398412
checkpoint_manager: CheckpointManager | None,
399413
data_iterator: MultiHostDataLoadIterator | list[MultiHostDataLoadIterator] | None,
@@ -446,7 +460,7 @@ def load_state_if_possible(
446460
if checkpoint_manager is not None:
447461
max_logging.log("checkpoint manager exists so trying to load this run's existing checkpoint")
448462

449-
step = checkpoint_manager.latest_step() if step < 0 else step # pyrefly: ignore[bad-assignment]
463+
step = latest_step(checkpoint_manager) if step < 0 else step # pyrefly: ignore[bad-assignment]
450464
if step is not None:
451465
max_logging.log(f"restoring from this run's directory step {step}")
452466

@@ -690,16 +704,18 @@ def _should_save_checkpoint_at_step(checkpoint_manager, step, config, force):
690704
else:
691705
base_checkpoint_due = step % config.checkpoint_period == 0
692706
local_checkpoint_due = _uses_local_checkpoint_period(config) and step % config.local_checkpoint_period == 0
693-
autocheckpoint_due = config.enable_autocheckpoint and checkpoint_manager.reached_preemption(step)
707+
autocheckpoint_due = config.enable_autocheckpoint and reached_preemption(checkpoint_manager, step)
694708
return base_checkpoint_due or local_checkpoint_due or autocheckpoint_due
695709

696710

697711
def _handle_post_checkpoint_preemption(checkpoint_manager, step, force_ckpt_save):
698712
"""Waits on final/preemption saves and raises if preempted."""
699-
reached_preemption = checkpoint_manager.reached_preemption(step)
700-
if force_ckpt_save or reached_preemption:
701-
checkpoint_manager.wait_until_finished()
702-
if reached_preemption:
713+
# Named is_preempted (not reached_preemption) so it doesn't shadow the module-level
714+
# reached_preemption dispatcher we call below.
715+
is_preempted = reached_preemption(checkpoint_manager, step)
716+
if force_ckpt_save or is_preempted:
717+
wait_until_finished(checkpoint_manager)
718+
if is_preempted:
703719
raise exceptions.StopTraining("Job is preempted.")
704720

705721

@@ -733,7 +749,7 @@ def maybe_save_checkpoint(checkpoint_manager, state, config, data_iterator, step
733749
_handle_post_checkpoint_preemption(checkpoint_manager, actual_step, force_ckpt_save)
734750
return
735751

736-
if checkpoint_manager.latest_step() == actual_step:
752+
if latest_step(checkpoint_manager) == actual_step:
737753
max_logging.log(f"Checkpoint for step {actual_step} already exists, skipping save.")
738754
return
739755

@@ -782,7 +798,7 @@ def save_checkpoint(checkpoint_manager, step, state, config=None, data_iterator=
782798
force
783799
or (step % config.checkpoint_period == 0 and not config.enable_continuous_checkpointing)
784800
or (_uses_local_checkpoint_period(config) and step % config.local_checkpoint_period == 0)
785-
or (config.enable_autocheckpoint and checkpoint_manager.reached_preemption(step))
801+
or (config.enable_autocheckpoint and reached_preemption(checkpoint_manager, step))
786802
):
787803
blocking_until_ready_start = time.time()
788804
max_logging.log(f"Waiting for step {step} to finish before checkpoint...")

src/maxtext/experimental/rl/grpo_trainer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,7 @@ def generation_worker_fn(
12381238
checkpointing.maybe_save_checkpoint(checkpoint_manager, state_to_save, config, data_iterator)
12391239
elif checkpoint_manager is not None:
12401240
# in case the last checkpoint_period checkpoint is still in progress
1241-
checkpoint_manager.wait_until_finished()
1241+
checkpointing.wait_until_finished(checkpoint_manager)
12421242
_job_completed_gracefully = True
12431243
except exceptions.StopTraining as e:
12441244
prof.deactivate()

src/maxtext/trainers/pre_train/train.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ def train_loop(config, recorder, state=None):
901901

902902
if checkpoint_manager is not None:
903903
# in case the last checkpoint_period checkpoint is still in progress
904-
checkpoint_manager.wait_until_finished()
904+
checkpointing.wait_until_finished(checkpoint_manager)
905905
_job_completed_gracefully = True
906906
except exceptions.StopTraining as e:
907907
prof.deactivate()

0 commit comments

Comments
 (0)