From 6d25944fdb375d6d4137068dba86696d37b777ac Mon Sep 17 00:00:00 2001 From: Marchematics Date: Mon, 31 Aug 2026 01:21:55 +0800 Subject: [PATCH 1/2] fix checkpoint hook for standalone validation --- mmengine/hooks/checkpoint_hook.py | 5 +++++ tests/test_hooks/test_checkpoint_hook.py | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mmengine/hooks/checkpoint_hook.py b/mmengine/hooks/checkpoint_hook.py index 92a4867bb9..62194cf138 100644 --- a/mmengine/hooks/checkpoint_hook.py +++ b/mmengine/hooks/checkpoint_hook.py @@ -326,6 +326,11 @@ def before_train(self, runner) -> None: self.keep_ckpt_ids: deque = deque(keep_ckpt_ids, self.max_keep_ckpts) + def before_val(self, runner) -> None: + """Initialize checkpoint state when validation runs standalone.""" + if not hasattr(self, 'file_backend'): + self.before_train(runner) + def after_train_epoch(self, runner) -> None: """Save the checkpoint and synchronize buffers after each epoch. diff --git a/tests/test_hooks/test_checkpoint_hook.py b/tests/test_hooks/test_checkpoint_hook.py index 13914341f7..b749a419a4 100644 --- a/tests/test_hooks/test_checkpoint_hook.py +++ b/tests/test_hooks/test_checkpoint_hook.py @@ -336,7 +336,6 @@ def test_after_val_epoch(self): petrel_client = MagicMock() for by_epoch, cfg in [(True, self.epoch_based_cfg), (False, self.iter_based_cfg)]: - isfile = MagicMock(return_value=True) self.clear_work_dir() with patch.dict(sys.modules, {'petrel_client': petrel_client}), \ patch('mmengine.fileio.backends.PetrelBackend.put') as put_mock, \ @@ -362,6 +361,18 @@ def test_after_val_epoch(self): isfile.assert_called_once() remove_mock.assert_called_once() + def test_before_val_initializes_save_best(self): + runner = self.build_runner(self.epoch_based_cfg) + checkpoint_hook = CheckpointHook(save_best='acc') + + checkpoint_hook.before_val(runner) + checkpoint_hook.after_val_epoch(runner, {'acc': 0.5}) + + self.assertEqual(runner.message_hub.get_info('best_score'), 0.5) + self.assertTrue( + osp.isfile( + osp.join(runner.work_dir, 'best_acc_epoch_0.pth'))) + def test_after_train_epoch(self): cfg = copy.deepcopy(self.epoch_based_cfg) runner = self.build_runner(cfg) From 5709fe0f59a467fa7af1fa3e931b16480c1068c8 Mon Sep 17 00:00:00 2001 From: Marchematics Date: Mon, 31 Aug 2026 02:12:38 +0800 Subject: [PATCH 2/2] format checkpoint hook test --- tests/test_hooks/test_checkpoint_hook.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_hooks/test_checkpoint_hook.py b/tests/test_hooks/test_checkpoint_hook.py index b749a419a4..dc02a76e81 100644 --- a/tests/test_hooks/test_checkpoint_hook.py +++ b/tests/test_hooks/test_checkpoint_hook.py @@ -370,8 +370,7 @@ def test_before_val_initializes_save_best(self): self.assertEqual(runner.message_hub.get_info('best_score'), 0.5) self.assertTrue( - osp.isfile( - osp.join(runner.work_dir, 'best_acc_epoch_0.pth'))) + osp.isfile(osp.join(runner.work_dir, 'best_acc_epoch_0.pth'))) def test_after_train_epoch(self): cfg = copy.deepcopy(self.epoch_based_cfg)