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