当前位置: 首页 > news >正文

模型转换案例学习:等效替换不支持算子

文章介绍

       Qualcomm Neural Processing SDK (以下简称SNPE)支持Caffe、ONNX、PyTorch和TensorFlow等不同ML框架的算子。对于某些特定的不支持的算子,我们介绍一种算子等效替换的方法来完成模型转换。本案例来源于https://github.com/quic/qidk/tree/master/Model-Enablement/Model-Conversion-Layer-Replacement

以PyTorch  MobilenetV3模型转换SNPE DLC的过程为例子,介绍如何使用等效算子替换的方法达成不支持算子的转换

前置条件

  • SNPE-2.7.x-PC上下载并设置好SNPE

相关步骤参考Snapdragon Neural Processing Engine SDK: SNPE Setup

  • python version 3.6.x and 3.8.x
  • Torch version 1.10
  • 安装pip install jupyter
  • 一台Linux机器
  • 高通Snapdragon 安卓手机,推荐Snapdragon® 8 Gen 2系列手机

特别注意:Qualcomm Neural Processing SDK需要python 3.6版本,型号repo需要python 3.8版本。因此,建议使用两个不同的虚拟环境。

操作步骤:

一、获取模型

1. 运行以下命令获取模型:

cd generatedModels

 wget https://download.pytorch.org/models/mobilenet_v3_large-8738ca79.pth

2. 现在,我们将使用MobileNetV3的Pytorch模型来获得ONNX模型。我们通常建议使用这种方法从pytorch模型生成dlc,方法是先转换为onnx,然后再转换为dlc。

运行getModel.py生成ONNX文件:
python getModel.py

cd ..

3. 这将生成ONNX模型可以在generatedModels/ONNX/文件夹中找到。

4. 现在,我们可以将ONNX模型转换为DLC

 

二、模型转换错误信息

1. 注意:在继续操作之前,请确保generatedModels/ONNX/mobilenet_v3.ONNX文件存在。

2. 使用Qualcomm Neural Processing SDK检查模型到dlc的转换

snpe-onnx-to-dlc -i generatedModels/ONNX/mobilenet_v3.onnx -o generatedModels/ONNX/mobilenet_v3.dlc

3. 以上,我们可以看到“onnx_hardsigmoid”转换没有注册,这里将用我们自己的自定义harsigmoid实现来更改。

三、替换架构-Harsigmoid

1. 找到模型源文件。

<python3.8-packages>/torchvision/models/mobilenetv3.py。

2. 搜索Hardsigmoid的调用/实现。

3. 对该行进行注释,并使用新的CustomHardsigmoid调用添加新的代码行。

4. 正如我们所看到的,Hardsigmoid是从nn模块调用为nn.Hardsigmoid。因此,我们找到<python3.8_path>/site packages/torch/nn/dir来编写我们自己的CustomHardsigmoid实现。

5. Hardsigmoid是一个激活函数。因此,它位于nn/modules/activation.py文件中。

6. 在__all__变量中添加``CustomHardsigmoid```,即要定义的自定义函数的名称。

7. 在nn/modules/activation.py中实现您自己的CustomHardsigmoid。注意:SDK没有nn.Hardsigmoid的转换。因此,我们将以与SDK兼容的方式定义Hardsigmoid。

Hardsigmoid可以表示为- torch.clamp((input*0.167+0.5),0,1)

8. 参考如下CustomHardsigmoid的实现代码

https://github.com/quic/qidk/blob/master/Model-Enablement/Model-Conversion-Layer-Replacement/class/CustomHardsigmoid.py

class CustomHardsigmoid(Module):

    __constants__ = ['inplace']

    inplace: bool

    def __init__(self, inplace : bool = False)->None:   

        super().__init__()

        self.inplace = inplace

    def forward(self, input: Tensor, inplace: bool = False) -> Tensor:

        return torch.clamp((input*0.167+0.5), 0, 1)

9. 我们已经定义了自己的实现,现在我们将查找nn.Hardsigmoid的所有依赖项

10. 在同一torc/nn/modules/目录中,在__init__.py文件中添加CustomHarsigmoid调用。然后保存后继续操作

11. 到MobileNetV3目录,并使用新实现的Customhardsigmoid层转储模型。

python generatedModels/getModel.py

 

四、再次转换,分析错误

1. 将具有新实现的CustomHardsigmoid层的ONNX模型转换为dlc

  snpe-onnx-to-dlc -i generatedModels/ONNX/mobilenet_v3.onnx -o generatedModels/ONNX/mobilenet_v3.dlc

Error :

2. 我们得到了一个新的框架错误,说“onnx_hadswish”转换没有注册,我们现在将来更改hardswish的实现。

五、替换架构-Hardswish

1. 找到模型源文件。

<python3.8-packages>/torchvision/models/mobilenetv3.py

2. 搜索Hardswish的调用/实现

Occurrence-1

Occurrence-2

Occurrence-3

Occurrence-4

3. 注释所有这些行,并使用新的CustomHardswish调用添加新的代码行。

4. 正如我们所看到的,Hardswish是从nn模块调用为nn.Hardswish的,因此,我们将到<python3.8_path>/site packages/torch/nn/目录来编写我们自己的CustomHardswish实现。

5. Hardswish是一个激活函数。因此,它位于nn/modules/activation.py文件中。

6. 在__all__变量中添加``CustomHardswish```,即要定义的自定义函数的名称。

