基于MMdeploy实现HorNet(GF)模型到ONNX转化的流程记录


前言

本文主要分为两部分,分别为:
第一部分介绍了 HorNet gf \texttt{HorNet}_{\texttt{gf}} HorNetgf模型转化为 HorNet gf -ONNX \texttt{HorNet}_{\texttt{gf}}\texttt{-ONNX} HorNetgf-ONNX模型过程中遇到的问题以及解决办法。
第二部分介绍了通过OpenMMLab发布的MMdeploy工具,实现将 HorNet gf \texttt{HorNet}_{\texttt{gf}} HorNetgf模型转化为 HorNet gf -ONNX \texttt{HorNet}_{\texttt{gf}}\texttt{-ONNX} HorNetgf-ONNX模型的过程。

注意:
1.只是针对 HorNet gf \texttt{HorNet}_{\texttt{gf}} HorNetgf模型, HorNet 7 × 7 \texttt{HorNet}_{7\times7} HorNet7×7可以通过mmcv自带的torch2onnx.py文件直接进行转化。当然MMdeploy也是可以的。
2.MMdeploy只针对MMCV框架下训练的模型进行部署。

参考资料:
1.MMdeploy官方GitHub
2.我对于HorNet的总结博客:Segmentation:HorNet 学习总结

1. 转换过程中的问题

HorNet gf \texttt{HorNet}_{\texttt{gf}} HorNetgf转换的过程中主要是三个问题:

  1. HorNet gf \texttt{HorNet}_{\texttt{gf}} HorNetgf中Global Filter模块中 torch.fft.rfft2和 torch.fft.irfft2这两个函数在ONNX中没有支持的算子。
  2. MMCV函数包中无法有效支持,除GlobalAveragePool(1)以外,其他尺度的GlobalAveragePool(n) n=2,3,4…。
  3. ONNX不支持使用Python算子CheckpointFunction。

1.1 operator fft_rfft2 to ONNX opset version 15 is not supported

RuntimeError: Exporting the operator fft_rfft2 to ONNX opset version 15 is not supported. Please feel free to request support or submit a pull request on PyTorch GitHub.

原因分析:更新到ONNX最新版本都发现无法支持 fft_rfft2和fft_irfft2的算子。因此,采用numpy库来替换 fft_rfft2和fft_irfft2的算子。经过测试,输出结果和torch的fft_rfft2和fft_irfft2的算子基本相同(极小的小数位差异。),并且可以转化成功。

解决方法

        # x2 = torch.fft.rfft2(x2, dim=(2, 3), norm='ortho')
        x2 = x2.detach().cpu().numpy()
        x2 = np.fft.rfft2(x2, axes=(-2, -1),  norm='ortho')
        x2 = torch.tensor(x2).to(device).to(torch.complex64)
# =====================================================================
        # x2 = torch.fft.irfft2(x2, s=(a, b), dim=(2, 3), norm='ortho')
        x2 = x2.detach().cpu().numpy()
        x2 = np.fft.irfft2(x2, s=(a, b), axes=(-2, -1), norm='ortho')
        x2 = torch.tensor(x2).to(device).to(torch.float32)

1.2 NotImplementedError [Adaptive pool] input size not accessible

问题:NotImplementedError [Adaptive pool] input size not accessible

原因分析:在C:\Users\Lee\AppData\Local\JetBrains\PyCharm2020.1\remote_sources-1671096312-1331535106\mmcv\onnx\symbolic.py中:
在这里插入图片描述
只有尺度为1,即output_size=[1]的情况才能有效运行,当尺度为其他情况时,总是会卡在第二个条件语句(if not input.isCompleteTensor())。因为input.isCompleteTensor()总是显示为Fasle,使得无法向下运行,导致运算结果失败。

解决方法:我尝试直接注释该条件语句,但是在dim = input.type().sizes()[2:]中,dim的结果为None,导致运行错误。我个人对于代码中对象input所属的Value类不是很熟悉,导致无法继续进行了,因此放弃该方式。

经过网上查询后,发现用MMdeploy可以解决该问题。经过测试后,确实转化成功了。本文后续就是总结MMdeploy的实现流程。

1.3 RuntimeError: ONNX export failed: Couldn’t export Python operator CheckpointFunction

