PyTorch | 加速模型訓練的妙招

引言

alt

提升機器學習模型的訓練速度是每位機器學習工程師的共同追求。訓練速度的提升意味著實驗周期的縮短,進而加速產品的迭代過程。同時,這也表示在進行單一模型訓練時,所需的資源將會減少。簡而言之,我們追求的是效率。

熟悉 PyTorch profiler

在進行任何優化之前,首先需要了解代碼中各個部分的執行時長。Pytorch profiler 是一款功能全面的訓練性能分析工具,能夠捕捉以下信息:

  • CPU 操作的耗時
  • CUDA 核心的運行時間
  • 內存使用情況的歷史記錄

這些就是你需要關注的所有內容。而且,使用起來非常簡單!記錄這些事件的方法是,將訓練過程封裝在一個 profiler 的上下文環境中,操作方式如下:

import?torch.autograd.profiler?as?profiler

with?profiler.profile(
??activities=[ProfilerActivity.CPU,?ProfilerActivity.CUDA],
??on_trace_ready=torch.profiler.tensorboard_trace_handler('./logs'),
)?as?prof:
??train(args)

之后,您可以啟動張量板并查看分析跟蹤。Profiler 提供了眾多選項,但最關鍵的是 "activities" 和 "profile_memory" 這兩個功能。盡管你可以探索其他功能,但請記住一個基本原則:啟用的選項越少,性能開銷也就越低。

例如,如果你的目的是分析 CUDA 內核的執行時間,那么最好的做法是關閉 CPU 分析和其他所有功能。這樣,分析結果會更貼近實際的執行情況。

為了讓分析結果更易于理解,建議添加一些描述代碼關鍵部分的分析上下文。如果分析功能沒有被激活,這些上下文就不會產生任何影響。

with?profiler.record_function("forward_pass"):
??result?=?model(**batch)

with?profiler.record_function("train_step"):
??step(**result)

這樣,您使用的標簽將在跡線中可見。因此,識別代碼塊會更容易。或者更精細的內部模式的前進:

with?profiler.record_function("transformer_layer:self_attention"):
??data?=?self.self_attention(**data)

...

with?profiler.record_function("transformer_layer:encoder_attention"):
??data?=?self.encoder_attention(**data,?**encoder_data)

了解 PyTorch traces

收集traces后,在張量板中打開它們。 CPU + CUDA 配置文件如下所示:

alt

立刻識別出任何訓練過程中的關鍵環節:

  • 數據加載
  • 前向傳播
  • 反向傳播

PyTorch 會在一個獨立線程中處理反向傳播(如上圖所示的線程 16893),這使得它很容易被識別出來。

數據加載

在數據加載方面,我們追求極致的效率,即幾乎不耗費時間。

原因在于,在數據加載的過程中,GPU 閑置不工作,這導致資源沒有得到充分利用。但是,由于數據處理和 GPU 計算是兩個獨立的部分,它們可以同時進行。

你可以通過查看分析器跟蹤中的 GPU 估計 SM 效率和 GPU 利用率來輕松識別 GPU 空閑的區域。那些活動量為零的區域就是我們需要注意的問題所在。在這些區域,GPU 并沒有參與任何工作。

解決這個問題的一個簡單方法是:

  • 在后臺進程中進行數據處理,這樣不會受到全局解釋器鎖(GIL)的限制。
  • 通過并行進程來同時執行數據增強和轉換操作。 如果你使用的是 PyTorch 的 DataLoader,通過設置 num_workers 參數就可以輕松實現這一點。如果你使用的是 IterableDataset,情況會稍微復雜一些,因為數據可能會被重復處理。不過,通過使用 get_worker_info() 方法,你仍然可以解決這個問題——你需要調整迭代方式,確保每個工作進程處理的是互不重疊的不同數據行。

如果你需要更靈活的數據處理方式,你可以考慮使用 multiprocessing 模塊來自己實現多進程轉換功能。

內存分配器

