1. 程式人生 > 其它 >【轉載】 pytorch鎖死在dataloader(訓練時卡死)

【轉載】 pytorch鎖死在dataloader(訓練時卡死)

 

版權宣告:本文為CSDN博主「Totoro-wen」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/qq_32526087/article/details/106350530

 

 

=================================================

 

 

1.問題描述

 

 

 

 

 

2.解決方案

(1)Dataloader裡面不用cv2.imread進行讀取圖片,用cv2.imread還會帶來一系列的不方便,比如不能結合torchvision進行資料增強,所以最好用PIL 裡面的Image.open來讀圖片。(並不適用本例)


(2)將DataLoader 裡面的參變數num_workers設定為0,但會導致資料的讀取很慢,拖慢整個模型的訓練。(並不適用本例)
(3)如果用了cv2.imread,不想改程式碼的,那就加兩條語句,來關閉Opencv的多執行緒:cv2.setNumThreads(0)和cv2.ocl.setUseOpenCL(False)。加了這兩條語句之後,並不影響模型的訓練。(並不適用本例)
(4)這種情況應該是屬於pytorch多執行緒鎖死,在github上看到有該問題,但是沒有解決的。

 

參考建議
首先確保num_works數量低於CPU數量(如果使用Kubernetes,則設定為pod),但是設定得足夠高,使資料隨時可以用於下一次迭代。如果GPU在t秒內執行每個迭代,而每個dataloader worker載入/處理單個批處理需要N*t秒,那麼您應該將num_workers設定為至少N,以避免GPU停滯。當然,系統中至少要有N個cpu。



不幸的是,如果Dataloader使用任何使用K個執行緒的庫,那麼生成的程序數量就會變成num_workersK = NK。這可能比計算機中的cpu數量大得多。這會使pod節流,而Dataloader會變得非常慢。這可能導致Dataloader不返回批處理每t秒,導致GPU暫停。

避免K個執行緒的一種方法是通過OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 python train.py呼叫主指令碼。這就限制了每個Dataloader工作程式只能使用一個執行緒,從而避免了使機器不堪重負。你仍然需要有足夠的num_workers來滿足GPU的需要。

您還應該在_get_item__中優化您的程式碼,以便每個worker在較短的時間內完成其批處理。請確保worker完成批處理的時間不受從磁碟讀取訓練資料的時間(特別是當您從網路儲存中讀取資料時)或網路頻寬(當您從網路磁碟讀取資料時)的影響。如果您的資料集很小,並且您有足夠的RAM,那麼可以考慮將資料集移動到RAM(或/tmpfs)中,並從那裡讀取資料以進行快速訪問。對於Kubernetes,您可以建立一個RAM磁碟(在Kubernetes中搜索emptyDir)。


如果你已經優化了你的_get_item__程式碼,並確保磁碟訪問/網路訪問不是罪魁禍首,但仍然會出現問題,你將需要請求更多的cpu(為了一個Kubernetes pod),或者將你的GPU移動到擁有更多cpu的機器上。

另一個選項是減少batch_size,這樣每個worker要做的工作就會減少,並且可以更快地完成預處理。後一種選擇在某些情況下是不可取的,因為會有空閒的GPU記憶體不被利用。

你也可以考慮離線做一些預處理,減輕每個worker的負擔。例如,如果每個worker正在讀取一個wav檔案並計算音訊檔案的譜圖,那麼可以考慮離線預先計算譜圖,只從工作者的磁碟中讀取計算的譜圖。這將減少每個worker的工作量。
你也可以考慮將dataloader裡的設定pin_memory=False。
上述的方法來自here

 

 


————————————————