search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

少花錢搭建深度學習系統的硬體指南

由於深度學習的計算相當密集,所以有人覺得「必須要購買一個多核快速CPU」,也有人認為「購買快速CPU可能是種浪費」。

那麼,這兩種觀點哪個是對的?其實,在建立深度學習系統時,最糟糕的事情之一就是把錢浪費在不必要的硬體上。本文將告訴你如何用最省錢的方式,來搭建一個高性能深度學習系統。

當初,在我研究并行深度學習過程中,我構建了一個GPU集群 ,所以我需要仔細選擇硬體。儘管經過了反覆的研究和推理,但當我挑選硬體時,我仍然會犯許多錯誤,並且當應用於實踐中時,那些錯誤就展現出來了。所以,在這裡,我想分享一下我所學到的知識,希望你不會像我一樣再陷入同樣的陷阱。

GPU

本文假設您將使用GPU進行深度學習。如果您正在建立或升級您的系統,那麼忽視GPU是不明智的。 GPU才是深度學習應用的核心,它能大大提升處理速度,所以絕對不能忽略。

我在之前的文章中詳細介紹了GPU的選擇,並且GPU的選擇可能是您的深度學習系統中最關鍵的選擇。

一般來說,如果您的資金預算有限,我推薦您購買GTX 680,或者GTX Titan X(如果你很有錢,可用它做卷積)或GTX 980(它性價比很高,但若做大型卷積神經網路就有些局限性了),它們在eBay上就能買得到。

另外,低成本高性價比的內存我推薦GTX Titan。之前我支持過GTX 580,但是由於新更新的cuDNN庫顯著提升了卷積速度,故而所有不支持cuDNN的GPU都已經過時了,其中 GTX 580就是這樣一款GPU。如果您不使用卷積神經網路,GTX 580仍然是一個很好的選擇。

你能識別上面哪個硬體會導致糟糕的表現?是這些GPU的其中一個?還是CPU?

CPU要選擇CPU,我們首先要了解CPU及它與深度學習的關係。CPU對深度學習有什麼作用?當您在GPU上運行深度網路時,CPU幾乎沒有計算,但是CPU仍然可以處理以下事情:
  • 在代碼中寫入和讀取變數

  • 執行諸如函數調用的指令

  • 在GPU上啟動函數調用

  • 創建小批量數據

  • 啟動到GPU的數據傳輸

所需CPU的數量

當我用三個不同的庫訓練深度神經網路時,我總是看到一個CPU線程是100%(有時另一個線程會在0到100%之間波動)。而且這一切立即告訴你,大多數深入學習的庫,以及實際上大多數的軟體應用程序,一般僅使用一個線程。

這意味著多核CPU相當無用。如果您運行多個GPU,並使用MPI之類的并行化框架,那麼您將一次運行多個程序,同時,也需要多個線程。

每個GPU應該是一個線程,但每個GPU運行兩個線程將會為大多數深入學習庫帶來更好的性能;這些庫在單核上運行,但是有時會非同步調用函數,就使用了第二個CPU線程。

請記住,許多CPU可以在每個內核上運行多個線程(這對於Intel的CPU尤為如此),因此通常每個GPU對應一個CPU核就足夠了。

CPU和PCI-Express

這是一個陷阱!一些新的Haswell CPU不支持那些舊CPU所支持的全部40個PCIe通道。如果要使用多個GPU構建系統,請避免使用這些CPU。另外,如果您有一個帶有3.0的主板,則還要確保您的處理器支持PCIe 3.0。

CPU緩存大小

正如我們將在後面看到的那樣,CPU高速緩存大小在「CPU-GPU-管線」方面是相當無關緊要的,但是我還是要做一個簡短的分析,以便我們確保沿著這條計算機管道能考慮到每一個可能出現的瓶頸,進而我們可以全面了解整體流程。

通常人們購買CPU時會忽略緩存,但通常它是整體性能問題中非常重要的一部分。 CPU緩存的片上容量非常小,且位置非常靠近CPU,可用於高速計算和操作。 CPU通常具有緩存的分級,從小型高速緩存(L1,L2)到低速大型緩存(L3,L4)。

