日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

图像 pipeline_多面体优化,Pipeline与深度学习编译器

發(fā)布時間:2023/12/10 pytorch 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像 pipeline_多面体优化,Pipeline与深度学习编译器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

有幸參與了MICRO2020,見識到了很多優(yōu)秀的論文,其中最讓我驚艷的是華為的在多面體優(yōu)化上做優(yōu)化的文章 <Optimizing the Memory Hierarchy by Compositing Automatic Transformations on Computations and Data>(https://www.di.ens.fr/~zhaojie/micro2020-paper),再看到video之后立刻讀了原文,覺得其中很多思想和Halide提出的Pipeline很像。因此我想在這里發(fā)表一下自己對深度學(xué)習(xí)與編譯器的結(jié)合的看法,拋磚引玉,和各位大佬討論一下。

傳統(tǒng)的多面體優(yōu)化(Polyhedral model)會將給定的程序直接當(dāng)成一大坨進(jìn)行分析,在一大段復(fù)雜的數(shù)學(xué)和工程實(shí)現(xiàn)后,將模型完成轉(zhuǎn)換,得到一個相對不錯的(自動挖掘并行度)程序。

我們都知道,在HPC領(lǐng)域我們關(guān)注的主要是循環(huán)結(jié)構(gòu),對循環(huán)結(jié)構(gòu)的調(diào)整可以影響locality, reuse distance等等。多面體優(yōu)化就是可以在保證正確性的情況下自動對循環(huán)進(jìn)行調(diào)整,并行,如下所示:

當(dāng)然,多面體優(yōu)化本身是一個極復(fù)雜的算法,我會在之后的文章單獨(dú)來寫,這次只是給大家一個直觀的認(rèn)識。

華為的這篇文章做了什么事情?首先考慮下面的代碼(例子來自論文原文)

對這個代碼做變化的話,可能會得到兩種結(jié)果:

這種方法得到的循環(huán)結(jié)構(gòu)比較整齊,都是嵌套循環(huán),利于并行

這種方法雖然盡可能的消掉了循環(huán),但是計算邏輯復(fù)雜,有很多的if判斷。

對于GPU,我們自然希望模型并行度高,而且diverge少,也就是分支判斷少,那么顯然第一種變換優(yōu)于第二種。

因此我們的目標(biāo)也比較明確:就是將程序做變換,使變換后得到的模型并行度好。

一般來說,GPU程序都是對output做并行,因此我們也希望可以整齊的切分output。這里可以介紹一下tiling的概念,對于一個普通的二重循環(huán):

for(int i = 0; i < 16; i++)for(int j = 0; j < 16; j++)fn(i,j);

如果我們將兩重循環(huán)分別做切割,得到四重循環(huán):

for(int i_outer = 0; i_outer<4;i_outer++)for(int i_inner = 0; i_inner<4; i_inner++)for(int j_outer = 0; j_outer < 4; j_outer++)for(int j_inner = 0; j_inner < 4; j_inner++)int i = i_outer * 4 + i_inner;int j = j_outer * 4 + j_inner;fn(i, j);

再對四重循環(huán)的二三層做交換,即順序變成i outer, j outer, i inner, j inner,那么這個變換就叫做tiling

tiling往往和棋盤格格式緊密相連,下面圖中矩陣乘法的例子就用了tiling,把C切成了9*16塊

tiling的好處在此不做展開,網(wǎng)上的資料比較多。有興趣的同學(xué)直接搜CUDA的矩陣乘法優(yōu)化即可。

介紹完了我們的目標(biāo),還要提一下另一個重要的概念:Pipeline。這個概念最開始在Halide的論文中(http://people.csail.mit.edu/jrk/halide-pldi13.pdf)被提出。Halide是一個圖像處理編譯器,做過CV的同學(xué)都知道,我們處理圖像一般都是走一個Pipeline。比如正則化->高斯模糊->調(diào)整對比度。在這里面有一個偏序關(guān)系,那就是Consumer和Producer(其實(shí)就是上下游兩個op)

生產(chǎn)者生產(chǎn)的值只會被消費(fèi)者使用,也就是說消費(fèi)者的使用決定了生產(chǎn)者的生產(chǎn)。

舉一個最經(jīng)典的例子,假設(shè)我有一個2D矩陣,我希望計算每個點(diǎn)和相鄰8個點(diǎn)的和。

那我可以把這個算法拆成一個Pipeline:

輸入矩陣->blurx矩陣(每個矩陣的元素存儲輸入矩陣每個點(diǎn)和左右兩個點(diǎn)的和)->output(每個矩陣的元素存儲blurx矩陣每個點(diǎn)和上下兩個點(diǎn)的和)

實(shí)際上就是干了下面的事情:

然而根據(jù)消費(fèi)者(out)不同的使用情況,生產(chǎn)者(blurx)的生產(chǎn)也不同,比如下面兩種例子:

第一個例子很正常,一般人都會這么寫,體現(xiàn)不出來啥。。。

這種寫法就很奇葩:幾乎不把blurx存到內(nèi)存里面,用到的時候當(dāng)場算一遍。

算法1算法2
內(nèi)存占用2048*30723
計算量2048*30722046*3072*3

可以發(fā)現(xiàn)前者有最大的內(nèi)存,最小的計算量,而后者正好相反。這兩種不同的producer-consumer模式可以看作是computation和memory的tradeoff

華為的文章利用了這種思想:你不是想并行度好么?行,那我直接就把最后的輸出切一下,每個輸出需要哪些producer用多面體優(yōu)化技術(shù)算一遍,這樣我又可以做tiling(因為output被切了),又可以利用多面體優(yōu)化,對每個output小塊做優(yōu)化

論文中給的例子也很直觀:先把右下角的output均勻切成4塊,然后算每塊output需要的producer(左下角)。

我在深度學(xué)習(xí)編譯器方面也有一些了解,覺得目前看來,這種producer-consumer的優(yōu)化很popular,TVM也在用(compute_at原語)。這種通過輸出推導(dǎo)輸入可以盡可能避免冗余計算,同時生成對于output并行的結(jié)構(gòu)有良好性質(zhì)的代碼。

總結(jié)一下,之前的多面體優(yōu)化是把模型當(dāng)成一坨來優(yōu)化,而在華為的工作中,把模型看作了層級很清楚的Pipeline,對每層分別做優(yōu)化,這樣生成的程序就有更好的并行性。當(dāng)然,這篇論文更可貴的地方是提供了詳細(xì)的完整的代碼實(shí)現(xiàn),真的可以落地到實(shí)際應(yīng)用場景。不過鑒于篇幅有限(主要是我懶。。。),就簡單的把思想說一下。還是強(qiáng)烈推薦有興趣的讀者看看原文!

總結(jié)

以上是生活随笔為你收集整理的图像 pipeline_多面体优化,Pipeline与深度学习编译器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。