@@ -512,11 +512,21 @@ def handle_evaluation_request(self, request: CustomRequestHandler):
512512 request .send_text ("Evaluation requested" )
513513
514514 def _save_checkpoint (self ):
515- # Saving checkpoint is only enabled when running single process training
516- # (rank is -1) or master process of DDP training (rank is 0).
515+ # Full checkpoint saving is only enabled when running single process
516+ # training (rank is -1) or the master process of DDP training (rank is
517+ # 0). Other DDP ranks only save their local replay buffers.
518+ global_step = alf .summary .get_global_counter ()
517519 if self ._rank <= 0 :
518- global_step = alf .summary .get_global_counter ()
519- self ._checkpointer .save (global_step = global_step )
520+ # Replay buffers are saved separately below as sharded per-rank
521+ # source files, so rank 0's full checkpoint only contains model,
522+ # optimizer, metrics, and trainer progress.
523+ self ._checkpointer .save (global_step = global_step ,
524+ including_replay_buffer = False )
525+ # Every rank writes one sharded replay-buffer source file into the
526+ # checkpoint directory. Restore will redistribute these files across the
527+ # active worker count, which may differ from the save-time worker count.
528+ self ._checkpointer .save_replay_buffer (global_step = global_step ,
529+ rank = max (self ._rank , 0 ))
520530
521531 def _save_video_clip (self , name : str = "video_clip" ):
522532 # Saving video clip is only enabled when running single process training
@@ -550,7 +560,13 @@ def _restore_checkpoint(self, checkpointer):
550560 # train_iter() once before loading the checkpoint
551561 self ._algorithm .train_iter ()
552562 try :
553- recovered_global_step = checkpointer .load ()
563+ context = PerProcessContext ()
564+ replay_buffer_rank = max (self ._rank , 0 )
565+ # For sharded replay-buffer checkpoints, rank 0 creates per-worker
566+ # restore shards and every rank loads only its own shard.
567+ recovered_global_step = checkpointer .load (
568+ replay_buffer_rank = replay_buffer_rank ,
569+ replay_buffer_world_size = context .num_processes )
554570 self ._trainer_progress .update ()
555571 except RuntimeError as e :
556572 raise RuntimeError (
0 commit comments