You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中TFLite模型推理报Fatal signal 11错误的解决方法

解决YOLOv4 TFLite在Android上的SIGSEGV段错误

核心原因分析

Fatal signal 11 (SIGSEGV) 是内存访问越界错误,你的代码中主要存在输入输出尺寸不匹配、Bitmap缩放错误两个关键问题,同时可能伴随模型转换或Interpreter初始化的问题。


解决方案步骤

1. 修正输入Bitmap尺寸,避免像素读取越界

你的代码中没有将输入图像缩放到模型要求的416x416,导致getPixels读取超出Bitmap范围的像素,触发内存错误:

// 修改createBoundingBox方法中的resizedImage创建逻辑
public void createBoundingBox(Bitmap image){
    // 强制将图像缩放到模型要求的416x416
    Bitmap resizedImage = Bitmap.createScaledBitmap(image, 416, 416, true);
    try {
        MappedByteBuffer tfliteModel = loadModelFile();
        TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 416, 416, 3}, DataType.FLOAT32);
        ByteBuffer byteBuffer = convertBitmapToByteBuffer(resizedImage);
        inputFeature0.loadBuffer(byteBuffer);
        
        // 后续代码...
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// 同时修正convertBitmapToByteBuffer方法,固定输入尺寸为416
private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap){
    final int INPUT_SIZE = 416;
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * INPUT_SIZE * INPUT_SIZE * 3);
    byteBuffer.order(ByteOrder.nativeOrder());
    int[] intValues = new int[INPUT_SIZE * INPUT_SIZE];
    
    // 确保读取的像素范围不超过Bitmap尺寸
    bitmap.getPixels(intValues, 0, INPUT_SIZE, 0, 0, INPUT_SIZE, INPUT_SIZE);
    
    for (int i = 0; i < INPUT_SIZE; i++){
        for(int j = 0; j < INPUT_SIZE; j++) {
            int val = intValues[i * INPUT_SIZE + j];
            // 注意:部分YOLO模型要求输入为BGR格式,若推理结果异常可交换R和B的顺序
            byteBuffer.putFloat(((val >> 16) & 0xFF) * (1.f / 255)); // R通道
            byteBuffer.putFloat(((val >> 8) & 0xFF) * (1.f / 255));  // G通道
            byteBuffer.putFloat((val & 0xFF) * (1.f / 255));         // B通道
        }
    }
    return byteBuffer;
}

2. 修正模型输出尺寸,匹配实际模型结构

YOLOv4 TFLite模型的输出不是[1,416,416,3],通常是3个不同尺度的检测张量(比如针对COCO 80类,形状为[1,13,13,255]、[1,26,26,255]、[1,52,52,255])。硬编码错误的输出尺寸会导致内存越界:

// 替换手动创建输出张量的逻辑,动态获取模型输出形状
Interpreter tflite = new Interpreter(tfliteModel);
Object[] inputs = {inputFeature0.getBuffer()};
Map<Integer, Object> outputs = new HashMap<>();

// 遍历所有输出张量,动态创建对应尺寸的TensorBuffer
int outputCount = tflite.getOutputTensorCount();
for (int i = 0; i < outputCount; i++) {
    Tensor outputTensor = tflite.getOutputTensor(i);
    int[] outputShape = outputTensor.shape();
    TensorBuffer outputBuffer = TensorBuffer.createFixedSize(outputShape, outputTensor.dataType());
    outputs.put(i, outputBuffer.getBuffer());
}

// 执行推理
tflite.runForMultipleInputsOutputs(inputs, outputs);

// 后续处理输出时,根据实际输出形状解析检测结果
// List<Detection> detections = processModelOutputs(outputs);

3. 重新生成ML Model Binding代码(若使用自动生成)

如果使用Android Studio的ML Model Binding插件,重新导入模型:

  • 确保导入时选择正确的模型文件,插件会自动识别输入输出形状
  • 若生成的代码仍报错,检查模型是否转换正确:在Python中用以下代码验证模型的输入输出:
import tensorflow as tf
interpreter = tf.lite.Interpreter(model_path="yolov4.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
print("输入形状:", input_details[0]['shape'])
print("输出形状列表:", [d['shape'] for d in output_details])

将输出的形状对应到自动生成的代码中,确保没有不匹配的情况。

4. 优化Interpreter初始化配置

添加线程数和NNAPI设置,避免内存或性能问题:

// 创建Interpreter时添加配置选项
Interpreter.Options options = new Interpreter.Options();
options.setNumThreads(4); // 根据设备核心数调整
options.setUseNNAPI(true); // 启用硬件加速
Interpreter tflite = new Interpreter(tfliteModel, options);

内容的提问来源于stack exchange,提问作者Maël

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:12:55