31 深度學習硬件:CPU 和 GPU【動手學深度學習v2】

深度學習硬件
計算機
構成

- CPU(處理器):除了運行操作系統(tǒng)和其他許多功能外,還能執(zhí)行程序;通常由 8 個或者更多個核心組成
- 內(nèi)存(隨機訪問存儲,RAM):用于存儲和檢索計算結果,如權重向量和激活參數(shù),以及訓練數(shù)據(jù)
- 以太網(wǎng):一個或者多個,速度從 1 GB/s 到 100 GB/s 不等
- 高速擴展總線(PCle):用于系統(tǒng)連接一個或者多個 GPU;服務器最多有 8 個加速卡,通常以更高級的拓撲方式連接,而桌面系統(tǒng)則有 1 個或 2 個加速卡,具體取決于用戶的預算和電源負載的大小。
- 持久性存儲設備:為系統(tǒng)需要的訓練數(shù)據(jù)和中間檢查點需要的存儲提供了足夠的傳輸速度;如磁盤驅動器、固態(tài)驅動器,在許多情況下使用高速擴展總線連接
程序執(zhí)行的原理
- 在計算機上運行代碼的時候,需要將數(shù)據(jù)轉移到處理器(GPU 或者 CPU)上執(zhí)行計算
- 然后將結果從處理器轉移回到隨機訪問存儲和持久訪問存儲器中
內(nèi)存
- 主要用于存儲需要隨時訪問的數(shù)據(jù)
當想要從內(nèi)存中讀取一部分內(nèi)容時,需要先將地址(信息的位置)發(fā)送到 RAM,然后可以選擇只讀取一條 64 位記錄還是一長串記錄(突發(fā)讀取,burst read)
- 向內(nèi)存發(fā)送地址并設置傳輸大約需要 100 ns(細節(jié)取決于所用內(nèi)存芯片的特定定時系數(shù)),每個后續(xù)傳輸只需要 0.2 ns
- 第一次讀取的成本是后續(xù)讀取的 500 倍
- 每秒最多可以執(zhí)行一千萬次隨機讀取
- 應該盡可能地避免隨機內(nèi)存訪問,而是使用突發(fā)模式讀取和寫入
當擁有多個存儲體時,每個存儲體大部分時候都可以獨立地讀取內(nèi)存
- 如果隨機操作均勻分布在內(nèi)存中,有效的隨機操作次數(shù)將高達 4 倍(突發(fā)讀取的速度也快了 4 倍)
- 由于內(nèi)存對齊是 64 位邊界,因此最好將任何數(shù)據(jù)結構與相同的邊界對齊(當設置了適當?shù)臉酥緯r,編譯器基本上就是自動地執(zhí)行對齊操作)
因為 GPU 的處理單元比 CPU 多得多,因此它對內(nèi)存帶寬的需要也更高
- 一種解決辦法是使內(nèi)存總線變得更寬,這樣可以同時傳輸更多的信息(首要方法)
- 另一種方法是在 GPU 中使用特定的高性能內(nèi)存(GPU 雖然速度更快,但是它的內(nèi)存通常比 CPU 的內(nèi)存小得多,因為成本更高,價格昂貴,通常僅限于在高端服務器的芯片上使用)
存儲器
- 隨機訪問存儲的一些關鍵特性是帶寬(bandwidth)和延遲(latency),存儲設備也是如此,只是不同設備之間的特性差異可能更大
硬盤驅動器(hard disk drive,HDD)
- 它包含許多旋轉的盤片,這些盤片的磁頭可以放置在任何給定的磁道上進行讀寫
優(yōu)點
- 相對便宜
缺點
1、典型的災難性故障模式
2、相對較高的讀取延遲
- 硬盤驅動器的轉速大約為 7200 RPM(每分鐘轉速),如果速度再快一點,就會由于施加在碟片上的離心力而破碎
- 在訪問磁盤上的特定扇區(qū)時,需要等待碟片旋轉到位(可以移動磁頭,但是無法對磁盤加速),因此可能需要 8 毫秒才能使用請求的數(shù)據(jù)
- 硬盤驅動器可以以大約 100 IOPs(每秒輸入/輸出操作)的速度工作,在過去二十年中這個數(shù)字基本上沒變,帶寬(大約為 100 - 200 MB/s)也很難增加(每個磁頭讀取一個磁道的比特,因此比特率只隨信息密度的平方根縮放)
- 對于非常大的數(shù)據(jù)集,HDD 正迅速降級為歸檔存儲和低級存儲
固態(tài)驅動器(solid state drives,SSD)
- 固態(tài)驅動器使用閃存持久存儲信息以更快地訪問存儲的記錄
缺點
1、固態(tài)驅動器以塊的方式( 256KB 或更大)存儲信息
- 塊只能作為一個整體寫入(而且塊必須被讀取、擦除,然后再重新寫入新的信息),需要耗費大量的時間,導致固態(tài)驅動器在按位隨機寫入時性能非常差
2、存儲單元磨損比較快
- 通常在幾千次寫入之后就已經(jīng)老化了
- 不建議將固態(tài)驅動器用于交換分區(qū)文件或大型日志文件
3、帶寬的大幅增加迫使計算機設計者將固態(tài)驅動器與 PCIe 總線相連接,這種驅動器稱為 NVMe(非易失性內(nèi)存增強)
- 最多可以使用 4 個 PCIe 通道
- 在 PCIe4.0 上最高可達 8 GB/s
云存儲
中央處理器(CPU)
組成
1、處理器核心(processor cores):用于執(zhí)行機器代碼
- 前端加載指令并嘗試預測將采用哪條路徑,然后將指令從匯編代碼解碼為微指令(匯編代碼通常不是處理器執(zhí)行的最低級別代碼,復雜的微指令可以被解碼成一組更低級的操作,然后由實際的執(zhí)行核心處理,通常執(zhí)行核心能夠同時執(zhí)行許多操作)
- 高效的程序可以在每個時鐘周期內(nèi)執(zhí)行多條指令,前提是這些指令可以獨立執(zhí)行
- 為了提高吞吐量,處理器還可以在分支指令中同時執(zhí)行多條代碼路徑,然后丟棄未選擇分支的結果
2、總線(bus):連接不同組件??偩€會因為處理器型號、各代產(chǎn)品和供應商之間的特定拓撲結構有明顯不同
3、緩存(cache):相比主內(nèi)存實現(xiàn)更高的讀取帶寬和更低的延遲內(nèi)存訪問
- 為了避免出現(xiàn)向 CPU 傳輸用于處理的數(shù)據(jù)不足的情況,應該盡量避免從內(nèi)存中加載新數(shù)據(jù),而是應該將數(shù)據(jù)放在 CPU 的緩存上

