Mask_RCNN的TensorRT加速

         现有的网络上,主流的Mask RCNN主要有两个,一个是matterport的Keras版本https://github.com/matterport/Mask_RCNN,有13.5K的star,一个是facebookresearch的PyTorch版本6.2K的star,链接如下https://github.com/facebookresearch/maskrcnn-benchmark

        现有条件下,Keras版本转onnx各种不太支持,optset现在支持的版本也不太新,而新版本的PyTorch自带的onnx功能比较好用,本身的PyTorch版本可以支持最新的optset_vision9,全部的网络直接用来onnx-->TensorRT太复杂,所以可以先单独的加速Backbone来进行整体的加速。       

        在进行的过程中,出现了一些问题,在这记录以下,防止后人踩坑,也好为之后出现问题好做。

        在trace其Backbone的时候,有一个算子不受支持,需要修改下即可。

        RuntimeError: ONNX export failed: Couldn't export operator aten::rsqrt

        不支持的算子为rsqrt,这个算子是对Tensor进行sqrt然后取倒数,修改为 torch.reciprocal(self.running_var.sqrt()),修改完成之后其效果是不发生改变的。

        在转换的过程中,就是torch.jit.trace的问题,在过程中,需要新建tensor,在新建的tensor的时候,注意是新建的cpu变量还是cuda变量,两个类型不同的话,就报错,注意在新建的变量后面加上.cuda()就可以。

        trace的时候,如果单单是trace没有FPN的ResNet50-C4网络,在输出的时候,是一个dict,无法实现追踪,需要在ResNet中进行output类型的修改,添加一句话output=tuple(output)来将dict修改为tuple就可以进行trace了。

       有FPN的部分,在trace的时候会出现"Assertion failed: axis >= 0 && axis < nbDims" in convert_axis()这个Error,从Github上看到的都是关于x=x.view(x.size(),-1) 平铺的时候出现的问题,现在的是FPN在处理的过程中没事append进去的,所以还不太清楚改怎么解决,这个问题是应该可以解决的,目前就暂时先trace没有fpn的部分。

       将 x=x.view(x.size(),-1) 修改为 x=x.flatten(1)

       经过好久的研究发觉,包括从Netron观察模型结构,按照分析,应该是第1041个算子的问题,这个算子是Gather算子,当indices=2的时候,TensorRT无法进行解析,导致出现的现在的问题,所以索性就直接修改PyTorch中的源码,这一个算子存在于F.interpolate中,是其中的源码程序,function.py中的程序,修改如下:

源码:
if torch._C._get_tracing_state():
            return [(torch.floor(input.size(i + 2) * torch.tensor(float(scale_factors[i])))) for i in range(dim)]
        else:
            return [int(math.floor(int(input.size(i + 2)) * scale_factors[i])) for i in range(dim)]

修改为:
return [int(math.floor(input.size(i + 2) * scale_factors[i])) for i in range(dim)]

    

      修改完成之后, 可以成功解析。

      自从上次成功解析之后,就对视频进行了尝试,发现了在进行视频检测的时候,显存会一直增加,后来就一直在分析问题,直到昨天才分析出来可能的原因。可能的原因有很多,曾经怀疑是不是onnx导出的时候我修改的function导致的onnx有问题,但是用了OnnxRuntime进行onnx模型的驱动,发现可以出现正常的结果不会出现错误。

      通过对源码的分析和注释的Debug测试,定位增加显存的那句话,发现这句话就在do_inference中,是这一句话导致的。

context.execute_async(batch_size=batch_size, bindings=bindings, stream_handle=stream.handle)

# 主要是context 导致显存一直增加,所以现在出现的问题就是 每一次的循环中一直在新建context导致显存增加
# 重复执行下一句话
with engine.create_execution_context() as context:

    将其顺序调整一下就可以实现显存保持基本恒定。

    分享一下测试速度:目前是GTX1060 显卡平台下的速度是 12FPS,欢迎其他朋友来进行分享呀~   

   过一段时间可能会把完善之后的程序放在Github上,敬请期待~ (点赞多的话,就放,哈哈哈哈哈~)

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值