GPU對CNN計算的加速原理到底是怎樣的?

想了解GPU到底是如何加速深度網路中的計算,與用CPU進行計算有何差別?


這裡默認你說的gpu加速是指NVIDIA的cuda加速

CPU是中央處理單元,gpu是圖形處理單元

簡單的說,gpu由上千個流處理器(core)作為運算器。執行採用單指令多線程(SIMT)模式。

在cuda編程中有grids、blocks、threads三個維度,大量threads組成一個block,大量blocks組成一個grid。每個block內的所有threads執行相同的操作。

在gpu上執行的函數叫kernel函數,用__device__或__global__聲明

下面是一個典型的kernel函數的例子,實現向量加法

void __global__ vectorADD_gpu(double *A,
double *B,
double *C,
int const N)
{

int const tid = blockDim.x * blockIdx.x + threadIdx.x;
int const t_n=gridDim.x*blockDim.x;
while(tid &< N) { C[tid] = A[tid] + B[tid]; tid+=t_n; } }

在主機端:

vectorADD_gpu&<&<&&>&>(A, B, C, N);

blockDim.x、blockIdx.x、threadIdx.x分別表示每個block有多少thread、當前block的索引、當前thread的索引。

在主機(CPU)調用kernel函數,傳遞調用的grids、block、threads的數量和函數參數,kernel函數會在每個線程(threads)同時對數組A、B、C內的tid(thread"s ID)位置的元素進行

C[tid] = A[tid] + B[tid];

的計算。

也就是說如果兩個1000個元素的矩陣相加,開啟1000線程,一個指令同時在1000個線程上執行一次。相比於單核CPU(向量機)流水線式的串列操作,雖然gpu單個core計算能力很弱,但是通過大量線程進行同時計算,在數據量很大是會活動較為可觀的加速效果。

同理,具體到cnn,利用gpu加速主要是在conv(卷積)過程上。卷積基本原理請自行學習。

conv過程同理可以像以上的向量加法一樣通過cuda實現並行化。具體的方法很多,不過最好的還是利用fft進行快速卷積。NVIDIA提供了cufft庫實現fft,複數乘法則可以使用cublas庫里的對應的level3的cublasCgemm函數。

再具體到各大框架是如何使用gpu對cnn進行加速的,目前主流的做法是使用NVIDIA的cudnn庫NVIDIA cuDNN。這個庫集成了tensors變數、cnn、rnn等重要基礎模型的ff、bp、update的函數,並支持multi device,框架通過傳遞tensors並調用cudnn來實現cnn、rnn等模型的核心運算。

cudnn庫和上面的cublas、cufft等庫一樣,是NVIDIA花重金打造的cuda加速庫,性能優化幾乎達到了巔峰,除非有強烈的造輪子衝動或者定製函數的需求(比如我),使用NVIDIA官方加速庫是最佳選擇。不過在GitHub的上一個叫deepcore的輕量級框架項目里,開發者聲稱cnn速度比cudnn快,看代碼也是使用的fft快速卷積。說明cudnn還有提升潛力。

而且通過閱讀NVIDIA的cudnn的sample,我覺得cudnn作為一個全面嚴謹的深度學習加速庫(報錯、張量定義),雖然體現了開發者高超的編程能力,但是對於個人使用者來說,體系過於龐大、使用太繁瑣。

cuda菜鳥,拋磚引玉,如有錯誤望諒解並指正,不勝感激!


GPU加速的基本準則就是「人多力量大」

CNN說到底主要問題就是計算量大,但是卻可以比較有效的拆分成並行問題

隨便拿一個層的filter來舉例子

假設某一層有n個filter

每一個需要對上一層輸入過來的譜進行卷積操作

那麼,這個卷積操作並不需要按照線性的流程去做

每個濾波器互相之間並不影響,可以大家同時做,然後大家生成了n張新的譜之後

再繼續接下來的操作。

既然可以並行,那麼同一時間處理單元越多,理論上速度優勢就會越大

所以,處理問題就變得很簡單粗暴,就像NV那樣,暴力增加顯卡單元數(當然,顯卡的架構、內部數據的傳輸速率、演算法的優化等等也都很重要)

現在NV那邊統一都命名成「CUDA核心」,以10系顯卡為例,1050,1060,1070,1080,TitanXP,核心數是一個比一個多,那麼自然並行處理能力也會一個比一個強

#####

CPU方面,你肯定也知道民用的一般就算很屌的CPU,最多也就幾十個核心撐到頂了。

即便性能高,但是只是處理一些拆分出來的細化任務的時候「好漢架不住人多」,就算其他方面先進,也施展不出完全的能力來

#####

當然,CUDA加速也不是說完全只靠GPU就行了

CPU其實還起到一個宏觀管控的工作

也就是說,計算的時候,CPU會像一個監工一樣,把數據分配好,然後扔進GPU的流水線里

利用GPU做苦力,去高效計算

結果出來之後,CPU回收一下,然後又進行下一輪的計算。。。

所以,一些CUDA的程序,每次計算的時候,都是會有一個「GPU初始分配」的工作,有時候深度學習處理,是需要一次性放進去大量的數據,比如圖像組(視你batch大小);以及整個模型參數(cnn層數越深,參數自然越多,佔地面積也越大)

所以,你想要設計更大規模的網路的時候,你的顯存就必須要很大,不然數據放不進去

這時候,NV又可以用「大顯存」為理由,去專門做一些高端顯卡來忽悠人了

我反正是不信,1070這樣的顯卡做得出8G顯存,就做不出12G顯存了?就非要1萬多的泰坦XP才能做12G的顯存?

NV就是故意把大顯存的顯卡賣的很貴,你愛買不買


個人認為是因為GPU主要是針對圖形顯示及渲染等技術的出眾,而其中的根本是因為處理矩陣演算法能力的強大,剛好CNN中涉及大量的卷積,也就是矩陣乘法等,所以在這方面具有優勢


推薦閱讀:

對深度學習的理解達到什麼水平才能應聘大型互聯網公司的機器學習相關崗位?
深度學習畢設有什麼好的題目?
什麼是稀疏特徵(Sparse Features)?
如何評價MSRA的新paper:Deep Image Analogy?
需要一個「隨機梯度下降」的詳細教程?

TAG:深度學習DeepLearning | GPU | Caffe深度學習框架 | TensorFlow | 卷積神經網路CNN |