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   


 

相关内容

热门资讯

安卓linux系统软件,功能与... 你知道吗?在智能手机的世界里,有一个系统可是独树一帜,那就是安卓Linux系统。它就像一位多才多艺的...
安卓ios双系统接单,拓展业务... 你知道吗?现在这个时代,手机双系统已经成为了很多人的选择。安卓和iOS,这两个操作系统就像是一对双胞...
安卓系统和linux系统的区别... 你有没有想过,为什么你的手机里装的是安卓系统而不是Linux系统呢?这两者虽然听起来都挺高大上的,但...
小米4安卓系统几代,引领科技潮... 你有没有想过,你的手机里那个小小的操作系统,其实就像是一个默默无闻的超级英雄呢?今天,咱们就来聊聊小...
安卓系统里的SE,功能与操作指... 你有没有发现,安卓系统里有个叫SE的小家伙?别小看了它,这个小家伙可是隐藏着不少秘密呢!今天,就让我...
手机系统flyme是安卓系统吗... 你有没有想过,你的手机里那个飞快如风的系统,Flyme,它是不是安卓的“好兄弟”呢?今天,就让我带你...
安卓os系统怎么使用,Andr... 你手里那台安卓手机是不是总感觉有点儿复杂,不知道怎么玩转呢?别急,今天就来给你详细介绍一下安卓OS系...
安卓怎么装旧系统,安卓设备如何... 你有没有想过,手机用久了,系统更新换代,新功能层出不穷,但有时候,那些旧系统里的经典操作和熟悉感,简...
电脑怎装安卓系统,轻松实现多系... 你有没有想过,你的电脑除了装Windows系统,还能装上安卓系统呢?没错,就是那个让你手机不离手的安...
安卓系统找不到软件,探寻解决方... 最近是不是你也遇到了这样的烦恼:手机里明明有安卓系统,却怎么也找不到心仪的软件?别急,今天就来给你详...
小米独立系统取代安卓,迈向自主... 小米独立系统:小米与安卓的较量在科技领域,每一次系统的更新换代都牵动着无数科技爱好者和行业从业者的目...
安卓系统会员价格,性价比与权益... 你有没有发现,最近手机上的安卓系统会员价格又涨了?这可真是让人有点头疼呢!咱们一起来聊聊这个话题,看...
安卓点歌系统怎么点歌,享受音乐... 你有没有想过,在安卓手机上点歌竟然也能这么有趣呢?没错,现在就让我带你一起探索安卓点歌系统的奥秘吧!...
w222安卓系统,功能解析与使... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那款备受瞩目的W222安卓系统!...
iphone手机使用安卓系统,... 你有没有想过,如果有一天你的iPhone手机突然变成了安卓系统,会是怎样的场景呢?想象那熟悉的苹果界...
安卓系统珠宝手绘软件,艺术与科... 你有没有想过,手机上那些精美的珠宝手绘作品是怎么诞生的呢?其实,这一切都离不开安卓系统上一款神奇的应...
安卓系统app签名方案,安全与... 你有没有想过,为什么你的手机上那么多应用都能无缝运行?这其中,安卓系统app签名方案可是功不可没哦!...
安卓系统关闭应用存储,释放手机... 手机里的应用越来越多,存储空间越来越紧张,是不是感觉手机像是个装满杂物的仓库?别急,今天就来教你怎么...
安卓系统的占比,引领移动设备市... 你知道吗?在智能手机的世界里,有一个系统可是占据了半壁江山,那就是安卓系统!想象你手中的手机,是不是...
在线安卓翻译系统实现,便捷跨语... 你有没有想过,在这个信息爆炸的时代,语言不再是沟通的障碍?没错,我要说的是,在线安卓翻译系统正在悄悄...