PaddlePaddle / Paddle

PArallel Distributed Deep LEarning: Machine Learning Framework from Industrial Practice (『飞桨』核心框架,深度学习&机器学习高性能单机、分布式训练和跨平台部署)
http://www.paddlepaddle.org/
Apache License 2.0
22.16k stars 5.56k forks source link

Optimizing Mask R-CNN Training Performance #55907

Closed AndSonder closed 10 months ago

AndSonder commented 1 year ago

赛题进展

1. 背景

飞桨深度学习框架已经发布了很多涵盖多个领域的开源模型,本赛题旨在通过对飞桨深度学习框架支持的开源模型进行优化,提高模型的训练性能,探索飞桨在模型上的性能优化最佳实践。欢迎对深度学习框架和模型优化感兴趣的开发者,展示在模型优化领域的经验和创新性。

本赛题详细介绍见中国软件开源创新大赛:飞桨框架任务挑战赛-赛题9,主要需求为:

  1. 对经典的Mask R-CNN模型进行FP32和AMP训练性能的极致优化,完成性能分析、挖掘模型的性能优化点,制定优化计划并完成开发
  2. 测试3种Batch Size(2/4/8)在单机单卡下的优化效果(可能受限于V100显存,根据自己申请的AI Studio资源测试出能运行的最大Batch Size)
  3. 模型配置限定:https://github.com/PaddlePaddle/PaddleDetection/blob/develop/configs/mask_rcnn/mask_rcnn_r50_1x_coco.yml

2. 参考资料

这里我们将任务相关的参考资料列出,也会持续补充......

2.1 官方参考资料

2.2 模型分析报告

征集详细的模型分析报告,供大家交流学习

2.2.1 MaskRCNN 各部分性能

下表为使用 Profier 记录的 MaskRCNN 三大部分(bbox head, rpn head, mask head)CPU与GPU的使用情况

image-20230802234346002

根据表格可得出如下可能的优化点:

  1. BBoxHeadself.bbox_assigner CPU 操作占用时间较多,且该操作中GPU利用率不高;

image-20230802235329645

  1. RPNHeadself.gen_proposal CPU 和 GPU 操作均占用较多时间,且根据Timeline可得该操作中有较多的GPU空闲时间;

image-20230803000110879

结合 Profier 进一步定位可得,self.gen_proposalrpn_target_assign 有着较多的CPU耗时。相关代码如下:

score_tgt, bbox_tgt, loc_tgt, norm = self.rpn_target_assign(inputs, anchors)

通过优化 RPNTargetAssign 的代码,使得更多的操作在GPU上进行,可优化模型的推理速度,预计优化幅度 10ms+。

  1. MaskHeadself.mask_assigner 中 CPU 操作占据了大部分时间;

经过进一步的分析,在 self.mask_assigner 中使用了 cocoapi 中的 polygons_to_mask。该操作只能在 CPU 上进行计算。 现在有两种优化方案:第一种是将 PolygonToMask 部分的计算放在dataloader里面并行计算加速。第二种是参考 OneFlow 的写法,自定义一个 PolygonToMask Kernel 对该部分运算进行加速。 预估优化时间 15ms +。

名称 Calls CPU Total / Avg / Max / Min / Ratio(%) [ms] GPU Total / Avg / Max / Min / Ratio(%) [ms]
MaskHead::assign_mask 1 36.89 / 36.89 / 36.89 / 36.89 / 7.66 0.24 / 0.24 / 0.24 / 0.24 / 0.06
MaskHead::assign_mask::rasterize_polygons_within_box 1 34.78 / 17.39 / 19.08 / 15.70 / 7.22 0.13 / 0.07 / 0.11 / 0.02 / 0.03

参考资料:

  1. OneFlow 中的 PolygonToMask
  2. MMDetection 中的 LoadAnnotations

2.2.2 耗时较长的Op

根据 Profier 分析可得,下列 Operator 耗时较多,可考虑进行优化

Op名称 Calls CPU Total / Avg / Max / Min / Ratio(%) [ms] GPU Total / Avg / Max / Min / Ratio(%) [ms]
RoiAlignGradNode(phi::GPURoiAlignBackward) 1 224.41 / 224.41 / 224.41 / 224.41 / 54.61 15.93 / 15.93 / 15.93 / 15.93 / 3.94
Pool2dGradNode(phi::funcs::KernelPool2DGrad) 1 0.07 / 0.07 / 0.07 / 0.07 / 0.02 7.79 / 7.79 / 7.79 / 7.79 / 1.93
generate_proposals dygraph 2 18.14 / 9.07 / 12.42 / 5.72 / 4.41 6.87 / 3.44 / 3.51 / 3.36 / 1.70
roi_align dygraph(phi::GPURoiAlignForward) 1 0.11 / 0.11 / 0.11 / 0.11 / 0.03 6.73 / 6.73 / 6.73 / 6.73 / 1.67

