RTX 40時代,給深度學習買的顯卡居然能保值9年?仔細一算繃不住了(1)
FP8 訓練帶來的速度提升可能要一統 AI 領域,但這是我要考慮的問題嗎?
深度學習對于算力的要求很高,對于個人來說,GPU 的選擇很大程度上決定了你的工作、學習體驗。顯卡既貴又復雜,如果想購買新的 GPU,哪些功能最重要?內存、核心、Tensor Core 還是緩存?如何做出性價比高的選擇?每出一代新 GPU 這些問題就要重新審視一番。
近日,華盛頓大學在讀博士 Tim Dettmers 通過一篇長文在 RTX 40 時代的背景下深入探討了這些問題,此文一出就獲得了陳天奇等人的轉推。
本文將解決常見的誤解,讓你直觀地了解如何看待 GPU 并提供建議,幫你做出適合自己的選擇。
這篇博文的結構如下:首先,我將解釋是什么讓 GPU 變快的,我將討論 CPU 與 GPU、Tensor Core、內存帶寬和 GPU 的內存層次結構,以及它們與深度學習性能的關系。我們將討論新的 NVIDIA RTX 40 Ampere GPU 系列的獨特功能。隨后我們將針對不同的場景提出 GPU 推薦。
與深度學習相關性最高的 GPU 規格
本節按每個組件的重要性排序。Tensor Core 是最重要的,其次是 GPU 的內存帶寬、緩存層次結構,然后才是 GPU 的純算力 FLOPS。
Tensor Core
Tensor Core(張量核心)是執行非常高效的矩陣乘法的微核心。由于任何深度神經網絡中最耗費算力的部分就是矩陣乘法,所以張量核心非常有用。它們非常強大,想搞深度學習,不推薦任何沒有 Tensor Core 的 GPU。
這里展示一個簡單的 A×B=C 矩陣乘法示例,其中所有矩陣的大小均為 32×32,計算模式在使用和不使用 Tensor Cores 時的樣子。這是一個簡化的示例,并不是編寫高性能矩陣乘法內核的確切方式,但它具有所有基礎知識。CUDA 程序員會把它作為第一個「草稿」,然后用雙倍緩沖、寄存器優化、占用優化、指令級并行等概念逐步優化它,這里不會一一討論。
要完全理解此示例,你必須了解循環的概念。如果處理器以 1GHz 運行,它每秒可以執行 10^9 個周期。每個循環代表一個計算機會。但大多數時候,操作需要的時間超過一個周期?;\統地說這里有一個隊列,下一個操作需要等待上一個操作完成。這也稱為操作的延遲。
以下是一些重要的操作延遲周期時間。這些時間數字每代 GPU 都不一樣,這里的適用于緩存相對較慢的 Ampere GPU:
全局內存訪問(多至 80GB):~380 個周期
L2 緩存:~200 個周期
L1 緩存或共享內存訪問(每個流式多處理器最多 128 kb):~34 個周期
融合乘法和加法,ab+c (FFMA):4 個周期張量核心矩陣乘法:1 個周期
每個操作總是由一組 32 個線程執行,它的集合被稱為線程 warp。warp 通常以同步模式運行 ——warp 中的線程必須相互等待。GPU 上的所有內存操作都針對 warp 進行了優化。例如,從全局內存加載以 32×4 字節的粒度發生,正好是 32 個浮點數,一個 warp 中的每個線程正好對應一個浮點數。我們最多可以在一個流式多處理器 (SM) 中擁有 32 個 warps = 1024 個線程,相當于一個 CPU 核心的 GPU。SM 的資源在所有活躍的 warp 之間分配。這意味著有時我們希望運行更少的 warp,以便每個 warp 擁有更多的寄存器 / 共享內存 / Tensor Core 資源。
對于以下兩個示例,我們假設擁有相同的計算資源。對于這個 32×32 矩陣乘法的小例子,我們使用 8 個 SM(大約是 RTX 3090 的 10%)和每個 SM 8 個 warp。
要了解循環延遲如何與每個 SM 的線程和每個 SM 的共享內存等資源一起發揮作用,我們現在來看一下矩陣乘法的示例。雖然以下示例大致遵循了使用和不使用 Tensor Core 的矩陣乘法的計算步驟序列,但請注意,這些示例非常簡化。矩陣乘法的真實案例涉及更大的共享內存塊和略有不同的計算模式。
沒有張量核的矩陣乘法
如果我們想要進行 A×B=C 矩陣乘法,其中每個矩陣的大小為 32×32,那么就要將重復訪問的內存加載到共享內存中,因為它的延遲大約低五倍(200 周期對 34 周期)。共享內存中的內存塊通常稱為內存塊或簡稱為塊。使用 232 warp 可以并行地將兩個 32×32 的浮點數加載到共享內存塊中。我們有 8 個 SM,每個 8 warp,因此由于并行化,我們只需要執行一次從全局到共享內存的順序加載,這需要 200 個周期。
要進行矩陣乘法,我們現在要從共享內存 A 和共享內存 B 加載一個包含 32 個數字的向量,并執行融合乘加 (FFMA)。然后將輸出存儲在寄存器 C 中。我們劃分工作,使每個 SM 進行 8 次點積 (32×32) 來計算 C 的 8 個輸出。為什么這恰好是 8(在舊算法中為 4)是非常技術性的。
這里推薦 Scott Gray 關于矩陣乘法的博文 (https://github.com/NervanaSystems/maxas/wiki/SGEMM) 來理解這一點。
這意味著我們有 8 次共享內存訪問,每次訪問花費 34 個周期和 8 個 FFMA 操作(并行 32 個),每個操作花費 4 個周期??偟膩碚f成本是:200 個周期(全局內存)+ 834 個周期(共享內存)+ 84 個周期(FFMA)= 504 個周期。
讓我們看看使用 Tensor Cores 的周期成本。
用 Tensor Core 進行矩陣乘法
使用 Tensor Core,我們可以在一個周期內執行 4×4 矩陣乘法。為此我們首先需要將內存放入 Tensor Core。與上面類似,我們需要從全局內存(200 個周期)中讀取并存儲在共享內存中。要進行 32×32 矩陣乘法,我們需要進行 8×8=64 個 Tensor Core 運算。單個 SM 有 8 個 Tensor Core。因此,有了 8 個 SM 我們就有了 64 個 Tensor Core—— 這正是我們需要的數量!我們可以通過 1 次內存傳輸(34 個周期)將數據從共享內存傳輸到 Tensor Core,然后執行這 64 個并行 Tensor Core 操作(1 個周期)。
這意味著 Tensor Cores 矩陣乘法的總成本,在這種情況下是:200 個周期(全局內存)+ 34 個周期(共享內存)+ 1 個周期(Tensor Core)= 235 個周期。
因此,我們通過 Tensor Core 將矩陣乘法成本從 504 個周期減少到了 235 個周期。在這個簡化的案例中,Tensor Cores 降低了共享內存訪問和 FFMA 操作的成本。借助新的 Hooper (H100) 和 Ada(RTX 40 系)架構,我們還擁有可以進一步加速此操作的張量內存加速器 (TMA) 單元。
用 Tensor Core 和 TMA 進行矩陣乘法
TMA 單元允許將全局內存加載到共享內存中,而無需用完寶貴的線程資源。因此當 TMA 執行異步傳輸時,線程可以專注于共享內存和 Tensor Core 之間的工作,就像這樣
TMA 從全局內存獲取內存到共享內存(200 個周期)。數據到達后,TMA 就會從全局內存中異步獲取下一個數據塊。這樣,線程從共享內存加載數據并通過張量核心執行矩陣乘法。線程完成后,它們等待 TMA 完成下一個數據傳輸,然后重復該序列。
由于異步性質,TMA 讀取的第二個全局內存已經在線程處理當前共享內存塊時進行。這意味著第二次讀取僅需 200 – 34 – 1 = 165 個周期。
由于我們進行了多次讀取,只有第一個內存訪問會很慢,所有其他內存訪問將與 TMA 部分重疊。因此平均而言,我們將時間減少了 35 個周期。
165 個周期(等待 TMA 完成)+ 34 個周期(共享內存)+ 1 個周期(Tensor Core)= 200 個周期。這又將矩陣乘法加速了 15%。
從這些示例中可以清楚地看出為什么下一個屬性內存帶寬對于配備 Tensor-Core 的 GPU 如此重要。由于全局內存是迄今為止使用 Tensor Core 進行矩陣乘法的最大周期成本,如果可以減少全局內存延遲,我們甚至可以擁有更快的 GPU。我們可以通過增加內存的時鐘頻率(每秒更多的周期,但也有更多的熱量和更高的供電需求)或增加可以在任何時間傳輸的元素數量(總線寬度)來做到這一點。
內存帶寬
我們已經知道 Tensor Core 是非??斓?,事實上,它們大部分時間都處于空閑狀態,因為它們正在等待內存從全局內存到達。例如,在使用巨大矩陣的 GPT-3 訓練期間(模型越大,對 Tensor Core 越友好)我們的 Tensor Core TFLOPS 利用率約為 45-65%,這意味著即使對于大型神經網絡也有大約 50% 時間處于閑置狀態。
所以當比較兩個有 Tensor Core 的 GPU 時,GPU 性能的最重要指標之一是它們的內存帶寬。例如 A100 GPU 的內存帶寬為 1,555 GB/s,而 V100 為 900 GB/s。因此,A100 與 V100 的加速比基本估計為 1555/900 = 1.73 倍。
L2 緩存 / 共享內存 / L1 緩存 / 寄存器
由于內存傳輸到 Tensor Core 是性能的限制因素,我們應當尋求更快的內存傳輸到 Tensor Cores 的方式。二級緩存、共享內存、一級緩存和使用的寄存器數量與該速度都是相關的。
為了執行矩陣乘法,我們利用了 GPU 的內存層次結構,從慢速全局內存到更快的 L2 內存,再到快速本地共享內存,再到快如閃電的寄存器。但是,內存越快,它就越小。
雖然從邏輯上講,L2 和 L1 內存相同,但 L2 緩存更大,因此檢索緩存行需要遍歷的平均物理距離更大。你可以將 L1 和 L2 緩存視為有組織的倉庫,可以在其中檢索項目。你知道物品在哪里,但是對于較大的倉庫來說,去那里平均需要更長的時間。這就是 L1 和 L2 緩存的本質區別:大 = 慢,小 = 快。
對于矩陣乘法,我們可以使用這種層次把結構分割開,用更快的內存塊來執行快速的矩陣乘法。為此,我們需要將大矩陣乘法分塊為更小的子矩陣乘法。這些塊稱為內存塊,或通常簡稱為塊(tile)。
我們在快速且接近流式多處理器 (SM,相當于 CPU 內核)的本地共享內存中對這些較小的塊執行矩陣乘法。對于 Tensor Cores 則更進一步:我們獲取每個塊并將這些塊的一部分加載到 Tensor Core 中,這些 Tensor Core 由寄存器直接尋址。L2 緩存中的矩陣內存塊比全局 GPU 內存(GPU RAM)快 3-5 倍,共享內存比全局 GPU 內存快約 7-10 倍,而 Tensor Cores 的寄存器比全局 GPU 內存快約 200 倍。
擁有更大的塊意味著我們可以重用更多的內存。事實上,你可以看到 TPU 的每個 Tensor Core 都有非常非常大的塊。因此,TPU 可以在每次從全局內存傳輸時重用更多的內存,這使得它們在矩陣乘法方面比 GPU 更高效。
每個塊大小取決于每個流式多處理器 (SM) 有多少內存,以及所有 SM 有多少二級緩存。我們在以下架構上有以下共享內存大?。?/span>
Volta (Titan V):128kb 共享內存 / 6 MB L2
Turing(RTX 20 系):96 kb 共享內存 / 5.5 MB L2
Ampere(RTX 30 系):128 kb 共享內存 / 6 MB L2
Ada(RTX 40 系):128 kb 共享內存 / 72 MB L2
顯然 Ada 有很大的 L2 緩存,允許更大的塊體量,這減少了全局內存訪問。例如在 BERT large 在訓練期間,任何矩陣乘法的輸入和權重矩陣都可以很好地適合 Ada 的 L2 緩存,更早期的英偉達 GPU 則不然。因此,數據只需從全局內存加載一次,然后可通過 L2 緩存使用,使 Ada 的這種架構的矩陣乘法速度提高約 1.5-2.0 倍。對于較大的模型,訓練期間的加速比較低,但存在某些最佳點可能會使某些模型更快。推理時,batch size 大于 8 也可以從更大的 L2 緩存中獲益匪淺。
Ada / Hopper 架構的深度學習性能
英偉達已經在廣泛的計算機視覺和自然語言理解任務中對 A100、V100 和 H100 進行了基準測試。不幸的是,英偉達的測試通過盡可能使用不同的 batch size 和 GPU 數量來確保這些數字不能直接比較,以支持 H100 更好的結果。因此從某種意義上說,基準數字部分是誠實的,部分是營銷數字。你可能會爭辯說使用更大的 batch size 是公平的,因為 H100/A100 有更多內存。盡管如此,為了比較 GPU 架構,我們應該評估具有相同 batch size 的無偏內存性能。
為獲得無偏估計,我們可以通過兩種方式擴展數據中心 GPU 結果:(1) 考慮 batch size 的差異,(2) 考慮使用 1 塊 GPU 與 8 塊 GPU 的差異。幸運的是,我們可以在英偉達提供的數據中找到對這兩種偏差的估計。
將 batch size 加倍可將 CNN 網絡的圖像 / 秒吞吐量提高 13.6%。在我的 RTX Titan 上對 transformer 的相同問題進行了基準測試,結果令人驚訝地發現了完全相同的結果:13.5%—— 這似乎是一個可靠的估計。
隨著我們在越來越多的 GPU 上并行化網絡,我們會因為一些網絡開銷而損失性能。A100 8x GPU 系統具有比 V100 8x GPU 系統(NVLink 2.0)更好的網絡(NVLink 3.0)—— 這是另一個第三方因素。直接看英偉達的數據我們可以發現,對于 CNN,8x A100 的系統比 8x V100 的系統開銷低 5%。這意味著如果從 1x A100 提升到 8x A100 進行加速,比如得到了 7.00x,那么從 1x V100 到 8x V100 只能給你 6.67x 的加速。對于 transformer,這個數字是 7%。
使用這些數字,我們可以從英偉達提供的直接數據中估計一些特定深度學習架構的加速。與 Tesla V100 相比,A100 提供以下加速:
SE-ResNeXt101:1.43x
Masked-R-CNN:1.47x
Transformer(12 層,機器翻譯,WMT14 en-de):1.70x
這些數字略低于計算機視覺的理論估計值。這可能是由于較小的張量維度、準備矩陣乘法所需的操作(如 img2col 或快速傅里葉變換,FFT)的開銷,或者無法使 GPU 飽和的操作(最終層通常相對較?。?。它也可能是特定架構(分組卷積)的產物。
實際 transformer 估計值非常接近理論估計值。這可能是因為巨大矩陣的算法非常簡單。我將使用這些實際估算來計算 GPU 的成本效率。
需要注意的是,以上估算值適用于 H100、A100 和 V100 GPU。英偉達曾在「游戲用」的 RTX GPU 中偷偷降低了未宣布的性能:(1) 降低 Tensor Core 利用率,(2) 用于冷卻的風扇,(3) 禁用點對點 GPU 傳輸。與完整的 Hopper H100 相比,RTX 40 系列可能存在未明確的性能下降。
*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。