Skip to content

Commit 023a881

Browse files
committed
feat: warn when training batches are fewer than accumulate_grad_batches
On-behalf-of: @Bocconi-Open-Source-Society
1 parent 4819088 commit 023a881

3 files changed

Lines changed: 27 additions & 0 deletions

File tree

src/lightning/pytorch/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
1414

1515
- Added `log_key_prefix` parameter to `LearningRateMonitor` callback for prefixing logged metric names ([#21612](https://github.com/Lightning-AI/pytorch-lightning/issues/21612))
1616

17+
- Added a `PossibleUserWarning` when the number of training batches is smaller than `accumulate_grad_batches`, since Lightning always steps on the last batch of the epoch and gradients end up accumulated over fewer batches than configured ([#21808](https://github.com/Lightning-AI/pytorch-lightning/issues/21808))
18+
1719
### Changed
1820

1921
-

src/lightning/pytorch/loops/fit_loop.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ def setup_data(self) -> None:
325325
category=PossibleUserWarning,
326326
)
327327

328+
if self.max_batches < trainer.accumulate_grad_batches:
329+
rank_zero_warn(
330+
f"The number of training batches ({self.max_batches}) is smaller than "
331+
f"`accumulate_grad_batches={trainer.accumulate_grad_batches}`. Since Lightning always performs an"
332+
" optimizer step on the last batch of the epoch, gradients will effectively be accumulated over only"
333+
f" {self.max_batches} batch(es) instead of {trainer.accumulate_grad_batches} for this epoch.",
334+
category=PossibleUserWarning,
335+
)
336+
328337
@property
329338
def restarted_on_epoch_start(self) -> bool:
330339
return self._restart_stage == RestartStage.RESTARTED_ON_EPOCH_START

tests/tests_pytorch/trainer/test_dataloaders.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,22 @@ def test_warning_with_small_dataloader_and_logging_interval(log_interval, tmp_pa
690690
trainer.fit(model)
691691

692692

693+
def test_warning_with_dataloader_shorter_than_accumulate_grad_batches(tmp_path):
694+
"""Test that a warning message is shown if the dataloader has fewer batches than `accumulate_grad_batches`, since
695+
Lightning always steps on the last batch of the epoch and gradients end up accumulated over fewer batches than
696+
configured."""
697+
model = BoringModel()
698+
dataloader = DataLoader(RandomDataset(32, length=2))
699+
model.train_dataloader = lambda: dataloader
700+
701+
trainer = Trainer(default_root_dir=tmp_path, max_epochs=1, accumulate_grad_batches=4, logger=False)
702+
with pytest.warns(
703+
UserWarning,
704+
match=r"The number of training batches \(2\) is smaller than `accumulate_grad_batches=4`",
705+
):
706+
trainer.fit(model)
707+
708+
693709
def test_warning_with_small_dataloader_and_fast_dev_run(tmp_path):
694710
"""Test that a warning message is shown if the dataloader length is too short for the chosen logging interval."""
695711
model = BoringModel()

0 commit comments

Comments
 (0)