3. 运行说明

给出基本的运行方式

3.1 使用飞桨profier进行性能分析

首先按照环境配置文档配置环境,接着将赛题群中的 trainer.py 替换本地的 trainer.py

python tools/train.py -c configs/mask_rcnn/mask_rcnn_r50_1x_coco.yml -o LearningRate.base_lr=0.0001 log_iter=1 use_gpu=True save_dir=./test_tipc/output/mask_rcnn_r50_1x_coco/benchmark_train/norm_train_gpus_0_autocast_fp32 epoch=1 pretrain_weights=https://paddledet.bj.bcebos.com/models/mask_rcnn_r50_1x_coco.pdparams TrainReader.batch_size=2 filename=mask_rcnn_r50_1x_coco TrainReader.shuffle=False   --enable_ce=True > profier.txt

Profiler 生成的 log 会保存在 profier.txt 当中。也可以直接下载赛题群中的 profier3.txt 查看

3.2 使用nsight进行性能分析

使用 nsys 生成 nsys-rep 文件导入到 nsight 中进行分析:

nsys profile --stats=true -t cuda,nvtx  -o train_report -f true bash test_tipc/benchmark_train.sh test_tipc/configs/mask_rcnn/mask_rcnn_r50_1x_coco_train_infer_python.txt benchmark_train dynamic_bs2_fp32_DP_N1C1

4. 优化进展

优化方向 任务内容 BS=2,提升幅度 BS=4,提升幅度 附件 PR链接 任务负责人
Baseline 初始性能 1.26, 0% - baseline log - @AndSonder
AMP优化 开启AMP优化 3.35, 165.87% - amp log - @AndSonder
autotune优化 使用 autotune 优化卷积 1.39, 10% - autotune log - @AndSonder
为MaskRCNN支持nhwc数据输入 优化AMP开启后nchw->nhwc转换的时间 4.10, 225.40% - nhwc+amp log https://github.com/PaddlePaddle/PaddleDetection/pull/8640 @AndSonder
加速 polygons_to_mask 自定义Kernel 优化运算速度 @zeroRains
为 RoIAlign 添加 nhwc 支持 优化 RoIAlign 在 nhwc 数据格式下的速度 https://github.com/PaddlePaddle/Paddle/pull/57576 @AndSonder
为 GenerateProposal 添加 nhwc 支持 优化 GenerateProposal 在 nhwc 数据格式下的速度 @WintersMontagne10335
加速 RPNTargetAssign 优化 RPNTargetAssign 运算速度 @WintersMontagne10335
AndSonder commented 1 year ago

环境配置:

PaddleDetection 环境安装

# export LD_LIBRARY_PATH=/usr/lib64/
git clone -b develop https://github.com/PaddlePaddle/PaddleDetection --depth=1
python -m pip install paddlepaddle-gpu==2.5.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
cd PaddleDetection
pip install -r requirements.txt --user -i https://pypi.tuna.tsinghua.edu.cn/simple
python setup.py install --user
python ppdet/modeling/tests/test_architectures.py

测试环境准备