作為程序員,您可以將其視為哈希表,其中每個數據都是鍵值對(key-value-pair),您可以在特定鍵上進行快速查找:如果找到該鍵,則可以對高速緩存中的值執行快速讀寫操作;如果沒有找到(這被稱為緩存未命中),則CPU將需要等待RAM趕上,然後從那裡讀取該值(這是非常緩慢的過程)。重複的緩存未命中會導致性能顯著降低。高效的CPU高速緩存方案和架構,通常對CPU的性能至關重要。

CPU如何確定其緩存方案,是一個非常複雜的主題,但通常可以假定重複使用的變數、指令和RAM地址將保留在緩存中,而其他不太頻繁出現的則不會。

在深度學習中,相同的內存範圍會重複被小批量讀取,直到送到GPU,並且該內存範圍會被新數據覆蓋。但是如果內存數據可以存儲在緩存中,則取決於小批量大小。

對於128位的小批量大小,我們對應於MNIST和CIFAR分別有0.4MB和1.5 MB,這適合大多數CPU緩存;對於ImageNet,我們每個小批量有超過85 MB的數據,即使是最大的緩存(L3緩存不超過幾MB),也算是很大的了。

由於數據集通常太大而無法適應緩存,所以新的數據需要從RAM中每個讀取一小部分新的,並且需要能夠以任何方式持續訪問RAM。

RAM內存地址保留在緩存中(CPU可以在緩存中執行快速查找,並指向RAM中數據的確切位置),但是這僅限於整個數據集都存儲於RAM時才會如此,否則內存地址將改變,並且緩存也不會加速(稍後你會看到的,使用固定內存時則不會出現這種情況,但這並不重要)。

深度學習代碼的其他部分(如變數和函數調用),將從緩存中受益,但這些代碼通常數量較少,可輕鬆適應幾乎任何CPU的小型快速L1緩存。

從這個推理結果可以看出,CPU緩存大小不應該很重要。下一節進一步分析的結果,也與此結論相一致。

所需的CPU時鐘頻率(frequency)

當人們想到快速的CPU時,他們通常首先想到時鐘頻率(clockrate)。 4GHz真的比3.5GHz快嗎?這對於具有相同架構的處理器來說,通常是正確的,例如「Ivy Bridge」。但在不同架構的處理器之間,就不能這樣比較了。此外,時鐘頻率也並非總是最佳的性能指標。

在深度學習上,使用CPU的計算很少:比如增加一些變數、評估一些布爾表達式、在GPU或程序中調用一些函數。以上這些都取決於CPU內核時鐘率。雖然這個推理似乎是合理的,但是當我運行深度學習程序時,CPU卻有100%的使用率,這是為什麼?為了找到原因,我做了一些CPU核頻率的降頻實驗。

在MNIST和ImageNet上的CPU降頻測試 :以上數據,是在具有不同CPU內核時鐘頻率時,對ImageNet運行200個周期MNIST數據集,或1/4 ImageNet周期所用時間,進行性能測量的。其中以最大時鐘頻率作為每個CPU的基準線。為了比較:從GTX 680升級到GTX Titan,性能約為15%;從GTX Titan到GTX 980提升20%; GPU超頻為所有GPU提升約5%的性能。

那麼為什麼CPU內核頻率對系統來說無關緊要,而使用率卻是100%?答案可能是CPU緩存未命中(CPU持續忙於訪問RAM,但是同時CPU必須等待RAM以跟上其較慢的時鐘頻率,這可能會導致忙碌和等待兩者同時存在的矛盾狀態)。如果這是真的,就像上面看到的結果一樣,那麼CPU內核的降頻不會導致性能急劇下降。

另外,CPU還執行其他操作,如將數據複製到小批量中,並將準備複製到GPU的數據準備好,但這些操作取決於內存時鐘頻率,而不是CPU內核時鐘頻率。所以,現在我們來看看內存方面。

RAM時鐘頻率

