GPU 可以大大加速深度學習模型的訓練,因為它們專門用于執行神經網絡核心的張量運算。
由于 GPU 是昂貴的資源,因此充分利用它們至關重要。GPU 使用率、內存利用率和功耗等指標可以洞悉資源利用率及其改進潛力。提高 GPU 使用率的策略包括混合精度訓練、優化數據傳輸和處理以及在 CPU 和 GPU 之間適當劃分工作負載。可以使用 Neptune 等 ML 實驗跟蹤器監控 GPU 和 CPU 指標,使團隊能夠識別瓶頸并系統地提高訓練性能。
作為數據科學家或機器學習工程師,我們日常工作的一項任務是快速實驗并在不同設置下訓練多個模型,以找出最有效的模型。這個迭代過程通常是最昂貴且最耗時的階段之一,因此任何可能的優化都值得探索。
利用圖形處理單元 (GPU) 進行深度學習 (DL) 可以顯著加快訓練速度,這得益于 GPU 的并行處理能力和高內存帶寬。GPU 的內核專門用于執行 DL 算法核心的矩陣乘法。
GPU 通常是訓練流程中最昂貴的資源。因此,我們必須充分利用它們。這需要仔細關注 GPU 設置,例如利用率和內存分配。優化 GPU 實例可確保您的組織只支付其所需的費用,尤其是在使用云端服務時,因為賬單上分秒必爭。
在本文中,我們將首先探討一些關鍵的 GPU 指標,然后介紹優化 GPU 性能的技術。我們將探討批次大小、框架選擇以及數據流水線設計等因素如何深刻影響 GPU 的高效利用。在本文的后半部分,我們將了解如何監控 GPU、CPU 和內存等資源的利用率,從而確定 GPU 未能充分發揮其潛力的原因。
評估 GPU 性能的指標
為了了解 GPU 是否以最大潛能運行,我們依賴一些能夠提供寶貴見解的特定指標,包括利用率、使用量和溫度。對于我們大多數人可能使用的 NVIDIA GPU,當然也可以使用“nvidia-smi”命令行工具來檢查這些指標。
利用率
GPU利用率指標量化了 GPU 在深度學習模型訓練過程中的參與程度。該指標以百分比表示,表示在過去的采樣周期內執行了一條或多條指令(?CUDA 內核?)的時間比例。
記憶
GPU 內存在模型訓練過程中發揮著重要作用。它負責保存從模型參數到正在處理的數據的所有內容。
GPU 內存使用率指標反映了分配給 GPU 的內存量相對于其總內存容量的比例。通過觀察此指標,我們可以找到盡可能大的批處理大小,從而最大限度地利用 GPU 的并行處理能力。跟蹤此指標對于避免內存不足錯誤也至關重要。
GPU 內存利用率指標表示 GPU 內存控制器在過去一秒內用于讀取或寫入內存的時間百分比。較低的 GPU 內存利用率通常表示 GPU 的計算時間多于從內存中獲取數據的時間。降低此百分比的一種方法是增加批處理大小,以減少 GPU 獲取數據的時間。
我們還可以讓 GPU 同時執行計算和訪問內存。NVIDIA 的博客上有一篇關于如何在 CUDA 中重疊數據傳輸的精彩文章。
功率和溫度
跟蹤 GPU 的溫度和功耗可確保最佳性能,并防止過熱等問題。GPU 是功耗密集型硬件,運行時會產生熱量。因此,它們需要冷卻解決方案來將其溫度保持在可接受的水平。
GPU 溫度以攝氏度為單位,監控溫度對于確保 GPU 在可接受的溫度范圍內運行至關重要。高溫會導致過熱問題,觸發 GPU 自動降低時鐘速度以防止進一步過熱,從而影響性能。
GPU 功耗指標反映了總用電量(以瓦特為單位)。該指標對于驗證 GPU 是否獲得最佳運行所需的功率至關重要,同時也是檢測潛在硬件問題(包括電源問題)的有效指標。
GPU性能優化技術
人們沉迷于使用強大的 GPU,卻很容易忘記高效管理這些資源的重要性。盡管 GPU 擅長并行計算,但如果分配和管理不當,其全部潛力可能會被浪費。?
在上一節中,我們介紹了一些可能表明未充分利用 GPU 資源的標準指標。讓我們來探索解決此問題并最大限度地利用 GPU 的有效策略。
增加批次大小以提高 GPU 利用率
如果在訓練時遇到 GPU 使用率低的問題,那么首先應該嘗試增加批次大小。可用的 GPU 內存限制了最大批次大小,超過該大小會觸發內存不足錯誤。
增加批次大小時需要考慮的另一個問題是,它可能會導致測試數據的準確率降低。最近,一項關于批次大小在訓練深度學習模型過程中影響的研究發現,設置較大的批次大小通常會導致訓練收斂到尖銳的最小值,從而導致泛化能力下降。
有效的解決方法,例如提高學習率或采用逐層自適應速率縮放(LARS)等技術,可以在不影響模型準確性的情況下允許更大的批量大小。
由于這些權衡,找到最佳批量大小通常需要采用反復試驗的方法來平衡正面和負面影響。
使用混合精度訓練來最大化 GPU 性能
神經網絡通過操作數值來運行,這些數值通常以 32 位或 64 位格式的浮點數表示。存儲數字的位數直接影響模型的計算效率和準確性。需要操作的位數越少,計算速度越快,但精度也越低。
混合精度訓練是模型訓練中采用的一種技術,它利用不同的浮點類型(例如 32 位和 16 位)來提高計算速度并減少內存占用,同時保持準確性。它通過以 16 位格式執行操作來實現計算加速,同時將模型的某些部分保留為 32 位格式以確保數值穩定性。
混合精度訓練通過降低所需內存、允許訓練更大的模型或設置更大的批次大小來提高 GPU 的使用率。它可將批次大小最多增加一倍,從而顯著提高 GPU 的利用率。
另一個顯著的優勢是減少了計算時間,因為 16 位運算將訪問的字節數減少了一半,從而減少了在內存受限的層(例如批量歸一化、激活和池化)上花費的時間。NVIDIA 聲稱,其 GPU 的 16 位運算吞吐量是 32 位的八倍。值得注意的是,計算能力達到7.0 或更高的 NVIDIA GPU 能夠從混合精度中獲得最顯著的性能提升。它們擁有專門用于 16 位矩陣運算的硬件單元,稱為Tensor Core。
我推薦這個混合精度訓練教程,以獲得更全面的介紹。
深度學習中的優化
請查看我們博客上探討深度學習優化方面的其他文章:
- 深度學習模型優化方法:深度學習模型表現出色,但需要大量計算資源。剪枝、量化和知識提煉等技術對于提高計算效率至關重要。
- 模型調整和超參數優化的最佳工具:系統地調整機器學習模型的超參數以提高其性能是任何機器學習工作流程中的關鍵步驟。
- 深度學習優化算法:訓練深度學習模型意味著解決優化問題:逐步調整模型以最小化目標函數。深度學習中使用了一系列優化器,每種優化器都針對基本梯度下降方法的一個特定缺陷。
優化數據管道以提高 GPU 利用率
為了最大限度地提高 GPU 利用率,我們必須確保 GPU 始終保持繁忙狀態,避免其處于空閑狀態并等待數據。為了實現這一目標,我們需要一個經過優化的數據流水線。
該流水線包含多個步驟。首先,數據樣本從存儲器加載到主內存,這需要輸入和輸出操作 (I/O)。隨后,數據進行預處理,主要在 CPU 上進行;最后,預處理后的數據被傳輸到 GPU 的內存中。
確保所有這些步驟高效執行至關重要。因此,讓我們深入研究 I/O 的具體細節,重點關注從存儲到主存以及從主存到 GPU 的數據傳輸。
優化數據加載
數據加載成本主要由 I/O 操作決定。由于 I/O 請求通常頻率較高,因此有效管理 I/O 操作對于機器學習工作負載至關重要。例如,在大型數據集上進行訓練時,數據可能分散在多個較小的文件中。在其他情況下,數據是增量收集的,例如從硬件傳感器收集。使用 GPU 時,I/O 可能成為瓶頸,因為向 GPU 提供數據的速度可能是一個限制因素,從而影響整個流水線的整體速度。
對于處理較小數據集的團隊來說,本地 SSD 驅動器可提供卓越的性能。然而,對于更大規模的深度學習任務,連接到 GPU 集群的遠程存儲解決方案必不可少。GPU 的快速處理能力與云存儲服務較慢的數據檢索速度之間的不匹配可能會造成性能瓶頸。解決此 I/O 瓶頸的一種方法是緩存頻繁訪問的數據,使其更靠近計算資源。這可以顯著提高處理大型數據集時的性能。
優化 CPU 和 GPU 之間的數據傳輸
關于數據的另一個重要考慮因素是 CPU 和 GPU 之間的傳輸速度。優化此速度的一個簡單方法是利用所謂的CPU 固定內存 (CPU-pinned memory),通過讓 CPU 寫入 GPU 可以直接訪問的內存部分,可以加快從 CPU 內存到 GPU 內存的數據傳輸速度。(此功能在PyTorch 的 DataLoader中可用,只需將 pin_memory 設置為 True 即可。)通過利用固定內存,還可以將數據傳輸與 GPU 上的計算重疊。
優化數據預處理
除了 I/O 和向 GPU 的數據傳輸之外,數據預處理也可能成為 GPU 利用率的瓶頸。在訓練階段,CPU 負責數據預處理,當一個或多個 CPU 達到其最大利用率時,就會出現瓶頸,導致 GPU 在等待 CPU 提供下一批訓練數據時處于部分空閑狀態。
我們可以通過多種方式來解決這個問題。一種方法是將預處理流程構建成可以離線完成的任務,例如在訓練開始之前的數據創建階段完成。將操作轉移到數據創建階段可以在訓練期間釋放一些 CPU 周期。
為了優化運行時間,將數據預處理流水線中的所有任務都遷移到離線似乎合乎邏輯。然而,這種方法對于訓練來說可能并不理想,因為在訓練過程中引入一定程度的隨機性對輸入樣本有益。例如,引入隨機旋轉和翻轉可以改善某些任務(例如對抗訓練)的結果。
解決數據預處理瓶頸的另一種方法是將數據操作轉移到 GPU 上。NVIDIA 提供了數據加載庫 (DALI),用于構建高度優化的數據預處理流水線,將特定任務(例如解碼、裁剪和調整圖像大小)卸載到 GPU 上。雖然這種方法提高了數據加載流水線的效率,但它也存在一個缺點,即會給 GPU 帶來額外的工作負載。
深度學習框架的選擇
在深度學習中,我們可以從多個框架中進行選擇,例如TensorFlow、PyTorch和JAX(所有這些框架也可在多后端框架Keras中使用)。
每個框架都有不同的性能特性,并采用各種技術來優化算法的實現。因此,同一算法在不同框架之間的性能可能會存在相當大的差異。
現在,在選擇框架時,可能會考慮各種各樣的標準,例如編碼的簡易性、靈活性、社區支持或學習曲線。但今天,我們將重點關注這些框架如何利用資源,尤其是 GPU。
值得注意的是,這些框架中沒有絕對的贏家,因為它們的 GPU 利用率會根據各種因素而波動,例如具體任務、數據集特征和神經網絡的架構。
2021 年發表的一篇研究論文比較了當時流行的不同深度學習框架。研究人員實現了不同的模型架構,例如 CNN 和 LSTM,并在 CIFAR-100 和 IMDB Reviews 等不同數據集上訓練模型,并觀察了不同的 CPU 和 GPU 指標。之后,他們還比較了模型的性能。研究人員發現,不同框架在 GPU 使用率、訓練時間和任務性能方面存在顯著差異。
不同框架的 GPU 使用情況比較分析。(a)此條形圖比較了不同框架在訓練期間的平均 GPU 利用率,突出顯示了使用不同數據集訓練 CNN 時效率的差異。(b)同樣,此條形圖還比較了不同框架在訓練 LSTM 期間的平均 GPU 利用率,顯示了使用不同數據集時效率的差異。|來源
優化 GPU 使用率的策略
了解 GPU、CPU 和內存等資源在訓練階段的利用情況,有助于優化訓練并最大限度地發揮 GPU 的性能。以下指南或許能幫助你們根據這些資源的使用情況識別潛在的瓶頸:?
- 如果GPU 利用率低而CPU 利用率高,則表明數據加載或預處理中存在潛在瓶頸。
- 如果注意到CPU 內存利用率較低,那么提高性能的快速方法是增加數據加載器使用的工作器數量。
- 如果GPU 利用率較低,并且盡管數據集足夠大,但 CPU 利用率仍然持續較低,則可能表明代碼中的資源利用率不夠理想。在這種情況下,需要探索并行化和代碼優化技術,并確保模型架構能夠高效地利用 GPU。
- 如果GPU 內存利用率較低,增加批量大小是提高資源利用率的潛在策略。
案例研究:使用neptune.ai監控和優化 GPU 使用情況
密切監控資源利用率(包括 CPU、GPU 和內存)會給我們的工作流程帶來額外的復雜性。Neptune等實驗跟蹤工具可以簡化這一流程,使我們的工作更輕松,并確保監控井然有序。
Neptune 會自動記錄系統指標,包括 CPU、GPU(僅限 NVIDIA)和內存使用情況等硬件消耗指標。此外,還可以將任何硬件指標記錄到 Neptune 中,并通過訓練腳本訪問這些指標。
Neptune 應用程序中的實時訓練監控
Brainly 如何使用 Neptune 優化其 GPU 使用情況
Brainly 是一個學習平臺,提供涵蓋所有學校科目的廣泛知識庫。Brainly 的視覺搜索團隊使用 Neptune 來跟蹤視覺內容提取 (VICE) 系統的訓練,以實現其“Snap to Solve”功能。這項核心功能允許用戶拍攝并上傳帶有疑問或問題的照片,并提供相關的解決方案。
在監控他們的訓練時,訓練過程中生成的圖表顯示,GPU 并未得到充分利用。事實上,它經常處于完全閑置狀態。
使用 Neptune 生成的 GPU 利用率圖。折線圖展示了 Brainly 視覺搜索團隊使用的各個 GPU 隨時間的變化情況。GPU 利用率經常會降至 25% 以下,有時甚至接近于零。這表明,通過提高 GPU 利用率,可以加快訓練速度,并更高效地利用 GPU 資源。
因此,Brainly 團隊徹底調查了這個問題,跟蹤了包括 CPU 在內的各種資源的使用情況。他們發現數據預處理流水線中的瓶頸是問題的根源。具體來說,他們注意到將圖像從 CPU 內存復制到 GPU 內存以及數據增強過程中的效率低下。為了解決這個問題,他們通過解壓縮 JPEG 圖像并將數據預處理從普通的 TensorFlow 和 Keras 轉換為NVIDIA DALI來優化數據增強任務。他們進一步選擇使用多處理而非多線程來處理作業,以創建更高效??的數據流水線。
團隊使用 Neptune 分析了每個優化步驟帶來的性能提升。
GPU 優化清單?
在本文中,我們研究了各種評估 GPU 使用率的方法,并探索了改進策略。用于訓練深度學習模型的最佳 GPU 設置和配置因具體任務而異,徹底的分析和系統的實驗是不可或缺的。
然而,在我參與的眾多項目中,以下優化 GPU 使用率的指南通常是有效的:
- 訓練期間務必監控 GPU 內存使用情況。如果仍有大量可用內存,請嘗試將批量大小設置得較大,同時使用不會因使用較大批量大小而影響模型性能的技術。
- 檢查GPU 是否支持混合精度并在訓練時實現它以獲得最佳性能。
- 跟蹤 CPU 和 GPU 的利用率,以識別數據管道中可能存在的瓶頸。仔細評估每項改進對整體性能的影響。
- 探索深度學習框架的功能并了解其實現細節。每個框架在 GPU 利用方面都展現出獨特的能力,受模型架構和任務類型等因素的影響。