4、开发环境搭建:交叉编译工具链安装、Python虚拟环境配置、ONNX Runtime与TensorRT的安装踩坑记录
说实话,每次开新课,我最怕的就是环境搭建这一章。
不是技术难,是坑多。而且每个坑都长得不一样。
我记得有一次给客户部署一个多模态模型,光环境就折腾了两天。最后发现是交叉编译工具链版本不对,跟板子的glibc不匹配。嗯,从那以后,我养成了一个习惯——先把环境搭好,再写代码。
这一章,我把这些年踩过的坑,一个一个说清楚。
4.1 交叉编译工具链:别小看这一步
交叉编译,说白了就是在你的PC上编译出能在ARM板子上跑的程序。
你想想看,你的开发机是x86架构,目标板是ARM架构。直接在板子上编译?慢得你想哭。尤其是编译ONNX Runtime这种大项目,板子上跑一天都未必能搞定。
4.1.1 工具链的选择
我个人习惯用Linaro提供的工具链。为什么?稳定,社区活跃,踩坑了有人管。
常见工具链对比
| 工具链 | 适用平台 | 我的评价 |
|---|---|---|
| Linaro GCC | ARMv7/ARMv8 | 最稳,推荐 |
| ARM GCC | ARM全系列 | 官方出品,但更新慢 |
| Buildroot | 自定义Linux | 适合深度定制,学习成本高 |
| Yocto | 企业级 | 功能强大,但太重了 |
我建议新手直接用Linaro。别折腾。
4.1.2 安装步骤
以ARMv8(aarch64)为例,我常用的安装方式:
# 下载工具链
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
# 解压到指定目录
tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz -C /opt/
# 配置环境变量
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
我曾经踩过的坑:
工具链版本跟板子的glibc不匹配。比如你的板子是glibc 2.28,工具链用的是2.27编译的,跑起来直接报错。解决办法:用板子自带的工具链,或者用Buildroot自己编译一套。
4.2 Python虚拟环境:隔离是美德
做嵌入式AI,Python环境经常乱成一锅粥。
一个项目用TensorFlow 1.x,另一个用2.x。不隔离?等着哭吧。
4.2.1 我推荐的方案
我个人习惯用 conda 管理虚拟环境。为什么?
- 能管理Python版本
- 包依赖解决能力强
- 跨平台支持好
但注意,在边缘设备上,conda可能装不上。这时候用 venv 或者 virtualenv 也行。
# 创建虚拟环境
python3 -m venv edge_ai_env
# 激活环境
source edge_ai_env/bin/activate
# 安装依赖
pip install numpy opencv-python pillow
小技巧:
在边缘设备上,pip源经常很慢。我习惯用清华源:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名
4.2.2 交叉编译Python包
这里有个大坑——很多Python包需要编译C扩展。
比如 numpy、opencv-python,在x86上直接pip install就行。但在ARM上?你得交叉编译。
我常用的做法:
- 在板子上用
pip download下载源码包 - 传到PC上交叉编译
- 把编译好的whl包传回板子安装
# 在板子上下载源码包
pip download numpy --no-binary :all: -d ./packages
# 在PC上交叉编译(需要设置好交叉编译环境)
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export LD=aarch64-linux-gnu-ld
pip wheel --no-deps ./packages/numpy-*.tar.gz
注意:
交叉编译Python包时,一定要确保目标板上的Python版本跟编译环境一致。否则会出现ABI不兼容的问题。我曾经因为这个折腾了一整天。
4.3 ONNX Runtime安装:看似简单,实则暗坑
ONNX Runtime,说白了就是把训练好的模型转成ONNX格式,然后用它来推理。
在边缘设备上,我们通常用 ONNX Runtime 的 Python 包,或者用 C++ 的 shared library。
4.3.1 Python版本安装
如果板子能联网,直接pip安装是最简单的:
pip install onnxruntime
但注意,这个装的是CPU版本。如果你要用GPU或者NPU加速,得装对应的包:
onnxruntime-gpu:NVIDIA GPU加速onnxruntime-openvino:Intel加速onnxruntime-tensorrt:NVIDIA TensorRT加速
我踩过的坑:
有一次在Jetson Nano上装 onnxruntime-gpu,结果发现它依赖的CUDA版本跟板子上的不一致。后来我改用 onnxruntime-tensorrt,才解决问题。所以,装之前一定要确认板子上的CUDA版本。
4.3.2 交叉编译ONNX Runtime
如果板子不能联网,或者你需要定制ONNX Runtime,就得交叉编译。
步骤大致如下:
# 1. 下载源码
git clone --recursive https://github.com/microsoft/onnxruntime.git
cd onnxruntime
# 2. 设置交叉编译参数
./build.sh --config Release \
--build_shared_lib \
--parallel \
--arm64 \
--cmake_extra_defines CMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake
# 3. 编译
make -j$(nproc)
注意:
交叉编译ONNX Runtime时,toolchain.cmake 文件一定要写对。尤其是 CMAKE_SYSROOT 和 CMAKE_STAGING_PREFIX 这两个变量。我见过有人因为 SYSROOT 指向了错误的目录,编译出来的库在板子上跑不起来。
4.4 TensorRT安装:性能与痛苦的平衡
TensorRT,NVIDIA的推理优化库。用好了,性能翻倍。用不好,编译到怀疑人生。
4.4.1 安装方式
TensorRT的安装方式有三种:
| 方式 | 适用场景 | 难度 |
|---|---|---|
| Deb包安装 | Ubuntu桌面版 | 低 |
| Tar包安装 | 嵌入式Linux | 中 |
| 源码编译 | 深度定制 | 高 |
在Jetson系列板子上,我建议用NVIDIA提供的 JetPack 安装。它会把TensorRT、CUDA、cuDNN一起装好,省心。
4.4.2 踩坑记录
嗯,说到TensorRT的坑,我能写一本书。
坑1:版本匹配
TensorRT、CUDA、cuDNN的版本必须严格匹配。差一个版本号,可能就编译不过。
我常用的版本组合:
- TensorRT 8.5 + CUDA 11.8 + cuDNN 8.6
- TensorRT 8.4 + CUDA 11.6 + cuDNN 8.4
坑2:Python包安装
TensorRT的Python包,不能直接用pip装。你得用Tar包里的whl文件:
# 找到TensorRT安装目录下的Python包
cd /opt/TensorRT-8.5.3.1/python
pip install tensorrt-8.5.3.1-cp38-none-linux_aarch64.whl
坑3:动态形状
TensorRT默认不支持动态输入形状。如果你的模型输入尺寸会变,得在构建引擎时设置 optimization profile。
我的建议:
刚开始用TensorRT时,先用固定尺寸跑通。等熟悉了,再搞动态形状。别一上来就挑战高难度。
4.5 环境验证:跑通第一个Demo
环境搭好了,怎么知道对不对?
跑一个简单的Demo验证一下。
# 验证ONNX Runtime
import onnxruntime as ort
print("ONNX Runtime version:", ort.__version__)
print("Available providers:", ort.get_available_providers())
# 验证TensorRT
import tensorrt as trt
print("TensorRT version:", trt.__version__)
如果这两行代码能跑通,恭喜你,环境搭好了。
如果报错,别慌。先看错误信息,八成是版本不匹配或者路径没设对。
最后说一句:
环境搭建是最磨人的一步。但这一步走稳了,后面就顺了。
我见过太多人,环境没搭好就急着写代码,最后花了两倍的时间来排查问题。
所以,慢慢来,比较快。
公众号:蓝海资料掘金营,微信deep3321