@@ -374,15 +374,17 @@ void Train(const nn::parallel::Rank &rank) {
374374 start_step = resume_result.global_step ;
375375 size_t consumed_batches = resume_result.consumed_batches ;
376376
377- // TODO(jym): Replace with Sampler abstraction when available.
378- // Skip dataloader to resume from the correct batch position.
379- if (consumed_batches > 0 ) {
380- size_t start = train_iter.BatchIndex ();
381- // Each rank processes every ddp_world_size-th batch starting from its own rank.
382- // num_skips calculates how many ++ iterations to reach the saved batch position.
383- size_t num_skips = (consumed_batches - start) / ddp_world_size;
384- for (size_t i = 0 ; i < num_skips; ++i) { ++train_iter; }
385- }
377+ // consumed_batches is the number of global dataloader batches consumed across cyclic epochs.
378+ train_iter.SeekGlobalBatch (consumed_batches % train_loader.NumGlobalBatches ());
379+ auto next_train_batch = [&]() {
380+ auto batch = *train_iter;
381+ ++train_iter;
382+ if (train_iter == train_loader.end ()) {
383+ train_iter = train_loader.begin ();
384+ }
385+ ++consumed_batches;
386+ return batch;
387+ };
386388
387389 auto save_checkpoint = [&](const std::filesystem::path &save_dir, int64_t global_step) {
388390 SaveCheckpoint ({
@@ -457,11 +459,7 @@ void Train(const nn::parallel::Rank &rank) {
457459 infini_train::AutocastGuard autocast_guard (device.type (), dtype);
458460
459461 // (bs, seq_len), (bs, seq_len)
460- auto [x, y] = *train_iter;
461- // if we are trying to overfit a single batch, we reset the loader here by commenting out the line below
462- // TODO(dcj): support dataloader.reset() later
463- ++train_iter;
464- consumed_batches = train_iter.BatchIndex ();
462+ auto [x, y] = next_train_batch ();
465463 x = std::make_shared<Tensor>(x->To (device));
466464 y = std::make_shared<Tensor>(y->To (device));
467465
@@ -491,11 +489,7 @@ void Train(const nn::parallel::Rank &rank) {
491489 scheduler->Step ();
492490 }
493491 } else {
494- auto [x, y] = *train_iter;
495- // if we are trying to overfit a single batch, we reset the loader here by commenting out the line below
496- // TODO(dcj): support dataloader.reset() later
497- ++train_iter;
498- consumed_batches = train_iter.BatchIndex ();
492+ auto [x, y] = next_train_batch ();
499493 x = std::make_shared<Tensor>(x->To (device));
500494 y = std::make_shared<Tensor>(y->To (device));
501495
0 commit comments