We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
框架有很多没有通过测试的Bug
在我运行res50_freihand2d_224x224.py的过程中就碰到了两个问题

1. tools/dist_train.sh里面没有定义$MASTER_ADDR

2. res50_freihand2d_224x224.py 没有定义runner = dict(type='EpochBasedRunner', max_epochs=total_epochs)

其他的还没有跑，但感觉会有很多小问题

发布的版本有点粗糙呀，期待把这些小Bug尽快解决，后续很期待在这个框架上做更多实验


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/train.py`
Content:
```
1 # Copyright (c) OpenMMLab. All rights reserved.
2 import argparse
3 import copy
4 import os
5 import os.path as osp
6 import time
7 import warnings
8 
9 import mmcv
10 import torch
11 import torch.distributed as dist
12 from mmcv import Config, DictAction
13 from mmcv.runner import get_dist_info, init_dist, set_random_seed
14 from mmcv.utils import get_git_hash
15 
16 from mmpose import __version__
17 from mmpose.apis import init_random_seed, train_model
18 from mmpose.datasets import build_dataset
19 from mmpose.models import build_posenet
20 from mmpose.utils import collect_env, get_root_logger, setup_multi_processes
21 
22 
23 def parse_args():
24     parser = argparse.ArgumentParser(description='Train a pose model')
25     parser.add_argument('config', help='train config file path')
26     parser.add_argument('--work-dir', help='the dir to save logs and models')
27     parser.add_argument(
28         '--resume-from', help='the checkpoint file to resume from')
29     parser.add_argument(
30         '--no-validate',
31         action='store_true',
32         help='whether not to evaluate the checkpoint during training')
33     group_gpus = parser.add_mutually_exclusive_group()
34     group_gpus.add_argument(
35         '--gpus',
36         type=int,
37         help='(Deprecated, please use --gpu-id) number of gpus to use '
38         '(only applicable to non-distributed training)')
39     group_gpus.add_argument(
40         '--gpu-ids',
41         type=int,
42         nargs='+',
43         help='(Deprecated, please use --gpu-id) ids of gpus to use '
44         '(only applicable to non-distributed training)')
45     group_gpus.add_argument(
46         '--gpu-id',
47         type=int,
48         default=0,
49         help='id of gpu to use '
50         '(only applicable to non-distributed training)')
51     parser.add_argument('--seed', type=int, default=None, help='random seed')
52     parser.add_argument(
53         '--diff_seed',
54         action='store_true',
55         help='Whether or not set different seeds for different ranks')
56     parser.add_argument(
57         '--deterministic',
58         action='store_true',
59         help='whether to set deterministic options for CUDNN backend.')
60     parser.add_argument(
61         '--cfg-options',
62         nargs='+',
63         action=DictAction,
64         default={},
65         help='override some settings in the used config, the key-value pair '
66         'in xxx=yyy format will be merged into config file. For example, '
67         "'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'")
68     parser.add_argument(
69         '--launcher',
70         choices=['none', 'pytorch', 'slurm', 'mpi'],
71         default='none',
72         help='job launcher')
73     parser.add_argument('--local-rank', type=int, default=0)
74     parser.add_argument(
75         '--local_rank', type=int, default=0, help='An alias to --local-rank')
76     parser.add_argument(
77         '--autoscale-lr',
78         action='store_true',
79         help='automatically scale lr with the number of gpus')
80     args = parser.parse_args()
81     if 'LOCAL_RANK' not in os.environ:
82         os.environ['LOCAL_RANK'] = str(args.local_rank)
83 
84     return args
85 
86 
87 def main():
88     args = parse_args()
89 
90     cfg = Config.fromfile(args.config)
91 
92     if args.cfg_options is not None:
93         cfg.merge_from_dict(args.cfg_options)
94 
95     # set multi-process settings
96     setup_multi_processes(cfg)
97 
98     # set cudnn_benchmark
99     if cfg.get('cudnn_benchmark', False):
100         torch.backends.cudnn.benchmark = True
101 
102     # work_dir is determined in this priority: CLI > segment in file > filename
103     if args.work_dir is not None:
104         # update configs according to CLI args if args.work_dir is not None
105         cfg.work_dir = args.work_dir
106     elif cfg.get('work_dir', None) is None:
107         # use config filename as default work_dir if cfg.work_dir is None
108         cfg.work_dir = osp.join('./work_dirs',
109                                 osp.splitext(osp.basename(args.config))[0])
110     if args.resume_from is not None:
111         cfg.resume_from = args.resume_from
112     if args.gpus is not None:
113         cfg.gpu_ids = range(1)
114         warnings.warn('`--gpus` is deprecated because we only support '
115                       'single GPU mode in non-distributed training. '
116                       'Use `gpus=1` now.')
117     if args.gpu_ids is not None:
118         cfg.gpu_ids = args.gpu_ids[0:1]
119         warnings.warn('`--gpu-ids` is deprecated, please use `--gpu-id`. '
120                       'Because we only support single GPU mode in '
121                       'non-distributed training. Use the first GPU '
122                       'in `gpu_ids` now.')
123     if args.gpus is None and args.gpu_ids is None:
124         cfg.gpu_ids = [args.gpu_id]
125 
126     if args.autoscale_lr:
127         # apply the linear scaling rule (https://arxiv.org/abs/1706.02677)
128         cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8
129 
130     # init distributed env first, since logger depends on the dist info.
131     if args.launcher == 'none':
132         distributed = False
133         if len(cfg.gpu_ids) > 1:
134             warnings.warn(
135                 f'We treat {cfg.gpu_ids} as gpu-ids, and reset to '
136                 f'{cfg.gpu_ids[0:1]} as gpu-ids to avoid potential error in '
137                 'non-distribute training time.')
138             cfg.gpu_ids = cfg.gpu_ids[0:1]
139     else:
140         distributed = True
141         init_dist(args.launcher, **cfg.dist_params)
142         # re-set gpu_ids with distributed training mode
143         _, world_size = get_dist_info()
144         cfg.gpu_ids = range(world_size)
145 
146     # create work_dir
147     mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))
148     # init the logger before other steps
149     timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())
150     log_file = osp.join(cfg.work_dir, f'{timestamp}.log')
151     logger = get_root_logger(log_file=log_file, log_level=cfg.log_level)
152 
153     # init the meta dict to record some important information such as
154     # environment info and seed, which will be logged
155     meta = dict()
156     # log env info
157     env_info_dict = collect_env()
158     env_info = '\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()])
159     dash_line = '-' * 60 + '\n'
160     logger.info('Environment info:\n' + dash_line + env_info + '\n' +
161                 dash_line)
162     meta['env_info'] = env_info
163 
164     # log some basic info
165     logger.info(f'Distributed training: {distributed}')
166     logger.info(f'Config:\n{cfg.pretty_text}')
167 
168     # set random seeds
169     seed = init_random_seed(args.seed)
170     seed = seed + dist.get_rank() if args.diff_seed else seed
171     logger.info(f'Set random seed to {seed}, '
172                 f'deterministic: {args.deterministic}')
173     set_random_seed(seed, deterministic=args.deterministic)
174     cfg.seed = seed
175     meta['seed'] = seed
176 
177     model = build_posenet(cfg.model)
178     datasets = [build_dataset(cfg.data.train)]
179 
180     if len(cfg.workflow) == 2:
181         val_dataset = copy.deepcopy(cfg.data.val)
182         val_dataset.pipeline = cfg.data.train.pipeline
183         datasets.append(build_dataset(val_dataset))
184 
185     if cfg.checkpoint_config is not None:
186         # save mmpose version, config file content
187         # checkpoints as meta data
188         cfg.checkpoint_config.meta = dict(
189             mmpose_version=__version__ + get_git_hash(digits=7),
190             config=cfg.pretty_text,
191         )
192     train_model(
193         model,
194         datasets,
195         cfg,
196         distributed=distributed,
197         validate=(not args.no_validate),
198         timestamp=timestamp,
199         meta=meta)
200 
201 
202 if __name__ == '__main__':
203     main()
204
```
--- 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/tools/train.py b/tools/train.py
--- a/tools/train.py
+++ b/tools/train.py
@@ -70,9 +70,7 @@
         choices=['none', 'pytorch', 'slurm', 'mpi'],
         default='none',
         help='job launcher')
-    parser.add_argument('--local-rank', type=int, default=0)
-    parser.add_argument(
-        '--local_rank', type=int, default=0, help='An alias to --local-rank')
+    parser.add_argument('--local_rank', type=int, default=0)
     parser.add_argument(
         '--autoscale-lr',
         action='store_true',

{"golden_diff": "diff --git a/tools/train.py b/tools/train.py\n--- a/tools/train.py\n+++ b/tools/train.py\n@@ -70,9 +70,7 @@\n         choices=['none', 'pytorch', 'slurm', 'mpi'],\n         default='none',\n         help='job launcher')\n-    parser.add_argument('--local-rank', type=int, default=0)\n-    parser.add_argument(\n-        '--local_rank', type=int, default=0, help='An alias to --local-rank')\n+    parser.add_argument('--local_rank', type=int, default=0)\n     parser.add_argument(\n         '--autoscale-lr',\n         action='store_true',\n", "issue": "\u6846\u67b6\u6709\u5f88\u591a\u6ca1\u6709\u901a\u8fc7\u6d4b\u8bd5\u7684Bug\n\u5728\u6211\u8fd0\u884cres50_freihand2d_224x224.py\u7684\u8fc7\u7a0b\u4e2d\u5c31\u78b0\u5230\u4e86\u4e24\u4e2a\u95ee\u9898\r\n\r\n1. tools/dist_train.sh\u91cc\u9762\u6ca1\u6709\u5b9a\u4e49$MASTER_ADDR\r\n\r\n2. res50_freihand2d_224x224.py \u6ca1\u6709\u5b9a\u4e49runner = dict(type='EpochBasedRunner', max_epochs=total_epochs)\r\n\r\n\u5176\u4ed6\u7684\u8fd8\u6ca1\u6709\u8dd1\uff0c\u4f46\u611f\u89c9\u4f1a\u6709\u5f88\u591a\u5c0f\u95ee\u9898\r\n\r\n\u53d1\u5e03\u7684\u7248\u672c\u6709\u70b9\u7c97\u7cd9\u5440\uff0c\u671f\u5f85\u628a\u8fd9\u4e9b\u5c0fBug\u5c3d\u5feb\u89e3\u51b3\uff0c\u540e\u7eed\u5f88\u671f\u5f85\u5728\u8fd9\u4e2a\u6846\u67b6\u4e0a\u505a\u66f4\u591a\u5b9e\u9a8c\r\n\n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport copy\nimport os\nimport os.path as osp\nimport time\nimport warnings\n\nimport mmcv\nimport torch\nimport torch.distributed as dist\nfrom mmcv import Config, DictAction\nfrom mmcv.runner import get_dist_info, init_dist, set_random_seed\nfrom mmcv.utils import get_git_hash\n\nfrom mmpose import __version__\nfrom mmpose.apis import init_random_seed, train_model\nfrom mmpose.datasets import build_dataset\nfrom mmpose.models import build_posenet\nfrom mmpose.utils import collect_env, get_root_logger, setup_multi_processes\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Train a pose model')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument('--work-dir', help='the dir to save logs and models')\n    parser.add_argument(\n        '--resume-from', help='the checkpoint file to resume from')\n    parser.add_argument(\n        '--no-validate',\n        action='store_true',\n        help='whether not to evaluate the checkpoint during training')\n    group_gpus = parser.add_mutually_exclusive_group()\n    group_gpus.add_argument(\n        '--gpus',\n        type=int,\n        help='(Deprecated, please use --gpu-id) number of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-ids',\n        type=int,\n        nargs='+',\n        help='(Deprecated, please use --gpu-id) ids of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-id',\n        type=int,\n        default=0,\n        help='id of gpu to use '\n        '(only applicable to non-distributed training)')\n    parser.add_argument('--seed', type=int, default=None, help='random seed')\n    parser.add_argument(\n        '--diff_seed',\n        action='store_true',\n        help='Whether or not set different seeds for different ranks')\n    parser.add_argument(\n        '--deterministic',\n        action='store_true',\n        help='whether to set deterministic options for CUDNN backend.')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        default={},\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. For example, '\n        \"'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'\")\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local-rank', type=int, default=0)\n    parser.add_argument(\n        '--local_rank', type=int, default=0, help='An alias to --local-rank')\n    parser.add_argument(\n        '--autoscale-lr',\n        action='store_true',\n        help='automatically scale lr with the number of gpus')\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    cfg = Config.fromfile(args.config)\n\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n\n    # set multi-process settings\n    setup_multi_processes(cfg)\n\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n    if args.resume_from is not None:\n        cfg.resume_from = args.resume_from\n    if args.gpus is not None:\n        cfg.gpu_ids = range(1)\n        warnings.warn('`--gpus` is deprecated because we only support '\n                      'single GPU mode in non-distributed training. '\n                      'Use `gpus=1` now.')\n    if args.gpu_ids is not None:\n        cfg.gpu_ids = args.gpu_ids[0:1]\n        warnings.warn('`--gpu-ids` is deprecated, please use `--gpu-id`. '\n                      'Because we only support single GPU mode in '\n                      'non-distributed training. Use the first GPU '\n                      'in `gpu_ids` now.')\n    if args.gpus is None and args.gpu_ids is None:\n        cfg.gpu_ids = [args.gpu_id]\n\n    if args.autoscale_lr:\n        # apply the linear scaling rule (https://arxiv.org/abs/1706.02677)\n        cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n        if len(cfg.gpu_ids) > 1:\n            warnings.warn(\n                f'We treat {cfg.gpu_ids} as gpu-ids, and reset to '\n                f'{cfg.gpu_ids[0:1]} as gpu-ids to avoid potential error in '\n                'non-distribute training time.')\n            cfg.gpu_ids = cfg.gpu_ids[0:1]\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n        # re-set gpu_ids with distributed training mode\n        _, world_size = get_dist_info()\n        cfg.gpu_ids = range(world_size)\n\n    # create work_dir\n    mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))\n    # init the logger before other steps\n    timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n    log_file = osp.join(cfg.work_dir, f'{timestamp}.log')\n    logger = get_root_logger(log_file=log_file, log_level=cfg.log_level)\n\n    # init the meta dict to record some important information such as\n    # environment info and seed, which will be logged\n    meta = dict()\n    # log env info\n    env_info_dict = collect_env()\n    env_info = '\\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()])\n    dash_line = '-' * 60 + '\\n'\n    logger.info('Environment info:\\n' + dash_line + env_info + '\\n' +\n                dash_line)\n    meta['env_info'] = env_info\n\n    # log some basic info\n    logger.info(f'Distributed training: {distributed}')\n    logger.info(f'Config:\\n{cfg.pretty_text}')\n\n    # set random seeds\n    seed = init_random_seed(args.seed)\n    seed = seed + dist.get_rank() if args.diff_seed else seed\n    logger.info(f'Set random seed to {seed}, '\n                f'deterministic: {args.deterministic}')\n    set_random_seed(seed, deterministic=args.deterministic)\n    cfg.seed = seed\n    meta['seed'] = seed\n\n    model = build_posenet(cfg.model)\n    datasets = [build_dataset(cfg.data.train)]\n\n    if len(cfg.workflow) == 2:\n        val_dataset = copy.deepcopy(cfg.data.val)\n        val_dataset.pipeline = cfg.data.train.pipeline\n        datasets.append(build_dataset(val_dataset))\n\n    if cfg.checkpoint_config is not None:\n        # save mmpose version, config file content\n        # checkpoints as meta data\n        cfg.checkpoint_config.meta = dict(\n            mmpose_version=__version__ + get_git_hash(digits=7),\n            config=cfg.pretty_text,\n        )\n    train_model(\n        model,\n        datasets,\n        cfg,\n        distributed=distributed,\n        validate=(not args.no_validate),\n        timestamp=timestamp,\n        meta=meta)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "tools/train.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport copy\nimport os\nimport os.path as osp\nimport time\nimport warnings\n\nimport mmcv\nimport torch\nimport torch.distributed as dist\nfrom mmcv import Config, DictAction\nfrom mmcv.runner import get_dist_info, init_dist, set_random_seed\nfrom mmcv.utils import get_git_hash\n\nfrom mmpose import __version__\nfrom mmpose.apis import init_random_seed, train_model\nfrom mmpose.datasets import build_dataset\nfrom mmpose.models import build_posenet\nfrom mmpose.utils import collect_env, get_root_logger, setup_multi_processes\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Train a pose model')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument('--work-dir', help='the dir to save logs and models')\n    parser.add_argument(\n        '--resume-from', help='the checkpoint file to resume from')\n    parser.add_argument(\n        '--no-validate',\n        action='store_true',\n        help='whether not to evaluate the checkpoint during training')\n    group_gpus = parser.add_mutually_exclusive_group()\n    group_gpus.add_argument(\n        '--gpus',\n        type=int,\n        help='(Deprecated, please use --gpu-id) number of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-ids',\n        type=int,\n        nargs='+',\n        help='(Deprecated, please use --gpu-id) ids of gpus to use '\n        '(only applicable to non-distributed training)')\n    group_gpus.add_argument(\n        '--gpu-id',\n        type=int,\n        default=0,\n        help='id of gpu to use '\n        '(only applicable to non-distributed training)')\n    parser.add_argument('--seed', type=int, default=None, help='random seed')\n    parser.add_argument(\n        '--diff_seed',\n        action='store_true',\n        help='Whether or not set different seeds for different ranks')\n    parser.add_argument(\n        '--deterministic',\n        action='store_true',\n        help='whether to set deterministic options for CUDNN backend.')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        default={},\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. For example, '\n        \"'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'\")\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    parser.add_argument('--local_rank', type=int, default=0)\n    parser.add_argument(\n        '--autoscale-lr',\n        action='store_true',\n        help='automatically scale lr with the number of gpus')\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    cfg = Config.fromfile(args.config)\n\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n\n    # set multi-process settings\n    setup_multi_processes(cfg)\n\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n    if args.resume_from is not None:\n        cfg.resume_from = args.resume_from\n    if args.gpus is not None:\n        cfg.gpu_ids = range(1)\n        warnings.warn('`--gpus` is deprecated because we only support '\n                      'single GPU mode in non-distributed training. '\n                      'Use `gpus=1` now.')\n    if args.gpu_ids is not None:\n        cfg.gpu_ids = args.gpu_ids[0:1]\n        warnings.warn('`--gpu-ids` is deprecated, please use `--gpu-id`. '\n                      'Because we only support single GPU mode in '\n                      'non-distributed training. Use the first GPU '\n                      'in `gpu_ids` now.')\n    if args.gpus is None and args.gpu_ids is None:\n        cfg.gpu_ids = [args.gpu_id]\n\n    if args.autoscale_lr:\n        # apply the linear scaling rule (https://arxiv.org/abs/1706.02677)\n        cfg.optimizer['lr'] = cfg.optimizer['lr'] * len(cfg.gpu_ids) / 8\n\n    # init distributed env first, since logger depends on the dist info.\n    if args.launcher == 'none':\n        distributed = False\n        if len(cfg.gpu_ids) > 1:\n            warnings.warn(\n                f'We treat {cfg.gpu_ids} as gpu-ids, and reset to '\n                f'{cfg.gpu_ids[0:1]} as gpu-ids to avoid potential error in '\n                'non-distribute training time.')\n            cfg.gpu_ids = cfg.gpu_ids[0:1]\n    else:\n        distributed = True\n        init_dist(args.launcher, **cfg.dist_params)\n        # re-set gpu_ids with distributed training mode\n        _, world_size = get_dist_info()\n        cfg.gpu_ids = range(world_size)\n\n    # create work_dir\n    mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))\n    # init the logger before other steps\n    timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n    log_file = osp.join(cfg.work_dir, f'{timestamp}.log')\n    logger = get_root_logger(log_file=log_file, log_level=cfg.log_level)\n\n    # init the meta dict to record some important information such as\n    # environment info and seed, which will be logged\n    meta = dict()\n    # log env info\n    env_info_dict = collect_env()\n    env_info = '\\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()])\n    dash_line = '-' * 60 + '\\n'\n    logger.info('Environment info:\\n' + dash_line + env_info + '\\n' +\n                dash_line)\n    meta['env_info'] = env_info\n\n    # log some basic info\n    logger.info(f'Distributed training: {distributed}')\n    logger.info(f'Config:\\n{cfg.pretty_text}')\n\n    # set random seeds\n    seed = init_random_seed(args.seed)\n    seed = seed + dist.get_rank() if args.diff_seed else seed\n    logger.info(f'Set random seed to {seed}, '\n                f'deterministic: {args.deterministic}')\n    set_random_seed(seed, deterministic=args.deterministic)\n    cfg.seed = seed\n    meta['seed'] = seed\n\n    model = build_posenet(cfg.model)\n    datasets = [build_dataset(cfg.data.train)]\n\n    if len(cfg.workflow) == 2:\n        val_dataset = copy.deepcopy(cfg.data.val)\n        val_dataset.pipeline = cfg.data.train.pipeline\n        datasets.append(build_dataset(val_dataset))\n\n    if cfg.checkpoint_config is not None:\n        # save mmpose version, config file content\n        # checkpoints as meta data\n        cfg.checkpoint_config.meta = dict(\n            mmpose_version=__version__ + get_git_hash(digits=7),\n            config=cfg.pretty_text,\n        )\n    train_model(\n        model,\n        datasets,\n        cfg,\n        distributed=distributed,\n        validate=(not args.no_validate),\n        timestamp=timestamp,\n        meta=meta)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "tools/train.py"}]}