使用 PyTorch 在 CUDA 設備上分配張量時,PyTorch 會利用緩存分配器來避免執行成本較高的 cudaMalloccudaFree 操作。PyTorch 的分配器會嘗試復用之前通過 cudaMalloc 分配的內存塊。如果分配器手頭有合適的內存塊,它將直接提供這塊內存,而無需再次調用 cudaMalloc,這樣 cudaMalloc 只在程序啟動時調用一次。

但是,如果你處理的是長度不一的數據,不同前向傳播過程可能需要不同大小的中間張量。這時,PyTorch 的分配器可能沒有合適的內存塊可用。在這種情況下,分配器會嘗試通過調用 cudaFree 釋放之前分配的內存塊,以便為新的內存分配騰出空間。

釋放內存后,分配器會重新開始構建其緩存,這將涉及到大量的 cudaMalloc 調用,這是一個資源消耗較大的操作。你可以通過觀察 tensorboard profiler viewer 的內存分析部分來識別這個問題。

alt

請注意,代表分配器預留內存的紅線持續波動。這表明 PyTorch 的內存分配器在處理內存請求時遇到了效率問題。

當內存分配在沒有觸發分配器緊急情況下順利進行時,你會看到紅線保持平穩。

alt

本文由 mdnice 多平臺發布

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/45224.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/45224.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/45224.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

padStart方法用來格式化數據

在別人寫的代碼中看到的padStart方法,沒用過,淺淺記錄一下~ padStart方法的使用 padStart是 字符串類型的方法,可以用來格式化字符串,在字符串添加指定的字符以達到指定的長度,例如:可以用來格式化日期 …

SpringSecurity框架【認證】

目錄 一. 快速入門 二. 認證 2.1 登陸校驗流程 2.2 原理初探 2.3 解決問題 2.3.1 思路分析 2.3.2 準備工作 2.3.3 實現 2.3.3.1 數據庫校驗用戶 2.3.3.2 密碼加密存儲 2.3.3.3 登錄接口 2.3.3.4 認證過濾器 2.3.3.5 退出登錄 Spring Security是Spring家族中的一個…

Python爬蟲并輸出