CPU-RAM,以及與RAM的其他交互,都相當複雜。我將在這裡展示一個簡化版本的過程。為了能更全面地理解,就我們先來深入了解從CPU RAM到GPU RAM這一過程。

CPU內存時鐘和RAM交織在一起。您的CPU的內存時鐘決定了RAM的最大時鐘頻率,這兩個部分構成CPU的總體內存帶寬,但通常RAM本身確定了總體可用帶寬,原因是它比CPU內存頻率慢。

您可以這樣確定帶寬:

(其中64是指64位CPU架構。對於我的處理器和RAM模塊,帶寬為51.2GB / s)

但是,如果您複製大量的數據,這時會和帶寬相關。通常,您的RAM上的時序(例如8-8-8)對於小數據量來說更為相關,並且決定您的CPU等待RAM追趕的時間。但是如上所述,您深入學習程序中的幾乎所有數據都將輕鬆適應CPU緩存,除非因為太大,才無法從緩存中獲益。這意味著計時器將是不重要的,而帶寬可能才是重要的。

那麼這與深度學習程序有什麼關係呢?我剛剛只是說帶寬可能很重要,但是在下一步里,它就不是很重要了。您的RAM的內存帶寬決定了一個小批量可以被重寫和分配用於初始化GPU傳輸的速度,但下一步,CPU-RAM到GPU-RAM是真正的瓶頸,這一步使用直接內存存取(DMA)。如上所述,我的RAM模塊的內存帶寬為51.2GB/ s,但DMA帶寬只有12GB / s!

DMA帶寬與常規帶寬有關,但細節並不一定必須了解。如果您想詳細了解,可到該維基百科詞條查看,您可以在詞條內查找RAM模塊的DMA帶寬(峰值傳輸限制)。但是先讓我們看看DMA是如何工作的吧。