问题:RuntimeError: ONNX export failed: Couldn’t export Python operator CheckpointFunction

原因分析:ONNX不支持使用Python算子CheckpointFunction。

解决方法:将模型配置文件中的use_checkpoint参数从True修改为False。经过网上查询,有说法是改这个参数不会影响网络(未证实,仅供参考)。修改完就可以转化成功了。
在这里插入图片描述

2. MMdeploy的部署过程

2.1 MMdeploy的环境配置

MMdeploy的环境配置过程分为如下步骤:

1.从MMdeploy官方GitHub中下载MMdeploy的代码。
在这里插入图片描述
2. 下载MMdeploy包。
我是通过清华园镜像下载的,速度较快。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple mmdeploy==0.11.0

下载结果如下图所示:在这里插入图片描述
3. 运行setup.py

在下载好的MMdeploy代码中,分别运行python setup.py installpython setup.py build
在这里插入图片描述

python setup.py install

这个代码是可以修改环境中包的版本,以适配MMdeploy的运行环境。
在这里插入图片描述
运行结果:
在这里插入图片描述

python setup.py build

在这里插入图片描述
运行结果:
在这里插入图片描述
4. 值得注意的是,版本为0.11.0的MMdeploy只支持最高到mmcv==1.6.0。
我原本是1.7.0,所以,我还需要降下版本:
在这里插入图片描述
5.最后,我的整体环境如下:
在这里插入图片描述

2.2 模型的配置

从PyTorch转化为ONNX,我们需要配置三个脚本。分辨是ONNX的配置脚本,模型的配置脚本以及torch2onnx.py。

2.2.1 ONNX配置脚本

1.ONNX的配置脚本位于/configs/mmseg文件夹中。该文件夹中有很多转换脚本。如下图所示:
在这里插入图片描述在该文件夹中,只需要根据需求找到对应的脚本。
由于我的HorNet模型的输入是512x512,并且是转化为onnxruntime。因此我选用
“segmentation_onnxruntime_static-512x512.py”。内容如下图,可以修改图像输入尺寸:

在这里插入图片描述

在segmentation_onnxruntime_static-512x512.py中还也会涉及三个脚本,分别如下图:

  • config/mmseg/segmentation_static.py
    这个不用管。直接用。
    在这里插入图片描述
  • config/_base_/onnx_config.py
    可以修改opet_version和最终输出ONNX模型的名字。
    在这里插入图片描述
  • config/_base_/backends/onnxruntime.py
    这个不用管。直接用。
    在这里插入图片描述

2.2.2 模型配置脚本

该脚本其实就是MMCV框架下的模型脚本。
具体位置在模型训练后输出文件夹下,如下图所示。
在这里插入图片描述
脚本中内容如下图:
在这里插入图片描述

2.2.3 torch2onnx.py配置

终于到最后一步了,此处我们需要配置torch2onnx.py。torch2onnx.py位于tools/文件夹下:
在这里插入图片描述

需要配置的内容如下:
在这里插入图片描述
其中:

  • deploy_cfg指的是ONNX配置脚本的路径。
  • model_cfg指的是模型配置脚本的路径。
  • checkpoint指的是模型权重的路径
  • img指的是输入的图像。(和训练同尺度的图就行)
  • work-dir指的是输出文件的路径
  • device指的是转化时使用的显卡。【注意:转化所选的device不影响测试时的device】

3. 后续问题

最后重点说下,由于ONNX的具体转化过程我没有深入研究,但是经过转化后模型的大小明显变小,推测是对模型进行了量化。因此,精度明显降低。我转了两个模型,分别是建筑物和道路。建筑转化后,预测结果尚可接受。但是道路模型转化后,预测结果很差。因此,如果和我一样对于ONNX机制不是很了解的读者朋友,转化需慎重。

转化前大小:
在这里插入图片描述
转化后大小:
在这里插入图片描述

建筑物结果展示【红色为转化前,黄色为转化后】:
在这里插入图片描述
道路结果展示【红色为转化前,黄色为转化后】:
在这里插入图片描述

可以明显看到,道路的转化后的结果很差。所以,后续打算对ONNX进行进一步的学习。如果读者朋友可以解决该问题的也可以在评论区指导我。感谢!

猜你喜欢

转载自blog.csdn.net/weixin_43610114/article/details/128393889