Linux程序崩溃时的信号量(signal)说明_linux signal 4-CSDN博客
SIGILL 是当一个进程尝试执行一个非法指令时发送给它的信号。
ILL_ILLOPN:非法的操作数
常见原因有:
1、CPU架构不匹配
2、.so 文件被破坏,或者代码段被破坏导致;
3、主动崩溃,如 _builtintrap() 也会使用非法指令来实现。
但是这些原因应该都不太可能,看这行代码感觉可能是模拟器版本的问题
所以换了真机调试,真机调试上报了另一个指令SIGSEGV的错误:
SIGSEGV意味着一个进程执行了一个无效的内存引用,或发生段错误
SEGV_ACCERR:没有访问权限
仔细查看backtrace下的指令,发现有几行指令是pytorch包jni中so库的内容(忘记截图了),由于之前发生过opencv和pytorch的so库冲突的问题:opencv和pytorch的so库冲突(2 files found with path ‘lib/x86_64/libc++_shared.so‘ from inputs)-CSDN博客
当时在jniLibs/x86_64文件下放了opencv的libc++_shared.so,所以考虑是在加载pytorch模型的时候没有用到pytorch的so库。
把pytorch的libc++_shared.so放到jniLibs/arm64-v8a(真机架构)下,就没有出现指令问题了,但是不知道后续会不会出现opencv so库引起的指令问题。
看新的报错,至少模型可以正常加载了:
主要是这两个报错:
- java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wmt.keypoint_onlytest/com.wmt.keypoint_onlytest.MainActivity}: java.lang.RuntimeException: The following operation failed in the TorchScript interpreter.
- RuntimeError: expected scalar type Char but found Float.
看意思是推理过程中解释器发生了错误,这个错误是模型期望输入的数据类型与提供的输入张量的数据类型不匹配导致的,期望的数据类型是char,提供的是float。于是又回头看模型训练和构造数据集的代码,模型训练的输入tensor就是float,而且根本不可能是char,因为pytorch不支持。又在网上查了很久,根本查不到这个问题,类似的问题都是expected scalar type long(或者int) but found Float.
chatGPT说可能是输入张量的形状不匹配导致的,这个我也从头检查了,没问题。
卡了两天。。。。。。。
解决啦!
用这行代码代替了我自己写的inputTensor,就解决了。。。。。成功得到准确的输出张量。
final Tensor inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap,
TensorImageUtils.TORCHVISION_NORM_MEAN_RGB, TensorImageUtils.TORCHVISION_NORM_STD_RGB, MemoryFormat.CHANNELS_LAST);
总结:因为报错提示的是期待输入的数据类型为char,而找到的输入是float,并且我的输入张量也确实是float,所以一直以为是我模型的问题,没想过会是我的输入张量的问题。这篇文章pytorch模型运行到android手机上(仅使用pytorch+AndroidStudio)_android pytorch-CSDN博客
也是推理.pt模型,除了用的模型和他不一样,那就是输入不一样了,既然模型找不出问题,那就试试用他的方法计算输入张量吧,然后问题就解决了。
TensorImageUtils.bitmapToFloat32Tensor()其实是pytorch_android官方提供的方法,只是因为我的输入图片需要做一些其他的预处理,得把bitmap转成Mat, 所以就在Mat的基础上计算了inputTensor,还是我自己把问题搞复杂了(尴尬...)
补充:最后是在真机调试成功的,虚拟机还是报SIGILL 、ILL_ILLOPN的指令错误,应该是虚拟机版本太低了