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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

深入浅出PyTorch(算子篇)

發布時間:2023/12/19 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 深入浅出PyTorch(算子篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Tensor

自從張量(Tensor)計算這個概念出現后,神經網絡的算法就可以看作是一系列的張量計算。所謂的張量,它原本是個數學概念,表示各種向量或者數值之間的關系。PyTorch的張量(torch.Tensor)表示的是N維矩陣與一維數組的關系。

torch.Tensor的使用方法和numpy很相似(https://pytorch.org/...tensor-tutorial-py),兩者唯一的區別在于torch.Tensor可以使用GPU來計算,這就比用CPU的numpy要快很多。

張量計算的種類有很多,比如加法、乘法、矩陣相乘、矩陣轉置等,這些計算被稱為算子(Operator),它們是PyTorch的核心組件。

算子的backend一般是C/C++的拓展程序,PyTorch的backend是稱為"ATen"的C/C++庫,ATen是"A Tensor"的縮寫。

Operator

PyTorch所有的Operator都定義在Declarations.cwrap和native_functions.yaml這兩個文件中,前者定義了從Torch那繼承來的legacy operator(aten/src/TH),后者定義的是native operator,是PyTorch的operator。

相比于用C++開發的native code,legacy code是在PyTorch編譯時由gen.py根據Declarations.cwrap的內容動態生成的。因此,如果你想要trace這些code,需要先編譯PyTorch。

legacy code的開發要比native code復雜得多。如果可以的話,建議你盡量避開它們。

MatMul

本文會以矩陣相乘--torch.matmul()為例來分析PyTorch算子的工作流程。

我在深入淺出全連接層(fully connected layer)中有講在GPU層面是如何進行矩陣相乘的。Nvidia、AMD等公司提供了優化好的線性代數計算庫--cuBLAS/rocBLAS/openBLAS,PyTorch只需要調用它們的API即可。

Figure 1是torch.matmul()在ATen中的function flow。可以看到,這個flow可不短,這主要是因為不同類型的tensor(2d or Nd, batched gemm or not,with or without bias,cuda or cpu)的操作也不盡相同。

at::matmul()主要負責將Tensor轉換成cuBLAS需要的格式。前面說過,Tensor可以是N維矩陣,如果tensor A是3d矩陣,tensor B是2d矩陣,就需要先將3d轉成2d;如果它們都是>=3d的矩陣,就要考慮batched matmul的情況;如果bias=True,后續就應該交給at::addmm()來處理;總之,matmul要考慮的事情比想象中要多。

除此之外,不同的dtype、device和layout需要調用不同的操作函數,這部分工作交由c10::dispatcher來完成。

Dispatcher

dispatcher主要用于動態調用dtype、device以及layout等方法函數。用過numpy的都知道,np.array()的數據類型有:float32, float16,int8,int32,.... 如果你了解C++就會知道,這類程序最適合用模板(template)來實現。

很遺憾,由于ATen有一部分operator是用C語言寫的(從Torch繼承過來),不支持模板功能,因此,就需要dispatcher這樣的動態調度器。

類似地,PyTorch的tensor不僅可以運行在GPU上,還可以跑在CPU、mkldnn和xla等設備,Figure 1中的dispatcher4就根據tensor的device調用了mm的GPU實現。

layout是指tensor中元素的排布。一般來說,矩陣的排布都是緊湊型的,也就是strided layout。而那些有著大量0的稀疏矩陣,相應地就是sparse layout。

Figure 2是strided layout的演示實例,這里創建了一個2行2列的矩陣a,它的數據實際存放在一維數組(a.storage)里,2行2列只是這個數組的視圖。

stride充當了從數組到視圖的橋梁,比如,要打印第2行第2列的元素時,可以通過公式:(1 * stride(0) + 1 * stride(1))來計算該元素在數組中的索引。

除了dtype、device、layout之外,dispatcher還可以用來調用legacy operator。比如說addmm這個operator,它的GPU實現就是通過dispatcher來跳轉到legacy::cuda::_th_addmm。

END

到此,就完成了對PyTorch算子的學習。如果你要學習其他算子,可以先從aten/src/ATen/native目錄的相關函數入手,從native_functions.yaml中找到dispatch目標函數,詳情可以參考Figure 1。


更多精彩文章,歡迎掃碼關注下方的公眾號, 并訪問我的簡書博客:https://www.jianshu.com/u/c0fe8671254e

歡迎轉發至朋友圈,工作號轉載請后臺留言申請授權~

總結

以上是生活随笔為你收集整理的深入浅出PyTorch(算子篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。