1.运行报错
前段时候推理时遇到一个非常奇怪的bug,ONNX模型在运行时会报ORT_RUNTIME_EXCEPTION的异常:
2.错误排查
继续运行,断点看到是在Session.Run()的时候报错。
断点逐语句跟踪没有更多详情的信息,重新看了好几遍代码后都没有看出任何问题。于是去看其他能正常推理的代码, 参数和流程都一致,不知道哪里导致的问题。
只能推断Session对象是全局变量,类的构造函数中初始化后,在其它地方调用Session.Run()方法引起。
// <summary>
/// ONNX模型的初始化。
/// </summary>
/// <param name="modelFile">模型文件的绝对路径,可空,如果为空则从当前目录查找,默认文件名是model.onnx。</param>
/// <param name="threadNum">启用线程数</param>
ONNXDetect::ONNXDetect(std::string modelName, int threadNum) {
string modelPathStr;
if (!FindModel(modelName, modelPathStr))
throw exception("未找到模型文件");
初始化环境
Ort::SessionOptions sessionOptions;
sessionOptions.SetIntraOpNumThreads(threadNum);
启用所有可能的优化。
sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
env=Ort::Env(ORT_LOGGING_LEVEL_ERROR, "test");
//string 转 wchart_t;
wchar_t* wc = new wchar_t[modelPathStr.size()];
//wc指向的内存区域存储这wchar_t类型的 string。
swprintf(wc, modelPathStr.size() + 1, L"%S", modelPathStr.c_str()); //注意大写
session = new Ort::Session(env, wc, sessionOptions);
}
///运行推理
vector<Value> ONNXDetect::Detect(Mat src)
{
//预处理。
PreProcessRBC(src, inputData);
array<int64_t, 4> input_shape{ 1, 3, inputHeight, inputWidth };
MemoryInfo allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
Value input = Value::CreateTensor<float>(allocator_info, inputData.data(),
inputData.size(), input_shape.data(), input_shape.size());
vector<Value> output = session->Run(RunOptions{ nullptr }, inputNames, &input,
inputBatch, outputNames, outputBatch);
return output;
}
花了点时间终于逐步对比排查发现是初始化Session的变量Env对象的问题:
不知为何,如果env设置为局部变量,Session对象为全局变量,env初始化Session就会异常。
3.解决方法
方法1:Env对象的的初始化在这里是局部变量,需要把这个对象设置为全局变量 。
方法2:不把这个对象设置为全局变量,只在头文件.h中定义一个空的Env对象,也能正常运行。
希望对遇到相同问题的人有帮助。
本文含有隐藏内容,请 开通VIP 后查看