- 添加緩存一方面能夠確保處理器核心不缺乏數(shù)據(jù),但同時也增加了芯片的尺寸,消耗了原本可以用來提高處理能力的面積
4、向量處理單元(vector processing unit):為高性能線性代數(shù)和卷積運算提供輔助
- CPU在一個時鐘周期內(nèi)執(zhí)行許多操作,是通過向量處理單元實現(xiàn)的(這些處理單元有不同的名稱:在 ARM 上叫做 NEON,在 x86 上被稱為 AVX2)
- 常見的功能是能夠執(zhí)行單指令多數(shù)據(jù)操作(single instruction multiple data,SIMD)
如何提升cpu的利用率?(如何使運算在cpu上進行的更快,特別是數(shù)值運算:矩陣乘法、線性運算等)
1、提升空間和時間的內(nèi)存本地性
如果要計算兩個向量的和a+b
在計算之前需要準備數(shù)據(jù),a 和b很有可能是放在主內(nèi)存中的,如果想要將a和b進行相加,就需要將數(shù)據(jù)從主內(nèi)存搬運到寄存器中(數(shù)據(jù)只有被搬運到寄存器中才能參與運算):主內(nèi)存=>L3 cache(shared LLC)=>L2 cache=>L1 cache=>寄存器
- 這條路徑中最快的是寄存器,寄存器可以認為是和主頻一樣快
- L1 訪問延時:0.5ns (L1比寄存器要大,訪問延遲比寄存器要高)
- L2 訪問延時:7ns (14 *L1 ,訪問一次L2相當于訪問14次L1)
- 主內(nèi)存訪問延時:100ns (200 * L1 ,訪問一次主內(nèi)存相當于訪問200次L1)
- 雖然cpu算的比較快、頻率比較高,但是在實際測試的時候運算速度可能遠低于理論值:這通常是由于內(nèi)存訪問速度過慢導致的
所以一般來說,加速的關鍵點就是提升空間和時間的內(nèi)存本地性,來提升緩存的效率
- 提升時間上的本地性:重用數(shù)據(jù)使得保持在他們的緩存里(計算時需要將數(shù)據(jù)從主內(nèi)存搬運到寄存器中,如果計算完的數(shù)據(jù)不再使用,cpu會將數(shù)據(jù)從寄存器一直回退到主內(nèi)存中,因此,對于重復使用的數(shù)據(jù),就希望能夠將重復使用的數(shù)據(jù)一直保持在寄存器或者是L1中,以便于下一次使用)
- 提升空間上的本地性:按序讀寫數(shù)據(jù)使得可以預讀取(cpu在讀取內(nèi)存的時候是一塊一塊地讀,如果所要計算的數(shù)據(jù)如果在內(nèi)存中是存儲在一起的話,就希望下一次計算所使用到的數(shù)據(jù)和前一次計算所需要的數(shù)據(jù)是相鄰的,這樣能夠提升cpu讀取數(shù)據(jù)的效率)
例:

