Pytorch~ONNX
创始人
2024-04-29 03:31:31
0

pytorch转onnx其实也就是python转的 ,之前有个帖子了讲的怎么操作,这个就是在说说为什么这么做~~~

(1)Pytorch转ONNX的意义

一般来说转ONNX只是一个手段,在之后得到ONNX模型后还需要再将它做转换,比如转换到TensorRT上完成部署,或者有的人多加一步,从ONNX先转换到caffe,再从caffe到tensorRT。原因是Caffe对tensorRT更为友好,这里关于友好的定义后面会谈。

因此在转ONNX工作开展之前,首先必须明确目标后端。ONNX只是一个格式,就和json一样。只要你满足一定的规则,都算是合法的,因此单纯从Pytorch转成一个ONNX文件很简单。但是不同后端设备接受的onnx是不一样的,因此这才是坑的来源。

Pytorch自带的torch.onnx.export转换得到的ONNX,ONNXRuntime需要的ONNX,TensorRT需要的ONNX都是不同的。

这里面举一个最简单的Maxpool的例:

Maxunpool可以被看作Maxpool的逆运算,咱们先来看一个Maxpool的例子,假设有如下一个C*H*W的tensor(shape[2, 3, 3]),其中每个channel的二维矩阵都是一样的,如下所示

在这种情况下,如果我们在Pytorch对它调用MaxPool(kernel_size=2, stride=1,pad=0)

那么会得到两个输出,第一个输出是Maxpool之后的值:

另一个是Maxpool的Idx,即每个输出对应原来的哪个输入,这样做反向传播的时候就可以直接把输出的梯度传给对应的输入: 

细心的同学会发现其实Maxpool的Idx还可以有另一种写法: 

即每个channel的idx放到一起,并不是每个channel单独从0开始。这两种写法都没什么问题,毕竟只要反向传播的时候一致就可以。

但是当我在支持OpenMMEditing的时候,会涉及到Maxunpool,即Maxpool的逆运算:输入MaxpoolId和Maxpool的输出,得到Maxpool的输入。

Pytorch的MaxUnpool实现是接收每个channel都从0开始的Idx格式,而Onnxruntime则相反。因此如果你希望用Onnxruntime跑一样的结果,那么必须对输入的Idx(即和Pytorch一样的输入)做额外的处理才可以。换言之,Pytorch转出来的神经网络图和ONNXRuntime需要的神经网络图是不一样的。

(2)ONNX与Caffe

主流的模型部署有两种路径,以TensorRT为例,一种是Pytorch->ONNX->TensorRT,另一种是Pytorch->Caffe->TensorRT。个人认为目前后者更为成熟,这主要是ONNX,Caffe和TensorRT的性质共同决定的

上面的表列了ONNX和Caffe的几点区别,其中最重要的区别就是op的粒度。举个例子,如果对Bert的Attention层做转换,ONNX会把它变成MatMul,Scale,SoftMax的组合,而Caffe可能会直接生成一个叫做Multi-Head Attention的层,同时告诉CUDA工程师:“你去给我写一个大kernel“(很怀疑发展到最后会不会把ResNet50都变成一个层。。。)

 

因此如果某天一个研究员提了一个新的State-of-the-art的op,很可能它直接就可以被转换成ONNX(如果这个op在Pytorch的实现全都是用Aten的库拼接的),但是对于Caffe的工程师,需要重新写一个kernel。

细粒度op的好处就是非常灵活,坏处就是速度会比较慢。这几年有很多工作都是在做op fushion(比如把卷积和它后面的relu合到一起算),XLA和TVM都有很多工作投入到了op fushion,也就是把小op拼成大op。

TensorRT是NVIDIA推出的部署框架,自然性能是首要考量的,因此他们的layer粒度都很粗。在这种情况下把Caffe转换过去有天然的优势。

除此之外粗粒度也可以解决分支的问题。TensorRT眼里的神经网络就是一个单纯的DAG:给定固定shape的输入,执行相同的运算,得到固定shape的输出。

**目前TensorRT的一个发展方向是支持dynamic shape,但是还很不成熟。

tensor i = funcA();
if(i==0)
j = funcB(i);
else
j = funcC(i);
funcD(j);

对于上面的网络,假设funcA,funcB,funcC和funcD都是onnx支持的细粒度算子,那么ONNX就会面临一个困难,它转换得到的DAG要么长这样:funcA->funcB->funcD,要么funcA->funcC->funcD。但是无论哪种肯定都是有问题的。

而Caffe可以用粗粒度绕开这个问题

开这个问题

tensor i = funcA();
coarse_func(tensor i) {
if(i==0) return funcB(i);
else return funcC(i);
}
funcD(coarse_func(i))

因此它得到的DAG是:funcA->coarse_func->funcD

当然,Caffe的代价就是苦逼的HPC工程师就要手写一个coarse_func kernel。。。(希望Deep Learning Compiler可以早日解放HPC工程师)

(3)Pytorch本身的局限

熟悉深度学习框架的同学都知道,Pytorch之所以可以在tensorflow已经占据主流的情况下横空出世,成功抢占半壁江山,主要的原因是它很灵活。举个不恰当的例子,tensorflow就像是C++,而Pytorch就是Python。

