ONNX 运行时报错 ORT_RUNTIME_EXCEPTION Ort::Exception 未经处理的异常

1.运行报错

前段时候推理时遇到一个非常奇怪的bug,ONNX模型在运行时会报ORT_RUNTIME_EXCEPTION的异常:

ONNX 运行时报错 ORT_RUNTIME_EXCEPTION Ort::Exception 未经处理的异常_第1张图片

2.错误排查

继续运行,断点看到是在Session.Run()的时候报错。

ONNX 运行时报错 ORT_RUNTIME_EXCEPTION Ort::Exception 未经处理的异常_第2张图片断点逐语句跟踪没有更多详情的信息,重新看了好几遍代码后都没有看出任何问题。于是去看其他能正常推理的代码, 参数和流程都一致,不知道哪里导致的问题。

只能推断Session对象是全局变量,类的构造函数中初始化后,在其它地方调用Session.Run()方法引起。

// 
/// ONNX模型的初始化。
/// 
/// 模型文件的绝对路径,可空,如果为空则从当前目录查找,默认文件名是model.onnx。
/// 启用线程数
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 ONNXDetect::Detect(Mat src)
{
	//预处理。
	PreProcessRBC(src, inputData);
	 
	array input_shape{ 1, 3, inputHeight, inputWidth };
	MemoryInfo allocator_info = MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
	Value input = Value::CreateTensor(allocator_info, inputData.data(),
		inputData.size(), input_shape.data(), input_shape.size());

	vector output = session->Run(RunOptions{ nullptr }, inputNames, &input,
		inputBatch, outputNames, outputBatch);

	return output;
}

花了点时间终于逐步对比排查发现是初始化Session的变量Env对象的问题:

不知为何,如果env设置为局部变量,Session对象为全局变量,env初始化Session就会异常

ONNX 运行时报错 ORT_RUNTIME_EXCEPTION Ort::Exception 未经处理的异常_第3张图片

3.解决方法

 方法1:Env对象的的初始化在这里是局部变量,需要把这个对象设置为全局变量

方法2:不把这个对象设置为全局变量,只在头文件.h中定义一个空的Env对象,也能正常运行。

ONNX 运行时报错 ORT_RUNTIME_EXCEPTION Ort::Exception 未经处理的异常_第4张图片

希望对遇到相同问题的人有帮助。

你可能感兴趣的:(AI,ai)