第三章:环境搭建与工具链
好,咱们直接进入正题。环境搭建这事儿,说难不难,说简单吧,我见过太多人在这一步卡上好几天。说白了,就是要把交叉编译工具链、Docker镜像、还有各家硬件的SDK都伺候好。今天我就把这几年的经验捋一捋,帮你少走弯路。
3.1 交叉编译工具链——你的代码翻译官
先聊聊交叉编译。你想想看,你的开发机是x86架构,但目标硬件是ARM或者别的架构。代码在x86上编译出来,直接扔到ARM上跑?跑不了的。这时候就需要交叉编译工具链。
我个人习惯用Linaro提供的工具链,稳定且社区活跃。安装其实不复杂:
# 以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 -xf gcc-linaro-*.tar.xz
sudo mv gcc-linaro-* /opt/
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin
嗯,这里要注意。环境变量最好写到 ~/.bashrc 里,不然每次开终端都要重新export。我在项目中遇到过有人忘了这步,编译出来的程序在板子上跑起来全是段错误,排查了半天才发现是工具链没配好。
3.2 Docker镜像构建——让环境可复现
Docker这东西,说白了就是给你的开发环境拍个快照。团队里有人环境坏了?把镜像拉下来重新跑一个容器就行。我建议每个项目都维护一个Dockerfile。
下面是我常用的一个基础Dockerfile模板:
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
wget \
python3-dev \
python3-pip \
libopencv-dev \
&& rm -rf /var/lib/apt/lists/*
# 安装交叉编译工具链
COPY gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz /opt/
RUN cd /opt && tar -xf gcc-linaro-*.tar.xz && \
ln -s /opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu /opt/cross-toolchain
ENV PATH="/opt/cross-toolchain/bin:${PATH}"
WORKDIR /workspace
构建镜像时,我习惯加上 --no-cache 参数,避免缓存导致依赖没更新。你想想看,要是因为缓存问题导致编译失败,那多冤。
3.3 目标硬件SDK安装——三巨头各有脾气
接下来是重头戏。Jetson、RK3588、Intel这三家,SDK安装方式完全不同。我一个个说。
3.3.1 NVIDIA Jetson 系列
Jetson用的是JetPack SDK。我个人建议用SDK Manager来装,图形化界面,省心。但如果你跟我一样喜欢命令行:
# 下载JetPack
wget https://developer.nvidia.com/embedded/jetpack
# 安装依赖
sudo apt-get install -y qemu-user-static
# 运行SDK Manager
./sdkmanager
安装完成后,你会得到CUDA、cuDNN、TensorRT这些好东西。我记得第一次在Jetson Nano上跑YOLOv5,TensorRT优化后推理速度从200ms降到了30ms,那感觉,真爽。
scp 传到板子上。直接在板子上编译?嗯,除非你很有耐心。
3.3.2 Rockchip RK3588
RK3588的SDK叫RKNN Toolkit。这玩意儿有点特殊,它依赖Python环境。安装步骤:
# 创建虚拟环境
python3 -m venv rknn_env
source rknn_env/bin/activate
# 安装RKNN Toolkit
pip install rknn-toolkit2-1.5.0-cp38-cp38-linux_x86_64.whl
# 验证安装
python -c "from rknn.api import RKNN; print('OK')"
我在项目中遇到过一个问题:RKNN的版本跟NPU驱动版本必须严格对应。有一次我升级了固件,忘了更新RKNN Toolkit,结果模型转换一直报错。折腾了两天才发现是版本不匹配。
3.3.3 Intel 系列(OpenVINO)
Intel这边,主要是OpenVINO Toolkit。安装方式比较友好,有在线安装和离线安装两种。我推荐离线安装,因为在线安装经常因为网络问题中断。
# 下载OpenVINO
wget https://storage.openvinotoolkit.org/repositories/openvino/packages/2023.3/linux/l_openvino_toolkit_ubuntu20_2023.3.0.20231005_x86_64.tgz
# 解压并安装
tar -xf l_openvino_toolkit_*.tgz
cd l_openvino_toolkit_*
sudo ./install.sh
# 设置环境变量
source /opt/intel/openvino_2023/setupvars.sh
Intel的OpenVINO有个好处:它支持把模型从各种框架(TensorFlow、PyTorch、ONNX)转换成IR格式。你想想看,这省了多少事。我有个项目,客户给的模型是PyTorch的,我直接用Model Optimizer转成IR,在Intel NUC上跑得飞起。
| 硬件平台 | SDK名称 | 安装方式 | 关键依赖 |
|---|---|---|---|
| Jetson | JetPack | SDK Manager / 命令行 | CUDA、cuDNN、TensorRT |
| RK3588 | RKNN Toolkit | pip安装 | Python 3.8、NPU驱动 |
| Intel | OpenVINO | 离线安装包 | CMake、Python 3.8+ |
3.4 环境验证——别等到最后才发现问题
环境搭好了,怎么知道对不对?我习惯写一个简单的测试脚本。比如,验证交叉编译工具链:
# test_toolchain.c
#include <stdio.h>
int main() {
printf("Hello from %s!\n", "Edge Device");
return 0;
}
# 编译
aarch64-linux-gnu-gcc test_toolchain.c -o test_toolchain
# 查看文件类型
file test_toolchain
# 输出应该是:ELF 64-bit LSB executable, ARM aarch64
对于Docker镜像,我建议跑一个简单的推理测试。比如用OpenCV读取一张图片,看看能不能正常处理。我在项目中遇到过Docker镜像里OpenCV编译时没开NEON优化,结果推理速度慢得离谱。后来在Dockerfile里加了 -DCMAKE_CXX_FLAGS="-march=armv8-a+simd" 才解决。
env_check.sh 脚本,把工具链版本、SDK路径、依赖库版本都打印出来。这样出了问题,一眼就能看出是哪个环节不对。
好了,环境搭建这部分就聊到这儿。说白了,工具链和SDK就是你的武器,武器不趁手,仗就没法打。下一章咱们开始真正接触推理框架的定制,到时候这些环境就派上用场了。