如果一個矩陣是按行存儲的(在行上面的內(nèi)存地址是連續(xù)的),訪問一行會比訪問一列要快
- cpu一次讀取64字節(jié)(緩存線),一個Float是4個字節(jié)
- cpu會提前讀取下一個(緩存線)
2、盡量使用多核并行計算
高端cpu有幾十個核
并行來利用所有核
- 超線程不一定提升性能,因為它們共享寄存器
例:
使用以下兩種方式來計算a + b

左邊使用循環(huán)對元素進行逐個相加,右邊是使用計算框架(numpy等)進行加法運算,最終在運算的時候左邊會比右邊慢很多:
1、左邊調(diào)用了n次函數(shù)(n是a的長度),每次調(diào)用都是有開銷的
2、右邊很容易做并行(C++的并行實現(xiàn)如下所示)

- omp:C++中比較常用的并行方法
- 第一行omp的標記表示該循環(huán)可以被多個線程并行執(zhí)行,可以很好地利用多核
網(wǎng)絡和總線
- 當單個設備不足以進行優(yōu)化時,需要使用網(wǎng)絡和總線來回傳輸數(shù)據(jù)以實現(xiàn)同步處理
深度學習的互聯(lián)方式:

cpu和gpu的對比

- 表中的“/”表示一般型號的參數(shù)/高端型號的參數(shù)
- GPU的核心數(shù)量遠多于CPU,所以就導致了GPU每秒能計算的浮點數(shù)(TFLOPS,可以用核心數(shù)量和主頻的乘積來做一個簡單的近似)也遠高于CPU
- 每一次計算都需要從內(nèi)存中讀取數(shù)據(jù),因此內(nèi)存帶寬也很重要,通常來說,如果達不到計算峰值一般是由于內(nèi)存帶寬的限制
- 核心數(shù)量和內(nèi)存帶寬的優(yōu)勢使得GPU在運算速度上要遠快于CPU,但是這也導致了GPU的內(nèi)存大小不是很大,控制流很弱(CPU是做通用計算的,因此需要很強的控制流)
如何提升GPU的利用率?
1、并行
- 使用數(shù)千個線程
2、內(nèi)存本地性
- 緩存更小,架構更簡單(GPU為了節(jié)省面積將緩存做得比較小,這樣做的好處是內(nèi)存的帶寬會更高一點)
3、少用控制語句
- 支持有限
- 同步開銷很大
CPU/GPU帶寬

