onnx进阶算子优化

一、定义

  1. 如何保证pytorch 模型顺利转为onnx. 前言
  2. pytorch 算子是如何与onnx 算子对齐的?
  3. Asinh 算子出现于第 9 个 ONNX 算子集。PyTorch 在 9 号版本的符号表文件中是怎样支持这个算子的?
  4. BitShift 算子出现于第11个 ONNX 算子集。PyTorch 在 11 号版本的符号表文件中是怎样支持这个算子的?
  5. 算子在pytorch 中已经实现,onnx 算子也实现,缺少映射方法,自己注册,实现转换。
  6. 自定义onnx 算子。
  7. 构造onnx 模型,并测试。
  8. onnx提取子模型

二、实现

  1. 如何保证pytorch 模型顺利转为onnx. 前言, 参考:https://zhuanlan.zhihu.com/p/513387413
    要使 PyTorch 算子顺利转换到 ONNX ,我们需要保证以下三个环节都不出错:
    算子在 PyTorch 中有实现
    有把该 PyTorch 算子映射成一个或多个 ONNX 算子的方法
    ONNX 有相应的算子
    可在实际部署中,这三部分的内容都可能有所缺失。其中最坏的情况是:我们定义了一个全新的算子,它不仅缺少 PyTorch 实现,还缺少 PyTorch 到 ONNX 的映射关系。但所谓车到山前必有路,对于这三个环节,我们也分别都有以下的添加支持的方法:
    PyTorch 算子
    组合现有算子
    添加 TorchScript 算子
    添加普通 C++ 拓展算子
    映射方法
    为 ATen 算子添加符号函数
    为 TorchScript 算子添加符号函数
    封装成 torch.autograd.Function 并添加符号函数
    ONNX 算子
    使用现有 ONNX 算子
    定义新 ONNX 算子

  2. pytorch 算子是如何与onnx 算子对齐的?
    onnx 算子文档:https://github.com/onnx/onnx/blob/main/docs/Operators.md
    torch 对onnx算子映射:https://github.com/pytorch/pytorch/tree/main/torch/onnx
    在这里插入图片描述
    表格的第一列是算子名,第二列是该算子发生变动的算子集版本号,也就是我们之前在torch.onnx.export中提到的opset_version表示的算子集版本号。在这里插入图片描述
    symbolic_opset{n}.py(符号表文件)即表示 PyTorch 在支持第 n 版 ONNX 算子集时新加入的内容。判定是否存在映射方法。

  3. Asinh 算子出现于第 9 个 ONNX 算子集。PyTorch 在 9 号版本的符号表文件中是怎样支持这个算子的?
    Asinh 在第9版本onnx 中实现,检查symbolic_opset9.py 发现,但pytorch 中已经实现torch.asinh(), 即缺少映射方法。

  4. BitShift 算子出现于第11个 ONNX 算子集。PyTorch 在 11 号版本的符号表文件中是怎样支持这个算子的?
    通过在 torch.onnx.symbolic_opset11.py 搜索 BitShift,我们可以发现 PyTorch 在 _lshift 和 _rshift 里用到了ONNX的 BitShift 算子。当输入类型为 Byte 时,PyTorch会把算子直接翻译翻译
    BitShift,以代替乘除 2 的次幂的操作。

  5. 算子在pytorch 中已经实现,onnx 算子也实现,缺少映射方法,自己注册,实现转换。
    1. 获取 ATen 中算子接口定义
    2. 添加符号函数

  6. 整合模型,导出onnx文件

  7. 测试算子
    ================================================================

import torchclass Model(torch.nn.Module):def __init__(self):super().__init__()def forward(self, x):return torch.asinh(x)from torch.onnx.symbolic_registry import register_opdef asinh_symbolic(g, input, *, out=None):return g.op("Asinh", input)register_op('asinh', asinh_symbolic, '', 9)model = Model()
input = torch.rand(1, 3, 10, 10)
torch.onnx.export(model, input, 'asinh.onnx')

测试

