[英]What does "RuntimeError: CUDA error: device-side assert triggered" in PyTorch mean?
我看過很多針對特定案例特定問題的具體帖子,但沒有基本的動機解釋。 這個錯誤是什么:
RuntimeError: CUDA error: device-side assert triggered
意思是? 具體來說,被觸發的斷言是什么,為什么會有斷言,以及我們如何逆向調試問題?
照原樣,此錯誤消息在診斷任何問題時幾乎沒有用,因為它似乎在說“某處接觸 GPU 的某些代碼”有問題。 Cuda 的文檔在這方面似乎也沒有幫助,盡管我可能是錯的。 https://docs.nvidia.com/cuda/cuda-gdb/index.html
當我將代碼轉移到 CPU 而不是 GPU 上工作時,出現以下錯誤:
IndexError: index 128 is out of bounds for dimension 0 with size 128
所以,也許代碼中可能有一個錯誤,由於某種奇怪的原因,它會以 CUDA 錯誤的形式出現。
當 CUDA 設備代碼運行時檢測到設備端錯誤時,會通過通常的CUDA 運行時 API 錯誤報告機制報告該錯誤。 設備代碼中通常檢測到的錯誤類似於非法地址(例如嘗試取消引用無效指針),但另一種類型是設備端斷言。 每當設備代碼中出現 C/C++ assert()
並且斷言條件為假時,都會生成此類錯誤。
由於特定內核而發生此類錯誤。 CUDA 中的運行時錯誤檢查必然是異步的,但可能至少有 3 種可能的方法可以開始調試它。
修改源代碼以有效地將異步內核啟動轉換為同步內核啟動,並在每次內核啟動后進行嚴格的錯誤檢查。 這將識別導致錯誤的特定內核。 此時,只需查看該內核代碼中的各種斷言就足夠了,但您也可以使用下面的步驟 2 或 3。
使用cuda-memcheck
運行您的代碼。 這是一個類似於“用於設備代碼的 valgrind”的工具。 當您使用cuda-memcheck
運行代碼時,它往往會運行得更慢,但運行時錯誤報告將得到增強。 通常最好使用-lineinfo
編譯您的代碼。 在這種情況下,當觸發設備端斷言時, cuda-memcheck
將報告斷言所在的源代碼行號,以及斷言本身和錯誤的條件。 您可以在此處查看使用它的演練(盡管使用非法地址錯誤而不是assert()
,但使用assert()
的過程將是相似的。
也應該可以使用調試器。 如果您使用諸如cuda-gdb
之類的調試器(例如在 linux 上),那么調試器將具有回溯報告,該報告將指示斷言在哪一行被擊中。
如果 CUDA 代碼是從 python 腳本啟動的,則可以使用cuda-memcheck
和調試器。
至此,您已經發現了斷言是什么以及它在源代碼中的位置。 為什么它在那里無法籠統地回答。 這將取決於開發人員的意圖,如果沒有注釋或其他明顯的,您將需要一些方法來以某種方式直覺。 “如何向后工作”的問題也是一個通用的調試問題,並非特定於 CUDA。 您可以在 CUDA 內核代碼中使用printf
,也可以使用cuda-gdb
類的調試器來協助完成此操作(例如,在斷言之前設置斷點,並檢查機器狀態 - 例如變量 - 當斷言即將被擊中時) .
對於較新的 GPU,您可能希望使用compute-sanitizer
而不是cuda-memcheck
。 它以類似的方式工作。
在我的情況下,這個錯誤是因為我的損失函數只接收 [0, 1] 之間的值,而我正在傳遞其他值。
所以,標准化我的損失函數輸入,解決這個問題:
saida_G -= saida_G.min(1, keepdim=True)[0]
saida_G /= saida_G.max(1, keepdim=True)[0]
閱讀: 鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.