We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[bug]resume error
Thanks for your error report and we appreciate it a lot.

**Checklist**

1. I have searched related issues but cannot get the expected help.
2. I have read the [FAQ documentation](https://mmengine.readthedocs.io/en/latest/faq.html) but cannot get the expected help.
3. The bug has not been fixed in the latest version.

**Describe the bug**
A clear and concise description of what the bug is.

**Reproduction**

1. What command or script did you run?

when I try to resume the model by adding `resume=True, load_from='epoch_380.pth'` in the config, the newest version of mmeingne raise a RuntimeError:

```
RuntimeError: The model and loaded state dict do not match exactly

unexpected key in source state_dict: data_preprocessor.mean, data_preprocessor.std
```

The error disappears when checkout to v0.1.0


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmengine/hooks/ema_hook.py`
Content:
```
1 # Copyright (c) OpenMMLab. All rights reserved.
2 import copy
3 import itertools
4 import logging
5 from typing import Dict, Optional
6 
7 from mmengine.logging import print_log
8 from mmengine.model import is_model_wrapper
9 from mmengine.registry import HOOKS, MODELS
10 from .hook import DATA_BATCH, Hook
11 
12 
13 @HOOKS.register_module()
14 class EMAHook(Hook):
15     """A Hook to apply Exponential Moving Average (EMA) on the model during
16     training.
17 
18     Note:
19         - EMAHook takes priority over CheckpointHook.
20         - The original model parameters are actually saved in ema field after
21           train.
22         - ``begin_iter`` and ``begin_epoch`` cannot be set at the same time.
23 
24     Args:
25         ema_type (str): The type of EMA strategy to use. You can find the
26             supported strategies in :mod:`mmengine.model.averaged_model`.
27             Defaults to 'ExponentialMovingAverage'.
28         strict_load (bool): Whether to strictly enforce that the keys of
29             ``state_dict`` in checkpoint match the keys returned by
30             ``self.module.state_dict``. Defaults to True.
31         begin_iter (int): The number of iteration to enable ``EMAHook``.
32             Defaults to 0.
33         begin_epoch (int): The number of epoch to enable ``EMAHook``. Defaults
34             to 0.
35         **kwargs: Keyword arguments passed to subclasses of
36             :obj:`BaseAveragedModel`
37     """
38 
39     priority = 'NORMAL'
40 
41     def __init__(self,
42                  ema_type: str = 'ExponentialMovingAverage',
43                  strict_load: bool = True,
44                  begin_iter: int = 0,
45                  begin_epoch: int = 0,
46                  **kwargs):
47         self.strict_load = strict_load
48         self.ema_cfg = dict(type=ema_type, **kwargs)
49         assert not (begin_iter != 0 and begin_epoch != 0), (
50             '`begin_iter` and `begin_epoch` should not be both set.')
51         assert begin_iter >= 0, (
52             f'begin_iter must larger than 0, but got begin: {begin_iter}')
53         assert begin_epoch >= 0, (
54             f'begin_epoch must larger than 0, but got begin: {begin_epoch}')
55         self.begin_iter = begin_iter
56         self.begin_epoch = begin_epoch
57         # If `begin_epoch` and `begin_iter` are not set, `EMAHook` will be
58         # enabled at 0 iteration.
59         self.enabled_by_epoch = self.begin_epoch > 0
60 
61     def before_run(self, runner) -> None:
62         """Create an ema copy of the model.
63 
64         Args:
65             runner (Runner): The runner of the training process.
66         """
67         model = runner.model
68         if is_model_wrapper(model):
69             model = model.module
70         self.src_model = model
71         self.ema_model = MODELS.build(
72             self.ema_cfg, default_args=dict(model=self.src_model))
73 
74     def before_train(self, runner) -> None:
75         """Check the begin_epoch/iter is smaller than max_epochs/iters.
76 
77         Args:
78             runner (Runner): The runner of the training process.
79         """
80         if self.enabled_by_epoch:
81             assert self.begin_epoch <= runner.max_epochs, (
82                 'self.begin_epoch should be smaller than runner.max_epochs: '
83                 f'{runner.max_epochs}, but got begin: {self.begin_epoch}')
84         else:
85             assert self.begin_iter <= runner.max_iters, (
86                 'self.begin_iter should be smaller than runner.max_iters: '
87                 f'{runner.max_iters}, but got begin: {self.begin_iter}')
88 
89     def after_train_iter(self,
90                          runner,
91                          batch_idx: int,
92                          data_batch: DATA_BATCH = None,
93                          outputs: Optional[dict] = None) -> None:
94         """Update ema parameter.
95 
96         Args:
97             runner (Runner): The runner of the training process.
98             batch_idx (int): The index of the current batch in the train loop.
99             data_batch (Sequence[dict], optional): Data from dataloader.
100                 Defaults to None.
101             outputs (dict, optional): Outputs from model. Defaults to None.
102         """
103         if self._ema_started(runner):
104             self.ema_model.update_parameters(self.src_model)
105         else:
106             ema_params = self.ema_model.module.state_dict()
107             src_params = self.src_model.state_dict()
108             for k, p in ema_params.items():
109                 p.data.copy_(src_params[k].data)
110 
111     def before_val_epoch(self, runner) -> None:
112         """We load parameter values from ema model to source model before
113         validation.
114 
115         Args:
116             runner (Runner): The runner of the training process.
117         """
118         self._swap_ema_parameters()
119 
120     def after_val_epoch(self,
121                         runner,
122                         metrics: Optional[Dict[str, float]] = None) -> None:
123         """We recover source model's parameter from ema model after validation.
124 
125         Args:
126             runner (Runner): The runner of the validation process.
127             metrics (Dict[str, float], optional): Evaluation results of all
128                 metrics on validation dataset. The keys are the names of the
129                 metrics, and the values are corresponding results.
130         """
131         self._swap_ema_parameters()
132 
133     def before_test_epoch(self, runner) -> None:
134         """We load parameter values from ema model to source model before test.
135 
136         Args:
137             runner (Runner): The runner of the training process.
138         """
139         self._swap_ema_parameters()
140 
141     def after_test_epoch(self,
142                          runner,
143                          metrics: Optional[Dict[str, float]] = None) -> None:
144         """We recover source model's parameter from ema model after test.
145 
146         Args:
147             runner (Runner): The runner of the testing process.
148             metrics (Dict[str, float], optional): Evaluation results of all
149                 metrics on test dataset. The keys are the names of the
150                 metrics, and the values are corresponding results.
151         """
152         self._swap_ema_parameters()
153 
154     def before_save_checkpoint(self, runner, checkpoint: dict) -> None:
155         """Save ema parameters to checkpoint.
156 
157         Args:
158             runner (Runner): The runner of the testing process.
159         """
160         checkpoint['ema_state_dict'] = self.ema_model.state_dict()
161         # Save ema parameters to the source model's state dict so that we
162         # can directly load the averaged model weights for deployment.
163         # Swapping the state_dict key-values instead of swapping model
164         # parameters because the state_dict is a shallow copy of model
165         # parameters.
166         self._swap_ema_state_dict(checkpoint)
167 
168     def after_load_checkpoint(self, runner, checkpoint: dict) -> None:
169         """Resume ema parameters from checkpoint.
170 
171         Args:
172             runner (Runner): The runner of the testing process.
173         """
174         from mmengine.runner.checkpoint import load_state_dict
175         if 'ema_state_dict' in checkpoint and runner._resume:
176             # The original model parameters are actually saved in ema
177             # field swap the weights back to resume ema state.
178             self._swap_ema_state_dict(checkpoint)
179             self.ema_model.load_state_dict(
180                 checkpoint['ema_state_dict'], strict=self.strict_load)
181 
182         # Support load checkpoint without ema state dict.
183         else:
184             if runner._resume:
185                 print_log(
186                     'There is no `ema_state_dict` in checkpoint. '
187                     '`EMAHook` will make a copy of `state_dict` as the '
188                     'initial `ema_state_dict`', 'current', logging.WARNING)
189             load_state_dict(
190                 self.ema_model.module,
191                 copy.deepcopy(checkpoint['state_dict']),
192                 strict=self.strict_load)
193 
194     def _swap_ema_parameters(self) -> None:
195         """Swap the parameter of model with ema_model."""
196         avg_param = (
197             itertools.chain(self.ema_model.module.parameters(),
198                             self.ema_model.module.buffers())
199             if self.ema_model.update_buffers else
200             self.ema_model.module.parameters())
201         src_param = (
202             itertools.chain(self.src_model.parameters(),
203                             self.src_model.buffers())
204             if self.ema_model.update_buffers else self.src_model.parameters())
205         for p_avg, p_src in zip(avg_param, src_param):
206             tmp = p_avg.data.clone()
207             p_avg.data.copy_(p_src.data)
208             p_src.data.copy_(tmp)
209 
210     def _swap_ema_state_dict(self, checkpoint):
211         """Swap the state dict values of model with ema_model."""
212         model_state = checkpoint['state_dict']
213         ema_state = checkpoint['ema_state_dict']
214         for k in ema_state:
215             if k[:7] == 'module.':
216                 tmp = ema_state[k]
217                 ema_state[k] = model_state[k[7:]]
218                 model_state[k[7:]] = tmp
219 
220     def _ema_started(self, runner) -> bool:
221         """Whether ``EMAHook`` has been initialized at current iteration or
222         epoch.
223 
224         :attr:`ema_model` will be initialized when ``runner.iter`` or
225         ``runner.epoch`` is greater than ``self.begin`` for the first time.
226 
227         Args:
228             runner (Runner): Runner of the training, validation process.
229 
230         Returns:
231             bool: Whether ``EMAHook`` has been initialized.
232         """
233         if self.enabled_by_epoch:
234             return runner.epoch + 1 >= self.begin_epoch
235         else:
236             return runner.iter + 1 >= self.begin_iter
237
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mmengine/hooks/ema_hook.py b/mmengine/hooks/ema_hook.py
--- a/mmengine/hooks/ema_hook.py
+++ b/mmengine/hooks/ema_hook.py
@@ -27,11 +27,12 @@
             Defaults to 'ExponentialMovingAverage'.
         strict_load (bool): Whether to strictly enforce that the keys of
             ``state_dict`` in checkpoint match the keys returned by
-            ``self.module.state_dict``. Defaults to True.
+            ``self.module.state_dict``. Defaults to False.
+            Changed in v0.3.0.
         begin_iter (int): The number of iteration to enable ``EMAHook``.
             Defaults to 0.
-        begin_epoch (int): The number of epoch to enable ``EMAHook``. Defaults
-            to 0.
+        begin_epoch (int): The number of epoch to enable ``EMAHook``.
+            Defaults to 0.
         **kwargs: Keyword arguments passed to subclasses of
             :obj:`BaseAveragedModel`
     """
@@ -40,7 +41,7 @@
 
     def __init__(self,
                  ema_type: str = 'ExponentialMovingAverage',
-                 strict_load: bool = True,
+                 strict_load: bool = False,
                  begin_iter: int = 0,
                  begin_epoch: int = 0,
                  **kwargs):

{"golden_diff": "diff --git a/mmengine/hooks/ema_hook.py b/mmengine/hooks/ema_hook.py\n--- a/mmengine/hooks/ema_hook.py\n+++ b/mmengine/hooks/ema_hook.py\n@@ -27,11 +27,12 @@\n             Defaults to 'ExponentialMovingAverage'.\n         strict_load (bool): Whether to strictly enforce that the keys of\n             ``state_dict`` in checkpoint match the keys returned by\n-            ``self.module.state_dict``. Defaults to True.\n+            ``self.module.state_dict``. Defaults to False.\n+            Changed in v0.3.0.\n         begin_iter (int): The number of iteration to enable ``EMAHook``.\n             Defaults to 0.\n-        begin_epoch (int): The number of epoch to enable ``EMAHook``. Defaults\n-            to 0.\n+        begin_epoch (int): The number of epoch to enable ``EMAHook``.\n+            Defaults to 0.\n         **kwargs: Keyword arguments passed to subclasses of\n             :obj:`BaseAveragedModel`\n     \"\"\"\n@@ -40,7 +41,7 @@\n \n     def __init__(self,\n                  ema_type: str = 'ExponentialMovingAverage',\n-                 strict_load: bool = True,\n+                 strict_load: bool = False,\n                  begin_iter: int = 0,\n                  begin_epoch: int = 0,\n                  **kwargs):\n", "issue": "[bug]resume error\nThanks for your error report and we appreciate it a lot.\r\n\r\n**Checklist**\r\n\r\n1. I have searched related issues but cannot get the expected help.\r\n2. I have read the [FAQ documentation](https://mmengine.readthedocs.io/en/latest/faq.html) but cannot get the expected help.\r\n3. The bug has not been fixed in the latest version.\r\n\r\n**Describe the bug**\r\nA clear and concise description of what the bug is.\r\n\r\n**Reproduction**\r\n\r\n1. What command or script did you run?\r\n\r\nwhen I try to resume the model by adding `resume=True, load_from='epoch_380.pth'` in the config, the newest version of mmeingne raise a RuntimeError:\r\n\r\n```\r\nRuntimeError: The model and loaded state dict do not match exactly\r\n\r\nunexpected key in source state_dict: data_preprocessor.mean, data_preprocessor.std\r\n```\r\n\r\nThe error disappears when checkout to v0.1.0\r\n\n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport itertools\nimport logging\nfrom typing import Dict, Optional\n\nfrom mmengine.logging import print_log\nfrom mmengine.model import is_model_wrapper\nfrom mmengine.registry import HOOKS, MODELS\nfrom .hook import DATA_BATCH, Hook\n\n\n@HOOKS.register_module()\nclass EMAHook(Hook):\n    \"\"\"A Hook to apply Exponential Moving Average (EMA) on the model during\n    training.\n\n    Note:\n        - EMAHook takes priority over CheckpointHook.\n        - The original model parameters are actually saved in ema field after\n          train.\n        - ``begin_iter`` and ``begin_epoch`` cannot be set at the same time.\n\n    Args:\n        ema_type (str): The type of EMA strategy to use. You can find the\n            supported strategies in :mod:`mmengine.model.averaged_model`.\n            Defaults to 'ExponentialMovingAverage'.\n        strict_load (bool): Whether to strictly enforce that the keys of\n            ``state_dict`` in checkpoint match the keys returned by\n            ``self.module.state_dict``. Defaults to True.\n        begin_iter (int): The number of iteration to enable ``EMAHook``.\n            Defaults to 0.\n        begin_epoch (int): The number of epoch to enable ``EMAHook``. Defaults\n            to 0.\n        **kwargs: Keyword arguments passed to subclasses of\n            :obj:`BaseAveragedModel`\n    \"\"\"\n\n    priority = 'NORMAL'\n\n    def __init__(self,\n                 ema_type: str = 'ExponentialMovingAverage',\n                 strict_load: bool = True,\n                 begin_iter: int = 0,\n                 begin_epoch: int = 0,\n                 **kwargs):\n        self.strict_load = strict_load\n        self.ema_cfg = dict(type=ema_type, **kwargs)\n        assert not (begin_iter != 0 and begin_epoch != 0), (\n            '`begin_iter` and `begin_epoch` should not be both set.')\n        assert begin_iter >= 0, (\n            f'begin_iter must larger than 0, but got begin: {begin_iter}')\n        assert begin_epoch >= 0, (\n            f'begin_epoch must larger than 0, but got begin: {begin_epoch}')\n        self.begin_iter = begin_iter\n        self.begin_epoch = begin_epoch\n        # If `begin_epoch` and `begin_iter` are not set, `EMAHook` will be\n        # enabled at 0 iteration.\n        self.enabled_by_epoch = self.begin_epoch > 0\n\n    def before_run(self, runner) -> None:\n        \"\"\"Create an ema copy of the model.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        model = runner.model\n        if is_model_wrapper(model):\n            model = model.module\n        self.src_model = model\n        self.ema_model = MODELS.build(\n            self.ema_cfg, default_args=dict(model=self.src_model))\n\n    def before_train(self, runner) -> None:\n        \"\"\"Check the begin_epoch/iter is smaller than max_epochs/iters.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        if self.enabled_by_epoch:\n            assert self.begin_epoch <= runner.max_epochs, (\n                'self.begin_epoch should be smaller than runner.max_epochs: '\n                f'{runner.max_epochs}, but got begin: {self.begin_epoch}')\n        else:\n            assert self.begin_iter <= runner.max_iters, (\n                'self.begin_iter should be smaller than runner.max_iters: '\n                f'{runner.max_iters}, but got begin: {self.begin_iter}')\n\n    def after_train_iter(self,\n                         runner,\n                         batch_idx: int,\n                         data_batch: DATA_BATCH = None,\n                         outputs: Optional[dict] = None) -> None:\n        \"\"\"Update ema parameter.\n\n        Args:\n            runner (Runner): The runner of the training process.\n            batch_idx (int): The index of the current batch in the train loop.\n            data_batch (Sequence[dict], optional): Data from dataloader.\n                Defaults to None.\n            outputs (dict, optional): Outputs from model. Defaults to None.\n        \"\"\"\n        if self._ema_started(runner):\n            self.ema_model.update_parameters(self.src_model)\n        else:\n            ema_params = self.ema_model.module.state_dict()\n            src_params = self.src_model.state_dict()\n            for k, p in ema_params.items():\n                p.data.copy_(src_params[k].data)\n\n    def before_val_epoch(self, runner) -> None:\n        \"\"\"We load parameter values from ema model to source model before\n        validation.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def after_val_epoch(self,\n                        runner,\n                        metrics: Optional[Dict[str, float]] = None) -> None:\n        \"\"\"We recover source model's parameter from ema model after validation.\n\n        Args:\n            runner (Runner): The runner of the validation process.\n            metrics (Dict[str, float], optional): Evaluation results of all\n                metrics on validation dataset. The keys are the names of the\n                metrics, and the values are corresponding results.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def before_test_epoch(self, runner) -> None:\n        \"\"\"We load parameter values from ema model to source model before test.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def after_test_epoch(self,\n                         runner,\n                         metrics: Optional[Dict[str, float]] = None) -> None:\n        \"\"\"We recover source model's parameter from ema model after test.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n            metrics (Dict[str, float], optional): Evaluation results of all\n                metrics on test dataset. The keys are the names of the\n                metrics, and the values are corresponding results.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def before_save_checkpoint(self, runner, checkpoint: dict) -> None:\n        \"\"\"Save ema parameters to checkpoint.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n        \"\"\"\n        checkpoint['ema_state_dict'] = self.ema_model.state_dict()\n        # Save ema parameters to the source model's state dict so that we\n        # can directly load the averaged model weights for deployment.\n        # Swapping the state_dict key-values instead of swapping model\n        # parameters because the state_dict is a shallow copy of model\n        # parameters.\n        self._swap_ema_state_dict(checkpoint)\n\n    def after_load_checkpoint(self, runner, checkpoint: dict) -> None:\n        \"\"\"Resume ema parameters from checkpoint.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n        \"\"\"\n        from mmengine.runner.checkpoint import load_state_dict\n        if 'ema_state_dict' in checkpoint and runner._resume:\n            # The original model parameters are actually saved in ema\n            # field swap the weights back to resume ema state.\n            self._swap_ema_state_dict(checkpoint)\n            self.ema_model.load_state_dict(\n                checkpoint['ema_state_dict'], strict=self.strict_load)\n\n        # Support load checkpoint without ema state dict.\n        else:\n            if runner._resume:\n                print_log(\n                    'There is no `ema_state_dict` in checkpoint. '\n                    '`EMAHook` will make a copy of `state_dict` as the '\n                    'initial `ema_state_dict`', 'current', logging.WARNING)\n            load_state_dict(\n                self.ema_model.module,\n                copy.deepcopy(checkpoint['state_dict']),\n                strict=self.strict_load)\n\n    def _swap_ema_parameters(self) -> None:\n        \"\"\"Swap the parameter of model with ema_model.\"\"\"\n        avg_param = (\n            itertools.chain(self.ema_model.module.parameters(),\n                            self.ema_model.module.buffers())\n            if self.ema_model.update_buffers else\n            self.ema_model.module.parameters())\n        src_param = (\n            itertools.chain(self.src_model.parameters(),\n                            self.src_model.buffers())\n            if self.ema_model.update_buffers else self.src_model.parameters())\n        for p_avg, p_src in zip(avg_param, src_param):\n            tmp = p_avg.data.clone()\n            p_avg.data.copy_(p_src.data)\n            p_src.data.copy_(tmp)\n\n    def _swap_ema_state_dict(self, checkpoint):\n        \"\"\"Swap the state dict values of model with ema_model.\"\"\"\n        model_state = checkpoint['state_dict']\n        ema_state = checkpoint['ema_state_dict']\n        for k in ema_state:\n            if k[:7] == 'module.':\n                tmp = ema_state[k]\n                ema_state[k] = model_state[k[7:]]\n                model_state[k[7:]] = tmp\n\n    def _ema_started(self, runner) -> bool:\n        \"\"\"Whether ``EMAHook`` has been initialized at current iteration or\n        epoch.\n\n        :attr:`ema_model` will be initialized when ``runner.iter`` or\n        ``runner.epoch`` is greater than ``self.begin`` for the first time.\n\n        Args:\n            runner (Runner): Runner of the training, validation process.\n\n        Returns:\n            bool: Whether ``EMAHook`` has been initialized.\n        \"\"\"\n        if self.enabled_by_epoch:\n            return runner.epoch + 1 >= self.begin_epoch\n        else:\n            return runner.iter + 1 >= self.begin_iter\n", "path": "mmengine/hooks/ema_hook.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport itertools\nimport logging\nfrom typing import Dict, Optional\n\nfrom mmengine.logging import print_log\nfrom mmengine.model import is_model_wrapper\nfrom mmengine.registry import HOOKS, MODELS\nfrom .hook import DATA_BATCH, Hook\n\n\n@HOOKS.register_module()\nclass EMAHook(Hook):\n    \"\"\"A Hook to apply Exponential Moving Average (EMA) on the model during\n    training.\n\n    Note:\n        - EMAHook takes priority over CheckpointHook.\n        - The original model parameters are actually saved in ema field after\n          train.\n        - ``begin_iter`` and ``begin_epoch`` cannot be set at the same time.\n\n    Args:\n        ema_type (str): The type of EMA strategy to use. You can find the\n            supported strategies in :mod:`mmengine.model.averaged_model`.\n            Defaults to 'ExponentialMovingAverage'.\n        strict_load (bool): Whether to strictly enforce that the keys of\n            ``state_dict`` in checkpoint match the keys returned by\n            ``self.module.state_dict``. Defaults to False.\n            Changed in v0.3.0.\n        begin_iter (int): The number of iteration to enable ``EMAHook``.\n            Defaults to 0.\n        begin_epoch (int): The number of epoch to enable ``EMAHook``.\n            Defaults to 0.\n        **kwargs: Keyword arguments passed to subclasses of\n            :obj:`BaseAveragedModel`\n    \"\"\"\n\n    priority = 'NORMAL'\n\n    def __init__(self,\n                 ema_type: str = 'ExponentialMovingAverage',\n                 strict_load: bool = False,\n                 begin_iter: int = 0,\n                 begin_epoch: int = 0,\n                 **kwargs):\n        self.strict_load = strict_load\n        self.ema_cfg = dict(type=ema_type, **kwargs)\n        assert not (begin_iter != 0 and begin_epoch != 0), (\n            '`begin_iter` and `begin_epoch` should not be both set.')\n        assert begin_iter >= 0, (\n            f'begin_iter must larger than 0, but got begin: {begin_iter}')\n        assert begin_epoch >= 0, (\n            f'begin_epoch must larger than 0, but got begin: {begin_epoch}')\n        self.begin_iter = begin_iter\n        self.begin_epoch = begin_epoch\n        # If `begin_epoch` and `begin_iter` are not set, `EMAHook` will be\n        # enabled at 0 iteration.\n        self.enabled_by_epoch = self.begin_epoch > 0\n\n    def before_run(self, runner) -> None:\n        \"\"\"Create an ema copy of the model.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        model = runner.model\n        if is_model_wrapper(model):\n            model = model.module\n        self.src_model = model\n        self.ema_model = MODELS.build(\n            self.ema_cfg, default_args=dict(model=self.src_model))\n\n    def before_train(self, runner) -> None:\n        \"\"\"Check the begin_epoch/iter is smaller than max_epochs/iters.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        if self.enabled_by_epoch:\n            assert self.begin_epoch <= runner.max_epochs, (\n                'self.begin_epoch should be smaller than runner.max_epochs: '\n                f'{runner.max_epochs}, but got begin: {self.begin_epoch}')\n        else:\n            assert self.begin_iter <= runner.max_iters, (\n                'self.begin_iter should be smaller than runner.max_iters: '\n                f'{runner.max_iters}, but got begin: {self.begin_iter}')\n\n    def after_train_iter(self,\n                         runner,\n                         batch_idx: int,\n                         data_batch: DATA_BATCH = None,\n                         outputs: Optional[dict] = None) -> None:\n        \"\"\"Update ema parameter.\n\n        Args:\n            runner (Runner): The runner of the training process.\n            batch_idx (int): The index of the current batch in the train loop.\n            data_batch (Sequence[dict], optional): Data from dataloader.\n                Defaults to None.\n            outputs (dict, optional): Outputs from model. Defaults to None.\n        \"\"\"\n        if self._ema_started(runner):\n            self.ema_model.update_parameters(self.src_model)\n        else:\n            ema_params = self.ema_model.module.state_dict()\n            src_params = self.src_model.state_dict()\n            for k, p in ema_params.items():\n                p.data.copy_(src_params[k].data)\n\n    def before_val_epoch(self, runner) -> None:\n        \"\"\"We load parameter values from ema model to source model before\n        validation.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def after_val_epoch(self,\n                        runner,\n                        metrics: Optional[Dict[str, float]] = None) -> None:\n        \"\"\"We recover source model's parameter from ema model after validation.\n\n        Args:\n            runner (Runner): The runner of the validation process.\n            metrics (Dict[str, float], optional): Evaluation results of all\n                metrics on validation dataset. The keys are the names of the\n                metrics, and the values are corresponding results.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def before_test_epoch(self, runner) -> None:\n        \"\"\"We load parameter values from ema model to source model before test.\n\n        Args:\n            runner (Runner): The runner of the training process.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def after_test_epoch(self,\n                         runner,\n                         metrics: Optional[Dict[str, float]] = None) -> None:\n        \"\"\"We recover source model's parameter from ema model after test.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n            metrics (Dict[str, float], optional): Evaluation results of all\n                metrics on test dataset. The keys are the names of the\n                metrics, and the values are corresponding results.\n        \"\"\"\n        self._swap_ema_parameters()\n\n    def before_save_checkpoint(self, runner, checkpoint: dict) -> None:\n        \"\"\"Save ema parameters to checkpoint.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n        \"\"\"\n        checkpoint['ema_state_dict'] = self.ema_model.state_dict()\n        # Save ema parameters to the source model's state dict so that we\n        # can directly load the averaged model weights for deployment.\n        # Swapping the state_dict key-values instead of swapping model\n        # parameters because the state_dict is a shallow copy of model\n        # parameters.\n        self._swap_ema_state_dict(checkpoint)\n\n    def after_load_checkpoint(self, runner, checkpoint: dict) -> None:\n        \"\"\"Resume ema parameters from checkpoint.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n        \"\"\"\n        from mmengine.runner.checkpoint import load_state_dict\n        if 'ema_state_dict' in checkpoint and runner._resume:\n            # The original model parameters are actually saved in ema\n            # field swap the weights back to resume ema state.\n            self._swap_ema_state_dict(checkpoint)\n            self.ema_model.load_state_dict(\n                checkpoint['ema_state_dict'], strict=self.strict_load)\n\n        # Support load checkpoint without ema state dict.\n        else:\n            if runner._resume:\n                print_log(\n                    'There is no `ema_state_dict` in checkpoint. '\n                    '`EMAHook` will make a copy of `state_dict` as the '\n                    'initial `ema_state_dict`', 'current', logging.WARNING)\n            load_state_dict(\n                self.ema_model.module,\n                copy.deepcopy(checkpoint['state_dict']),\n                strict=self.strict_load)\n\n    def _swap_ema_parameters(self) -> None:\n        \"\"\"Swap the parameter of model with ema_model.\"\"\"\n        avg_param = (\n            itertools.chain(self.ema_model.module.parameters(),\n                            self.ema_model.module.buffers())\n            if self.ema_model.update_buffers else\n            self.ema_model.module.parameters())\n        src_param = (\n            itertools.chain(self.src_model.parameters(),\n                            self.src_model.buffers())\n            if self.ema_model.update_buffers else self.src_model.parameters())\n        for p_avg, p_src in zip(avg_param, src_param):\n            tmp = p_avg.data.clone()\n            p_avg.data.copy_(p_src.data)\n            p_src.data.copy_(tmp)\n\n    def _swap_ema_state_dict(self, checkpoint):\n        \"\"\"Swap the state dict values of model with ema_model.\"\"\"\n        model_state = checkpoint['state_dict']\n        ema_state = checkpoint['ema_state_dict']\n        for k in ema_state:\n            if k[:7] == 'module.':\n                tmp = ema_state[k]\n                ema_state[k] = model_state[k[7:]]\n                model_state[k[7:]] = tmp\n\n    def _ema_started(self, runner) -> bool:\n        \"\"\"Whether ``EMAHook`` has been initialized at current iteration or\n        epoch.\n\n        :attr:`ema_model` will be initialized when ``runner.iter`` or\n        ``runner.epoch`` is greater than ``self.begin`` for the first time.\n\n        Args:\n            runner (Runner): Runner of the training, validation process.\n\n        Returns:\n            bool: Whether ``EMAHook`` has been initialized.\n        \"\"\"\n        if self.enabled_by_epoch:\n            return runner.epoch + 1 >= self.begin_epoch\n        else:\n            return runner.iter + 1 >= self.begin_iter\n", "path": "mmengine/hooks/ema_hook.py"}]}