2. 开发环境搭建:交叉编译工具链、Python虚拟环境与推理库安装

说实话,模型移植最让人头疼的往往不是算法本身,而是环境搭建。我见过太多人在这一步卡上好几天——工具链版本不对、库冲突、路径配错,最后连个demo都跑不起来。这一章,我就带你把这些坑一个个填平。

2.1 交叉编译工具链安装

嵌入式设备资源有限,没法直接在板子上编译代码。我们得在PC上生成目标平台能运行的二进制文件——这就是交叉编译。说白了,就是用一台高性能的x86机器,编译出能在ARM或RISC-V芯片上跑的程序。

2.1.1 工具链选择

我个人习惯用Linaro提供的GCC工具链,稳定且社区活跃。根据目标平台选对应的版本:

目标架构 工具链名称 典型设备
ARMv7-A (32位) arm-linux-gnueabihf NVIDIA Jetson Nano, RK3288
ARMv8-A (64位) aarch64-linux-gnu Jetson Xavier NX, RK3588, 树莓派4
RISC-V 64 riscv64-linux-gnu 全志D1, 赛昉星光

2.1.2 安装步骤

以aarch64为例,我通常这样装:

# 下载工具链(以Ubuntu 20.04为例)
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/

# 配置环境变量(写入~/.bashrc)
export PATH=/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

# 验证安装
aarch64-linux-gnu-gcc --version
我曾经踩过的坑:工具链版本和内核版本不匹配。比如用gcc 9.x编译Linux 4.19内核,会出现奇怪的链接错误。建议先查目标板子的官方文档,确认推荐的gcc版本范围。

2.2 Python虚拟环境配置

做模型移植,Python环境经常要切换——训练用PyTorch 1.13,转ONNX需要onnxruntime 1.14,部署到TensorRT又得用特定版本的CUDA。如果不隔离,你会被依赖冲突折磨到怀疑人生。

2.2.1 为什么用虚拟环境?

你想想看,一个项目依赖numpy 1.21,另一个项目需要numpy 1.19。全局装的话,总有一个会挂。虚拟环境就是给每个项目一个独立的Python沙箱。

2.2.2 使用conda创建环境

我个人更推荐miniconda,轻量且包管理方便:

# 创建环境,指定Python版本
conda create -n defect_detection python=3.8

# 激活环境
conda activate defect_detection

# 安装基础依赖
pip install numpy==1.21.6 opencv-python==4.5.5.64 pillow==9.4.0

# 安装PyTorch(根据CUDA版本选)
pip install torch==1.13.1 torchvision==0.14.1 --index-url https://download.pytorch.org/whl/cu117

2.2.3 环境导出与复现

项目做完后,记得导出环境配置,方便别人或自己以后复现:

# 导出当前环境的所有包
conda env export > environment.yaml

# 别人拿到后,直接创建一模一样的环境
conda env create -f environment.yaml
小技巧:我习惯在项目根目录放一个requirements.txt和一个environment.yaml。前者给pip用户用,后者给conda用户用。团队协作时,这能省去很多“我这边跑不起来”的沟通成本。

2.3 ONNX Runtime安装

ONNX Runtime是微软开源的推理引擎,支持跨平台部署。我们的模型转成ONNX格式后,用它来做推理验证。

2.3.1 安装方式

根据目标平台选对应的包:

平台 安装命令 说明
x86_64 (PC) pip install onnxruntime-gpu==1.14.1 带CUDA加速
ARM64 (Jetson) pip install onnxruntime==1.14.1 Jetson自带CUDA,用CPU版即可
ARMv7 (树莓派) 从源码编译 性能受限,建议用TFLite替代

2.3.2 验证安装

import onnxruntime as ort

# 检查可用后端
print(ort.get_available_providers())
# 输出示例:['CUDAExecutionProvider', 'CPUExecutionProvider']

# 创建推理会话
session = ort.InferenceSession("model.onnx", providers=['CUDAExecutionProvider'])
print("ONNX Runtime 安装成功!")

