【mmdeploy】【TODO】使用mmdeploy将mmdetection模型转tensorrt

mmdetection转换


先上结论:作者最后是转tensorrt的小图才成功的,大图一直不行。文章仅作者自我记录使用,请谨慎参考。
部分版本可参考作者的上篇文章《【mmdeploy】mmdeploy安装(linux + windows)》

  • mmdetection-2.22.0 自带转 onnx 无法测试(MMCVDeformConv2d ),issue中也说明要转mmdeploy
  • mmdeploy的onnx同样无法测试
  • mmdeploy整图转tensorRT结果有问题

mmdetection 自带转换ONNX——无法测试

一开始参考官方文档TUTORIAL 8: PYTORCH TO ONNX的教程来进行:

CUDA_VISIBLE_DEVICES=0 python -u tools/deployment/pytorch2onnx.py \
    work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/zjw_final_skin_config.py \
    work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/epoch_12.pth \
    --output-file work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/dcn_mask_rcnn_nwd.onnx \
    --input-img /home/wangjy/data/facedata_croped_1209/images/val_whole/CXM__何易霖_痤疮_20200904131918000_斑点.jpg \
    --test-img /home/wangjy/data/facedata_croped_1209/images/val_whole/CXM__何易霖_痤疮_20200904131918000_斑点.jpg \
    --shape 3448 4600 \
#     --show \
#     --verify \
    --dynamic-export \
#     --cfg-options \
#       model.test_cfg.deploy_nms_pre=-1 \
#     > work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/pytorch2onnx.log

原项目是版本是2.14.0,在转换添加了DCN的Mask R-CNN模型时出现问题:

RuntimeError: DeformConv is not implemented on CPU

到mmdetection的issus中搜索,mmdetection/issues/6047可知是mmcv的版本不够。刚好有个之前安装的2.22.0版本。但采用官方文档中的命令会在经过pytorch2onnx函数的torch.onnx.export(...)调用时直接被Kill,没有错误信息。

把以上的命令修改一下,精简为:

CUDA_VISIBLE_DEVICES=0 python -u tools/deployment/pytorch2onnx.py \
    work_dirs/train_skin_220416_maskrcnn/20220417_124418/skin_config_whole.py \
    work_dirs/train_skin_220416_maskrcnn/20220417_124418/epoch_14.pth \
    --output-file work_dirs/train_skin_220416_maskrcnn/20220417_124418/dcn_mask_rcnn.onnx \
    --shape 3448 4600 \

能够输出一个onnx文件,但是使用官方文档后续的onnx eval命令还是会报错:

Fatal error: MMCVDeformConv2d is not a registered function/op

这个时候搜到的一篇博客《Exporting MMDetection models to ONNX format》说可以用openvinotoolkit/mmdetection,但我简单看了一下,并没有用。而在mmdetection的issues中搜索该报错信息,都建议使用mmdeploy。

使用mmdeploy(0.6.0)

在安装mmdeploy的基础上,参考文档,还需要安装mmdet库(可能是商汤自己封装的,所以用不了自己定义的方法)。


# 克隆 mmdetection 仓库。转换时,需要使用 mmdetection 仓库中的模型配置文件,构建 PyTorch nn module
python -m pip install mmdet==2.24.0
# git clone https://github.com/open-mmlab/mmdetection.git
export MMDET_DIR=$(pwd)/mmdetection

# 下载 Faster R-CNN 模型权重
export CHECKPOINT_DIR=$(pwd)/checkpoints
wget -P ${CHECKPOINT_DIR} https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth

# 设置工作路径
export WORK_DIR=$(pwd)/mmdeploy_models/faster-rcnn

# 执行转换命令,实现端到端的转换
python ${MMDEPLOY_DIR}/tools/deploy.py \
    ${MMDEPLOY_DIR}/configs/mmdet/detection/detection_tensorrt_dynamic-320x320-1344x1344.py \
    ${MMDET_DIR}/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
    ${CHECKPOINT_DIR}/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
    ${MMDET_DIR}/demo/demo.jpg \
    --work-dir ${WORK_DIR} \
    --device cuda:0 \
    --dump-info

使用mmdeploy转onnx

其中要把配置文件的test处理流程中的Resize行注释掉(经过测试发现mmdetection中似乎把它注释了也没什么问题)(220723:不对,还是会出问题,有待考量),否则其会专门处理一下。实际最终命令:

python -u tools/deploy.py \
    configs/mmdet/detection/detection_onnxruntime_dynamic.py \
    work_dirs/deploy_220721_dcn_mask_rcnn_nwd/zjw_final_skin_config.py \
    ../mmdetection-2.22.0/work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/epoch_12.pth \
    /home/wangjy/data/facedata_croped_1209/images/val_whole/CXM__何易霖_痤疮_20200904131918000_斑点.jpg \
    --work-dir work_dirs/deploy_220721_dcn_mask_rcnn_nwd \
    --device cuda:0 \
    --dump-info

报错:

KeyError: "MaskRCNN: 'RPNHeadNwd is not in the models registry'"

又看了下文档,参考文档MMDetection-install,可以用pip install -v -e .从本地编译mmdetection:

cd ../mmdetection-2.22.0   # 我的mmdet2.22.0本地文件
pip install -r requirements/build.txt
pip install -v -e .  # or "python setup.py develop"

其中由于报错改了一些代码:

File "/home/wangjy/research/mmdeploy/mmdeploy/codebase/mmdet/models/detectors/two_stage.py", line 58, in two_stage_detector__simple_test
    proposals, _ = self.rpn_head.simple_test_rpn(x, img_metas)
