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

调用TFLite C++ API的Invoke方法触发段错误问题求助

TFLite C++ API调用时process方法Invoke()触发段错误

问题现象

调用TFLite C++ API解释器时,构造函数中能成功加载模型并通过虚拟图像完成权重初始化,但在process方法中调用interpreter->Invoke()时触发Segmentation fault (core dumped)错误。将process中的代码移到构造函数则可正常运行,已确认process中能正常访问interpreter及输入输出张量详情,但Invoke()调用直接崩溃,无后续报错输出。

主cpp文件

#include "inference.hpp"
#include <iostream>

int main() {
  
    ObjectDetectionProcessor obj("/src/model.tflite");
    obj.process();

    return 0;
}

对应的hpp文件

#include <opencv2/opencv.hpp>

#include <fstream>
#include <string>
#include <vector>
#include <memory>
#include <iostream>

#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"

class ObjectDetectionProcessor {
public:
    ObjectDetectionProcessor(const std::string& model_path) {
                                
        auto model = tflite::FlatBufferModel::BuildFromFile(model_path.c_str());
        if (!model) {
            std::cout << "Failed to mmap model " << model_path << std::endl;
            exit(-1);
        }

        tflite::InterpreterBuilder(*model, resolver)(&interpreter);

        if (!interpreter) {
            std::cout << "Failed to construct interpreter" << std::endl;
            exit(-1);
        }

        if (interpreter->AllocateTensors() != kTfLiteOk) {
            std::cout << "Failed to allocate tensors!" << std::endl;
            exit(-1);
        }

        int input_index = interpreter->inputs()[0];
        input_tensor = interpreter->tensor(input_index);
        const uint input_width  = input_tensor->dims->data[2];
        const uint input_height = input_tensor->dims->data[1];
        const uint input_channels = input_tensor->dims->data[3];
        const uint input_type = input_tensor->type;

        // 获取量化参数
        input_scale = input_tensor->params.scale;
        input_zero_point = input_tensor->params.zero_point;

        is_initialized = false;

        int cv_type = (input_type == kTfLiteFloat32) ? CV_32FC3 : CV_8UC3; // 根据张量类型调整OpenCV图像类型
        
        // 创建指定尺寸和类型的全零虚拟图像
        cv::Mat dummy_frame = cv::Mat::zeros(input_height, input_width, cv_type);


        // 将虚拟图像传入解释器完成模型预热
        TfLiteTensor* input_data = interpreter->tensor(interpreter->inputs()[0]);
        
        std::memcpy(input_data->data.uint8, dummy_frame.ptr<uint8_t>(0), dummy_frame.total() * dummy_frame.elemSize());
        
        if (interpreter->Invoke() != kTfLiteOk) {
            std::cout << "Failed to warm up model!" << std::endl;
            exit(-1);
        }
        int output_index = interpreter->outputs()[0];
        output_tensor = interpreter->tensor(output_index);
        float* out_data = interpreter->typed_output_tensor<float>(0);

        is_initialized = true;

    }


    void process(){

        if (!is_initialized) {
            std::cout << "Model not initialized!" << std::endl;
            return;
        }

        // 从文件读取图像
        cv::Mat dummy_frame = cv::imread("/src/image.jpg", cv::IMREAD_COLOR);

        // 将图像缩放到模型输入尺寸
        cv::resize(dummy_frame, dummy_frame, cv::Size(input_tensor->dims->data[2], input_tensor->dims->data[1]));

        dummy_frame.convertTo(dummy_frame, CV_8UC3);


        // 获取输入输出张量
        TfLiteTensor* input_data = interpreter->tensor(interpreter->inputs()[0]);
        TfLiteTensor* output_data = interpreter->tensor(interpreter->outputs()[0]);

        std::memcpy(input_data->data.uint8, dummy_frame.ptr<uint8_t>(0), dummy_frame.total() * dummy_frame.elemSize());
        

        // 执行推理
        if (interpreter->Invoke() != kTfLiteOk) {
            std::cout << "Failed to invoke model!" << std::endl;
            return;
        }

        // 获取输出数据
        float* boxes = interpreter->tensor(interpreter->outputs()[0])->data.f;
        float* classes = interpreter->tensor(interpreter->outputs()[1])->data.f;
        float* scores = interpreter->tensor(interpreter->outputs()[2])->data.f;

    }


private:
    std::unique_ptr<tflite::FlatBufferModel> model;
    tflite::ops::builtin::BuiltinOpResolver resolver;
    std::unique_ptr<tflite::Interpreter> interpreter;
    TfLiteTensor* input_tensor = nullptr;
    TfLiteTensor* output_tensor = nullptr;
    float input_scale;
    int input_zero_point;
    bool is_initialized;

};

