在深度學習訓練模型的過程中,同樣的代碼,同樣的設備,為何訓練速度會差距很大呢?我查了一下GPU利用率,發現在0-100%之間振蕩,原來跑得快也有這種情況,只不過為0的時間沒有這麼長,為什麼同樣的代碼會有這麼多差距呢?


可能是讀數據或者數據預處理的時間過長,讀數據部分可以嘗試把全部或者部分數據放在內存,也可以放固態上。

數據預處理部分有些變換是否可以固定,假如是圖像數據,有些resize或者padding的操作是否可以離線處理好。

當然,適當調整dataloader讀數據的線程數可能也會有幫助。


數據讀取跟不上GPU運算,想辦法提高數據讀取的效率,比如:打包成tf-record、增加worker、把一些複雜的CPU運算挪到GPU、原始圖片縮小一點(總不能一直讀2k大小的圖片然後resize到224吧,那還不如先把所有圖片resize到224再用worker去讀)


因為載入在內存的時間不一樣,GPU利用率跟CPU性能相關,如果伺服器用得人不多,又或者自己用,建議先將數據掛在緩存上,然後GPU利用率不說用滿,至少可以用上一大半


說個通用思路:一查、二定、三優化:

查:用timer、strace、chrome/trace等,看看那個位置消耗了時間,是CPU還是GPU

定位:

1 I/O狀態:數據吞吐慢,從磁碟到CPU時間長。

2 數據預處理:CPU預處理太長,GPU空閑。

3 網路本身:數據量小,循環多(導致數據搬運工作太多)

4 多卡檢查通信狀態。

5 驅動/版本升級:升級了版本,但運算元未做對應的修改

優化:

對定位問題進行對應的優化。

最後說一下,0—100跳變的利用率,這應該本身是一個粗糙的代碼,建議在github上找個同功能代碼對比一下


數據載入和預處理需要優化。可以試試DALI


大概率是讀取訓練數據的IO喂不飽GPU計算能力。最簡單的辦法,先把讀取數據的地方換成內存張量,隨機數據那種,先忽略正確性,只看GPU利用率。如果換成內存張量後,GPU利用率穩定了,那就是IO問題了。 想辦法優化即可。


時間充足的時候:

檢查數據集pipline是不是寫的有問題,直接讀圖的效率能不能和訓練的速度匹配。如果不能先試試增大batch,還不能的話,對數據輸入做序列化操作(圖像轉tfrecord),用tf.data api做數據輸入pipline,使用prefetch等等。

大多數時候:

終於跑起來!顯卡利用率低?顯卡利用率低和我模型有什麼關係(手動狗頭)。


推薦閱讀:
相关文章