ValueError: not enough values to unpack (expected 2, got 1)

改为:

proposals = self.rpn_head.simple_test_rpn(x, img_metas)
File "/home/wangjy/research/mmdeploy/mmdeploy/codebase/mmdet/models/roi_heads/test_mixins.py", line 44, in bbox_test_mixin__simple_test_bboxes
    rois.shape[0], device=rois.device).float().view(-1, 1, 1).expand(
AttributeError: 'list' object has no attribute 'shape'

将上一行的rois = proposals改为rois = torch.stack(proposals)

最后报错,它要51个G,这谁顶得住???!!!

RuntimeError: CUDA out of memory. Tried to allocate 51.02 GiB (GPU 0; 23.70 GiB total capacity; 2.24 GiB already allocated; 14.99 GiB free; 3.57 GiB reserved in total by PyTorch)

发现了一些问题,基于mask rcnn的模型应该算实例分割,因而把上面的configs/mmdet/detection/detection_onnxruntime_dynamic.py换成了configs/mmdet/instance-seg/instance-seg_onnxruntime_dynamic.py可以成功生成。但进行eval的时候还是会报错:

onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Load model from work_dirs/deploy_220721_dcn_mask_rcnn_nwd/onnx_dynamic/end2end.onnx failed:Fatal error: MMCVDeformConv2d is not a registered function/op

使用mmdeploy直接转tensorRT

由于mmdetection配置中的coco_instance.py还是不能去掉,而--dump-info参数所引发的逻辑要判断Resize中一定要有img_scale参数,只好注释掉mmdeploy/backend/sdk/export_info.py中的部分语句(该部分应该是仅用来配合--dump-info保存json文件),变为:

    if 'transforms' in pipeline[-1]:
        transforms = pipeline[-1]['transforms']
        transforms.insert(0, pipeline[0])
        # for transform in transforms:
        #    # 220723: tools/deploy.py 最终调用到这里,似乎只是为了保存一个pipline.json文件,那你费这个劲
        #    if transform['type'] == 'Resize':
        #        transform['size'] = pipeline[-1].img_scale[::-1]
        #        if 'img_scale' in transform:
        #           transform.pop('img_scale')

命令如下(可能需要注意tensorRT,或者说所有后端的静态static与动态dynamic的区别,这里先跑起来再说):

python -u tools/deploy.py \
    configs/mmdet/instance-seg/instance-seg_tensorrt_dynamic-320x320-1344x1344.py \
    work_dirs/deploy_220721_dcn_mask_rcnn_nwd/zjw_final_skin_config.py \
    ../mmdetection-2.22.0/work_dirs/train_skin_220401_maskrcnn/zjw_skin_config_cfnwd3/epoch_12.pth \
    /home/wangjy/data/facedata_croped_1209/images/val_whole/CXM__何易霖_痤疮_20200904131918000_斑点.jpg \
    --work-dir work_dirs/deploy_220721_dcn_mask_rcnn_nwd/tensorrt_dynamic \
    --device cuda:1 \
    --dump-info

并且instance-seg_tensorrt_dynamic-320x320-1344x1344.py配置文件似乎一定需要三个shape,不能注释掉,因而采用以下三个shape进行替代,并且整图生成需要修改max_workspace_size。

_base_ = [
    '../_base_/base_instance-seg_dynamic.py',
    '../../_base_/backends/tensorrt.py'
]

backend_config = dict(
    # common_config=dict(max_workspace_size=1 << 30),
    common_config=dict(max_workspace_size=1 << 31),
    model_inputs=[
        dict(
            input_shapes=dict(
                input=dict(
#                     min_shape=[1, 3, 320, 320],
#                     opt_shape=[1, 3, 800, 1344],
#                     max_shape=[1, 3, 1344, 1344]
                    min_shape=[1, 3, 4171, 3128],
                    opt_shape=[1, 3, 4600, 3448],
                    max_shape=[1, 3, 5184, 3456]
                )))
    ])

先别急,参考模型重载,需要重新复现RPNHeadNwd的get_boxes方法(这个其实仿照mmdeploy原有的rpn_head的get_boxes方法写即可),然后要注意上文onnx调试时修改的proposals, _ = self.rpn_head.simple_test_rpn(x, img_metas)rois = proposals的代码要改回来,似乎原来这个是适配的tensorRT流程。

注意tensorRT有topK的限制,topK操作不能超过3840(参考tensorrt-topKsetup),这个可能要想办法规避。并且deploy后的整图模型进行test的时候效果极差(几乎无了),而crop1024的数据就正常,不知道为啥。

在这里记录一下,对于dcn_mask_rcnn模型来说(mmdetection-2.22.0/work_dirs/train_skin_220416_maskrcnn/20220417_124418,val_crop1024的test AP50为0.496的最好模型),其在val_whole整图测试中的结果也记录在了issues/814中(有人问)。

调试记录

配置了pycharm远程连接进行调试,目前可知mmdeploy/tools/test.py的调用如下:

flowchart TD
    mmdeploy/tools/test.py --> mmdetection/mmdet/apis/test.py:single_gpu_test --> mmdeploy/mmdeploy/codebase/mmdet/deploy/object_detection_model.py:forward --> mmdeploy/mmdeploy/backend/tensorrt/wrapper.py:forward

outputs是在最后的wrapper.py:forward中得到的,但似乎无法查看模型的中间变量。

220801,看一下post_processing,结果要么就RuntimeError: CUDA error: an illegal memory access was encountered,要么就爆显存,以为是后处理参数改一点都不行?那改回来吧,还是爆,绝望。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值