We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] MMSeparateDistributedDataParallel skip init_weights
### Prerequisite

- [X] I have searched [Issues](https://github.com/open-mmlab/mmengine/issues) and [Discussions](https://github.com/open-mmlab/mmengine/discussions) but cannot get the expected help.
- [X] The bug has not been fixed in the latest version(https://github.com/open-mmlab/mmengine).


### Reproduces the problem - code sample

I encountered this problem when running my own custom project based on `mmengine`, which is too complicated to present.


### Additional information

The `MMSeparateDistributedDataParallel` is a **model wrapper of model wrapper**, whose `module` may contain the `MMDistributedDataParallel`.

https://github.com/open-mmlab/mmengine/blob/4d7a29342c02d78cb3ffabe036607e801d6713d9/mmengine/model/wrappers/seperate_distributed.py#L82-L87

When initializing the model_wrapper weights, the `runner` initialize the weight of the `runner.model.module`:
 https://github.com/open-mmlab/mmengine/blob/4d7a29342c02d78cb3ffabe036607e801d6713d9/mmengine/runner/runner.py#L893-L902
The above codes will cause the `init_weights` functions in model not work because the children module of the `runner.model.module` in this case is of type `MMDistributedDataParallel` which does NOT have `init_weights` function.

--- 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/model/base_module.py`
Content:
```
1 # Copyright (c) OpenMMLab. All rights reserved.
2 import copy
3 import logging
4 from abc import ABCMeta
5 from collections import defaultdict
6 from logging import FileHandler
7 from typing import Iterable, List, Optional, Union
8 
9 import torch.nn as nn
10 
11 from mmengine.dist import master_only
12 from mmengine.logging import MMLogger, print_log
13 from .weight_init import initialize, update_init_info
14 
15 
16 class BaseModule(nn.Module, metaclass=ABCMeta):
17     """Base module for all modules in openmmlab. ``BaseModule`` is a wrapper of
18     ``torch.nn.Module`` with additional functionality of parameter
19     initialization. Compared with ``torch.nn.Module``, ``BaseModule`` mainly
20     adds three attributes.
21 
22     - ``init_cfg``: the config to control the initialization.
23     - ``init_weights``: The function of parameter initialization and recording
24       initialization information.
25     - ``_params_init_info``: Used to track the parameter initialization
26       information. This attribute only exists during executing the
27       ``init_weights``.
28 
29     Note:
30         :obj:`PretrainedInit` has a higher priority than any other
31         initializer. The loaded pretrained weights will overwrite
32         the previous initialized weights.
33 
34     Args:
35         init_cfg (dict or List[dict], optional): Initialization config dict.
36     """
37 
38     def __init__(self, init_cfg: Union[dict, List[dict], None] = None):
39         """Initialize BaseModule, inherited from `torch.nn.Module`"""
40 
41         # NOTE init_cfg can be defined in different levels, but init_cfg
42         # in low levels has a higher priority.
43 
44         super().__init__()
45         # define default value of init_cfg instead of hard code
46         # in init_weights() function
47         self._is_init = False
48 
49         self.init_cfg = copy.deepcopy(init_cfg)
50 
51         # Backward compatibility in derived classes
52         # if pretrained is not None:
53         #     warnings.warn('DeprecationWarning: pretrained is a deprecated \
54         #         key, please consider using init_cfg')
55         #     self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)
56 
57     @property
58     def is_init(self):
59         return self._is_init
60 
61     def init_weights(self):
62         """Initialize the weights."""
63 
64         is_top_level_module = False
65         # check if it is top-level module
66         if not hasattr(self, '_params_init_info'):
67             # The `_params_init_info` is used to record the initialization
68             # information of the parameters
69             # the key should be the obj:`nn.Parameter` of model and the value
70             # should be a dict containing
71             # - init_info (str): The string that describes the initialization.
72             # - tmp_mean_value (FloatTensor): The mean of the parameter,
73             #       which indicates whether the parameter has been modified.
74             # this attribute would be deleted after all parameters
75             # is initialized.
76             self._params_init_info = defaultdict(dict)
77             is_top_level_module = True
78 
79             # Initialize the `_params_init_info`,
80             # When detecting the `tmp_mean_value` of
81             # the corresponding parameter is changed, update related
82             # initialization information
83             for name, param in self.named_parameters():
84                 self._params_init_info[param][
85                     'init_info'] = f'The value is the same before and ' \
86                                    f'after calling `init_weights` ' \
87                                    f'of {self.__class__.__name__} '
88                 self._params_init_info[param][
89                     'tmp_mean_value'] = param.data.mean().cpu()
90 
91             # pass `params_init_info` to all submodules
92             # All submodules share the same `params_init_info`,
93             # so it will be updated when parameters are
94             # modified at any level of the model.
95             for sub_module in self.modules():
96                 sub_module._params_init_info = self._params_init_info
97 
98         module_name = self.__class__.__name__
99         if not self._is_init:
100             if self.init_cfg:
101                 print_log(
102                     f'initialize {module_name} with init_cfg {self.init_cfg}',
103                     logger='current',
104                     level=logging.DEBUG)
105 
106                 init_cfgs = self.init_cfg
107                 if isinstance(self.init_cfg, dict):
108                     init_cfgs = [self.init_cfg]
109 
110                 # PretrainedInit has higher priority than any other init_cfg.
111                 # Therefore we initialize `pretrained_cfg` last to overwrite
112                 # the previous initialized weights.
113                 # See details in https://github.com/open-mmlab/mmengine/issues/691 # noqa E501
114                 other_cfgs = []
115                 pretrained_cfg = []
116                 for init_cfg in init_cfgs:
117                     assert isinstance(init_cfg, dict)
118                     if init_cfg['type'] == 'Pretrained':
119                         pretrained_cfg.append(init_cfg)
120                     else:
121                         other_cfgs.append(init_cfg)
122 
123                 initialize(self, other_cfgs)
124 
125             for m in self.children():
126                 if hasattr(m, 'init_weights'):
127                     m.init_weights()
128                     # users may overload the `init_weights`
129                     update_init_info(
130                         m,
131                         init_info=f'Initialized by '
132                         f'user-defined `init_weights`'
133                         f' in {m.__class__.__name__} ')
134             if self.init_cfg and pretrained_cfg:
135                 initialize(self, pretrained_cfg)
136             self._is_init = True
137         else:
138             print_log(
139                 f'init_weights of {self.__class__.__name__} has '
140                 f'been called more than once.',
141                 logger='current',
142                 level=logging.WARNING)
143 
144         if is_top_level_module:
145             self._dump_init_info()
146 
147             for sub_module in self.modules():
148                 del sub_module._params_init_info
149 
150     @master_only
151     def _dump_init_info(self):
152         """Dump the initialization information to a file named
153         `initialization.log.json` in workdir."""
154 
155         logger = MMLogger.get_current_instance()
156         with_file_handler = False
157         # dump the information to the logger file if there is a `FileHandler`
158         for handler in logger.handlers:
159             if isinstance(handler, FileHandler):
160                 handler.stream.write(
161                     'Name of parameter - Initialization information\n')
162                 for name, param in self.named_parameters():
163                     handler.stream.write(
164                         f'\n{name} - {param.shape}: '
165                         f"\n{self._params_init_info[param]['init_info']} \n")
166                 handler.stream.flush()
167                 with_file_handler = True
168         if not with_file_handler:
169             for name, param in self.named_parameters():
170                 logger.info(
171                     f'\n{name} - {param.shape}: '
172                     f"\n{self._params_init_info[param]['init_info']} \n ")
173 
174     def __repr__(self):
175         s = super().__repr__()
176         if self.init_cfg:
177             s += f'\ninit_cfg={self.init_cfg}'
178         return s
179 
180 
181 class Sequential(BaseModule, nn.Sequential):
182     """Sequential module in openmmlab.
183 
184     Ensures that all modules in ``Sequential`` have a different initialization
185     strategy than the outer model
186 
187     Args:
188         init_cfg (dict, optional): Initialization config dict.
189     """
190 
191     def __init__(self, *args, init_cfg: Optional[dict] = None):
192         BaseModule.__init__(self, init_cfg)
193         nn.Sequential.__init__(self, *args)
194 
195 
196 class ModuleList(BaseModule, nn.ModuleList):
197     """ModuleList in openmmlab.
198 
199     Ensures that all modules in ``ModuleList`` have a different initialization
200     strategy than the outer model
201 
202     Args:
203         modules (iterable, optional): An iterable of modules to add.
204         init_cfg (dict, optional): Initialization config dict.
205     """
206 
207     def __init__(self,
208                  modules: Optional[Iterable] = None,
209                  init_cfg: Optional[dict] = None):
210         BaseModule.__init__(self, init_cfg)
211         nn.ModuleList.__init__(self, modules)
212 
213 
214 class ModuleDict(BaseModule, nn.ModuleDict):
215     """ModuleDict in openmmlab.
216 
217     Ensures that all modules in ``ModuleDict`` have a different initialization
218     strategy than the outer model
219 
220     Args:
221         modules (dict, optional): A mapping (dictionary) of (string: module)
222             or an iterable of key-value pairs of type (string, module).
223         init_cfg (dict, optional): Initialization config dict.
224     """
225 
226     def __init__(self,
227                  modules: Optional[dict] = None,
228                  init_cfg: Optional[dict] = None):
229         BaseModule.__init__(self, init_cfg)
230         nn.ModuleDict.__init__(self, modules)
231
```
--- 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/model/base_module.py b/mmengine/model/base_module.py
--- a/mmengine/model/base_module.py
+++ b/mmengine/model/base_module.py
@@ -11,6 +11,7 @@
 from mmengine.dist import master_only
 from mmengine.logging import MMLogger, print_log
 from .weight_init import initialize, update_init_info
+from .wrappers.utils import is_model_wrapper
 
 
 class BaseModule(nn.Module, metaclass=ABCMeta):
@@ -123,6 +124,8 @@
                 initialize(self, other_cfgs)
 
             for m in self.children():
+                if is_model_wrapper(m) and not hasattr(m, 'init_weights'):
+                    m = m.module
                 if hasattr(m, 'init_weights'):
                     m.init_weights()
                     # users may overload the `init_weights`

{"golden_diff": "diff --git a/mmengine/model/base_module.py b/mmengine/model/base_module.py\n--- a/mmengine/model/base_module.py\n+++ b/mmengine/model/base_module.py\n@@ -11,6 +11,7 @@\n from mmengine.dist import master_only\n from mmengine.logging import MMLogger, print_log\n from .weight_init import initialize, update_init_info\n+from .wrappers.utils import is_model_wrapper\n \n \n class BaseModule(nn.Module, metaclass=ABCMeta):\n@@ -123,6 +124,8 @@\n                 initialize(self, other_cfgs)\n \n             for m in self.children():\n+                if is_model_wrapper(m) and not hasattr(m, 'init_weights'):\n+                    m = m.module\n                 if hasattr(m, 'init_weights'):\n                     m.init_weights()\n                     # users may overload the `init_weights`\n", "issue": "[Bug] MMSeparateDistributedDataParallel skip init_weights\n### Prerequisite\r\n\r\n- [X] I have searched [Issues](https://github.com/open-mmlab/mmengine/issues) and [Discussions](https://github.com/open-mmlab/mmengine/discussions) but cannot get the expected help.\r\n- [X] The bug has not been fixed in the latest version(https://github.com/open-mmlab/mmengine).\r\n\r\n\r\n### Reproduces the problem - code sample\r\n\r\nI encountered this problem when running my own custom project based on `mmengine`, which is too complicated to present.\r\n\r\n\r\n### Additional information\r\n\r\nThe `MMSeparateDistributedDataParallel` is a **model wrapper of model wrapper**, whose `module` may contain the `MMDistributedDataParallel`.\r\n\r\nhttps://github.com/open-mmlab/mmengine/blob/4d7a29342c02d78cb3ffabe036607e801d6713d9/mmengine/model/wrappers/seperate_distributed.py#L82-L87\r\n\r\nWhen initializing the model_wrapper weights, the `runner` initialize the weight of the `runner.model.module`:\r\n https://github.com/open-mmlab/mmengine/blob/4d7a29342c02d78cb3ffabe036607e801d6713d9/mmengine/runner/runner.py#L893-L902\r\nThe above codes will cause the `init_weights` functions in model not work because the children module of the `runner.model.module` in this case is of type `MMDistributedDataParallel` which does NOT have `init_weights` function.\n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport logging\nfrom abc import ABCMeta\nfrom collections import defaultdict\nfrom logging import FileHandler\nfrom typing import Iterable, List, Optional, Union\n\nimport torch.nn as nn\n\nfrom mmengine.dist import master_only\nfrom mmengine.logging import MMLogger, print_log\nfrom .weight_init import initialize, update_init_info\n\n\nclass BaseModule(nn.Module, metaclass=ABCMeta):\n    \"\"\"Base module for all modules in openmmlab. ``BaseModule`` is a wrapper of\n    ``torch.nn.Module`` with additional functionality of parameter\n    initialization. Compared with ``torch.nn.Module``, ``BaseModule`` mainly\n    adds three attributes.\n\n    - ``init_cfg``: the config to control the initialization.\n    - ``init_weights``: The function of parameter initialization and recording\n      initialization information.\n    - ``_params_init_info``: Used to track the parameter initialization\n      information. This attribute only exists during executing the\n      ``init_weights``.\n\n    Note:\n        :obj:`PretrainedInit` has a higher priority than any other\n        initializer. The loaded pretrained weights will overwrite\n        the previous initialized weights.\n\n    Args:\n        init_cfg (dict or List[dict], optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self, init_cfg: Union[dict, List[dict], None] = None):\n        \"\"\"Initialize BaseModule, inherited from `torch.nn.Module`\"\"\"\n\n        # NOTE init_cfg can be defined in different levels, but init_cfg\n        # in low levels has a higher priority.\n\n        super().__init__()\n        # define default value of init_cfg instead of hard code\n        # in init_weights() function\n        self._is_init = False\n\n        self.init_cfg = copy.deepcopy(init_cfg)\n\n        # Backward compatibility in derived classes\n        # if pretrained is not None:\n        #     warnings.warn('DeprecationWarning: pretrained is a deprecated \\\n        #         key, please consider using init_cfg')\n        #     self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)\n\n    @property\n    def is_init(self):\n        return self._is_init\n\n    def init_weights(self):\n        \"\"\"Initialize the weights.\"\"\"\n\n        is_top_level_module = False\n        # check if it is top-level module\n        if not hasattr(self, '_params_init_info'):\n            # The `_params_init_info` is used to record the initialization\n            # information of the parameters\n            # the key should be the obj:`nn.Parameter` of model and the value\n            # should be a dict containing\n            # - init_info (str): The string that describes the initialization.\n            # - tmp_mean_value (FloatTensor): The mean of the parameter,\n            #       which indicates whether the parameter has been modified.\n            # this attribute would be deleted after all parameters\n            # is initialized.\n            self._params_init_info = defaultdict(dict)\n            is_top_level_module = True\n\n            # Initialize the `_params_init_info`,\n            # When detecting the `tmp_mean_value` of\n            # the corresponding parameter is changed, update related\n            # initialization information\n            for name, param in self.named_parameters():\n                self._params_init_info[param][\n                    'init_info'] = f'The value is the same before and ' \\\n                                   f'after calling `init_weights` ' \\\n                                   f'of {self.__class__.__name__} '\n                self._params_init_info[param][\n                    'tmp_mean_value'] = param.data.mean().cpu()\n\n            # pass `params_init_info` to all submodules\n            # All submodules share the same `params_init_info`,\n            # so it will be updated when parameters are\n            # modified at any level of the model.\n            for sub_module in self.modules():\n                sub_module._params_init_info = self._params_init_info\n\n        module_name = self.__class__.__name__\n        if not self._is_init:\n            if self.init_cfg:\n                print_log(\n                    f'initialize {module_name} with init_cfg {self.init_cfg}',\n                    logger='current',\n                    level=logging.DEBUG)\n\n                init_cfgs = self.init_cfg\n                if isinstance(self.init_cfg, dict):\n                    init_cfgs = [self.init_cfg]\n\n                # PretrainedInit has higher priority than any other init_cfg.\n                # Therefore we initialize `pretrained_cfg` last to overwrite\n                # the previous initialized weights.\n                # See details in https://github.com/open-mmlab/mmengine/issues/691 # noqa E501\n                other_cfgs = []\n                pretrained_cfg = []\n                for init_cfg in init_cfgs:\n                    assert isinstance(init_cfg, dict)\n                    if init_cfg['type'] == 'Pretrained':\n                        pretrained_cfg.append(init_cfg)\n                    else:\n                        other_cfgs.append(init_cfg)\n\n                initialize(self, other_cfgs)\n\n            for m in self.children():\n                if hasattr(m, 'init_weights'):\n                    m.init_weights()\n                    # users may overload the `init_weights`\n                    update_init_info(\n                        m,\n                        init_info=f'Initialized by '\n                        f'user-defined `init_weights`'\n                        f' in {m.__class__.__name__} ')\n            if self.init_cfg and pretrained_cfg:\n                initialize(self, pretrained_cfg)\n            self._is_init = True\n        else:\n            print_log(\n                f'init_weights of {self.__class__.__name__} has '\n                f'been called more than once.',\n                logger='current',\n                level=logging.WARNING)\n\n        if is_top_level_module:\n            self._dump_init_info()\n\n            for sub_module in self.modules():\n                del sub_module._params_init_info\n\n    @master_only\n    def _dump_init_info(self):\n        \"\"\"Dump the initialization information to a file named\n        `initialization.log.json` in workdir.\"\"\"\n\n        logger = MMLogger.get_current_instance()\n        with_file_handler = False\n        # dump the information to the logger file if there is a `FileHandler`\n        for handler in logger.handlers:\n            if isinstance(handler, FileHandler):\n                handler.stream.write(\n                    'Name of parameter - Initialization information\\n')\n                for name, param in self.named_parameters():\n                    handler.stream.write(\n                        f'\\n{name} - {param.shape}: '\n                        f\"\\n{self._params_init_info[param]['init_info']} \\n\")\n                handler.stream.flush()\n                with_file_handler = True\n        if not with_file_handler:\n            for name, param in self.named_parameters():\n                logger.info(\n                    f'\\n{name} - {param.shape}: '\n                    f\"\\n{self._params_init_info[param]['init_info']} \\n \")\n\n    def __repr__(self):\n        s = super().__repr__()\n        if self.init_cfg:\n            s += f'\\ninit_cfg={self.init_cfg}'\n        return s\n\n\nclass Sequential(BaseModule, nn.Sequential):\n    \"\"\"Sequential module in openmmlab.\n\n    Ensures that all modules in ``Sequential`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self, *args, init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.Sequential.__init__(self, *args)\n\n\nclass ModuleList(BaseModule, nn.ModuleList):\n    \"\"\"ModuleList in openmmlab.\n\n    Ensures that all modules in ``ModuleList`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        modules (iterable, optional): An iterable of modules to add.\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 modules: Optional[Iterable] = None,\n                 init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.ModuleList.__init__(self, modules)\n\n\nclass ModuleDict(BaseModule, nn.ModuleDict):\n    \"\"\"ModuleDict in openmmlab.\n\n    Ensures that all modules in ``ModuleDict`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        modules (dict, optional): A mapping (dictionary) of (string: module)\n            or an iterable of key-value pairs of type (string, module).\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 modules: Optional[dict] = None,\n                 init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.ModuleDict.__init__(self, modules)\n", "path": "mmengine/model/base_module.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport logging\nfrom abc import ABCMeta\nfrom collections import defaultdict\nfrom logging import FileHandler\nfrom typing import Iterable, List, Optional, Union\n\nimport torch.nn as nn\n\nfrom mmengine.dist import master_only\nfrom mmengine.logging import MMLogger, print_log\nfrom .weight_init import initialize, update_init_info\nfrom .wrappers.utils import is_model_wrapper\n\n\nclass BaseModule(nn.Module, metaclass=ABCMeta):\n    \"\"\"Base module for all modules in openmmlab. ``BaseModule`` is a wrapper of\n    ``torch.nn.Module`` with additional functionality of parameter\n    initialization. Compared with ``torch.nn.Module``, ``BaseModule`` mainly\n    adds three attributes.\n\n    - ``init_cfg``: the config to control the initialization.\n    - ``init_weights``: The function of parameter initialization and recording\n      initialization information.\n    - ``_params_init_info``: Used to track the parameter initialization\n      information. This attribute only exists during executing the\n      ``init_weights``.\n\n    Note:\n        :obj:`PretrainedInit` has a higher priority than any other\n        initializer. The loaded pretrained weights will overwrite\n        the previous initialized weights.\n\n    Args:\n        init_cfg (dict or List[dict], optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self, init_cfg: Union[dict, List[dict], None] = None):\n        \"\"\"Initialize BaseModule, inherited from `torch.nn.Module`\"\"\"\n\n        # NOTE init_cfg can be defined in different levels, but init_cfg\n        # in low levels has a higher priority.\n\n        super().__init__()\n        # define default value of init_cfg instead of hard code\n        # in init_weights() function\n        self._is_init = False\n\n        self.init_cfg = copy.deepcopy(init_cfg)\n\n        # Backward compatibility in derived classes\n        # if pretrained is not None:\n        #     warnings.warn('DeprecationWarning: pretrained is a deprecated \\\n        #         key, please consider using init_cfg')\n        #     self.init_cfg = dict(type='Pretrained', checkpoint=pretrained)\n\n    @property\n    def is_init(self):\n        return self._is_init\n\n    def init_weights(self):\n        \"\"\"Initialize the weights.\"\"\"\n\n        is_top_level_module = False\n        # check if it is top-level module\n        if not hasattr(self, '_params_init_info'):\n            # The `_params_init_info` is used to record the initialization\n            # information of the parameters\n            # the key should be the obj:`nn.Parameter` of model and the value\n            # should be a dict containing\n            # - init_info (str): The string that describes the initialization.\n            # - tmp_mean_value (FloatTensor): The mean of the parameter,\n            #       which indicates whether the parameter has been modified.\n            # this attribute would be deleted after all parameters\n            # is initialized.\n            self._params_init_info = defaultdict(dict)\n            is_top_level_module = True\n\n            # Initialize the `_params_init_info`,\n            # When detecting the `tmp_mean_value` of\n            # the corresponding parameter is changed, update related\n            # initialization information\n            for name, param in self.named_parameters():\n                self._params_init_info[param][\n                    'init_info'] = f'The value is the same before and ' \\\n                                   f'after calling `init_weights` ' \\\n                                   f'of {self.__class__.__name__} '\n                self._params_init_info[param][\n                    'tmp_mean_value'] = param.data.mean().cpu()\n\n            # pass `params_init_info` to all submodules\n            # All submodules share the same `params_init_info`,\n            # so it will be updated when parameters are\n            # modified at any level of the model.\n            for sub_module in self.modules():\n                sub_module._params_init_info = self._params_init_info\n\n        module_name = self.__class__.__name__\n        if not self._is_init:\n            if self.init_cfg:\n                print_log(\n                    f'initialize {module_name} with init_cfg {self.init_cfg}',\n                    logger='current',\n                    level=logging.DEBUG)\n\n                init_cfgs = self.init_cfg\n                if isinstance(self.init_cfg, dict):\n                    init_cfgs = [self.init_cfg]\n\n                # PretrainedInit has higher priority than any other init_cfg.\n                # Therefore we initialize `pretrained_cfg` last to overwrite\n                # the previous initialized weights.\n                # See details in https://github.com/open-mmlab/mmengine/issues/691 # noqa E501\n                other_cfgs = []\n                pretrained_cfg = []\n                for init_cfg in init_cfgs:\n                    assert isinstance(init_cfg, dict)\n                    if init_cfg['type'] == 'Pretrained':\n                        pretrained_cfg.append(init_cfg)\n                    else:\n                        other_cfgs.append(init_cfg)\n\n                initialize(self, other_cfgs)\n\n            for m in self.children():\n                if is_model_wrapper(m) and not hasattr(m, 'init_weights'):\n                    m = m.module\n                if hasattr(m, 'init_weights'):\n                    m.init_weights()\n                    # users may overload the `init_weights`\n                    update_init_info(\n                        m,\n                        init_info=f'Initialized by '\n                        f'user-defined `init_weights`'\n                        f' in {m.__class__.__name__} ')\n            if self.init_cfg and pretrained_cfg:\n                initialize(self, pretrained_cfg)\n            self._is_init = True\n        else:\n            print_log(\n                f'init_weights of {self.__class__.__name__} has '\n                f'been called more than once.',\n                logger='current',\n                level=logging.WARNING)\n\n        if is_top_level_module:\n            self._dump_init_info()\n\n            for sub_module in self.modules():\n                del sub_module._params_init_info\n\n    @master_only\n    def _dump_init_info(self):\n        \"\"\"Dump the initialization information to a file named\n        `initialization.log.json` in workdir.\"\"\"\n\n        logger = MMLogger.get_current_instance()\n        with_file_handler = False\n        # dump the information to the logger file if there is a `FileHandler`\n        for handler in logger.handlers:\n            if isinstance(handler, FileHandler):\n                handler.stream.write(\n                    'Name of parameter - Initialization information\\n')\n                for name, param in self.named_parameters():\n                    handler.stream.write(\n                        f'\\n{name} - {param.shape}: '\n                        f\"\\n{self._params_init_info[param]['init_info']} \\n\")\n                handler.stream.flush()\n                with_file_handler = True\n        if not with_file_handler:\n            for name, param in self.named_parameters():\n                logger.info(\n                    f'\\n{name} - {param.shape}: '\n                    f\"\\n{self._params_init_info[param]['init_info']} \\n \")\n\n    def __repr__(self):\n        s = super().__repr__()\n        if self.init_cfg:\n            s += f'\\ninit_cfg={self.init_cfg}'\n        return s\n\n\nclass Sequential(BaseModule, nn.Sequential):\n    \"\"\"Sequential module in openmmlab.\n\n    Ensures that all modules in ``Sequential`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self, *args, init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.Sequential.__init__(self, *args)\n\n\nclass ModuleList(BaseModule, nn.ModuleList):\n    \"\"\"ModuleList in openmmlab.\n\n    Ensures that all modules in ``ModuleList`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        modules (iterable, optional): An iterable of modules to add.\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 modules: Optional[Iterable] = None,\n                 init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.ModuleList.__init__(self, modules)\n\n\nclass ModuleDict(BaseModule, nn.ModuleDict):\n    \"\"\"ModuleDict in openmmlab.\n\n    Ensures that all modules in ``ModuleDict`` have a different initialization\n    strategy than the outer model\n\n    Args:\n        modules (dict, optional): A mapping (dictionary) of (string: module)\n            or an iterable of key-value pairs of type (string, module).\n        init_cfg (dict, optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 modules: Optional[dict] = None,\n                 init_cfg: Optional[dict] = None):\n        BaseModule.__init__(self, init_cfg)\n        nn.ModuleDict.__init__(self, modules)\n", "path": "mmengine/model/base_module.py"}]}