需求分析
算法那边提供的ONNX模型文件是YOLOX,leader想要将模型分为两个部分,卷积层和后处理。因为一般的AI芯片仅对常见的卷积等算子进行加速处理,对后处理中的操作不提供加速。所以前半通过芯片厂商提供的模型转换工具进行加速,后半部分有两种解决方案:1.使用c++手动实现 2.使用OnnxRuntime来执行后半部分
对于方案2存在一个问题是,开发板的存储空间较小,OnnxRuntime库文件体积过大,无法满足需求,需要进行精简编译
1. 完整编译OnnxRuntime
先完整编译一下,熟悉一下OnnxRuntime库的编译流程
1. git clone --recursive https://github.com/Microsoft/onnxruntime.git
cd onnxruntime
2. git submodule update --init --force --recursive
// 首先创建一个conda环境,因为./build.sh实际上调用的是./tools/cl_build/build.py
conda create -n onnxruntime python=3.8
pip install flatbuffers
conda activate onnxruntime
3 ./build.sh --skip_tests --config Release --build_shared_lib --parallel
由于onnxruntime依赖很多子项目模块,在CMake配置阶段会进行下载,如果不连外网很容易中断,可以通过给终端挂代理来解决。(注:网上有教程说可以通过修改.git/config文件来解决中断的问题,尝试之后还是经常会断,可能是我没修改对,可参考: https://zhuanlan.zhihu.com/p/411887386)
编译完成后路径为:build/Linux/Release/, 查看libonnxruntime.so.1.16.0文件大小为19.1Mb,通过测试可正常调用。
2. 可精简选项
可以看到官方也考虑到针对嵌入式开发的应用场景。
The most common scenario for customizing the ONNX Runtime build is for smaller footprint deployments, such as mobile and web.
有以下几种精简方案:
-
减少算子种类:
主要是根据ONNX文件生成所需的算子,官方提供了对应的python脚本,可以通过
python create_reduced_build_config.py ./onnx_file_name.onnx ./build.sh --skip_tests --config Release --build_shared_lib --parallel --include_ops_by_config ./xxx.config
-
减少能够支持的数据类型:’
选择是否支持float32,float16和int8。
-
最小构建
源码中有很多 if !define Minimal_Build 用来较少一些非必要的函数,但是仅支持ORT模型文件,即需要先使用官方提供给python脚本来将ONNX文件转为ORT模型文件
python ./convert_onnx_models_to_ort.py ./onnx_file_name.onnx --output_dir .
得到四个文件,两两对应
其中.ort文件用于模型推导,因为最小的编译的onnxruntime仅支持ort模型文件,不再支持onnx文件
.config文化用于编译过程中选择对应的算子来减下编译文件的体积
选择其中一个config文件用于编译,就要选择对应的ort文件用于模型推导
-
除此之外,还能够添加:
–skip_tests: 跳过测试文件
–disable_exceptions:禁止异常
–disable_ml_ops:禁止ML算子
–config MinSizeRel:最小编译
./build.sh --config=MinSizeRel --build_shared_lib --parallel --minimal_build --disable_ml_ops --disable_exceptions --disable_rtti --skip_tests --include_ops_by_config ./XX.with_runtime_opt.config
最终编译的ort库文件大小为1.09Mb
3. 验证
使用官方库和编译后的库,对比结果,确保编译文件正常可用。