train.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # Copyright (c) OpenMMLab. All rights reserved.
  2. import argparse
  3. import os
  4. import os.path as osp
  5. from mmengine.config import Config, DictAction
  6. from mmengine.registry import RUNNERS
  7. from mmengine.runner import Runner
  8. from mmdet.utils import setup_cache_size_limit_of_dynamo
  9. import model
  10. def parse_args():
  11. parser = argparse.ArgumentParser(description='Train a detector')
  12. parser.add_argument('config', help='train config file path')
  13. parser.add_argument('--work-dir', help='the dir to save logs and models')
  14. parser.add_argument(
  15. '--amp',
  16. action='store_true',
  17. default=False,
  18. help='enable automatic-mixed-precision training')
  19. parser.add_argument(
  20. '--auto-scale-lr',
  21. action='store_true',
  22. help='enable automatically scaling LR.')
  23. parser.add_argument(
  24. '--resume',
  25. nargs='?',
  26. type=str,
  27. const='auto',
  28. help='If specify checkpoint path, resume from it, while if not '
  29. 'specify, try to auto resume from the latest checkpoint '
  30. 'in the work directory.')
  31. parser.add_argument(
  32. '--cfg-options',
  33. nargs='+',
  34. action=DictAction,
  35. help='override some settings in the used config, the key-value pair '
  36. 'in xxx=yyy format will be merged into config file. If the value to '
  37. 'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
  38. 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
  39. 'Note that the quotation marks are necessary and that no white space '
  40. 'is allowed.')
  41. parser.add_argument(
  42. '--launcher',
  43. choices=['none', 'pytorch', 'slurm', 'mpi'],
  44. default='none',
  45. help='job launcher')
  46. # When using PyTorch version >= 2.0.0, the `torch.distributed.launch`
  47. # will pass the `--local-rank` parameter to `tools/train.py` instead
  48. # of `--local_rank`.
  49. parser.add_argument('--local_rank', '--local-rank', type=int, default=0)
  50. args = parser.parse_args()
  51. if 'LOCAL_RANK' not in os.environ:
  52. os.environ['LOCAL_RANK'] = str(args.local_rank)
  53. return args
  54. def main():
  55. args = parse_args()
  56. # Reduce the number of repeated compilations and improve
  57. # training speed.
  58. setup_cache_size_limit_of_dynamo()
  59. # load config
  60. cfg = Config.fromfile(args.config)
  61. cfg.launcher = args.launcher
  62. if args.cfg_options is not None:
  63. cfg.merge_from_dict(args.cfg_options)
  64. # work_dir is determined in this priority: CLI > segment in file > filename
  65. if args.work_dir is not None:
  66. # update configs according to CLI args if args.work_dir is not None
  67. cfg.work_dir = args.work_dir
  68. elif cfg.get('work_dir', None) is None:
  69. # use config filename as default work_dir if cfg.work_dir is None
  70. cfg.work_dir = osp.join('./work_dirs',
  71. osp.splitext(osp.basename(args.config))[0])
  72. # enable automatic-mixed-precision training
  73. if args.amp is True:
  74. cfg.optim_wrapper.type = 'AmpOptimWrapper'
  75. cfg.optim_wrapper.loss_scale = 'dynamic'
  76. # enable automatically scaling LR
  77. if args.auto_scale_lr:
  78. if 'auto_scale_lr' in cfg and \
  79. 'enable' in cfg.auto_scale_lr and \
  80. 'base_batch_size' in cfg.auto_scale_lr:
  81. cfg.auto_scale_lr.enable = True
  82. else:
  83. raise RuntimeError('Can not find "auto_scale_lr" or '
  84. '"auto_scale_lr.enable" or '
  85. '"auto_scale_lr.base_batch_size" in your'
  86. ' configuration file.')
  87. # resume is determined in this priority: resume from > auto_resume
  88. if args.resume == 'auto':
  89. cfg.resume = True
  90. cfg.load_from = None
  91. elif args.resume is not None:
  92. cfg.resume = True
  93. cfg.load_from = args.resume
  94. # build the runner from config
  95. if 'runner_type' not in cfg:
  96. # build the default runner
  97. runner = Runner.from_cfg(cfg)
  98. else:
  99. # build customized runner from the registry
  100. # if 'runner_type' is set in the cfg
  101. runner = RUNNERS.build(cfg)
  102. # start training
  103. runner.train()
  104. if __name__ == '__main__':
  105. main()