We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug] Possible bug in `mmpose/apis/train.py`
https://github.com/open-mmlab/mmpose/blob/8d668a578f1580373d90a1eea88f23f6816df60e/mmpose/apis/train.py#L140

Here is the code that may have problem. And I think the default value for `workers_per_gpu` should be an integer but not a dict. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmpose/apis/train.py`
Content:
```
1 # Copyright (c) OpenMMLab. All rights reserved.
2 import warnings
3 
4 import torch
5 from mmcv.parallel import MMDataParallel, MMDistributedDataParallel
6 from mmcv.runner import DistSamplerSeedHook, EpochBasedRunner, OptimizerHook
7 
8 from mmpose.core import DistEvalHook, EvalHook, build_optimizers
9 from mmpose.core.distributed_wrapper import DistributedDataParallelWrapper
10 from mmpose.datasets import build_dataloader, build_dataset
11 from mmpose.utils import get_root_logger
12 
13 try:
14     from mmcv.runner import Fp16OptimizerHook
15 except ImportError:
16     warnings.warn(
17         'Fp16OptimizerHook from mmpose will be deprecated from '
18         'v0.15.0. Please install mmcv>=1.1.4', DeprecationWarning)
19     from mmpose.core import Fp16OptimizerHook
20 
21 
22 def train_model(model,
23                 dataset,
24                 cfg,
25                 distributed=False,
26                 validate=False,
27                 timestamp=None,
28                 meta=None):
29     """Train model entry function.
30 
31     Args:
32         model (nn.Module): The model to be trained.
33         dataset (Dataset): Train dataset.
34         cfg (dict): The config dict for training.
35         distributed (bool): Whether to use distributed training.
36             Default: False.
37         validate (bool): Whether to do evaluation. Default: False.
38         timestamp (str | None): Local time for runner. Default: None.
39         meta (dict | None): Meta dict to record some important information.
40             Default: None
41     """
42     logger = get_root_logger(cfg.log_level)
43 
44     # prepare data loaders
45     dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]
46     # step 1: give default values and override (if exist) from cfg.data
47     loader_cfg = {
48         **dict(
49             seed=cfg.get('seed'),
50             drop_last=False,
51             dist=distributed,
52             num_gpus=len(cfg.gpu_ids)),
53         **({} if torch.__version__ != 'parrots' else dict(
54                prefetch_num=2,
55                pin_memory=False,
56            )),
57         **dict((k, cfg.data[k]) for k in [
58                    'samples_per_gpu',
59                    'workers_per_gpu',
60                    'shuffle',
61                    'seed',
62                    'drop_last',
63                    'prefetch_num',
64                    'pin_memory',
65                    'persistent_workers',
66                ] if k in cfg.data)
67     }
68 
69     # step 2: cfg.data.train_dataloader has highest priority
70     train_loader_cfg = dict(loader_cfg, **cfg.data.get('train_dataloader', {}))
71 
72     data_loaders = [build_dataloader(ds, **train_loader_cfg) for ds in dataset]
73 
74     # determine wether use adversarial training precess or not
75     use_adverserial_train = cfg.get('use_adversarial_train', False)
76 
77     # put model on gpus
78     if distributed:
79         find_unused_parameters = cfg.get('find_unused_parameters', True)
80         # Sets the `find_unused_parameters` parameter in
81         # torch.nn.parallel.DistributedDataParallel
82 
83         if use_adverserial_train:
84             # Use DistributedDataParallelWrapper for adversarial training
85             model = DistributedDataParallelWrapper(
86                 model,
87                 device_ids=[torch.cuda.current_device()],
88                 broadcast_buffers=False,
89                 find_unused_parameters=find_unused_parameters)
90         else:
91             model = MMDistributedDataParallel(
92                 model.cuda(),
93                 device_ids=[torch.cuda.current_device()],
94                 broadcast_buffers=False,
95                 find_unused_parameters=find_unused_parameters)
96     else:
97         model = MMDataParallel(
98             model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)
99 
100     # build runner
101     optimizer = build_optimizers(model, cfg.optimizer)
102 
103     runner = EpochBasedRunner(
104         model,
105         optimizer=optimizer,
106         work_dir=cfg.work_dir,
107         logger=logger,
108         meta=meta)
109     # an ugly workaround to make .log and .log.json filenames the same
110     runner.timestamp = timestamp
111 
112     if use_adverserial_train:
113         # The optimizer step process is included in the train_step function
114         # of the model, so the runner should NOT include optimizer hook.
115         optimizer_config = None
116     else:
117         # fp16 setting
118         fp16_cfg = cfg.get('fp16', None)
119         if fp16_cfg is not None:
120             optimizer_config = Fp16OptimizerHook(
121                 **cfg.optimizer_config, **fp16_cfg, distributed=distributed)
122         elif distributed and 'type' not in cfg.optimizer_config:
123             optimizer_config = OptimizerHook(**cfg.optimizer_config)
124         else:
125             optimizer_config = cfg.optimizer_config
126 
127     # register hooks
128     runner.register_training_hooks(cfg.lr_config, optimizer_config,
129                                    cfg.checkpoint_config, cfg.log_config,
130                                    cfg.get('momentum_config', None))
131     if distributed:
132         runner.register_hook(DistSamplerSeedHook())
133 
134     # register eval hooks
135     if validate:
136         eval_cfg = cfg.get('evaluation', {})
137         val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))
138         dataloader_setting = dict(
139             samples_per_gpu=1,
140             workers_per_gpu=cfg.data.get('workers_per_gpu', {}),
141             # cfg.gpus will be ignored if distributed
142             num_gpus=len(cfg.gpu_ids),
143             dist=distributed,
144             drop_last=False,
145             shuffle=False)
146         dataloader_setting = dict(dataloader_setting,
147                                   **cfg.data.get('val_dataloader', {}))
148         val_dataloader = build_dataloader(val_dataset, **dataloader_setting)
149         eval_hook = DistEvalHook if distributed else EvalHook
150         runner.register_hook(eval_hook(val_dataloader, **eval_cfg))
151 
152     if cfg.resume_from:
153         runner.resume(cfg.resume_from)
154     elif cfg.load_from:
155         runner.load_checkpoint(cfg.load_from)
156     runner.run(data_loaders, cfg.workflow, cfg.total_epochs)
157
```
--- 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/mmpose/apis/train.py b/mmpose/apis/train.py
--- a/mmpose/apis/train.py
+++ b/mmpose/apis/train.py
@@ -137,7 +137,7 @@
         val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))
         dataloader_setting = dict(
             samples_per_gpu=1,
-            workers_per_gpu=cfg.data.get('workers_per_gpu', {}),
+            workers_per_gpu=cfg.data.get('workers_per_gpu', 1),
             # cfg.gpus will be ignored if distributed
             num_gpus=len(cfg.gpu_ids),
             dist=distributed,

{"golden_diff": "diff --git a/mmpose/apis/train.py b/mmpose/apis/train.py\n--- a/mmpose/apis/train.py\n+++ b/mmpose/apis/train.py\n@@ -137,7 +137,7 @@\n         val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))\n         dataloader_setting = dict(\n             samples_per_gpu=1,\n-            workers_per_gpu=cfg.data.get('workers_per_gpu', {}),\n+            workers_per_gpu=cfg.data.get('workers_per_gpu', 1),\n             # cfg.gpus will be ignored if distributed\n             num_gpus=len(cfg.gpu_ids),\n             dist=distributed,\n", "issue": "[Bug] Possible bug in `mmpose/apis/train.py`\nhttps://github.com/open-mmlab/mmpose/blob/8d668a578f1580373d90a1eea88f23f6816df60e/mmpose/apis/train.py#L140\r\n\r\nHere is the code that may have problem. And I think the default value for `workers_per_gpu` should be an integer but not a dict. \n", "before_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\n\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import DistSamplerSeedHook, EpochBasedRunner, OptimizerHook\n\nfrom mmpose.core import DistEvalHook, EvalHook, build_optimizers\nfrom mmpose.core.distributed_wrapper import DistributedDataParallelWrapper\nfrom mmpose.datasets import build_dataloader, build_dataset\nfrom mmpose.utils import get_root_logger\n\ntry:\n    from mmcv.runner import Fp16OptimizerHook\nexcept ImportError:\n    warnings.warn(\n        'Fp16OptimizerHook from mmpose will be deprecated from '\n        'v0.15.0. Please install mmcv>=1.1.4', DeprecationWarning)\n    from mmpose.core import Fp16OptimizerHook\n\n\ndef train_model(model,\n                dataset,\n                cfg,\n                distributed=False,\n                validate=False,\n                timestamp=None,\n                meta=None):\n    \"\"\"Train model entry function.\n\n    Args:\n        model (nn.Module): The model to be trained.\n        dataset (Dataset): Train dataset.\n        cfg (dict): The config dict for training.\n        distributed (bool): Whether to use distributed training.\n            Default: False.\n        validate (bool): Whether to do evaluation. Default: False.\n        timestamp (str | None): Local time for runner. Default: None.\n        meta (dict | None): Meta dict to record some important information.\n            Default: None\n    \"\"\"\n    logger = get_root_logger(cfg.log_level)\n\n    # prepare data loaders\n    dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]\n    # step 1: give default values and override (if exist) from cfg.data\n    loader_cfg = {\n        **dict(\n            seed=cfg.get('seed'),\n            drop_last=False,\n            dist=distributed,\n            num_gpus=len(cfg.gpu_ids)),\n        **({} if torch.__version__ != 'parrots' else dict(\n               prefetch_num=2,\n               pin_memory=False,\n           )),\n        **dict((k, cfg.data[k]) for k in [\n                   'samples_per_gpu',\n                   'workers_per_gpu',\n                   'shuffle',\n                   'seed',\n                   'drop_last',\n                   'prefetch_num',\n                   'pin_memory',\n                   'persistent_workers',\n               ] if k in cfg.data)\n    }\n\n    # step 2: cfg.data.train_dataloader has highest priority\n    train_loader_cfg = dict(loader_cfg, **cfg.data.get('train_dataloader', {}))\n\n    data_loaders = [build_dataloader(ds, **train_loader_cfg) for ds in dataset]\n\n    # determine wether use adversarial training precess or not\n    use_adverserial_train = cfg.get('use_adversarial_train', False)\n\n    # put model on gpus\n    if distributed:\n        find_unused_parameters = cfg.get('find_unused_parameters', True)\n        # Sets the `find_unused_parameters` parameter in\n        # torch.nn.parallel.DistributedDataParallel\n\n        if use_adverserial_train:\n            # Use DistributedDataParallelWrapper for adversarial training\n            model = DistributedDataParallelWrapper(\n                model,\n                device_ids=[torch.cuda.current_device()],\n                broadcast_buffers=False,\n                find_unused_parameters=find_unused_parameters)\n        else:\n            model = MMDistributedDataParallel(\n                model.cuda(),\n                device_ids=[torch.cuda.current_device()],\n                broadcast_buffers=False,\n                find_unused_parameters=find_unused_parameters)\n    else:\n        model = MMDataParallel(\n            model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)\n\n    # build runner\n    optimizer = build_optimizers(model, cfg.optimizer)\n\n    runner = EpochBasedRunner(\n        model,\n        optimizer=optimizer,\n        work_dir=cfg.work_dir,\n        logger=logger,\n        meta=meta)\n    # an ugly workaround to make .log and .log.json filenames the same\n    runner.timestamp = timestamp\n\n    if use_adverserial_train:\n        # The optimizer step process is included in the train_step function\n        # of the model, so the runner should NOT include optimizer hook.\n        optimizer_config = None\n    else:\n        # fp16 setting\n        fp16_cfg = cfg.get('fp16', None)\n        if fp16_cfg is not None:\n            optimizer_config = Fp16OptimizerHook(\n                **cfg.optimizer_config, **fp16_cfg, distributed=distributed)\n        elif distributed and 'type' not in cfg.optimizer_config:\n            optimizer_config = OptimizerHook(**cfg.optimizer_config)\n        else:\n            optimizer_config = cfg.optimizer_config\n\n    # register hooks\n    runner.register_training_hooks(cfg.lr_config, optimizer_config,\n                                   cfg.checkpoint_config, cfg.log_config,\n                                   cfg.get('momentum_config', None))\n    if distributed:\n        runner.register_hook(DistSamplerSeedHook())\n\n    # register eval hooks\n    if validate:\n        eval_cfg = cfg.get('evaluation', {})\n        val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))\n        dataloader_setting = dict(\n            samples_per_gpu=1,\n            workers_per_gpu=cfg.data.get('workers_per_gpu', {}),\n            # cfg.gpus will be ignored if distributed\n            num_gpus=len(cfg.gpu_ids),\n            dist=distributed,\n            drop_last=False,\n            shuffle=False)\n        dataloader_setting = dict(dataloader_setting,\n                                  **cfg.data.get('val_dataloader', {}))\n        val_dataloader = build_dataloader(val_dataset, **dataloader_setting)\n        eval_hook = DistEvalHook if distributed else EvalHook\n        runner.register_hook(eval_hook(val_dataloader, **eval_cfg))\n\n    if cfg.resume_from:\n        runner.resume(cfg.resume_from)\n    elif cfg.load_from:\n        runner.load_checkpoint(cfg.load_from)\n    runner.run(data_loaders, cfg.workflow, cfg.total_epochs)\n", "path": "mmpose/apis/train.py"}], "after_files": [{"content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\n\nimport torch\nfrom mmcv.parallel import MMDataParallel, MMDistributedDataParallel\nfrom mmcv.runner import DistSamplerSeedHook, EpochBasedRunner, OptimizerHook\n\nfrom mmpose.core import DistEvalHook, EvalHook, build_optimizers\nfrom mmpose.core.distributed_wrapper import DistributedDataParallelWrapper\nfrom mmpose.datasets import build_dataloader, build_dataset\nfrom mmpose.utils import get_root_logger\n\ntry:\n    from mmcv.runner import Fp16OptimizerHook\nexcept ImportError:\n    warnings.warn(\n        'Fp16OptimizerHook from mmpose will be deprecated from '\n        'v0.15.0. Please install mmcv>=1.1.4', DeprecationWarning)\n    from mmpose.core import Fp16OptimizerHook\n\n\ndef train_model(model,\n                dataset,\n                cfg,\n                distributed=False,\n                validate=False,\n                timestamp=None,\n                meta=None):\n    \"\"\"Train model entry function.\n\n    Args:\n        model (nn.Module): The model to be trained.\n        dataset (Dataset): Train dataset.\n        cfg (dict): The config dict for training.\n        distributed (bool): Whether to use distributed training.\n            Default: False.\n        validate (bool): Whether to do evaluation. Default: False.\n        timestamp (str | None): Local time for runner. Default: None.\n        meta (dict | None): Meta dict to record some important information.\n            Default: None\n    \"\"\"\n    logger = get_root_logger(cfg.log_level)\n\n    # prepare data loaders\n    dataset = dataset if isinstance(dataset, (list, tuple)) else [dataset]\n    # step 1: give default values and override (if exist) from cfg.data\n    loader_cfg = {\n        **dict(\n            seed=cfg.get('seed'),\n            drop_last=False,\n            dist=distributed,\n            num_gpus=len(cfg.gpu_ids)),\n        **({} if torch.__version__ != 'parrots' else dict(\n               prefetch_num=2,\n               pin_memory=False,\n           )),\n        **dict((k, cfg.data[k]) for k in [\n                   'samples_per_gpu',\n                   'workers_per_gpu',\n                   'shuffle',\n                   'seed',\n                   'drop_last',\n                   'prefetch_num',\n                   'pin_memory',\n                   'persistent_workers',\n               ] if k in cfg.data)\n    }\n\n    # step 2: cfg.data.train_dataloader has highest priority\n    train_loader_cfg = dict(loader_cfg, **cfg.data.get('train_dataloader', {}))\n\n    data_loaders = [build_dataloader(ds, **train_loader_cfg) for ds in dataset]\n\n    # determine wether use adversarial training precess or not\n    use_adverserial_train = cfg.get('use_adversarial_train', False)\n\n    # put model on gpus\n    if distributed:\n        find_unused_parameters = cfg.get('find_unused_parameters', True)\n        # Sets the `find_unused_parameters` parameter in\n        # torch.nn.parallel.DistributedDataParallel\n\n        if use_adverserial_train:\n            # Use DistributedDataParallelWrapper for adversarial training\n            model = DistributedDataParallelWrapper(\n                model,\n                device_ids=[torch.cuda.current_device()],\n                broadcast_buffers=False,\n                find_unused_parameters=find_unused_parameters)\n        else:\n            model = MMDistributedDataParallel(\n                model.cuda(),\n                device_ids=[torch.cuda.current_device()],\n                broadcast_buffers=False,\n                find_unused_parameters=find_unused_parameters)\n    else:\n        model = MMDataParallel(\n            model.cuda(cfg.gpu_ids[0]), device_ids=cfg.gpu_ids)\n\n    # build runner\n    optimizer = build_optimizers(model, cfg.optimizer)\n\n    runner = EpochBasedRunner(\n        model,\n        optimizer=optimizer,\n        work_dir=cfg.work_dir,\n        logger=logger,\n        meta=meta)\n    # an ugly workaround to make .log and .log.json filenames the same\n    runner.timestamp = timestamp\n\n    if use_adverserial_train:\n        # The optimizer step process is included in the train_step function\n        # of the model, so the runner should NOT include optimizer hook.\n        optimizer_config = None\n    else:\n        # fp16 setting\n        fp16_cfg = cfg.get('fp16', None)\n        if fp16_cfg is not None:\n            optimizer_config = Fp16OptimizerHook(\n                **cfg.optimizer_config, **fp16_cfg, distributed=distributed)\n        elif distributed and 'type' not in cfg.optimizer_config:\n            optimizer_config = OptimizerHook(**cfg.optimizer_config)\n        else:\n            optimizer_config = cfg.optimizer_config\n\n    # register hooks\n    runner.register_training_hooks(cfg.lr_config, optimizer_config,\n                                   cfg.checkpoint_config, cfg.log_config,\n                                   cfg.get('momentum_config', None))\n    if distributed:\n        runner.register_hook(DistSamplerSeedHook())\n\n    # register eval hooks\n    if validate:\n        eval_cfg = cfg.get('evaluation', {})\n        val_dataset = build_dataset(cfg.data.val, dict(test_mode=True))\n        dataloader_setting = dict(\n            samples_per_gpu=1,\n            workers_per_gpu=cfg.data.get('workers_per_gpu', 1),\n            # cfg.gpus will be ignored if distributed\n            num_gpus=len(cfg.gpu_ids),\n            dist=distributed,\n            drop_last=False,\n            shuffle=False)\n        dataloader_setting = dict(dataloader_setting,\n                                  **cfg.data.get('val_dataloader', {}))\n        val_dataloader = build_dataloader(val_dataset, **dataloader_setting)\n        eval_hook = DistEvalHook if distributed else EvalHook\n        runner.register_hook(eval_hook(val_dataloader, **eval_cfg))\n\n    if cfg.resume_from:\n        runner.resume(cfg.resume_from)\n    elif cfg.load_from:\n        runner.load_checkpoint(cfg.load_from)\n    runner.run(data_loaders, cfg.workflow, cfg.total_epochs)\n", "path": "mmpose/apis/train.py"}]}