当前位置: 首页 > news >正文

在Ubuntu 20.04上编译OnnxRuntime C++库,我踩过的那些坑(附完整配置流程)

在Ubuntu 20.04上编译OnnxRuntime C++库:避坑指南与实战经验

当你在Ubuntu 20.04上尝试为C++项目集成OnnxRuntime时,可能会遇到各种意想不到的问题。作为一个在多个生产环境中部署过OnnxRuntime的开发者,我经历过几乎所有常见的编译陷阱。这篇文章不仅会提供完整的配置流程,更重要的是分享那些官方文档没有提及的"坑"和解决方案。

1. 环境准备:那些容易被忽视的细节

在开始编译OnnxRuntime之前,环境配置是第一个容易出错的环节。很多人以为简单地安装CMake和GCC就够了,但实际上远不止如此。

1.1 系统依赖的完整清单

首先,确保你的Ubuntu 20.04系统已经更新到最新状态:

sudo apt update && sudo apt upgrade -y

然后安装这些必需的依赖项:

sudo apt install -y build-essential cmake git python3-dev python3-pip libssl-dev libgtest-dev libgoogle-glog-dev libprotobuf-dev protobuf-compiler

注意libgtest-devlibgoogle-glog-dev虽然不是OnnxRuntime的直接依赖,但缺少它们会导致某些测试工具编译失败,即使你使用了--skip_tests选项。

1.2 Python环境的特殊要求

OnnxRuntime的构建系统实际上依赖Python环境,即使你只编译C++库。我推荐使用conda创建一个隔离环境:

conda create -n onnx_build python=3.8 conda activate onnx_build pip install numpy wheel

为什么选择Python 3.8?因为这是OnnxRuntime构建系统最稳定的支持版本。使用3.9或更高版本可能会导致一些难以诊断的构建错误。

2. 获取源代码:国内开发者的特殊挑战

直接从GitHub克隆OnnxRuntime仓库对国内开发者来说可能是个挑战。以下是几种可靠的替代方案。

2.1 使用镜像源

国内用户可以考虑从Gitee镜像克隆:

git clone --branch v1.12.1 --recursive https://gitee.com/mirrors/onnxruntime.git

重要提示--recursive参数必须加上,否则会缺少关键的子模块依赖。

2.2 子模块更新的问题

即使成功克隆了主仓库,子模块更新可能仍然会失败。这时可以手动更新:

cd onnxruntime git submodule sync git submodule update --init --recursive --jobs 8

如果某些子模块仍然无法获取,可以尝试修改.gitmodules文件,将相关URL替换为镜像地址。

3. 编译配置:参数选择的艺术

OnnxRuntime的build.sh脚本提供了大量配置选项,选择不当会导致编译失败或性能问题。

3.1 基础编译命令解析

一个典型的编译命令如下:

./build.sh --skip_tests --config Release --build_shared_lib --parallel $(nproc)

各参数含义:

  • --skip_tests:跳过测试编译,节省大量时间
  • --config Release:生成优化后的发布版本
  • --build_shared_lib:生成动态链接库而非静态库
  • --parallel $(nproc):使用所有CPU核心加速编译

3.2 CUDA支持的注意事项

如果需要CUDA支持,必须确保CUDA环境变量正确设置:

export CUDA_HOME=/usr/local/cuda-11.6 export CUDNN_HOME=/usr/local/cuda-11.6

然后添加编译选项:

./build.sh --use_cuda --cuda_version=11.6 --cudnn_home=$CUDNN_HOME --cuda_home=$CUDA_HOME

常见问题

  1. CUDA版本不匹配:OnnxRuntime 1.12.1官方支持CUDA 11.6,使用其他版本需要自行承担风险
  2. cuDNN路径错误:确保$CUDNN_HOME指向包含includelib64目录的路径

4. 安装与验证:确保一切就绪

编译完成后,安装过程看似简单,但有几个关键点需要注意。

4.1 安装到系统目录

cd build/Linux/Release sudo make install

默认安装路径是/usr/local,如果你想安装到自定义目录:

cmake -DCMAKE_INSTALL_PREFIX=/your/custom/path ..

4.2 验证安装是否成功

创建一个简单的测试程序test_onnx.cpp

#include <onnxruntime/core/session/onnxruntime_cxx_api.h> #include <iostream> int main() { Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test"); Ort::SessionOptions session_options; std::cout << "ONNX Runtime initialized successfully!" << std::endl; return 0; }

编译并运行:

g++ -std=c++17 test_onnx.cpp -o test_onnx -lonnxruntime ./test_onnx

如果看到成功消息,说明安装正确。如果遇到链接错误,检查/usr/local/lib是否在你的库路径中:

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

5. 高级技巧与性能优化

5.1 减少二进制体积

如果空间有限,可以移除不需要的Execution Provider:

./build.sh --disable_ml_ops --disable_contrib_ops --minimal_build

5.2 调试符号与性能分析

对于开发环境,你可能需要保留调试符号:

./build.sh --config Debug --build_shared_lib

或者同时保留优化和调试信息:

./build.sh --config RelWithDebInfo --build_shared_lib

