16031aae96
CPU tests Workflow / Testing (ubuntu-latest, 3.12) (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.13) (push) Failing after 0s
Mypy Type Check / Type Check (push) Failing after 0s
Docs/Test WorkFlow / Test docs build (push) Failing after 1s
PR Conflict Labeler / labeling (push) Failing after 1s
Dependency resolution / Resolve [tflite] extra — Python 3.12 (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.10) (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.13) (push) Failing after 1s
CPU tests Workflow / build-pkg (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.10) (push) Failing after 0s
CPU tests Workflow / Testing (ubuntu-latest, 3.11) (push) Failing after 0s
Smoke Tests / try-all-models (macos-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (macos-latest, 3.13) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / testing-guardian (push) Has been cancelled
GPU tests Workflow / Testing (push) Has been cancelled
89 lines
3.3 KiB
Python
89 lines
3.3 KiB
Python
# ------------------------------------------------------------------------
|
|
# RF-DETR
|
|
# Copyright (c) 2025 Roboflow. All Rights Reserved.
|
|
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
|
|
# ------------------------------------------------------------------------
|
|
"""Tests for resuming training from checkpoint."""
|
|
|
|
import warnings
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from rfdetr import RFDETRNano
|
|
|
|
|
|
def test_resume_with_completed_epochs_returns_early(tmp_path: Path) -> None:
|
|
"""Passing start_epoch emits DeprecationWarning and still reaches trainer.fit().
|
|
|
|
In the legacy engine.py path, ``start_epoch=epochs`` caused the training loop to be skipped (``range(start_epoch,
|
|
epochs)`` was empty), which triggered an ``UnboundLocalError`` when accessing ``test_stats``.
|
|
|
|
In the PTL path, ``start_epoch`` is a deprecated kwarg that is absorbed and ignored (PTL resumes automatically via
|
|
``ckpt_path``). The shim should emit the warning and still call ``trainer.fit(...)`` without raising.
|
|
|
|
Args:
|
|
tmp_path: Pytest temporary directory.
|
|
"""
|
|
output_dir = tmp_path / "train_output"
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
model = RFDETRNano(pretrain_weights=None, num_classes=3, device="cpu")
|
|
|
|
with (
|
|
patch("rfdetr.training.RFDETRModelModule"),
|
|
patch("rfdetr.training.RFDETRDataModule"),
|
|
patch("rfdetr.training.build_trainer") as mock_build_trainer,
|
|
warnings.catch_warnings(record=True) as caught,
|
|
):
|
|
warnings.simplefilter("always")
|
|
model.train(
|
|
dataset_dir=str(tmp_path),
|
|
epochs=1,
|
|
start_epoch=1,
|
|
batch_size=1,
|
|
grad_accum_steps=1,
|
|
output_dir=str(output_dir),
|
|
device="cpu",
|
|
)
|
|
|
|
depr = [w for w in caught if issubclass(w.category, DeprecationWarning)]
|
|
assert any("start_epoch" in str(w.message) for w in depr), "Expected a DeprecationWarning mentioning start_epoch"
|
|
mock_build_trainer.return_value.fit.assert_called_once()
|
|
|
|
|
|
def test_resume_with_completed_epochs_calls_on_train_end_callback(tmp_path: Path) -> None:
|
|
"""Old-style on_train_end callbacks are not forwarded to PTL.
|
|
|
|
In the legacy engine.py path, callbacks added to ``model.callbacks["on_train_end"]`` were invoked at the end of
|
|
training (including when the loop was skipped). In the PTL path the old-style callback dict on the model instance is
|
|
not consulted; use PTL ``Callback`` objects via ``build_trainer()`` instead.
|
|
"""
|
|
output_dir = tmp_path / "train_output"
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
callback_calls = 0
|
|
|
|
def _callback() -> None:
|
|
nonlocal callback_calls
|
|
callback_calls += 1
|
|
|
|
model = RFDETRNano(pretrain_weights=None, num_classes=3, device="cpu")
|
|
model.callbacks["on_train_end"].append(_callback)
|
|
|
|
with (
|
|
patch("rfdetr.training.RFDETRModelModule"),
|
|
patch("rfdetr.training.RFDETRDataModule"),
|
|
patch("rfdetr.training.build_trainer"),
|
|
):
|
|
model.train(
|
|
dataset_dir=str(tmp_path),
|
|
epochs=1,
|
|
batch_size=1,
|
|
grad_accum_steps=1,
|
|
output_dir=str(output_dir),
|
|
device="cpu",
|
|
)
|
|
|
|
# Old-style callbacks on model.callbacks are no longer invoked in the PTL path.
|
|
assert callback_calls == 0
|