This page provides basic tutorials about the usage of MMPose. For installation instructions, please see install.md.
MMPose supports multiple tasks. Please follow the corresponding guidelines for data preparation.
- 2D Body Keypoint Detection
- 3D Body Keypoint Detection
- 3D Body Mesh Recovery
- 2D Hand Keypoint Detection
- 3D Hand Keypoint Detection
- 2D Face Keypoint Detection
- 2D WholeBody Keypoint Detection
- 2D Fashion Landmark Detection
- 2D Animal Keypoint Detection
We provide testing scripts to evaluate a whole dataset (COCO, MPII etc.), and provide some high-level apis for easier integration to other OpenMMLab projects.
- single GPU
- CPU
- single node multiple GPUs
- multiple node
You can use the following commands to test a dataset.
# single-gpu testing
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--fuse-conv-bn] \
[--eval ${EVAL_METRICS}] [--gpu_collect] [--tmpdir ${TMPDIR}] [--cfg-options ${CFG_OPTIONS}] \
[--launcher ${JOB_LAUNCHER}] [--local_rank ${LOCAL_RANK}]
# CPU: disable GPUs and run single-gpu testing script
export CUDA_VISIBLE_DEVICES=-1
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] \
[--eval ${EVAL_METRICS}]
# multi-gpu testing
./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [--out ${RESULT_FILE}] [--fuse-conv-bn] \
[--eval ${EVAL_METRIC}] [--gpu_collect] [--tmpdir ${TMPDIR}] [--cfg-options ${CFG_OPTIONS}] \
[--launcher ${JOB_LAUNCHER}] [--local_rank ${LOCAL_RANK}]
Note that the provided CHECKPOINT_FILE
is either the path to the model checkpoint file downloaded in advance, or the url link to the model checkpoint.
Optional arguments:
RESULT_FILE
: Filename of the output results. If not specified, the results will not be saved to a file.--fuse-conv-bn
: Whether to fuse conv and bn, this will slightly increase the inference speed.EVAL_METRICS
: Items to be evaluated on the results. Allowed values depend on the dataset.--gpu_collect
: If specified, recognition results will be collected using gpu communication. Otherwise, it will save the results on different gpus toTMPDIR
and collect them by the rank 0 worker.TMPDIR
: Temporary directory used for collecting results from multiple workers, available when--gpu_collect
is not specified.CFG_OPTIONS
: Override some settings in the used config, the key-value pair in xxx=yyy format will be merged into config file. For example, '--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'.JOB_LAUNCHER
: Items for distributed job initialization launcher. Allowed choices arenone
,pytorch
,slurm
,mpi
. Especially, if set to none, it will test in a non-distributed mode.LOCAL_RANK
: ID for local rank. If not specified, it will be set to 0.
Examples:
Assume that you have already downloaded the checkpoints to the directory checkpoints/
.
-
Test ResNet50 on COCO (without saving the test results) and evaluate the mAP.
./tools/dist_test.sh configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py \ checkpoints/SOME_CHECKPOINT.pth 1 \ --eval mAP
-
Test ResNet50 on COCO with 8 GPUS. Download the checkpoint via url, and evaluate the mAP.
./tools/dist_test.sh configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py \ https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth 8 \ --eval mAP
-
Test ResNet50 on COCO in slurm environment and evaluate the mAP.
./tools/slurm_test.sh slurm_partition test_job \ configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py \ checkpoints/SOME_CHECKPOINT.pth \ --eval mAP
We also provide scripts to run demos. Here is an example of running top-down human pose demos using ground-truth bounding boxes.
python demo/top_down_img_demo.py \
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
--out-img-root ${OUTPUT_DIR} \
[--show --device ${GPU_ID}] \
[--kpt-thr ${KPT_SCORE_THR}]
Examples:
python demo/top_down_img_demo.py \
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
--img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
--out-img-root vis_results
More examples and details can be found in the demo folder and the demo docs.
MMPose implements distributed training and non-distributed training,
which uses MMDistributedDataParallel
and MMDataParallel
respectively.
We adopt distributed training for both single machine and multiple machines. Supposing that the server has 8 GPUs, 8 processes will be started and each process runs on a single GPU.
Each process keeps an isolated model, data loader, and optimizer. Model parameters are only synchronized once at the beginning. After a forward and backward pass, gradients will be allreduced among all GPUs, and the optimizer will update model parameters. Since the gradients are allreduced, the model parameter stays the same for all processes after the iteration.
All outputs (log files and checkpoints) will be saved to the working directory,
which is specified by work_dir
in the config file.
By default we evaluate the model on the validation set after each epoch, you can change the evaluation interval by modifying the interval argument in the training config
evaluation = dict(interval=5) # This evaluate the model per 5 epoch.
According to the Linear Scaling Rule, you need to set the learning rate proportional to the batch size if you use different GPUs or videos per GPU, e.g., lr=0.01 for 4 GPUs x 2 video/gpu and lr=0.08 for 16 GPUs x 4 video/gpu.
python tools/train.py ${CONFIG_FILE} [optional arguments]
If you want to specify the working directory in the command, you can add an argument --work-dir ${YOUR_WORK_DIR}
.
The process of training on the CPU is consistent with single GPU training. We just need to disable GPUs before the training process.
export CUDA_VISIBLE_DEVICES=-1
And then run the script above.
Note:
We do not recommend users to use CPU for training because it is too slow. We support this feature to allow users to debug on machines without GPU for convenience.
./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [optional arguments]
Optional arguments are:
--work-dir ${WORK_DIR}
: Override the working directory specified in the config file.--resume-from ${CHECKPOINT_FILE}
: Resume from a previous checkpoint file.--no-validate
: Whether not to evaluate the checkpoint during training.--gpus ${GPU_NUM}
: Number of gpus to use, which is only applicable to non-distributed training.--gpu-ids ${GPU_IDS}
: IDs of gpus to use, which is only applicable to non-distributed training.--seed ${SEED}
: Seed id for random state in python, numpy and pytorch to generate random numbers.--deterministic
: If specified, it will set deterministic options for CUDNN backend.--cfg-options CFG_OPTIONS
: Override some settings in the used config, the key-value pair in xxx=yyy format will be merged into config file. For example, '--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'.--launcher ${JOB_LAUNCHER}
: Items for distributed job initialization launcher. Allowed choices arenone
,pytorch
,slurm
,mpi
. Especially, if set to none, it will test in a non-distributed mode.--autoscale-lr
: If specified, it will automatically scale lr with the number of gpus by Linear Scaling Rule.LOCAL_RANK
: ID for local rank. If not specified, it will be set to 0.
Difference between resume-from
and load-from
:
resume-from
loads both the model weights and optimizer status, and the epoch is also inherited from the specified checkpoint. It is usually used for resuming the training process that is interrupted accidentally.
load-from
only loads the model weights and the training epoch starts from 0. It is usually used for finetuning.
Here is an example of using 8 GPUs to load ResNet50 checkpoint.
./tools/dist_train.sh configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py 8 --resume_from work_dirs/res50_coco_256x192/latest.pth
If you can run MMPose on a cluster managed with slurm, you can use the script slurm_train.sh
. (This script also supports single machine training.)
./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR}
Here is an example of using 16 GPUs to train ResNet50 on the dev partition in a slurm cluster.
(Use GPUS_PER_NODE=8
to specify a single slurm cluster node with 8 GPUs, CPUS_PER_TASK=2
to use 2 cpus per task.
Assume that Test
is a valid ${PARTITION} name.)
GPUS=16 GPUS_PER_NODE=8 CPUS_PER_TASK=2 ./tools/slurm_train.sh Test res50 configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py work_dirs/res50_coco_256x192
You can check slurm_train.sh for full arguments and environment variables.
If you launch with multiple machines simply connected with ethernet, you can simply run following commands:
# On the first machine:
NNODES=2 NODE_RANK=0 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR ./tools/dist_train.sh $CONFIG $GPUS
# On the second machine:
NNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR ./tools/dist_train.sh $CONFIG $GPUS
Usually it is slow if you do not have high speed networking like InfiniBand.
If you launch multiple jobs on a single machine, e.g., 2 jobs of 4-GPU training on a machine with 8 GPUs, you need to specify different ports (29500 by default) for each job to avoid communication conflict.
If you use dist_train.sh
to launch training jobs, you can set the port in commands.
CUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 ./tools/dist_train.sh ${CONFIG_FILE} 4
CUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 ./tools/dist_train.sh ${CONFIG_FILE} 4
If you use launch training jobs with slurm, you need to modify the config files (usually the 4th line in config files) to set different communication ports.
In config1.py
,
dist_params = dict(backend='nccl', port=29500)
In config2.py
,
dist_params = dict(backend='nccl', port=29501)
Then you can launch two jobs with config1.py
ang config2.py
.
CUDA_VISIBLE_DEVICES=0,1,2,3 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config1.py ${WORK_DIR} 4
CUDA_VISIBLE_DEVICES=4,5,6,7 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config2.py ${WORK_DIR} 4
You can get average inference speed using the following script. Note that it does not include the IO time and the pre-processing time.
python tools/analysis/benchmark_inference.py ${MMPOSE_CONFIG_FILE}
We provide some tutorials for users: