博客專欄

EEPW首頁 > 博客 > RTX 40時(shí)代,給深度學(xué)習(xí)買的顯卡居然能保值9年?仔細(xì)一算繃不住了(1)

RTX 40時(shí)代,給深度學(xué)習(xí)買的顯卡居然能保值9年?仔細(xì)一算繃不住了(1)

發(fā)布人:機(jī)器之心 時(shí)間:2023-01-17 來源:工程師 發(fā)布文章
FP8 訓(xùn)練帶來的速度提升可能要一統(tǒng) AI 領(lǐng)域,但這是我要考慮的問題嗎?


深度學(xué)習(xí)對于算力的要求很高,對于個(gè)人來說,GPU 的選擇很大程度上決定了你的工作、學(xué)習(xí)體驗(yàn)。顯卡既貴又復(fù)雜,如果想購買新的 GPU,哪些功能最重要?內(nèi)存、核心、Tensor Core 還是緩存?如何做出性價(jià)比高的選擇?每出一代新 GPU 這些問題就要重新審視一番。


近日,華盛頓大學(xué)在讀博士 Tim Dettmers 通過一篇長文在 RTX 40 時(shí)代的背景下深入探討了這些問題,此文一出就獲得了陳天奇等人的轉(zhuǎn)推。


圖片


本文將解決常見的誤解,讓你直觀地了解如何看待 GPU 并提供建議,幫你做出適合自己的選擇。


這篇博文的結(jié)構(gòu)如下:首先,我將解釋是什么讓 GPU 變快的,我將討論 CPU 與 GPU、Tensor Core、內(nèi)存帶寬和 GPU 的內(nèi)存層次結(jié)構(gòu),以及它們與深度學(xué)習(xí)性能的關(guān)系。我們將討論新的 NVIDIA RTX 40 Ampere GPU 系列的獨(dú)特功能。隨后我們將針對不同的場景提出 GPU 推薦。


與深度學(xué)習(xí)相關(guān)性最高的 GPU 規(guī)格


本節(jié)按每個(gè)組件的重要性排序。Tensor Core 是最重要的,其次是 GPU 的內(nèi)存帶寬、緩存層次結(jié)構(gòu),然后才是 GPU 的純算力 FLOPS。


Tensor Core


Tensor Core(張量核心)是執(zhí)行非常高效的矩陣乘法的微核心。由于任何深度神經(jīng)網(wǎng)絡(luò)中最耗費(fèi)算力的部分就是矩陣乘法,所以張量核心非常有用。它們非常強(qiáng)大,想搞深度學(xué)習(xí),不推薦任何沒有 Tensor Core 的 GPU。


這里展示一個(gè)簡單的 A×B=C 矩陣乘法示例,其中所有矩陣的大小均為 32×32,計(jì)算模式在使用和不使用 Tensor Cores 時(shí)的樣子。這是一個(gè)簡化的示例,并不是編寫高性能矩陣乘法內(nèi)核的確切方式,但它具有所有基礎(chǔ)知識。CUDA 程序員會把它作為第一個(gè)「草稿」,然后用雙倍緩沖、寄存器優(yōu)化、占用優(yōu)化、指令級并行等概念逐步優(yōu)化它,這里不會一一討論。


要完全理解此示例,你必須了解循環(huán)的概念。如果處理器以 1GHz 運(yùn)行,它每秒可以執(zhí)行 10^9 個(gè)周期。每個(gè)循環(huán)代表一個(gè)計(jì)算機(jī)會。但大多數(shù)時(shí)候,操作需要的時(shí)間超過一個(gè)周期?;\統(tǒng)地說這里有一個(gè)隊(duì)列,下一個(gè)操作需要等待上一個(gè)操作完成。這也稱為操作的延遲。


以下是一些重要的操作延遲周期時(shí)間。這些時(shí)間數(shù)字每代 GPU 都不一樣,這里的適用于緩存相對較慢的 Ampere GPU:


  • 全局內(nèi)存訪問(多至 80GB):~380 個(gè)周期

  • L2 緩存:~200 個(gè)周期

  • L1 緩存或共享內(nèi)存訪問(每個(gè)流式多處理器最多 128 kb):~34 個(gè)周期

  • 融合乘法和加法,ab+c (FFMA):4 個(gè)周期張量核心矩陣乘法:1 個(gè)周期


