Libtorch報錯:terminate called after throwing an instance of ‘c10::Error’ what(): isTensor() INTERNAL ASSERT FAILED
報錯
問題出現在筆者想要將 yolov5 通過 PyTorch 的 C++ 接口 Libtorch 部署到樹莓派上。
完整報錯信息:
terminate called after throwing an instance of 'c10::Error'what(): isTensor() INTERNAL ASSERT FAILED at "/home/pisong/miniconda3/lib/python3.7/site-packages/torch/include/ATen/core/ivalue_inl.h":133, please report a bug to PyTorch. Expected Tensor but got Tuple
Exception raised from toTensor at /home/pisong/miniconda3/lib/python3.7/site-packages/torch/include/ATen/core/ivalue_inl.h:133 (most recent call first):
frame #0: c10::Error::Error(c10::SourceLocation, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) + 0x8c (0xffffbd05c83c in /home/pisong/miniconda3/lib/python3.7/site-packages/torch/lib/libc10.so)
frame #1: c10::IValue::toTensor() && + 0xfc (0xaaaaaf102548 in ./build/resnet50)
frame #2: main + 0x324 (0xaaaaaf0fe178 in ./build/resnet50)
frame #3: __libc_start_main + 0xe8 (0xffffb90e6090 in /lib/aarch64-linux-gnu/libc.so.6)
frame #4: <unknown function> + 0x22c34 (0xaaaaaf0fdc34 in ./build/resnet50)Aborted (core dumped)
相比于 Python 這種腳本語言,C/C++ 還是相對難調試的。沒有充足的經驗的話,在上面的報錯信息中是很難找到問題出在哪。
尋找問題
在 PyTorch 官方討論區的一個帖子中,一位網友遇到了相同的問題,有大佬解答說:
對比其給出的以下代碼:
在 Python 中
output, hidden = model(examples.to(“cpu”), hidden)
和在 C++ 中
at::Tensor output = module->forward({indata1, tuple}).toTensor();
很明顯,模型的輸出應該不是一個 Tensor,可能是一個列表或者元組什么的,這就是為什么報錯信息中會出現:
isTensor() INTERNAL ASSERT FAILED
即檢測到輸出并不是 Tensor。
回到筆者自己的問題中,也確實是這樣,本來這段 C++ 代碼是處理分類模型 ResNet50 的,輸出確實直接就是一個 Tensor 各類別分類概率。在轉換到檢測任務時筆者沒有做細致的檢查,而是直接將處理分類模型的代碼拿過來用了,從而導致了該報錯。
解決方案
明確了問題之后,解決方案就很清楚了。去確定一下自己模型的輸出到底是什么,然后在 C++ 代碼中用適當的數據類型接收處理即可。
Ref:
https://discuss.pytorch.org/t/terminate-called-after-throwing-an-instance-of-c10-error-what-istensor-for-lstm/50114