- CPU和GPU并不是獨立的,所有的任務都是運行在CPU上的,如果要在GPU上做運算,就會存在帶寬的問題
- CPU和內(nèi)存之間的帶寬,可以認為CPU每個針腳會傳輸一定的數(shù)據(jù),分配給內(nèi)存的針腳越多,帶寬就越大
- CPU和GPU之間的帶寬:帶寬不是很高,特別是在多個GPU的情況下,可能需要共享帶寬
- 因此不要頻繁地在CPU和GPU之間傳遞數(shù)據(jù):帶寬限制,同步開銷(這里的同步是由驅動決定的)
如何在CPU上進行高性能計算編程?
C++或者任何高性能語言
- 編譯器成熟
如何在GPU上進行高性能計算編程?
Nvidia上用CUDA
- 編譯器和驅動成熟
其他使用OpenCL(CUDA也支持OpenCL)
- 質(zhì)量取決于硬件廠商(編譯器和驅動是根據(jù)硬件廠商決定)
總結
- CPU:可以處理通用計算。性能優(yōu)化考慮數(shù)據(jù)讀寫效率和多線程(多核)
- GPU:使用更多的小核和更好的內(nèi)存帶寬,適合能大規(guī)模并行的計算任務
- 設備有運行開銷,數(shù)據(jù)傳輸時要爭取量大次少而不是量少次多
- 在訓練過程中數(shù)據(jù)類型過小可能會導致數(shù)值的溢出(在推斷過程中影響不大)
Q&A
- 1、如果要提高泛化性,就有可能增加數(shù)據(jù)?調(diào)參的意思是不是最大了??QA P2 - 00:10?
- 2、我之前用alexnet先做的實驗,我發(fā)現(xiàn)resnet18比alexnet的模型文件要小很多,可是您之前的課程里里面有一張圖,好像是resnet的運算量比alexnet大,怎么解釋這個問題??QA P2 - 02:08?
- 3、我看resnet和gbdt很像,就是樹模型換神經(jīng)網(wǎng)絡??QA P2 - 03:50?
- 4、昨天用torch做梯度下降,根據(jù)課程書上描述的優(yōu)化不會出現(xiàn)梯度消失報錯w=lr*w.grad,但是換種寫法w=w-lr*w.grad就會消失,這是為什么呢?都在torch.nograd下執(zhí)行的。接前面補充下,不是梯度消失,是梯度那個參數(shù)變?yōu)閒alse?QA P2 - 04:30?
- 5、請問老師,訓練集準確率不斷增加,但是驗證集的準確率大幅震蕩,是過擬合的原因嗎,還是有其他原因導致的??QA P2 - 05:35?
- 6、請問增加的層數(shù)也是超參數(shù)嗎?如何去加層呢?哪些層可以加?哪些參數(shù)不能動?我現(xiàn)在不知道如何改,有技巧嗎?比如加ResNet-24??QA P2 - 06:36?
- 7、請問如何理解yolo v4輸出層(根據(jù)輸出層獲取預測框坐標等信息)?linux環(huán)境C++部署yolo v4推薦darknet,tensorflow還是其他框架C++ API(以部署簡易性為標準)??QA P2 - 08:04?
- 8、llc(last level cache)是顯存還是緩存?llc是L1還是L2,L3??QA P2 - 08:17?
- 9、請問加的層數(shù)也是超參數(shù)嗎?可以加哪些網(wǎng)絡層?加多少層合適?我現(xiàn)在不知道如何修改已有的網(wǎng)絡。例如可以加入多個網(wǎng)絡ResNet,然后加權取結果嗎?謝謝?QA P2 - 09:10??QA P2 - 08:49?
- 10、既然CPU這么垃圾,為啥現(xiàn)在生產(chǎn)的電腦不把GPU作為出廠設置和核心??QA P2 - 09:23?
- 11、按行存儲需要怎么改代碼??QA P2 - 10:36?
- 12、只能看到有文章預測未來計算設備都會專業(yè)化,而不是都在同樣的“計算機”上,比如醫(yī)療專用計算設備、物理專用計算設備,請問您對這件事情怎么看??QA P2 - 11:45?
- 13、C++有omp,python不也有multiprocessing嗎?還是不行??QA P2 - 20:00?
- 14、multiprocessing是會把計算分布到各個核上??QA P2 - 20:30?
- 15、做計算時把for-loops運算盡可能通過向量化??QA P2 - 21:03?
- 16、可視化時,常常需要把數(shù)據(jù)在CPU和GPU之間切換,如何不要頻繁在CPU和GPU之間傳輸數(shù)據(jù)?常見的這樣的錯誤操作有哪些?有命令能看到嗎?怎么排查這種錯誤??QA P2 - 21:27?
- 17、老師,go怎么樣?未來有可能用于高性能CPU或者GPU計算編程語言嗎??QA P2 - 24:34?
- 18、rust語言做底層怎么樣呢??QA P2 - 26:09?
- 19、FORTRAN現(xiàn)在做底層開發(fā)的多嗎?感覺一般都是用來做數(shù)值計算的??QA P2 - 26:38?
- 20、研一剛進入科研,是一直看論文嗎,代碼要怎么練習才能復現(xiàn)論文呢??QA P2 - 27:04?
- 21、我做了一個東西,現(xiàn)在想跟別人的算法去比,但是他原始的code是tf寫的,我現(xiàn)在把他改寫成torch版的,這樣去比較會不會有爭議??QA P2 - 29:30?
- 22、還能再比較一下GPU、TPU、NPU嗎??QA P2 - 30:49?
- 23、paddlepaddle比pytorch有更多什么優(yōu)勢嗎??QA P2 - 31:00?
- 24、請問老師有沒有推薦的適合做DL的筆記本,或者性價比高的云服務??QA P2 - 31:19?
- 25、您怎么看礦機asic,這個轉到深度學習芯片難度很大嗎??QA P2 - 31:30?
- 26、gpt3或者悟道2.0,也是按照咱們現(xiàn)在學的卷積網(wǎng)絡這樣構造的么??QA P2 - 31:41?
- 27、請問下國內(nèi)外有比較好的討論這些硬件架構的技術網(wǎng)站嗎??QA P2 - 31:56?
- 28、pytorch的data loader有哪些常用的加速方法??QA P2 - 32:16?
- 29、老師,分布式和高性能的區(qū)別是什么?為什么分布式做的好,高性能不行??QA P2 - 32:21?
- 30、分布式追求的高性能應該是高并發(fā),深度學習里面的高性能是大數(shù)據(jù)量計算,是這意思嗎??QA P2 - 32:53?
- 31、老師,請問未來對抗樣本方向的發(fā)展前景如何呢?目前比較流行的幾種對抗樣本算法(白盒、黑盒)是什么呢??QA P2 - 33:51?
- 32、這個QA是什么腳本寫的??QA P2 - 35:16?
- 33、深度學習可以做測量嗎?目前是不是還是用傳統(tǒng)算法做的多?比如測量一個物體的寬度??QA P2 - 36:01?
- 34、go語言可以做分布式很好,但為什么高性能不行?老師剛才說hpc和分布式一回事?QA P2 - 36:35?
- 35、框架調(diào)用Cppapi和pyapi差距大多少??QA P2 - 38:03?
- 36、yolo常用的除了darknet還有什么框架嗎,想在自己的數(shù)據(jù)集上做遷移學習,但是darknet不好編譯??QA P2 - 39:26?
- 37、對國內(nèi)出的AI芯片(比如:寒武紀、平頭哥)怎么看??QA P2 - 39:53?
- 38、做統(tǒng)計+神經(jīng)網(wǎng)絡的算法提升模型的魯棒性以及可解釋性,這個方向有做的嗎,怎么入手????QA P2 - 40:53?
- 39、礦機asic廠家轉深度學習芯片,為什么您認為不行?哪方面難度比較大??QA P2 - 41:54?
- 40、resnet只能用在圖像領域嗎?文本可以用嗎??QA P2 - 43:59?
- 41、老師說的julia用于機器學習和深度學習嗎??QA P2 - 44:08?
- 42、咱們課程會講分布式推薦系統(tǒng)嗎?國內(nèi)現(xiàn)在有很多做推薦學習的?QA P2 - 44:21?
- 43、tf/mxnet的底層都是c++,但是有些模型為什么在infer的時候還是c++調(diào)用更快呢??QA P2 - 45:13?
- 44、為啥v2版本的課程教的是pytorch而不是mxnet呢,是因為現(xiàn)在pytorch?QA P2 - 45:41?
- 45、arm被nvidia收購了,對移動端深度學習的影響??QA P2 - 47:15?
- 46、rust高性能計算前景如何??QA P2 - 47:18?
- 47、Xavier初始化可以和BN一起用嗎?效果會更好嗎??QA P2 - 47:30?
- 48、老師能幫忙比較一下,做DL,打算投資一個WmaiGPU,一塊3080ti和兩塊3060ti如何選擇??QA P2 - 47:38?
- 49、老師,我看了很多目標檢測的paper,但是現(xiàn)在打比賽就是會用一些簡單集成,數(shù)據(jù)增強,感覺沒有什么模型原創(chuàng)性,怎樣才能有更多的模型改造和優(yōu)化能力?有系統(tǒng)的成長方法嗎??QA P2 - 48:16?
- 50、老師,GoogLeNet中的Inception如果使用ResNet的跳轉連接,是否有意義??QA P2 - 48:51?
- 51、我覺得huggingface做的很好,現(xiàn)在如果要在ai方向創(chuàng)業(yè),做一個平臺類型的東西,老師有什么想法嗎?比如做一個平臺讓大家更加方便fine tuning(比sageMake更方便簡單)?QA P2 - 48:59?
- 52、現(xiàn)在是不是公司用spark比用mapreduce多很多?。?/strong>?QA P2 - 50:01?
- 53、老師您認為自動駕駛也是燒錢,但是短時間很難看到落地和未來的是嗎?就相當于您不看好nas一樣??QA P2 - 50:21?
- 54、老師,用現(xiàn)有的網(wǎng)絡如ResNet在一幅大圖像上做物體檢測,是需要先把大圖像切塊,再分塊輸入網(wǎng)絡進行檢測嗎?那切塊的大小一般怎么確定??QA P2 - 51:01?
----end----
其他參考:
1、《動手學深度學習》,課程安排,https://courses.d2l.ai/zh-v2/assets/pdfs/part-2_1.pdf
2、《動手學深度學習》,https://zh-v2.d2l.ai/chapter_computational-performance/hardware.html