每個(gè)操作總是由一組 32 個(gè)線程執(zhí)行,它的集合被稱為線程 warp。warp 通常以同步模式運(yùn)行 ——warp 中的線程必須相互等待。GPU 上的所有內(nèi)存操作都針對 warp 進(jìn)行了優(yōu)化。例如,從全局內(nèi)存加載以 32×4 字節(jié)的粒度發(fā)生,正好是 32 個(gè)浮點(diǎn)數(shù),一個(gè) warp 中的每個(gè)線程正好對應(yīng)一個(gè)浮點(diǎn)數(shù)。我們最多可以在一個(gè)流式多處理器 (SM) 中擁有 32 個(gè) warps = 1024 個(gè)線程,相當(dāng)于一個(gè) CPU 核心的 GPU。SM 的資源在所有活躍的 warp 之間分配。這意味著有時(shí)我們希望運(yùn)行更少的 warp,以便每個(gè) warp 擁有更多的寄存器 / 共享內(nèi)存 / Tensor Core 資源。


對于以下兩個(gè)示例,我們假設(shè)擁有相同的計(jì)算資源。對于這個(gè) 32×32 矩陣乘法的小例子,我們使用 8 個(gè) SM(大約是 RTX 3090 的 10%)和每個(gè) SM 8 個(gè) warp。


要了解循環(huán)延遲如何與每個(gè) SM 的線程和每個(gè) SM 的共享內(nèi)存等資源一起發(fā)揮作用,我們現(xiàn)在來看一下矩陣乘法的示例。雖然以下示例大致遵循了使用和不使用 Tensor Core 的矩陣乘法的計(jì)算步驟序列,但請注意,這些示例非常簡化。矩陣乘法的真實(shí)案例涉及更大的共享內(nèi)存塊和略有不同的計(jì)算模式。


沒有張量核的矩陣乘法


如果我們想要進(jìn)行 A×B=C 矩陣乘法,其中每個(gè)矩陣的大小為 32×32,那么就要將重復(fù)訪問的內(nèi)存加載到共享內(nèi)存中,因?yàn)樗难舆t大約低五倍(200 周期對 34 周期)。共享內(nèi)存中的內(nèi)存塊通常稱為內(nèi)存塊或簡稱為塊。使用 232 warp 可以并行地將兩個(gè) 32×32 的浮點(diǎn)數(shù)加載到共享內(nèi)存塊中。我們有 8 個(gè) SM,每個(gè) 8 warp,因此由于并行化,我們只需要執(zhí)行一次從全局到共享內(nèi)存的順序加載,這需要 200 個(gè)周期。


要進(jìn)行矩陣乘法,我們現(xiàn)在要從共享內(nèi)存 A 和共享內(nèi)存 B 加載一個(gè)包含 32 個(gè)數(shù)字的向量,并執(zhí)行融合乘加 (FFMA)。然后將輸出存儲在寄存器 C 中。我們劃分工作,使每個(gè) SM 進(jìn)行 8 次點(diǎn)積 (32×32) 來計(jì)算 C 的 8 個(gè)輸出。為什么這恰好是 8(在舊算法中為 4)是非常技術(shù)性的。


這里推薦 Scott Gray 關(guān)于矩陣乘法的博文 (https://github.com/NervanaSystems/maxas/wiki/SGEMM) 來理解這一點(diǎn)。


這意味著我們有 8 次共享內(nèi)存訪問,每次訪問花費(fèi) 34 個(gè)周期和 8 個(gè) FFMA 操作(并行 32 個(gè)),每個(gè)操作花費(fèi) 4 個(gè)周期??偟膩碚f成本是:200 個(gè)周期(全局內(nèi)存)+ 834 個(gè)周期(共享內(nèi)存)+ 84 個(gè)周期(FFMA)= 504 個(gè)周期。


讓我們看看使用 Tensor Cores 的周期成本。


用 Tensor Core 進(jìn)行矩陣乘法


使用 Tensor Core,我們可以在一個(gè)周期內(nèi)執(zhí)行 4×4 矩陣乘法。為此我們首先需要將內(nèi)存放入 Tensor Core。與上面類似,我們需要從全局內(nèi)存(200 個(gè)周期)中讀取并存儲在共享內(nèi)存中。要進(jìn)行 32×32 矩陣乘法,我們需要進(jìn)行 8×8=64 個(gè) Tensor Core 運(yùn)算。單個(gè) SM 有 8 個(gè) Tensor Core。因此,有了 8 個(gè) SM 我們就有了 64 個(gè) Tensor Core—— 這正是我們需要的數(shù)量!我們可以通過 1 次內(nèi)存?zhèn)鬏敚?4 個(gè)周期)將數(shù)據(jù)從共享內(nèi)存?zhèn)鬏數(shù)?Tensor Core,然后執(zhí)行這 64 個(gè)并行 Tensor Core 操作(1 個(gè)周期)。


這意味著 Tensor Cores 矩陣乘法的總成本,在這種情況下是:200 個(gè)周期(全局內(nèi)存)+ 34 個(gè)周期(共享內(nèi)存)+ 1 個(gè)周期(Tensor Core)= 235 個(gè)周期。


因此,我們通過 Tensor Core 將矩陣乘法成本從 504 個(gè)周期減少到了 235 個(gè)周期。在這個(gè)簡化的案例中,Tensor Cores 降低了共享內(nèi)存訪問和 FFMA 操作的成本。借助新的 Hooper (H100) 和 Ada(RTX 40 系)架構(gòu),我們還擁有可以進(jìn)一步加速此操作的張量內(nèi)存加速器 (TMA) 單元。


用 Tensor Core 和 TMA 進(jìn)行矩陣乘法


TMA 單元允許將全局內(nèi)存加載到共享內(nèi)存中,而無需用完寶貴的線程資源。因此當(dāng) TMA 執(zhí)行異步傳輸時(shí),線程可以專注于共享內(nèi)存和 Tensor Core 之間的工作,就像這樣


TMA 從全局內(nèi)存獲取內(nèi)存到共享內(nèi)存(200 個(gè)周期)。數(shù)據(jù)到達(dá)后,TMA 就會從全局內(nèi)存中異步獲取下一個(gè)數(shù)據(jù)塊。這樣,線程從共享內(nèi)存加載數(shù)據(jù)并通過張量核心執(zhí)行矩陣乘法。線程完成后,它們等待 TMA 完成下一個(gè)數(shù)據(jù)傳輸,然后重復(fù)該序列。


由于異步性質(zhì),TMA 讀取的第二個(gè)全局內(nèi)存已經(jīng)在線程處理當(dāng)前共享內(nèi)存塊時(shí)進(jìn)行。這意味著第二次讀取僅需 200 – 34 – 1 = 165 個(gè)周期。


由于我們進(jìn)行了多次讀取,只有第一個(gè)內(nèi)存訪問會很慢,所有其他內(nèi)存訪問將與 TMA 部分重疊。因此平均而言,我們將時(shí)間減少了 35 個(gè)周期。


165 個(gè)周期(等待 TMA 完成)+ 34 個(gè)周期(共享內(nèi)存)+ 1 個(gè)周期(Tensor Core)= 200 個(gè)周期。這又將矩陣乘法加速了 15%。


從這些示例中可以清楚地看出為什么下一個(gè)屬性內(nèi)存帶寬對于配備 Tensor-Core 的 GPU 如此重要。由于全局內(nèi)存是迄今為止使用 Tensor Core 進(jìn)行矩陣乘法的最大周期成本,如果可以減少全局內(nèi)存延遲,我們甚至可以擁有更快的 GPU。我們可以通過增加內(nèi)存的時(shí)鐘頻率(每秒更多的周期,但也有更多的熱量和更高的供電需求)或增加可以在任何時(shí)間傳輸?shù)脑財(cái)?shù)量(總線寬度)來做到這一點(diǎn)。


內(nèi)存帶寬


我們已經(jīng)知道 Tensor Core 是非??斓模聦?shí)上,它們大部分時(shí)間都處于空閑狀態(tài),因?yàn)樗鼈冋诘却齼?nèi)存從全局內(nèi)存到達(dá)。例如,在使用巨大矩陣的 GPT-3 訓(xùn)練期間(模型越大,對 Tensor Core 越友好)我們的 Tensor Core TFLOPS 利用率約為 45-65%,這意味著即使對于大型神經(jīng)網(wǎng)絡(luò)也有大約 50% 時(shí)間處于閑置狀態(tài)。


