mmdetection distributed train死鎖問題
表現:設置某些參數,或在某些特定情況下GPU顯存占滿,但並不繼續運行,暫停程序后停在(pid, sts) = os.waitpid(self.pid, wait_flags)
參考:distributed all_reduce deadlocks in v1.1 · Issue #20630 · pytorch/pytorch (github.com), dist_train keep waiting when filter_empty_gt=False · Issue #2193 · open-mmlab/mmdetection (github.com)
原因:總之是,不同卡之間同步使用all_reduce函數時,由於卡之間的結果不一致,導致一直等待,具體詳細原因可能如下
- 不同卡之間loss的個數不同
- 不同卡之間的計算圖不同,導致有些參數有grad,有些參數沒有
- Pytorch 1.1 uses nccl 2.4.2 which has a known issue of hanging with long running jobs that was fixed for 2.4.6. NVIDIA/nccl@f40ce73
解決方案:
- export NCCL_LL_THRESHOLD=0或者更新nccl,可以忽略上面所有因素,使程序繼續運行,但是可能導致all_reduce產生不符合預期的結果,導致錯誤結果
- 上述第一個因素,很好解決,略過
- 上述第二個因素,找到backward調用的位置(如:mmdet/core/fp16/hooks.py L65),打印所有grad不為None的parameters的名字,據此找到計算圖不同的原因,並修改網絡結構
mmdetection RoIPool an illegal memory access was encountered
表現:使用mmdetection自帶RoIPool會隨機出現內存訪問越界的問題,如
roi_layer=dict(type='RoIPool', out_size=7)
參考:CUDA error: an illegal memory access was encountered still exists for RoiPool · Issue #2145 · open-mmlab/mmdetection (github.com),Maybe certain bugs exists in the RoIPool cuda source file "roi_pool_kernel.cu" · Issue #1007 · open-mmlab/mmdetection (github.com)
解決方案:
- 據說新版本已經修復了,可以考慮copy新版本RoIPool代碼,或者更改設置使用torchvision的RoIPool如下
roi_layer=dict(type='RoIPool', out_size=7, use_torchvision=True),