tensorflow会把整个神经网络在运行前做一次编译,生成一个DAG(有向无环图),然后再去跑这张图。Pytorch则相反,属于走一步看一步,直到运行到这个节点算出结果,才知道下一个节点该算啥。

ONNX其实就是把上层深度学习框架中的网络模型转换成一张图,因为tensorflow本身就有一张图,因此只需要直接把这张图拿到手,修修补补就可以。

但是对于Pytorch,没有任何图的概念,因此如果想完成Pytorch到ONNX的转换,就需要让ONNX再旁边拿个小本子,然后跑一遍Pytorch,跑到什么就把什么记下来,把记录的结果抽象成一张图。因此Pytorch转ONNX有两个天然的局限。

1. 转换的结果只对特定的输入。如果换一个输入导致网络结构发生了变化,ONNX是无法察觉的(最常见的情况是如果网络中有if语句,这次的输入走了if的话,ONNX就只会生成if对应的图,把else里面全部的信息都丢掉)。

2. 需要比较多的计算量,因为需要真刀真枪的跑一遍神经网络。

PS:针对于以上的两个局限,我的本科毕设论文提出了一种解决方案,就是通过编译器里面的词法分析,语法分析直接扫描Pytorch或者tensorflow的源代码得到图结构,这样可以轻量级的完成模型到ONNX的转换,同时也可以得到分支判断等信息,这里放一个github链接(https://github.com/drcut/NN_transform),希望大家多多支持

*目前Pytorch官方希望通过用TorchScript的方式解决分支语句的问题,但据我所知还不是很成熟。

whaosoft aiot http://143ai.com   


 

相关内容

热门资讯

领克车机系统安卓,安卓智能驾驶... 你有没有发现,现在开车的时候,车机系统越来越智能了?尤其是领克的安卓车机系统,简直让人爱不释手。今天...
安卓原生系统通知声音,定制个性... 你知道吗?手机里那些时不时冒出来的通知,有时候就像小精灵在耳边悄悄说话,有时候又像是闹钟在催你起床。...
安卓系统电脑键盘功能 你有没有发现,用安卓系统电脑打字的时候,键盘功能可真是丰富得让人眼花缭乱呢?今天,就让我带你一起探索...
安卓修改文件系统后缀,解锁文件... 你有没有想过,你的安卓手机里的文件系统后缀可以随意修改?听起来是不是有点神奇?没错,今天就来带你一探...
安卓系统多任务流转 你有没有发现,在使用安卓手机的时候,有时候会突然冒出一个任务流转的功能,让你瞬间切换到另一个应用,是...
神姬红包版安卓系统,解锁全新游... 你知道吗?最近在手机圈里,有个神姬红包版安卓系统可是火得一塌糊涂呢!这不,我就迫不及待地来和你聊聊这...
为什么国内要用安卓系统,探索国... 你知道吗?在国内,安卓系统可是占据了半壁江山呢!为什么国内要用安卓系统呢?这背后可是有着不少有趣的故...
htc安卓系统怎么升级8.0,... 亲爱的手机控们,你是否也像我一样,对手机系统升级充满了期待和好奇呢?尤其是当HTC安卓系统升级到8....
安卓系统最好的应用助手,助你轻... 你有没有发现,手机里那些乱糟糟的图标和复杂的设置让你头疼不已?别担心,今天我要给你介绍一个安卓系统里...
安卓系统如何下载teamhub... 你有没有想过,在安卓系统上下载一个叫做Teamhub的应用程序呢?这可是个超级实用的工具,无论是工作...
安卓系统如何看无线密码,安卓系... 你有没有想过,你的安卓手机是怎么看懂无线密码的呢?是不是觉得这背后藏着什么神秘的黑科技?别急,今天就...
pd13安装安卓系统,PD13... 你有没有想过,给你的PD13平板电脑装个全新的安卓系统,让它焕发第二春呢?想象那流畅的操作体验,那丰...
苹果系统怎么比安卓好,五大优势... 你有没有想过,为什么苹果系统那么多人喜欢,而安卓系统虽然普及,但总感觉少了点啥?今天,就让我来给你细...
苏州攻略系统和安卓互通,安卓互... 你打算去苏州游玩一番,是不是已经迫不及待想要探索这座古城的韵味了呢?别急,别急,让我来给你支支招,让...
安卓变苹果系统教程荣耀,安卓变... 你是不是也和我一样,对手机系统转换充满了好奇?想要从安卓跳到苹果的阵营,却又觉得一头雾水?别担心,今...
安卓115系统编写 你有没有听说啊?安卓115系统最近可是火得一塌糊涂!作为一个紧跟科技潮流的数码达人,我怎么能不给你来...
安卓系统内录怎么搞,轻松实现屏... 你有没有想过,在安卓手机上录制屏幕,那可是一项超实用的技能呢!无论是想记录游戏操作,还是制作教程,或...
国服无法进入安卓系统,安卓系统... 最近有没有发现,你的安卓手机上那些心仪的国服游戏突然变得高不可攀了呢?别急,让我来给你揭秘这背后的故...
安卓系统破解wifi密码破解,... 你是不是也和我一样,对破解WiFi密码这个话题充满了好奇?想象当你身处一个陌生的环境,急需上网却苦于...
安卓系统项目发布平台 你知道吗?在科技飞速发展的今天,安卓系统项目发布平台可是个香饽饽呢!它就像一个巨大的舞台,让无数开发...