解决问题:将 MAN 模型在昇腾 310 设备上推理做准备

解决问题:将 MAN 模型在昇腾设备上推理做准备 - 202306


PyTorch 转 ONNX 动态输入、张量格式 - 将 MAN 超分辨率模型转换为 ONNX 模型 上文我们已经获得了 MAN 模型的 ONNX 格式,目标是迁移到昇腾平台上进行推理,最好是原生推理。

本次查找只要关注以下几点:

  1. 将 MAN 超分辨率模型的整个流程迁移到昇腾 CANN 架构所需步骤以及限制
    1. ATC 模型转换使用的参数及流程
    2. AscendCL 架构使能库的 Python 代码编写预处理、推理与后处理流程
    3. 整个流程可以使用的 CANN 原生组件

流程

ATC 模型转换

发现问题:动态输入仍然不够“动态”

设置输入图片的动态分辨率:适用于执行推理时,每次处理图片宽和高不固定的场景。
将解析的shape中的H和W设置为-1,会在shape下方出现Dynamic Image Size参数。在其中的编辑框中输入具体的动态分辨率参数,最少输入两组,每一组参数通过英文分号分隔,组内参数使用英文逗号分隔。最多支持100档配置,例如输入112,112;224,224。
来自 昇腾文档

昇腾 310 处理器不支持“完全的动态输入”,不能随意传入图片进行推理,只能对图片进行进一步预处理。
转换昇腾 OM 模型时发现所谓“动态分辨率”不是完全动态,而是可以设定多种输入尺寸,还特别说明而且如果设定尺寸种类过多可能会引起转换失败。所以我们需要对进行预处理,图片需要在边缘补充像素才能进入模型推理。
尝试过的解决方法:

  • 使用昇腾动态 AIPP 将图片补满像素,全黑或全白。

    • 动态分辨率下不能使用 AIPP 剪裁功能
  • 尝试使用 Python PIL / OpenCV 库将图片补全至合适分辨率(下策)

  • 使用 DVPP 缩放(下下策)

    • 基于深度学习的特点,缩放是次优解决方案,这会使特征变形。除非经过了拉伸图像训练(见“问题”部分)

最后打算使用 Python 的 Pillow / PIL 库来做这件事,生成一张纯色图片,然后将原先图片粘贴。所以这次推理为方便就不用 C++ 了。

发现问题:动态输入图片数量与动态图片输入分辨率只能择一

如果模型转换时设置了动态分辨率,并且要使用“Data Pre-Processing”中的数据预处理功能,该场景下不能设置数据预处理的CropPadding功能。
设置动态batch和动态分辨率不能同时使用,一次只能设置其中一个参数。
来自 昇腾文档

可尝试的解决:

  • 舍弃动态输入数量
  • 换 ONNX 运行时推理

最后只能舍弃动态输入数量,使用 ONNX 推理就没有 NPU 加速计算优势了
ONNXRuntime 是有昇腾 NPU 加速的,但仍在测试阶段,且性能是与原生 OM 有差异的。

AscendCL

探寻:预处理的图片需要处理成什么格式?

访问 CANN 社区版的文档,找不到图片应该预处理成什么样。所以大胆猜想:和之前训练的格式相等就行了。
最后发现 ACL 可以将 NumPy 对象转换为字节并传输到昇腾设备进行推理,情况就明了了:我们将图像转换为 NumPy 数组进行推理,内部的结构排列按照模型设定的方式即可。

调用acl.util.ptr_to_numpy接口将指针转换numpy对象:
来自 昇腾文档

探寻:MAN 超分辨率模型对训练图像的预处理方式

MAN 模型是用 BasicSR 库进行训练的,这是一个通用的超分辨率训练库,图片的预处理会定义在 util 文件夹内,可以从数据的加载方法中看到数据处理方法。

# From paired_image_dataset.py

# Load gt and lq images. Dimension order: HWC; channel order: BGR;
# image range: [0, 1], float32.
# BGR to RGB, HWC to CHW, numpy to tensor

看到了颜色通道排列方法是 R, G, B,而最终的张量排布是 NCHW,颜色需要均一化,精度为32位浮点。以上就是预处理方式,但是查看 MAN 代码后发现内部已经使用了均一化,所以均一化部分省去
但是调试代码过后发现均一化仍然是必须的,因为在 MAN 模型训练的过程中使用了多次均一化(一次是训练中的代码处理,一次是神经网络内 的处理)

# MAN_arch.py
self.sub_mean = MeanShift(1.0)
……
self.add_mean = MeanShift(1.0, sign=1)

探寻:现有示例代码可复用的地方

昇腾 CANN 推理拥有示例代码仓库,里面绝对有一些流程可以复用,至少的模型加载,推理,销毁这些流程肯定共用。
查看了“03-resnet50”的示例,这个示例拥有完整的 ACL 库使用流程,还有使用 PIL 库的部分,非常适合拿来替换。
Ascend/samples - (gitee.com)

还发现了一个动态分辨率示例,后期会用上,现在先专注于固定分辨率。
Ascend/samples - (gitee.com)

看了一下可以复用的部分:

  • 推理网络定义类,其中:
    • 修改初始化函数
    • 重写打印推理结果
    • 获取模型输出结果可能要改

以及必须重写的部分:

  • 图片预处理函数
  • 显示 / 保存图片函数
  • 主函数

对于昇腾设备来说它们要做的流程并没有变,只是我们需要使用 PIL 进行 CPU 方式的图片补边,推理后再裁边。

总结

  • 需要为昇腾 310 设备声明多个分辨率
  • 大小不一的图片需要补全成输入分辨率才可推理 (PIL)
  • 复用 AscendCL 示例加快推理代码编写时间
  • 实现 MAN 模型在原代码的预处理方法(颜色归一化)

问题

为什么超分辨率模型预处理图片时不应该使用缩放拉伸?

如果模型在训练的过程中使用了“图像拉伸”图片,那么确实可以使用拉伸图片进行推理。反之,模型没有学习这种特征,不能达到很好的效果。
更因为超分辨率是“像素敏感”推理,放大以及拉伸会引入其他算法生成的像素点(如 DVPP V1 的华为滤波算法),缩小则失去了超分辨率的初衷。
不是硬性的要求不能使用拉伸,若你的模型经过拉伸图片的训练则大可尽情使用。

接下来可以…

  • 开始转换为昇腾 OM 模型
  • 根据示例代码开发一个 MAN 模型推理应用
  • 进一步学习 AscendCL 开发

外部链接

samples: CANN Samples (gitee.com)
AscendCL Python 语言推理快速入门-昇腾社区 (hiascend.com)
ATC模型转换-昇腾社区 (hiascend.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值