91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解析Pytorch轉ONNX的理論分析

發布時間:2021-12-04 18:40:30 來源:億速云 閱讀:190 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關如何解析Pytorch轉ONNX的理論分析,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

(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轉ONNX的理論分析 如何解析Pytorch轉ONNX的理論分析

在這種情況下,如果我們在Pytorch對它調用MaxPool(kernel_size=2, stride=1,pad=0)

那么會得到兩個輸出,第一個輸出是Maxpool之后的值:

如何解析Pytorch轉ONNX的理論分析 如何解析Pytorch轉ONNX的理論分析

另一個是Maxpool的Idx,即每個輸出對應原來的哪個輸入,這樣做反向傳播的時候就可以直接把輸出的梯度傳給對應的輸入:

如何解析Pytorch轉ONNX的理論分析 如何解析Pytorch轉ONNX的理論分析

細心的同學會發現其實Maxpool的Idx還可以有另一種寫法:

如何解析Pytorch轉ONNX的理論分析 如何解析Pytorch轉ONNX的理論分析 ,

即每個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的性質共同決定的

如何解析Pytorch轉ONNX的理論分析

上面的表列了ONNX和Caffe的幾點區別,其中最重要的區別就是op的粒度。舉個例子,如果對Bert的Attention層做轉換,ONNX會把它變成MatMul,Scale,SoftMax的組合,而Caffe可能會直接生成一個叫做Multi-Head Attention的層,同時告訴CUDA工程師:“你去給我寫一個大kernel“(很懷疑發展到最后會不會把ResNet50都變成一個層。。。)

如何解析Pytorch轉ONNX的理論分析
因此如果某天一個研究員提了一個新的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的轉換,同時也可以得到分支判斷等信息。
*目前Pytorch官方希望通過用TorchScript的方式解決分支語句的問題,但據我所知還不是很成熟。

以上就是如何解析Pytorch轉ONNX的理論分析,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

濮阳市| 夏邑县| 六安市| 武安市| 通渭县| 平顶山市| 合作市| 渝北区| 新平| 庐江县| 利川市| 靖州| 江华| 巴楚县| 祁连县| 沈阳市| 黄山市| 扎鲁特旗| 山东省| 克山县| 绥化市| 宣汉县| 娄底市| 绩溪县| 古交市| 阳江市| 嘉兴市| 长治市| 海口市| 正定县| 九江市| 和静县| 衢州市| 淮滨县| 大关县| 瓦房店市| 牟定县| 朝阳县| 宣城市| 余江县| 澄迈县|