import onnxruntime 
import torch 
import numpy as np class Model(torch.nn.Module): def __init__(self): super().__init__() def forward(self, x): return torch.asinh(x) model = Model() 
input = torch.rand(1, 3, 10, 10) 
torch_output = model(input).detach().numpy() sess = onnxruntime.InferenceSession('asinh.onnx') 
ort_output = sess.run(None, {'0': input.numpy()})[0] assert np.allclose(torch_output, ort_output) 
  1. 自定义onnx 算子。
    https://zhuanlan.zhihu.com/p/513387413
  2. 构造onnx 模型,并测试。
import onnx
from onnx import helper
from onnx import TensorProto# input and output
a = helper.make_tensor_value_info('a', TensorProto.FLOAT, [10, 10])
x = helper.make_tensor_value_info('x', TensorProto.FLOAT, [10, 10])
b = helper.make_tensor_value_info('b', TensorProto.FLOAT, [10, 10])
output = helper.make_tensor_value_info('output', TensorProto.FLOAT, [10, 10])# Mul
mul = helper.make_node('Mul', ['a', 'x'], ['c'])# Add
add = helper.make_node('Add', ['c', 'b'], ['output'])# graph and model
graph = helper.make_graph([mul, add], 'linear_func', [a, x, b], [output])
model = helper.make_model(graph)# save model
onnx.checker.check_model(model)
print(model)
onnx.save(model, 'linear_func.onnx') 
import onnxruntime 
import numpy as np sess = onnxruntime.InferenceSession('linear_func.onnx') 
a = np.random.rand(10, 10).astype(np.float32) 
b = np.random.rand(10, 10).astype(np.float32) 
x = np.random.rand(10, 10).astype(np.float32) output = sess.run(['output'], {'a': a, 'b': b, 'x': x})[0] assert np.allclose(output, a * x + b)
  1. onnx提取子模型
    https://zhuanlan.zhihu.com/p/516920606

https://zhuanlan.zhihu.com/p/543973749
https://zhuanlan.zhihu.com/p/516920606

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/29641.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

事务AOP

事物管理 事务管理是指对一系列数据库操作进行管理,确保这些操作要么全部成功执行,要么在遇到错误时全部回滚,以维护数据的一致性和完整性。在多用户并发操作和大数据处理的现代软件开发领域中,事务管理已成为确保数据一致性和完…

链表相对于数组的优势,以及栈和队列的基本操作

链表(Linked List)和数组(Array)是两种常见的数据结构,它们各自在不同的场景下有其优势和劣势。链表相对于数组的优势主要体现在以下几个方面: 动态大小: 链表在插入和删除元素时,不…

4M-21:霸气侧漏高效的20+多模态AI模型

大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技(Mamba,xLSTM,KAN)则…

软件设计不是CRUD(22):在流式数据处理系统中进行业务抽象落地——设计思考