所以當(dāng)比較兩個(gè)有 Tensor Core 的 GPU 時(shí),GPU 性能的最重要指標(biāo)之一是它們的內(nèi)存帶寬。例如 A100 GPU 的內(nèi)存帶寬為 1,555 GB/s,而 V100 為 900 GB/s。因此,A100 與 V100 的加速比基本估計(jì)為 1555/900 = 1.73 倍。


L2 緩存 / 共享內(nèi)存 / L1 緩存 / 寄存器


由于內(nèi)存?zhèn)鬏數(shù)?Tensor Core 是性能的限制因素,我們應(yīng)當(dāng)尋求更快的內(nèi)存?zhèn)鬏數(shù)?Tensor Cores 的方式。二級緩存、共享內(nèi)存、一級緩存和使用的寄存器數(shù)量與該速度都是相關(guān)的。


為了執(zhí)行矩陣乘法,我們利用了 GPU 的內(nèi)存層次結(jié)構(gòu),從慢速全局內(nèi)存到更快的 L2 內(nèi)存,再到快速本地共享內(nèi)存,再到快如閃電的寄存器。但是,內(nèi)存越快,它就越小。


雖然從邏輯上講,L2 和 L1 內(nèi)存相同,但 L2 緩存更大,因此檢索緩存行需要遍歷的平均物理距離更大。你可以將 L1 和 L2 緩存視為有組織的倉庫,可以在其中檢索項(xiàng)目。你知道物品在哪里,但是對于較大的倉庫來說,去那里平均需要更長的時(shí)間。這就是 L1 和 L2 緩存的本質(zhì)區(qū)別:大 = 慢,小 = 快。


對于矩陣乘法,我們可以使用這種層次把結(jié)構(gòu)分割開,用更快的內(nèi)存塊來執(zhí)行快速的矩陣乘法。為此,我們需要將大矩陣乘法分塊為更小的子矩陣乘法。這些塊稱為內(nèi)存塊,或通常簡稱為塊(tile)。


我們在快速且接近流式多處理器 (SM,相當(dāng)于 CPU 內(nèi)核)的本地共享內(nèi)存中對這些較小的塊執(zhí)行矩陣乘法。對于 Tensor Cores 則更進(jìn)一步:我們獲取每個(gè)塊并將這些塊的一部分加載到 Tensor Core 中,這些 Tensor Core 由寄存器直接尋址。L2 緩存中的矩陣內(nèi)存塊比全局 GPU 內(nèi)存(GPU RAM)快 3-5 倍,共享內(nèi)存比全局 GPU 內(nèi)存快約 7-10 倍,而 Tensor Cores 的寄存器比全局 GPU 內(nèi)存快約 200 倍。


擁有更大的塊意味著我們可以重用更多的內(nèi)存。事實(shí)上,你可以看到 TPU 的每個(gè) Tensor Core 都有非常非常大的塊。因此,TPU 可以在每次從全局內(nèi)存?zhèn)鬏敃r(shí)重用更多的內(nèi)存,這使得它們在矩陣乘法方面比 GPU 更高效。


每個(gè)塊大小取決于每個(gè)流式多處理器 (SM) 有多少內(nèi)存,以及所有 SM 有多少二級緩存。我們在以下架構(gòu)上有以下共享內(nèi)存大小:


  • Volta (Titan V):128kb 共享內(nèi)存 / 6 MB L2

  • Turing(RTX 20 系):96 kb 共享內(nèi)存 / 5.5 MB L2

  • Ampere(RTX 30 系):128 kb 共享內(nèi)存 / 6 MB L2

  • Ada(RTX 40 系):128 kb 共享內(nèi)存 / 72 MB L2


顯然 Ada 有很大的 L2 緩存,允許更大的塊體量,這減少了全局內(nèi)存訪問。例如在 BERT large 在訓(xùn)練期間,任何矩陣乘法的輸入和權(quán)重矩陣都可以很好地適合 Ada 的 L2 緩存,更早期的英偉達(dá) GPU 則不然。因此,數(shù)據(jù)只需從全局內(nèi)存加載一次,然后可通過 L2 緩存使用,使 Ada 的這種架構(gòu)的矩陣乘法速度提高約 1.5-2.0 倍。對于較大的模型,訓(xùn)練期間的加速比較低,但存在某些最佳點(diǎn)可能會使某些模型更快。推理時(shí),batch size 大于 8 也可以從更大的 L2 緩存中獲益匪淺。


