pytorch多程序加速及程式碼優化
目標:優化程式碼,利用多程序,進行近實時預處理、網路預測及後處理:
本人嘗試了pytorch的multiprocessing,進行多程序同步處理以上任務。
from torch.multiprocessing import Pool,Manager
為了進行各程序間的通訊,使用Queue,作為資料傳輸載體。
manager = Manager()
input_queue = manager.Queue()
output_queue = manager.Queue()
show_queue = manager.Queue()
即將預處理程序處理後的影象放進 input_queue,而網路預測程序實時獲取 input_queue佇列中的資料,一旦放入,就從中取出,輸入網路:
while 1:
input = input_queue.get()
同理,將網路輸出放入output_queue,再由後處理程序實時獲取並進行後處理,處理後,放入show_queue
從而實現了多程序同步進行預處理、網路預測及後處理,加速了網路實時預測的表現。
問題及解決方案:
1. pytorch cuda報錯,re-initialization報錯問題:
習慣了在一開始將模型先載入進來放入gpu中,所以模型在主執行緒就完成了初始化,但是呼叫網路是在網路預測子程序進行的,就會導致跨程序重複初始化失敗。
解決方案:直接在子程序開始時初始化,其他程序可以設定個延時,等網路初始化好後再開始執行。
同理,資料輸入網路也是同樣的在子程序進行。
2. python3多程序程式設計,子程序不報錯問題:
一開始總是程式碼執行起來什麼都不出現,就開始各種debug,但因為python3中子程序不報錯,出錯了就卡在那裡,就每次自己找bug很麻煩,所以就急需子程序的報錯資訊。
解決方案: 用try except組合,來列印子程序中某段程式錯誤,如下:
try:
out = forward(input_img,model,1)
except Exception as error:
print(error)
3.程序完全不執行時,考慮是否是輸入設定的問題,即當單變數輸入時,後面要加都好,如:
pool.apply_async(load_frame,args=(input_queue,))
如果是pool.apply_async(load_frame,args=(input_queue))則該程序不會啟動執行。
4. 一開始想優化cv2.resize,想用gpu下的tensor的resize_代替,但發現這種方式和numpy.resize一脈相承啊,根本不是我們想要的resize,如果是變大的話,這種resize會直接按順序填,然後剩下的就填0,實在是太草率了。。。
解決方案:還沒有很好的替代方案,只找了一下,cuda::resize,但是好像貌似沒有python介面,要是混合程式設計好像有點小題大做,得不償失了。如果各位有較好的方案,歡迎指點迷津。