Android调用TFLite模型触发SIGFPE致命错误问题求助
问题根因
你遇到的SIGFPE (FPE_INTDIV)是整数除零错误,根因是代码里的输入张量尺寸和模型要求的输入尺寸完全不匹配,TFLite底层做维度计算时触发了非法运算:
你的模型要求输入尺寸为[1, 640, 480, 3](对应你创建的inputFeature0大小为6404803),但你在ImageProcessor里把输入图片缩成了1x1像素,处理后的张量尺寸只有[1, 1, 3],两者缓冲区大小完全不匹配,最终导致底层崩溃。
修复步骤
- 修改ResizeOp的缩放尺寸为模型要求的输入尺寸,确保预处理后的图片尺寸和模型输入对齐
- 输入预处理增加归一化操作,和模型训练时的预处理逻辑保持一致
- 将Interpreter初始化逻辑移出推理方法,避免每次推理重复加载模型造成不必要的性能开销
- 增加输入输出缓冲区大小校验,提前规避尺寸不匹配问题
修复后代码示例
首先在Activity成员变量里初始化Interpreter,避免重复加载模型:
private Interpreter tflite; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 页面初始化时一次性加载模型 try { MappedByteBuffer tfliteModel = FileUtil.loadMappedFile(this,"converted_model.tflite"); tflite = new Interpreter(tfliteModel); } catch (IOException e) { e.printStackTrace(); } }
修改后的推理方法:
public void testFunctionInference(Bitmap inputBitmap){ // 确保Bitmap是ARGB_8888格式,符合TensorImage加载要求 Bitmap bitmap = inputBitmap.copy(Bitmap.Config.ARGB_8888, true); ImageProcessor imageProcessor = new ImageProcessor.Builder() // 改为模型要求的输入尺寸,参数顺序为[高, 宽] .add(new ResizeOp(640, 480, ResizeOp.ResizeMethod.BILINEAR)) // 归一化操作需和训练逻辑对齐,以下是归一化到0~1的示例,若需归一化到-1~1改为NormalizeOp(127.5f, 127.5f) .add(new NormalizeOp(0.0f, 255.0f)) .build(); TensorImage tensorImage = new TensorImage(DataType.FLOAT32); tensorImage.load(bitmap); tensorImage = imageProcessor.process(tensorImage); TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 640, 480, 3}, DataType.FLOAT32); // 提前校验输入缓冲区大小是否匹配,避免底层崩溃 if (tensorImage.getBuffer().capacity() != inputFeature0.getBuffer().capacity()) { Log.e("InferenceError", "输入缓冲区大小不匹配,请检查Resize尺寸和模型输入要求"); return; } tflite.run(tensorImage.getBuffer(), inputFeature0.getBuffer()); // 此处添加输出结果处理逻辑 }
额外注意事项
- 如果你的模型输入格式是CHW(通道在前,即
[1, 3, 640, 480]),需要额外添加TransposeOp调整维度顺序 - Activity销毁时记得调用
tflite.close()释放模型资源
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