编译命令

g++ -g -o out src/infer.cpp tensorflow/tensorflow/lite/delegates/external/external_delegate.cc   -I/usr/local/tensorflow/include -L/usr/local/tensorflow/lib -ltensorflowlite  -I/usr/local/include/opencv4/ -L/usr/local/lib/ -lopencv_core -lopencv_imgcodecs -lopencv_imgproc

GDB回溯信息

(gdb) backtrace
#0  0x0000713a12be8ab9 in ?? () from /usr/local/lib/libtensorflowlite.so
#1  0x0000713a1290aa7b in ?? () from /usr/local/lib/libtensorflowlite.so
#2  0x0000713a12bf1474 in ?? () from /usr/local/lib/libtensorflowlite.so
#3  0x0000713a12bf18ae in ?? () from /usr/local/lib/libtensorflowlite.so
#4  0x0000713a12bd8a52 in ?? () from /usr/local/lib/libtensorflowlite.so
#5  0x0000713a1297e730 in ?? () from /usr/local/lib/libtensorflowlite.so
#6  0x0000713a1297f57e in ?? () from /usr/local/lib/libtensorflowlite.so
#7  0x0000713a1298190b in ?? () from /usr/local/lib/libtensorflowlite.so
#8  0x0000713a12982137 in TfLiteStatus tflite::ops::builtin::conv::EvalImpl<(tflite::ops::builtin::conv::KernelType)2, (TfLiteType)3>(TfLiteContext*, TfLiteNode*) () from /usr/local/lib/libtensorflowlite.so
#9  0x0000713a129821fb in TfLiteStatus tflite::ops::builtin::conv::Eval<(tflite::ops::builtin::conv::KernelType)2>(TfLiteContext*, TfLiteNode*) () from /usr/local/lib/libtensorflowlite.so
#10 0x0000713a12b8f519 in tflite::Subgraph::Invoke() () from /usr/local/lib/libtensorflowlite.so
#11 0x0000713a12b9508c in tflite::Interpreter::Invoke() () from /usr/local/lib/libtensorflowlite.so
#12 0x00006152b80498d9 in ObjectDetectionProcessor::process (this=0x7ffdf3118b20) at src/inference.hpp:226
#13 0x00006152b8047aaf in main () at src/infer.cpp:12

调试信息

构造函数中调试输出:

(gdb) p interpreter
$2 = std::unique_ptr<tflite::Interpreter> = {get() = 0x6152ecc21760}
(gdb) p input_tensor
$4 = (TfLiteTensor *) 0x6152ecc3aaa0
(gdb) p input_data 
$5 = (TfLiteTensor *) 0x6152ecc3aaa0

process方法中调试输出:

(gdb) p input_tensor
$7 = (TfLiteTensor *) 0x6152ecc3aaa0
(gdb) p interpreter
$8 = std::unique_ptr<tflite::Interpreter> = {get() = 0x6152ecc21760}
(gdb) p input_data 
$9 = (TfLiteTensor *) 0x6152ecc3aaa0

问题原因与修复方案

核心问题

构造函数中创建的model是局部变量,类成员model未被赋值。当构造函数执行完毕后,局部model被销毁,而interpreter内部持有指向FlatBufferModel的引用,导致后续调用Invoke()时访问已释放的内存,触发段错误。

修复步骤

  1. 修正模型所有权:将构造函数中的局部model赋值给类成员,确保模型在对象生命周期内保持有效:

    // 替换原构造函数中的auto model = ...
    model = tflite::FlatBufferModel::BuildFromFile(model_path.c_str());
    
  2. 添加图像加载检查:process方法中读取图像后,需检查是否加载成功,避免空矩阵导致的未定义行为:

    cv::Mat dummy_frame = cv::imread("/src/image.jpg", cv::IMREAD_COLOR);
    if (dummy_frame.empty()) {
        std::cout << "Failed to read image!" << std::endl;
        return;
    }
    

内容的提问来源于stack exchange,提问作者Maja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:38:11