关键点:ONNX Runtime的版本必须和ONNX模型导出时的opset版本兼容。我遇到过opset 15的模型在onnxruntime 1.12上跑不了,升级到1.14就好了。建议统一用opset 13或15,兼容性最好。

2.4 TensorRT库安装

TensorRT是NVIDIA的推理优化库,能把模型压榨到极致。对于工业缺陷检测这种实时性要求高的场景,几乎是必选项。

2.4.1 安装前检查

先确认你的硬件和驱动:

  • GPU:必须是NVIDIA,计算能力≥5.0(GTX 900系列以上)
  • 驱动版本:≥525.60.13(建议用最新稳定版)
  • CUDA版本:11.7或11.8(TensorRT 8.6要求)
  • cuDNN版本:8.6或8.9

2.4.2 安装步骤(以Ubuntu 20.04 + TensorRT 8.6为例)

# 1. 下载TensorRT的deb包(需要NVIDIA账号)
# 从 https://developer.nvidia.com/tensorrt 下载

# 2. 安装
sudo dpkg -i nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-11.8_1.0-1_amd64.deb
sudo apt-key add /var/nv-tensorrt-local-repo-ubuntu2004-8.6.1-cuda-11.8/*.pub
sudo apt-get update
sudo apt-get install tensorrt

# 3. 安装Python绑定
pip install tensorrt==8.6.1

# 4. 验证
python -c "import tensorrt as trt; print(trt.__version__)"
# 输出应为:8.6.1

2.4.3 交叉编译TensorRT(针对Jetson)

在Jetson上,TensorRT是预装的。但如果你需要自己编译特定版本:

# 在Jetson上直接安装(推荐)
sudo apt-get install nvidia-tensorrt

# 或者从源码交叉编译(不推荐,耗时很长)
# 需要先安装交叉编译工具链,然后配置CMake
cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
         -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
         -DCMAKE_SYSTEM_NAME=Linux \
         -DCMAKE_SYSTEM_PROCESSOR=aarch64
注意:TensorRT的版本必须和CUDA、cuDNN严格对应。我曾经因为CUDA 11.8配了TensorRT 8.5,结果模型序列化失败。查了半天才发现是版本不匹配。建议用nvidia-smi和nvcc --version先确认CUDA版本,再去NVIDIA官网查兼容矩阵。

2.5 环境验证与测试

所有东西装完后,跑一个完整的流程验证:

import torch
import onnx
import onnxruntime as ort
import tensorrt as trt

# 1. 创建一个简单的模型
class DummyModel(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.conv = torch.nn.Conv2d(3, 16, 3)
    def forward(self, x):
        return self.conv(x)

model = DummyModel()
dummy_input = torch.randn(1, 3, 224, 224)

# 2. 导出ONNX
torch.onnx.export(model, dummy_input, "test.onnx",
                  opset_version=13,
                  input_names=['input'],
                  output_names=['output'])

# 3. ONNX Runtime推理
ort_session = ort.InferenceSession("test.onnx")
ort_input = {ort_session.get_inputs()[0].name: dummy_input.numpy()}
ort_output = ort_session.run(None, ort_input)
print(f"ONNX Runtime 推理成功,输出shape: {ort_output[0].shape}")

# 4. TensorRT推理(需要GPU)
logger = trt.Logger(trt.Logger.WARNING)
builder = trt.Builder(logger)
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
parser = trt.OnnxParser(network, logger)

with open("test.onnx", "rb") as f:
    parser.parse(f.read())

config = builder.create_builder_config()
config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30)  # 1GB
serialized_engine = builder.build_serialized_network(network, config)

print("TensorRT 引擎构建成功!")
print("所有环境验证通过!")

如果这段代码能跑通,说明你的开发环境已经就绪。接下来就可以开始真正的模型移植工作了。

2.6 本章知识体系

下面这张图帮你理清整个环境搭建的脉络:

开发环境搭建知识体系 开发环境搭建 交叉编译工具链 Python虚拟环境 ONNX Runtime TensorRT ARM GCC RISC-V GCC conda pip CPU版 GPU版 PC版 Jetson版 核心原则 版本匹配 > 功能完整 > 性能优化