(地址:https://en.wikipedia.org/wiki/DDR3_SDRAM#JEDEC_standard_modules)

直接內存存取(DMA)

具有RAM的CPU只能通過DMA與GPU進行通信。

在第一步中,CPU RAM和GPU RAM都保留特定的DMA傳輸緩衝區;

在第二步,CPU將請求的數據寫入CPU側的DMA緩衝區;

在第三步中,保留的緩衝區無需CPU的幫助即可傳輸到GPURAM。

這裡有人可能會想:你的PCIe帶寬是8GB / s(PCIe 2.0)或15.75GB / s(PCIe 3.0),所以你應該買一個像上面所說的良好峰值傳輸限制的RAM嗎?

答案是:不必要。軟體在這裡會扮演重要角色。如果你以一種聰明的方式進行一些傳輸,那麼你就不再需要那些便宜且慢的內存。

非同步迷你批量分配(Asynchronousmini-batch allocation)

一旦您的GPU完成了當前迷你批量的計算,它就想立即計算下一迷你批次(mini-batch)。您現在可以初始化DMA傳輸,然後等待傳輸完成,以便您的GPU可以繼續處理數字。

但是有一個更有效的方法:提前準備下一個迷你批量,以便讓您的GPU不必等待。這可以輕鬆且非同步地完成,而不會降低GPU性能。

用於非同步迷你批次分配的CUDA代碼:當GPU開始處理當前批次時,執行前兩次調用;當GPU完成當前批處理時,執行最後兩個調用。數據傳輸在數據流的第二步同步之前就已經完成,因此GPU處理下一批次將不會有任何延遲。

Alex Krishevsky的卷積網路的ImageNet 2012迷你批次的大小為128,僅需要0.35秒就能完成它的完整的反向傳遞。我們能夠在如此短時間內分配下一批嗎?

如果我們採用大小為128的批次,並且維度244x244x3大小的數據,總量大約為0.085 GB。若使用超慢內存,我們有6.4 GB / s,即每秒75個迷你批次!所以使用非同步迷你批量分配,即使是最慢的RAM對深入學習也將足夠。如果使用非同步迷你批量分配,購買更快的RAM模塊沒有任何優勢。

該過程也間接地意味著CPU緩存是無關緊要的。您的CPU的快速覆蓋速度(在快速緩存中),以及準備(將緩存寫到RAM)一個迷你批次其實並不重要,因為在GPU請求下一個迷你批次之前,整個傳輸就已經完成了,所以一個大型緩存真的沒那麼重要。

所以底線確實是RAM的時鐘頻率是無關緊要的,所以買便宜的就行了。

但你需要買多少個呢?

RAM大小

您應該至少具有與GPU內存大小相同的RAM。當然,您可以使用較少的RAM,但這樣的話可能需要一步一步地傳輸數據。然而,從我的經驗來看,使用更大的RAM會更加方便。

心理學告訴我們,專註力是隨著時間的推移會慢慢耗盡的一種資源。有些為數不多的硬體,可以幫您節省注意力資源以解決更困難的編程問題, RAM就是其中之一。如果您有更多的RAM,您可以將更多的時間投入到更緊迫的事情上,而不是花費大量的時間來彌補RAM瓶頸。

有了很多RAM,您可以避免這些瓶頸,節省時間並提高生產率,使注意力投入到更緊迫的地方。特別是在Kaggle比賽中,我發現額外的RAM對於特徵操作非常有用。所以如果你資金充裕,並做了大量的預處理,那麼額外的RAM可能是一個不錯的選擇。

硬碟驅動器/SSD

在某些情況下,硬碟驅動器可能是深度學習的重大瓶頸。如果您的數據集很大,您通常會在SSD /硬碟驅動器上放一些數據,RAM中也有一些,以及GPURAM中也會放兩個迷你批量(mini-batch)。為了不斷地供給GPU,我們需要以GPU可以運行完的速度提供新的的迷你批量(mini-batch)。

為此,我們需要使用與非同步迷你批量分配相同的想法。我們需要非同步讀取多個小批量的文件,這真的很重要!如果我們不這樣做,結果表現會被削弱很多(約5-10%),並且你精心設計的硬體優勢將毫無作用(好的深入學習軟體在GTX 680也能運行很快,而壞的深入學習軟體即使用GTX 980也會步履維艱)

考慮到這一點,如果我們將數據保存為32位浮點數據,就會遇到Alex的ImageNet卷積網路遇到的數據傳輸速率的問題,約每0.3秒0.085GB即290MB / s。如果我們把它保存為jpeg數據,我們可以將它壓縮5-15倍,將所需的讀取帶寬降低到約30MB / s。如果我們看硬碟驅動器的速度,我們通常會看到速度為100-150MB / s,所以這對於壓縮為jpeg的數據是足夠的。

類似地,一個人可以使用mp3或其他壓縮技術處理的聲音文件,但是對於處理原始32位浮點數據的其他數據組,難以很好地壓縮數據(只能壓縮32位浮點數據10-15%)。所以如果你有大的32位數據組,那麼你肯定需要一個SSD,因為速度為100-150 MB / s的硬碟會很慢,難以跟上GPU。

所以如果你今後有可能遇到這樣的數據,那就買一個一個SSD;如果不會遇到那樣的數據,一個硬碟驅動器就足夠用了。

許多人購買SSD是為了感覺上更好:程序啟動和響應更快,並且使用大文件進行預處理也更快一些。但是對於深入學習,僅當輸入維度很高且無法充分壓縮數據時,才用得到SSD。

如果您購買SSD,您應該買一個能夠容納您常用大小的數據組的SSD,另外還需要額外留出幾十GB的空間。其實,讓硬碟驅動器來存儲未使用的數據組也是個好主意。

電源單元(PSU)

一般來說,您需要一個足夠的PSU來滿足未來的所有GPU。 GPU通常會隨著時間的推移而更加節能,所以即使當其他組件到了更換的時候,PSU也能繼續工作很長時間,所以良好的PSU是一個明智的投資。

您可以通過將CPU和GPU的所需瓦數,與其他組件所需瓦數相加,再加上作為電源峰值緩衝的100-300瓦,就能計算出所需的瓦數。

要注意的一個重要部分,是留意您的PSU的PCIe連接器是否支持帶有連接線的8pin + 6pin的接頭。我買了一個具有6x PCIe埠的PSU,但是只能為8pin或6pin連接器供電,所以我無法使用該PSU運行4個GPU。

另一個重要的事情是購買具有高功率效率等級的PSU,特別是當您運行多個GPU並想要運行很長時間。

在全功率(1000-1500瓦特)下運行4個GPU系統,對卷積網進行兩個星期的訓練,將消耗300-500千瓦時,而在德國的電力成本還要高出20美分/ kWh,即60~100€($ 66~111)。如果這個價格是百分之百效率的價格,那麼用80%電能訓練這樣一個網路會額外增加18-26歐元的成本!這對於單個GPU來說要少得多,但在高效電源上花費更多的錢是很有意義的。

散熱(Cooling)

散熱是十分重要的,它可能引發另一個重要的瓶頸,比不良硬體選擇更能降低性能。您的CPU可以使用標準散熱器,但是對於GPU,您需要特別注意。

現代GPU在運行演算法時,會將其速度提高到最大值,同時提高的還有功耗,但一旦GPU達到溫度上限閾值(通常為80°C),GPU將降低速度從而避免突破溫度閾值。這樣可以實現最佳性能,同時避免了GPU過熱。

然而,典型的風扇速度的預編程,不是為運行深度學習程序而設計的,因此在開始深入學習程序后的幾秒內,就達到了溫度閾值。結果是性能下降(約幾個百分點),對於多個GPU而言,GPU之間存在相互加熱的情況,所以整體性能會下降10-25%。

由於NVIDIA GPU是首屈一指的遊戲GPU,因此針對Windows進行了優化。您可以在Windows中點擊幾下更改風扇計劃,但在Linux中卻不行,因為大多數深入學習庫是為Linux編寫的,這是一個問題。

最簡單和最有性價比的解決方案是使用一個具有更合理風扇設定的BIOS程序刷新GPU,這樣即可以使GPU保持低溫,也能使噪音水平達到可接受的閾值(如果使用伺服器來作為解決方案,為了避免產生難以忍受的噪音,就要降低風扇的運行速度了)。

您也可能超速運行GPU的內存,雖然會產生30-50MHz的雜訊,不過也是一個可行的辦法。刷新BIO軟體是專為Windows設計的,但您可以使用wine操作系統從Linux / Unix操作系統調用該程序。

另一個方案是設置您的Xorg伺服器(Ubuntu操作系統)的配置,您可以在其中設置 「coolbits」選項。這對於單個GPU非常有效,但是如果您有多個GPU,其中有些是headless GPU,即沒有顯示器,則必須模擬一個顯示器(難度非常高)。我嘗試了很長時間,並且使用實時啟動CD來恢復我的圖形設置,結果令人沮喪,程序始終無法在這個GPU上正常運行。

另一個更昂貴也更複雜的方案是使用水來冷卻。

對於單個GPU,即使在最大負載下,水冷卻法也能降低一半溫度,從而使其達不到溫度閾值。甚至在多台GPU情況下,空氣降溫難以應對時,水冷卻也可以很好的降溫。

水冷卻的另一個優點是它運行得更加默默無聞,如果工作的地方運行多個GPU,水冷卻將會具有良好的表現。每個GPU的水冷卻將耗費大約100美元,還有一些額外的前期成本(約$ 50)。水冷還需要額外的精力來組裝您的電腦,但網上有很多詳細的指南手冊,而且總共只需要幾個小時就能搞定。後期維護很簡單。

根據我的經驗,我為我的深入學習集群購買過大型塔,因為他們擁有GPU區域的另加風扇,但我發現這在很大程度上是無關緊要的:大約只下降2-5°C,所以不值得投資那麼多錢去買這麼龐大的東西。最重要的還是直接對您的GPU採取降溫措施:刷新BIOS、使用水冷卻法、或忍受打了折扣的運行效果。在某些情況下,以上這些都是合理的選擇。你也可以根據自己的需要找出合適的解決方案。

主板和電腦機箱

您的主板應該有足夠的PCIe埠,以支持您要運行的GPU數量(通常限於4個GPU,即使還有多餘的PCIe插槽);請記住,大多數GPU都需要2個PCIe插槽的寬度,比如您將需要7個插槽來運行4個GPU。 PCIe 2.0介面對於單個GPU來說可以適用;但即使對於單個GPU,PCIe 3.0也更加經濟划算;對於多個GPU,通常總會購買PCIe3.0介面,這將是一個好的決定,因為PCIe連介面常常是個瓶頸。

主板的選擇很簡單:選一個支持所需硬體配置的主板。

當您選擇機箱時,您應該確保它滿足GPU的長度要求。大多數機箱都滿足,但如果您購買小機箱,您應該多留意,要檢查其尺寸和規格;您還可以嘗試用Google圖像搜索,並查看是否在其中找到帶有GPU的圖片。

我剛開始也認為談監視器是件愚蠢的事,但後來發現,它們確實有巨大的影響,而且非常重要,所以我必須要寫一些關於它的內容。

我在3英寸27寸顯示器上花費的錢,讓我感覺到肉疼。但使用多個顯示器時,效率確實提升了很多。如果我只使用單個顯示器,我感到非常困難。千萬不要在這件事上糾結,試想一下,如果您無法以更高效的方式操作,那麼即使有一個特別快速的深度學習系統又有什麼用呢?

當深度學習系統運行時,典型的顯示器布局:左:論文,Google搜索,gmail,stackoverflow;中間:代碼;右:輸出窗口,R,文件夾,系統顯示器,GPU顯示器,待辦事項列表和其他小應用程序。

當深度學習系統運行時,典型的顯示器布局:左:論文,Google搜索,gmail,stackoverflow;中間:代碼;右:輸出窗口,R,文件夾,系統顯示器,GPU顯示器,待辦事項列表和其他小應用程序。

建立PC的一些心得

很多人都害怕搭建電腦,因為硬體組件特別昂貴,誰都不想花冤枉錢。但是有一個很簡單的思路,就是不能裝在一起的硬體根本無法湊合。主板手冊通常會非常具體地闡明如何組裝所有部件。另外,如果您沒有經驗,還有大量的操作指南和視頻教程指導您完成整個過程。

自己組裝電腦的好處是,一旦你組裝過一次,你以後就知道它是如何組裝的了,因為所有的電腦都是以相同的方式組建的。組裝一台電腦將會成為一種陪伴你一生的技能。所以,立刻親自嘗試一次吧!

結論/TL; DR

GPU :GTX 680或GTX 960(資金有限); GTX 980(最佳性能); GTX Titan(如果你需要內存);GTX 970(無卷積網路);

CPU:每個GPU兩個線程;完整的40個PCIe線路和合適的PCIe配件(與主板匹配); > 2GHz;快速緩衝存儲區無關緊要

RAM:使用非同步迷你批量配置;時鐘頻率和計時器並不重要;購買至少與GPU RAM一樣多的CPU RAM;

硬碟驅動器/ SSD:如果您有圖像或聲音數據,請使用非同步批處理文件讀取和壓縮數據;除非你使用大的輸入維度的32位浮點數據組,否則一個硬碟驅動器就夠了。

PSU: GPU+ CPU +(100-300)的總瓦數就是所需的電源供應量;如果您使用大的卷積網路,那麼,就需要一個帶有高效能額定功率的PSU;另外,確保具有足夠的PCIe接頭(6 + 8pin),以及您將來可能會新購買的GPU所需的電量。

散熱:如果您運行單個GPU,請在您的配置中設置coolbits標誌;否則刷新BIOS以增加風扇速度是最簡單和最便宜的;若想沒有噪音就使用水冷卻法。

主板:選擇PCIe3.0,以及選擇您未來所需GPU數量一樣多的擴展插槽數(一個GPU需要兩個插槽,每個系統最多4個GPU);

顯示器:如果要升級系統以提高生產力,相對於升級GPU,多買一台顯示器可能更有意義。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