(接上文《软件设计不是CRUD(21):在流式数据处理系统中进行业务抽象落地——需求分析》) 那么思考到这里我们就能做一些关于设计思路的总结: 每一个独立的数据处理流,就是数据采集系统中的一个功能。这个功能具备一个静态的控制逻辑(当然控制逻辑也可以是动态的,本文不…

嵌入式技术学习——c51单片机——蜂鸣器

一、蜂鸣器介绍 蜂鸣器时一种将电信号转化成声音信号的器件,常用来产生设备的按键音,报警音等提示信号。 蜂鸣器分为有源蜂鸣器,无源蜂鸣器 。 有源蜂鸣器:内部自带震荡源,将正负极街上直流电压即可持续发声&#x…

通过摄像头检测步频

通过摄像头识别运动频率,比如步频。 打开摄像头 循环读取视频帧 灰度转换 统计中间一行数值和 人在摄像头前运动,该数值会呈现周期变化 通过快速傅里叶转换,将和步频相似频率显示出来。 (尝试人脸检测,跟着人脸位置变…

深度学习(十)——神经网络:非线性激活

一、Padding Layers简介 nn.ZeroPad2d:在输入的tensor数据类型周围用0进行填充 nn.ConstantPad2d:在输入的tensor数据类型周围用常数进行填充 这个函数的主要作用是对输入的图像进行填充,但里面所有功能都能用nn.Conv2d实现。 二、Non-li…

一文读懂OpenGVLab带来的最新视觉预训练框架

大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技(Mamba,xLSTM,KAN)则…

为什么直接用 cv2.imwrite 保存 PIL 的图片会导致奇怪的颜色?

在处理图像保存时,使用不同的库可能会导致颜色显示上的差异。特别是 Image.fromarray(synthesis).save 和 cv2.imwrite(save_dir, image) 两种方法之间的区别,会导致保存的图像颜色不同。这篇博客将解释这些方法的区别,以及具体导致颜色差异的…

.NET周刊【6月第3期 2024-06-18】

国内文章 记一次 .NET某游戏币自助机后端 内存暴涨分析 https://www.cnblogs.com/huangxincheng/p/18243233 文章讨论了程序中非托管内存暴涨的问题。作者描述了友人发现内存问题并请他帮助分析的背景,利用WinDbg工具分析Linux平台上的内存泄漏情况。文章介绍了如…

Maven POM:掌握项目对象模型的艺术

Maven POM:掌握项目对象模型的艺术 1. 引言 Maven,作为一个强大的项目管理和构建自动化工具,已经成为了Java社区中不可或缺的一部分。在Maven的世界里,POM(Project Object Model,项目对象模型&#xff09…

N32G031 DMA

目录 N32G031 DMA概述 DMA主要特点 DMA总线架构 DMA使用场景 DMA配置和使用 优点: 缺点: N32G031 DMA概述 N32G031系列芯片基于32位ARM Cortex-M0微控制器,其内置了DMA(直接内存访问)控制器。DMA控制器允许数据…

潮玩宇宙大逃杀APP系统开发成品案例分享指南

这是一款多人游戏,玩家需要选择一个房间躲避杀手。满足人数后,杀手会随机挑选一个房间杀掉里面所有的参与者,其他房间的幸存者将平均瓜分被杀房间的元宝。玩家在选中房间后,倒计时结束前可以自由切换不同房间。 软件项目开发成品…

LabVIEW开发为什么沟通需求非常重要

在LabVIEW开发项目中,需求沟通是项目成功的基石。以下是需求沟通的重要性及其原因: 明确项目目标: 定义清晰的目标:通过与用户的沟通,可以明确项目的目标和范围,确保开发团队理解用户的实际需求&#xff0c…

【Android-Compose】流式布局FlowRow 不能居中对齐的一种解决办法

问题描述: 在安卓Compose 开发中使用LazyColumn 流式布局 FlowRow 有时候比延迟网格布局更灵活,但是也可能出现自动流向下一行之后,末尾处留下一些小空白。如图: 问题解决: 为了尽可能居中对齐,我们可…

专业技能篇---计算机网络篇

文章目录 前言计算机网络基础一、网络分层模型 HTTP一、从输入URL到页面显示发生了什么?二、Http的状态码有哪些?三、 HTTP与HTTPS有什么区别?四、URI 和 URL 的区别是什么?五、Cookie和Session有什么区别?六、GET与POST 前言 主…

dmhs同步因目的端表自增列报错解决方法

dmhs同步因目的端表自增列报错解决方法 1 dmhs copy 装载数据时报错 HY000 CODE:-27232 配置源端捕获器cpt 1 dmhs copy 装载数据时报错 HY000 CODE:-2723 ERR:Only if specified in the column list and SET IDENTITY INSERT is ON, then identity column could be assigned …

2023-2024年新能源汽车市场盘点与展望

本文全面盘点了2023年和2024年新能源汽车市场的新车型、价格走势、智能化趋势以及市场竞争格局,涵盖了各个价格级别和车型类别,为消费者提供购车参考和市场洞察。 文章目录 1.1 2023年新能源汽车市场总结1.2 2024年新能源汽车市场趋势1.3 新车型发布概览…

洛谷 P3379:最近公共祖先(LCA)← RMQ+欧拉序

【题目来源】https://www.luogu.com.cn/problem/P3379【题目描述】 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。【输入格式】 第一行包含三个正整数 N,M,S,分别表示树的结点个数、询问的个数和树根结点的序号。 接下来 N−…

PostgreSQL源码分析——INSERT

这里我们对INSERT语句进行分析, 只分析其宏观过程,具体细节后续再分析。我们就分析下面的语句的执行过程。 insert into t1 values(4,4);主流程 主流程如下: exec_simple_query --> pg_parse_query //语法解析--> raw_parser-->…