5.3 交叉编译注意事项

如果你需要为其他平台编译,比如ARM架构:

./build.sh --config Release --arm64 --parallel $(nproc)

这需要提前安装交叉编译工具链:

sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu

6. 常见问题解决方案

6.1 "Could NOT find Protobuf"错误

这个问题通常发生在Protobuf版本冲突时。解决方案:

sudo apt remove libprotobuf-dev protobuf-compiler conda install -c conda-forge protobuf=3.20.1

然后重新运行cmake生成步骤。

6.2 内存不足导致的编译失败

OnnxRuntime编译是内存密集型操作。如果遇到OOM错误,尝试:

./build.sh --parallel 2 # 减少并行编译任务数

或者增加swap空间:

sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

6.3 Python绑定问题

即使你只需要C++库,构建系统仍可能尝试构建Python绑定。要完全禁用:

./build.sh --skip_tests --disable_pybind

7. 生产环境部署建议

7.1 容器化部署

考虑使用Docker确保环境一致性:

FROM ubuntu:20.04 RUN apt update && apt install -y build-essential cmake python3.8 COPY onnxruntime /onnxruntime WORKDIR /onnxruntime RUN ./build.sh --skip_tests --config Release --build_shared_lib --parallel $(nproc) RUN cd build/Linux/Release && make install

7.2 版本兼容性矩阵

不同OnnxRuntime版本对依赖的要求:

OnnxRuntime版本CUDA支持Python要求CMake最低版本
1.10.011.43.6-3.83.18
1.12.111.63.6-3.93.20
1.13.111.73.7-3.103.22

7.3 性能调优技巧

  1. 启用OpenMP支持:

    ./build.sh --enable_openmp
  2. 针对特定CPU架构优化:

    ./build.sh --cmake_extra_defines onnxruntime_USE_AVX2=ON
  3. 使用MKL加速数学运算:

    ./build.sh --use_mklml

在实际项目中,我发现最耗时的部分往往是第一次编译时的依赖下载和配置。建议在持续集成系统中缓存~/.cache/onnxruntime目录,可以显著减少后续构建时间。

http://www.jsqmd.com/news/714722/

相关文章:

  • 揭秘西门子、博世、华为HiCar联合提交的C++27协程提案附件B:37个真实产线故障案例中,86%源于await_suspend异常传播缺失
  • 如何高效保护键盘输入:iwck一键锁定键盘解决方案
  • AI Agent通信协议全景解读:MCP、ACP、A2A、ANP
  • AI原生应用框架lobu:快速构建与部署大语言模型应用
  • 告别调试烦恼:用C# Winform为欧姆龙PLC快速打造一个专属通讯调试助手
  • OBS虚拟背景插件终极指南:3步实现AI智能抠像的完整教程
  • 【含最新安装包】OpenClaw v2.6.6 安装指南|办公自动化神器
  • 5步掌握SD-PPP:Photoshop AI插件深度集成方案
  • Wan2.2-TI2V-5B终极部署指南:如何在本地运行720P高清AI视频生成
  • LangChain4j工作流编排深度解析:构建企业级AI智能体的5大核心模式
  • 春联生成模型-中文-base入门指南:避免‘福如东海’类固定搭配的创意突破技巧
  • 企业级开源项目管理平台:OpenProject深度应用与集成指南
  • 告别卡顿!STM32F407驱动ILI9341屏幕,用DMA+LVGL实现丝滑UI(RT-Thread实战)
  • LibreHardwareMonitor:终极硬件监控解决方案,让你的电脑健康一目了然
  • MediaFire批量下载工具:一键下载整个文件夹的终极指南
  • HTTPS 证书配置完全指南:从申请到自动化续期
  • 2026年昆明代理记账与工商变更全生命周期服务深度评测:云南本土企业财税合伙人选型指南 - 优质企业观察收录
  • TDA4VM与J721E选型指南:手把手教你评估算力、成本与开发周期,避开‘印度支持’的坑
  • 从vfork到写时复制:深入Linux进程创建的底层机制与性能选择
  • 网络安全学习第172天
  • 别再只用mdadm了!试试用LVM命令lvcreate直接创建RAID5阵列(附详细参数解析)
  • C++ com编程学习详解
  • 别再死记硬背了!用Vector Davinci Configurator实战理解AutoSar RTE的S/R Port
  • 为什么你的C++控制模块通不过ISO 26262 ASIL-B评审?(2024最新SGS审核清单+12处隐性非符合项逐行标注)
  • 跨平台鼠标自动化:提升工作效率的智能解决方案
  • 2026年云南代理记账与昆明工商变更全生命周期服务深度横评指南 - 优质企业观察收录
  • 3步智能配置黑苹果:OpCore-Simplify零基础EFI生成解决方案
  • 告别反向传播?Hinton新论文里的Forward-Forward算法,到底是个啥?
  • Unity卡牌游戏实战:用贝塞尔曲线实现《杀戮尖塔》同款拖拽引导箭头(附完整C#脚本)
  • 避坑指南:UG NX二次开发中MoveObjectBuilder的5个常见错误与调试技巧