1. 程式人生 > >pytorch多程序加速及程式碼優化

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介面,要是混合程式設計好像有點小題大做,得不償失了。如果各位有較好的方案,歡迎指點迷津。