# 提前下载一个小型的coco数据集用于测试
wget -nc -P ./dataset/coco/ https://bj.bcebos.com/v1/paddledet/data/cocomini.zip --no-check-certificate
cd ./dataset/coco/ && unzip cocomini.zip
mv -u cocomini/* ./

# 回到PaddleDetection目录
cd ../../
wget https://paddle-qa.bj.bcebos.com/benchmark/tools.tar.gz && tar xvf tools.tar.gz && export BENCHMARK_ROOT=$PWD/tools/

# test_tipc 在 PaddleDetection目录下
bash test_tipc/prepare.sh test_tipc/configs/mask_rcnn/mask_rcnn_r50_1x_coco_train_infer_python.txt benchmark_train;
bash test_tipc/benchmark_train.sh test_tipc/configs/mask_rcnn/mask_rcnn_r50_1x_coco_train_infer_python.txt benchmark_train dynamic_bs2_fp32_DP_N1C1;

dynamic_bs2_fp32_DP_N1C1,表示的是bs=2,fp32训练,N1C1单机单卡。如果要换bs,就相应改为dynamic_bs4_fp32_DP_N1C1;换amp训练就改为dynamic_bs2_fp16_DP_N1C1

AndSonder commented 1 year ago

如何使用 Profiler 生成 log:

首先按照环境配置文档配置环境,接着将赛题群中的 trainer.py 替换本地的 trainer.py

python tools/train.py -c configs/mask_rcnn/mask_rcnn_r50_1x_coco.yml -o LearningRate.base_lr=0.0001 log_iter=1 use_gpu=True save_dir=./test_tipc/output/mask_rcnn_r50_1x_coco/benchmark_train/norm_train_gpus_0_autocast_fp32 epoch=1 pretrain_weights=https://paddledet.bj.bcebos.com/models/mask_rcnn_r50_1x_coco.pdparams TrainReader.batch_size=2 filename=mask_rcnn_r50_1x_coco TrainReader.shuffle=False   --enable_ce=True > profier.txt

Profiler 生成的 log 会保存在 profier.txt 当中。也可以直接下载赛题群中的 profier3.txt 查看

[1] profiler使用文档.

luotao1 commented 1 year ago

@AndSonder 环境配置文档的链接打不开

AndSonder commented 1 year ago

@AndSonder 环境配置文档的链接打不开

可以打开,但是需要搭配梯子,我直接给写在Issue里面吧

flytocc commented 1 year ago

@AndSonder 能提供一下赛题群中的 trainer.py

AndSonder commented 1 year ago

flytocc

加你v了,麻烦同意下~

zeroRains commented 1 year ago

@zeroRains 领取加速 polygons_to_mask 任务

zeroRains commented 1 year ago

方案1小节:将 PolygonToMask 迁移到 Dataloader

方案调研: 参考MMDetection的Mask RCNN 设计,其内部在处理PolygonToMask的部分主要是在mask headROI Align操作中。其提了两个方案,方案一是利用Polygon类型的标签(coco数据集实例部分的segmentation部分)进行一个缩放,然后利用pycocotools.mask工具进行转化,转化成指定宽高的BitmapMask,方案二是利用pycocotools.mask工具先将Polygon标签转化成和原图一样大小的BitmapMask,然后利用mmcv里的roi_align API进行对齐。

优化方案: 在Paddle中,按照组长的指令运行baseline时,MMDetection的方案一与其执行顺序比较相似,这导致了在mask_headmask_assigner的每个batch计算中,会调用pycocotools.mask的API将polygon标签成Bitmap的Mask,这个函数是在CPU中执行的,会产生比较久的CPU执行时间。 这个方案的目的是将polygon转化成Bitmap的操作向前移动到DataLoader中(和MMDetection的方案二比较相似),然后利用paddle的paddle.vision.ops.roi_align进行对齐。

参数和环境: 执行指令:python tools/train.py -c configs/mask_rcnn/mask_rcnn_r50_1x_coco.yml -o LearningRate.base_lr=0.0001 log_iter=1 use_gpu=True save_dir=./test_tipc/output/mask_rcnn_r50_1x_coco/benchmark_train/norm_train_gpus_0_autocast_fp32 epoch=1 pretrain_weights=https://paddledet.bj.bcebos.com/models/mask_rcnn_r50_1x_coco.pdparams TrainReader.batch_size=2 filename=mask_rcnn_r50_1x_coco TrainReader.shuffle=False --enable_ce=True > profier.txt 配置:Tesla V100 (32GB) profier分析方式:在执行到第50个iter后启动profier分析第50~第60个iter的性能

方案执行结果: Profiler中设置timer_only=Truebaseline
Reader Ratio: 0.087% Time Unit: s, IPS Unit: steps/s
avg max min
reader_cost 0.00072 0.00111 0.00030
batch_cost 0.83135 0.76716 0.74502
ips 1.20287 1.34225 1.30351
前移 polygons_to_maskdataloader中 Reader Ratio: 0.107% Time Unit: s, IPS Unit: steps/s avg max min
reader_cost 0.00088 0.00178 0.00033
batch_cost 0.82278 0.75882 0.73806
ips 1.21540 1.35491 1.31783

baseline的mask_assigner执行情况: image

前移 polygons_to_maskdataloader中的mask_assigner执行情况: image

方案总结和其他问题描述: 该方案在模型整体训练速度上有微弱提升(ips: 1.20287 ->1.21540 ),在mask_headmask_assigner中执行时间缩短得比较明显。 其他问题:修改方案与原本的执行方案,在mask_assigner的输出tgt_masks的数值尚存在较大差异。

AndSonder commented 1 year ago

更新任务:优化 RPNTargetAssign

WintersMontagne10335 commented 1 year ago

@AndSonder 领取加速 RPNTargetAssign 任务

AndSonder commented 1 year ago

@luotao1 麻烦问下 PaddleDetection 的 PR 应该找谁 review 呢