7. 在nn/modules/activation.py中实现您自己的CustomHardswish。注意:SDK没有nn.Hardswish的转换。因此,我们将以与SDK兼容的方式定义Hardsigmoid。

Hardswish可以定义为一个简化的表达式- input*torch.clamp(input+3, min=0, max=6)/6

8. 参考CustomHardswish的实现代码

https://github.com/quic/qidk/blob/master/Model-Enablement/Model-Conversion-Layer-Replacement/class/CustomHardswish.py

class CustomHardswish(Module):

    __constants__ = ['inplace']

    inplace: bool

    def __init__(self, inplace : bool = False) -> None:

        super().__init__()

        self.inplace = inplace

    def forward(self, input: Tensor) -> Tensor:

        return input*torch.clamp(input+3, min=0,max=6)/6

9. 我们已经定义了自己的实现,现在我们将查找nn.Hardswish的所有依赖项。

10. 在同一torch/nn/modules/目录中,在__init.py文件中添加CustomHarswish调用,保存修改,继续下一步操作

11. 到MobileNetV3目录,并使用新实现的Customhardswish层转储模型。

   python generatedModels/getModel.py

 六、再次转换DLC

1. 将具有新实现的CustomHardswish以及CustomHardsigmoid层的ONNX模型转换为dlc

snpe-onnx-to-dlc -i generatedModels/ONNX/mobilenet_v3.onnx -o generatedModels/ONNX/mobilenet_v3.dlc

2. 现在,我们可以使用snpe-onx-to-dlc将ONNX模型转换为dlc。

最后我们完成了DLC模型的转换

作者:高通工程师,戴忠忠(Zhongzhong Dai)

相关文章:

  • 代码随想录算法训练营|二叉树总结
  • Sora 文生视频提示词实例集 2
  • 几个常见的C/C++语言冷知识
  • AIGC 实战:如何使用 Docker 在 Ollama 上离线运行大模型(LLM)
  • 深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
  • python子域名收集工具
  • 三防平板丨平板终端丨加固平板丨仓库管理应用
  • 软考-中级-系统集成2023年综合知识(一)
  • OpenWRT部署web站点并结合内网穿透实现无公网ip远程访问
  • Git合并固定分支的某一部分至当前分支
  • 如何使用useMemo来优化性能
  • 基于 Amazon EC2 和 Amazon Systems Manager Session Manager 的堡垒机的设计和自动化实现
  • jsx语言和js语言的区别
  • Cartographer框架简述
  • 【踩坑专栏】主机ping虚拟机失败
  • Cookie 在前端中的实践
  • Cumulo 的 ClojureScript 模块已经成型
  • Docker容器管理
  • Hibernate最全面试题
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • k8s如何管理Pod
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • ng6--错误信息小结(持续更新)
  • overflow: hidden IE7无效
  • python3 使用 asyncio 代替线程
  • SQLServer之创建显式事务
  • Vue 动态创建 component
  • vue中实现单选
  • windows下使用nginx调试简介
  • 从零搭建Koa2 Server
  • 观察者模式实现非直接耦合
  • 盘点那些不知名却常用的 Git 操作
  • 如何解决微信端直接跳WAP端
  • 如何利用MongoDB打造TOP榜小程序
  • 设计模式(12)迭代器模式(讲解+应用)
  • 什么是Javascript函数节流?
  • 学习JavaScript数据结构与算法 — 树
  • 怎么把视频里的音乐提取出来
  • Python 之网络式编程
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • # include “ “ 和 # include < >两者的区别
  • (04)odoo视图操作
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (论文阅读30/100)Convolutional Pose Machines
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET Core 实现 Redis 批量查询指定格式的Key