1. Python爬蟲并輸出示例 下面是一個使用Python編寫的簡單網絡爬蟲示例,該爬蟲將抓取某個網頁(例如,我們假設為https://example.com,但請注意實際使用時我們需要替換為一個真實且允許抓取的網站)的標題(Ti…

機器學習(V)--無監督學習(三)EM算法

EM算法 極大似然估計 極大似然估計:(maximum likelihood estimate, MLE) 是一種常用的模型參數估計方法。它假設觀測樣本出現的概率最大,也即樣本聯合概率(也稱似然函數)取得最大值。 為求解方便,對樣本聯合概率取對…

工作理念分享

上份工作的上級,分享他的工作理念,做個整理: 1 士氣上要奮發向上有追求,最低限度當然是要恰飯,保證生活,最好是做一些事情,把錢掙了的同時也能有更多的收獲。 2 公司為社會,用戶創造…

華為HCIP Datacom H12-821 卷36

1.單選題 在PIM- SM中,以下關于RP 的描述,錯誤的是哪一選項? A、在PIM-SM中,組播數據流量不一定必須經過RP的轉發。 B、對于一個組播組來說,可以同時有多個RP地址,提升網絡可靠性。 C、組播網絡中,可以…

【BUG】已解決:JsonMappingException

已解決:JsonMappingException 歡迎來到英杰社區https://bbs.csdn.net/topics/617804998 概述: 沒有getter方法的實體的序列化,并解決Jackson引發的JsonMappingException異常。 默認情況下,Jackson 2只會處理公有字段或具有公有get…

vue 級聯下拉框選擇的思維

在原來的js的思維下,級聯下拉框的選擇往往是,先綁定一級下拉框的菜單,然后在該下拉框下onchange, 在onchange事件中獲取當前選項,然后綁定二級下拉框的數據,以此類推…… 在vue框架下應該改變思維,首先設置…

經典再現,回顧常見排序算法之冒泡排序,附Java源碼及優化改進實現

回顧一下排序算法,老酒裝新瓶,給自己的技能點做個回放。 排序(Sorting) 是計算機程序設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個有序的序列,也可以理解為高矮個站隊。 衡量排…

Renesas R7FA8D1BH (Cortex?-M85) 控制DS18B20

目錄 概述 1 軟硬件 1.1 軟硬件環境信息 1.2 開發板信息 1.3 調試器信息 2 FSP和KEIL配置 2.1 硬件接口電路 2.2 FSB配置DS18B20的IO 2.3 生成Keil工程文件 3 DS18B20驅動代碼 3.1 DS18B20介紹 3.2 DS18B20驅動實現 3.2.1 IO狀態定義 3.2.2 讀IO狀態函數 3.2.3…

OpenCV:python圖像旋轉,cv2.getRotationMatrix2D 和 cv2.warpAffine 函數

前言 僅供個人學習用,如果對各位朋友有參考價值,給個贊或者收藏吧 ^_^ 一. cv2.getRotationMatrix2D(center, angle, scale) 1.1 參數說明 parameters center:旋轉中心坐標,是一個元組參數(col, row) angle:旋轉角度…

Go-知識測試-模糊測試

Go-知識測試-模糊測試 1. 定義2. 例子3. 數據結構4. tesing.F.Add5. 模糊測試的執行6. testing.InternalFuzzTarget7. testing.runFuzzing8. testing.fRunner9. FuzzXyz10. RunFuzzWorker11. CoordinateFuzzing12. 總結 建議先看:https://blog.csdn.net/a1879272183…

一文入門【NestJs】Providers

Nest學習系列 ??一文入門【NestJS】 ??一文入門【NestJs】Controllers 控制器 🚩 前言 在NestJS的世界里,理解“Providers”是構建健壯、可維護的后端服務的關鍵。NestJS,作為Node.js的一個現代框架,采用了Angular的一些核…

Redis的安裝配置及IDEA中使用

目錄 一、安裝redis,配置redis.conf 1.安裝gcc 2.將redis的壓縮包放到指定位置解壓 [如下面放在 /opt 目錄下] 3.編譯安裝 4.配置redis.conf文件 5.開機自啟 二、解決虛擬機本地可以連接redis但是主機不能連接redis 1.虛擬機網絡適配器網絡連接設置為橋接模式…

VSCode上通過C++實現單例模式

單例模式實際上就是為了確保一個類最多只有一個實例,并且在程序的任何地方都可以訪問這個實例,也就是提供一個全局訪問點,單例對象不需要手動釋放,交給系統來釋放就可以了,單例模式的設計初衷就是為了在整個應用程序的…

vue 下拉菜單樹形結構——vue-treeselect的組件使用

參考: https://www.cnblogs.com/syjtiramisu/p/17672866.htmlhttps://www.cnblogs.com/syjtiramisu/p/17672866.html vue-treeselect的使用 - 簡書下載依賴 使用https://www.jianshu.com/p/459550e1477d 實際項目使用:

uni-app iOS上架相關App store App store connect 云打包有次數限制

相冊權限 uni-app云打包免費有次數 切換一個賬號繼續

使用SOAP與TrinityCore交互(待定)

原文:SOAP with TrinityCore | TrinityCore MMo Project Wiki 如何使用SOAP與TC交互 SOAP代表簡單對象訪問協議,是一種類似于REST的基于標準的web服務訪問協議的舊形式。只要必要的配置到位,您就可以利用SOAP向TrinityCore服務器發送命令。 …

Open3D 計算點云配準的精度和重疊度

目錄 一、概述 1.1計算配準精度 1.2計算點云重疊度 二、代碼實現 2.1關鍵函數 2.2完整代碼 三、實現效果 3.1原始點云 3.2計算結果 一、概述 在點云配準中,精度和重疊度是兩個重要的評價指標。精度通常用均方根誤差(RMSE)來衡量,而重疊度則表示兩個點云在…

centos環境啟動/重啟java服務腳本優化

centos環境啟動/重啟java服務腳本優化 引部分命令說明根據端口查詢服務進程殺死進程函數腳本接收參數 腳本注意重啟文檔位置異常 引 在離線環境部署的多個java應用組成的系統,測試階段需要較為頻繁的發布,因資源限制,沒有弄devops或CICD那套…