Ada / Hopper 架構(gòu)的深度學(xué)習(xí)性能


英偉達(dá)已經(jīng)在廣泛的計(jì)算機(jī)視覺和自然語言理解任務(wù)中對 A100、V100 和 H100 進(jìn)行了基準(zhǔn)測試。不幸的是,英偉達(dá)的測試通過盡可能使用不同的 batch size 和 GPU 數(shù)量來確保這些數(shù)字不能直接比較,以支持 H100 更好的結(jié)果。因此從某種意義上說,基準(zhǔn)數(shù)字部分是誠實(shí)的,部分是營銷數(shù)字。你可能會爭辯說使用更大的 batch size 是公平的,因?yàn)?H100/A100 有更多內(nèi)存。盡管如此,為了比較 GPU 架構(gòu),我們應(yīng)該評估具有相同 batch size 的無偏內(nèi)存性能。


為獲得無偏估計(jì),我們可以通過兩種方式擴(kuò)展數(shù)據(jù)中心 GPU 結(jié)果:(1) 考慮 batch size 的差異,(2) 考慮使用 1 塊 GPU 與 8 塊 GPU 的差異。幸運(yùn)的是,我們可以在英偉達(dá)提供的數(shù)據(jù)中找到對這兩種偏差的估計(jì)。


將 batch size 加倍可將 CNN 網(wǎng)絡(luò)的圖像 / 秒吞吐量提高 13.6%。在我的 RTX Titan 上對 transformer 的相同問題進(jìn)行了基準(zhǔn)測試,結(jié)果令人驚訝地發(fā)現(xiàn)了完全相同的結(jié)果:13.5%—— 這似乎是一個(gè)可靠的估計(jì)。


隨著我們在越來越多的 GPU 上并行化網(wǎng)絡(luò),我們會因?yàn)橐恍┚W(wǎng)絡(luò)開銷而損失性能。A100 8x GPU 系統(tǒng)具有比 V100 8x GPU 系統(tǒng)(NVLink 2.0)更好的網(wǎng)絡(luò)(NVLink 3.0)—— 這是另一個(gè)第三方因素。直接看英偉達(dá)的數(shù)據(jù)我們可以發(fā)現(xiàn),對于 CNN,8x A100 的系統(tǒng)比 8x V100 的系統(tǒng)開銷低 5%。這意味著如果從 1x A100 提升到 8x A100 進(jìn)行加速,比如得到了 7.00x,那么從 1x V100 到 8x V100 只能給你 6.67x 的加速。對于 transformer,這個(gè)數(shù)字是 7%。


使用這些數(shù)字,我們可以從英偉達(dá)提供的直接數(shù)據(jù)中估計(jì)一些特定深度學(xué)習(xí)架構(gòu)的加速。與 Tesla V100 相比,A100 提供以下加速:


  • SE-ResNeXt101:1.43x

  • Masked-R-CNN:1.47x

  • Transformer(12 層,機(jī)器翻譯,WMT14 en-de):1.70x


這些數(shù)字略低于計(jì)算機(jī)視覺的理論估計(jì)值。這可能是由于較小的張量維度、準(zhǔn)備矩陣乘法所需的操作(如 img2col 或快速傅里葉變換,F(xiàn)FT)的開銷,或者無法使 GPU 飽和的操作(最終層通常相對較?。?。它也可能是特定架構(gòu)(分組卷積)的產(chǎn)物。


實(shí)際 transformer 估計(jì)值非常接近理論估計(jì)值。這可能是因?yàn)榫薮缶仃嚨乃惴ǚ浅:唵?。我將使用這些實(shí)際估算來計(jì)算 GPU 的成本效率。


需要注意的是,以上估算值適用于 H100、A100 和 V100 GPU。英偉達(dá)曾在「游戲用」的 RTX GPU 中偷偷降低了未宣布的性能:(1) 降低 Tensor Core 利用率,(2) 用于冷卻的風(fēng)扇,(3) 禁用點(diǎn)對點(diǎn) GPU 傳輸。與完整的 Hopper H100 相比,RTX 40 系列可能存在未明確的性能下降。


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: 芯片

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