[TOC]
文章参考:https://github.com/onnx/onnx
概述 环境搭建 PyPi 1 pip install onnx -i https://pypi.tuna.tsinghua.edu.cn/simple
Conda packages A binary build of ONNX is available from Conda , in conda-forge :
1 2 conda install -c conda-forge numpy protobuf==3.16.0 libprotobuf=3.16.0 conda install -c conda-forge onnx
You can also use the onnx-dev docker image for a Linux-based installation without having to worry about dependency versioning.
ONNX Runtime环境搭建 文章参考:https://onnxruntime.ai/
python版本环境搭建
1 2 3 4 pip install onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple # 可以指定版本号 (py36) frewen@freweniubuntu:~$ pip install onnxruntime==1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
Mac下C++的ONNX Runtime环境搭建 文章参考:https://juejin.cn/post/7120494957625868325
文章参考:https://blog.csdn.net/qq_44747572/article/details/121467657?spm=1001.2014.3001.5502
文章参考:https://blog.csdn.net/qq_44747572/article/details/120820964?spm=1001.2014.3001.5501
文章参考:https://github.com/luogantt/onnxruntime_cpp_demo
下载对应的依赖库
https://onnxruntime.ai/
https://github.com/microsoft/onnxruntime/releases
集成到我们项目工程中
添加dependence依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (BUILD_ONNX_LIB) set (ONNX_VERSION v1.14.1 ) set (ONNX_BASE_DIR ${LIB_DIR} /onnx/${ONNX_VERSION} /${TARGET_OS} -${TARGET_ARCH} -release) set (ONNX_INCLUDE_DIR ${ONNX_BASE_DIR} /include ) set (ONNX_LINK_DIR ${ONNX_BASE_DIR} /lib) set (ONNX_LIB onnxruntime) include_directories (${ONNX_INCLUDE_DIR} ) link_directories (${ONNX_LINK_DIR} ) message (STATUS "[Dependency] onnx ONNX_INCLUDE_DIR = ${ONNX_INCLUDE_DIR}" ) message (STATUS "[Dependency] onnx ONNX_LINK_DIR = ${ONNX_LINK_DIR}" ) message (STATUS "[Dependency] onnx ONNX_LIB = ${ONNX_LIB}" ) else () message (STATUS "[Dependency] NotBuild onnx dependence ignored" ) endif ()
参考集成的实例库
https://github.com/microsoft/onnxruntime-inference-examples
源码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class OnnxPredictor : public AbsPredictor {public : ~OnnxPredictor () override = default ; int init (const ModelInfo &model) override ; int doPredict (aura_cv::TensorArray &inputs, aura_cv::TensorArray &outputs) override ; int deInit () override ; private : Ort::Session session; Ort::MemoryInfo memoryInfo; size_t inputTensorSize; std::vector<float > inputTensorValues; std::vector<const char *> input_node_names = {"input" , "input_mask" }; std::vector<const char *> output_node_names = {"output" , "output_mask" }; std::vector<int64_t > input_node_dims = {10 , 20 }; };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 int OnnxPredictor::init(const ModelInfo &model) { if (model.blobs.size() != 1) { ALOGE(TAG, "Predictor model mem error, one blob needed! error model info:%s", model.version.c_str()); VA_RET(Error::MODEL_INIT_ERR); } auto *modelData = static_cast<const uint8_t *>(model.blobs[0].data); auto modelSize = static_cast<const size_t>(model.blobs[0].len); // onnxruntime setup onnxruntime的初始化 Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "example-model-explorer"); // 获取配置 Ort::SessionOptions session_options; // 使用1个线程执行op,若想提升速度,增加线程数 session_options.SetIntraOpNumThreads(1); // CUDA加速开启(由于onnxruntime的版本太高,无cuda_provider_factory.h的头文件,加速可以使用onnxruntime V1.8的版本) // OrtSessionOptionsAppendExecutionProvider_CUDA(session_options, 0); // 设置图优化的级别 // ORT_DISABLE_ALL = 0, // ORT_ENABLE_BASIC = 1, # 启用基础优化 // ORT_ENABLE_EXTENDED = 2, // ORT_ENABLE_ALL = 99 # 启用所有可能的优化 session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL); // 创建通过ONNX模型路径进行实例化的Session // Ort::Session session(env, "model_path", session_options); // 通过ONNX模型的原始数据和模型大小 session = Ort::Session(env, modelData, modelSize, session_options); // print model input layer (node names, types, shape etc.) Ort::AllocatorWithDefaultOptions allocator; // print number of model input nodes size_t num_input_nodes = session.GetInputCount(); // 初始化输入张量的大小 inputTensorSize = 10 * 20; inputTensorValues = std::vector<float>(inputTensorSize); for (unsigned int i = 0; i < inputTensorSize; i++) { inputTensorValues[i] = (float) i / (inputTensorSize + 1); } // create MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); } int OnnxPredictor::doPredict(aura_cv::TensorArray &inputs, aura_cv::TensorArray &outputs) { Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memoryInfo, inputTensorValues.data(), inputTensorSize, input_node_dims.data(), 2); assert(input_tensor.IsTensor()); std::vector<int64_t> input_mask_node_dims = {1, 20, 4}; size_t input_mask_tensor_size = 1 * 20 * 4; std::vector<float> input_mask_tensor_values(input_mask_tensor_size); for (unsigned int i = 0; i < input_mask_tensor_size; i++) input_mask_tensor_values[i] = (float) i / (input_mask_tensor_size + 1); // create input tensor object from data values auto mask_memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); Ort::Value input_mask_tensor = Ort::Value::CreateTensor<float>(mask_memory_info, input_mask_tensor_values.data(), input_mask_tensor_size, input_mask_node_dims.data(), 3); assert(input_mask_tensor.IsTensor()); std::vector<Ort::Value> ort_inputs; ort_inputs.push_back(std::move(input_tensor)); ort_inputs.push_back(std::move(input_mask_tensor)); // score model & input tensor, get back output tensor auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_node_names.data(), ort_inputs.data(), ort_inputs.size(), output_node_names.data(), 2); // Get pointer to output tensor float values float *floatarr = output_tensors[0].GetTensorMutableData<float>(); float *floatarr_mask = output_tensors[1].GetTensorMutableData<float>(); printf("Done!\n"); return 0; } int OnnxPredictor::deInit() { return 0; } }