4、环境搭建与开发板准备:安装交叉编译工具、NPU驱动、RKNN工具包,并验证基本运行
RK3588 的 NPU 性能测试并非在真空中进行,它依赖于一套完整、正确且版本匹配的软件栈。本章将聚焦于性能测试前的“最后一公里”——环境搭建。我们将系统性地完成交叉编译工具链、NPU 驱动以及 RKNN 工具包的安装与验证,确保后续的延迟与吞吐测试数据真实、可靠。整个流程的核心在于理解 宿主机(x86) 与 目标板(ARM64) 之间的协作关系,以及 NPU 软件栈各层级的依赖逻辑。
上图清晰地展示了性能测试环境的双端架构。宿主机负责模型转换、交叉编译与测试脚本开发,目标板则负责驱动加载与真实推理。本章将按照“工具链 → 驱动 → 工具包 → 验证”的顺序,逐步构建这一环境。
4.1 交叉编译工具链:构建 ARM64 测试程序的基石
核心原理
RK3588 的 SoC 基于 ARMv8.2-A 架构,其上运行的操作系统(通常为 Ubuntu 或 Debian for ARM)无法直接执行 x86 架构的二进制文件。交叉编译即在 x86 宿主机上,通过专门的编译器生成可在 ARM64 目标板上运行的机器码。对于 NPU 性能测试,我们不仅需要编译 C/C++ 测试程序,还需要确保链接器能够找到 NPU 运行时库(librknnrt.so)的头文件与动态库路径。
安装与配置流程
- 安装基础工具包:在宿主机执行
sudo apt-get update与sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu。该命令会安装 GNU 交叉编译器。 - 验证编译器:运行
aarch64-linux-gnu-gcc --version,确认输出为aarch64-linux-gnu-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0类似信息。 - 设置环境变量:为方便后续编译,建议在
~/.bashrc中添加export CROSS_COMPILE=aarch64-linux-gnu-与export CC=${CROSS_COMPILE}gcc。
aarch64-linux-gnu-pkg-config 或手动指定 --host=arm-linux-gnueabihf 参数,否则会出现“无法找到 -lstdc++”等链接错误。
案例拆解:编译一个最小 NPU 测试程序
假设我们编写了一个 npu_test.c,调用 RKNN API 查询 NPU 版本。编译命令如下:
${CROSS_COMPILE}gcc npu_test.c -o npu_test \
-I./rknn-toolkit2/rknpu2/runtime/Linux/librknn_api/include \
-L./rknn-toolkit2/rknpu2/runtime/Linux/librknn_api/aarch64 \
-lrknnrt -lpthread -lm
编译完成后,使用 file npu_test 检查输出,应显示 ELF 64-bit LSB executable, ARM aarch64。将该文件通过 scp npu_test user@板卡IP:/home/user/ 传输至目标板。
常见误区
- 误用宿主机 GCC:直接使用
gcc编译会生成 x86 二进制,在板卡上执行会报Exec format error。 - 动态库路径缺失:即使编译成功,运行时若找不到
librknnrt.so,需在板卡上设置export LD_LIBRARY_PATH=/path/to/lib。
4.2 NPU 驱动与运行时库:激活硬件加速的钥匙
核心原理
RK3588 的 NPU 由内核态驱动(负责内存管理、任务调度)与用户态运行时库(librknnrt.so,提供 API 接口)组成。驱动版本必须与内核版本匹配,而运行时库则需与驱动版本严格对应。Rockchip 官方发布的 rknpu2 驱动包中,包含了 driver 与 runtime 两个目录。
安装步骤
| 组件 | 版本要求 | 安装方式 |
|---|---|---|
| 内核驱动 | 需与内核版本匹配(如 5.10.x) | 将 driver/rknn.ko 拷贝至板卡,执行 insmod rknn.ko |
| 运行时库 | 0.9.3 及以上 | 将 runtime/Linux/librknn_api/aarch64/librknnrt.so 拷贝至 /usr/lib/ |
| 设备节点 | 自动创建 | 确认 /dev/rknpu 存在,若不存在则手动 mknod /dev/rknpu c 10 120 |
- 获取驱动包:从 Rockchip 官方 GitHub 或网盘下载
rknpu2压缩包。 - 加载驱动:在板卡上执行
sudo insmod rknn.ko,并通过dmesg | tail查看是否有rknn: RKNPU driver version: 0.9.3的日志。 - 设置动态链接:在
/etc/ld.so.conf.d/下新建rknn.conf,写入/usr/lib,执行sudo ldconfig。
Unknown symbol 错误。此时需使用与内核配套的驱动版本,或升级内核。
验证驱动状态
ls -l /dev/rknpu
cat /proc/rknpu/version
若输出 RKNPU driver: v0.9.3,说明驱动已正确加载。此步骤是后续所有性能测试的前提,驱动异常会导致 NPU 初始化失败或计算错误。
4.3 RKNN 工具包:模型转换与仿真的核心
核心原理
RKNN-Toolkit2 运行在 x86 宿主机上,负责将 TensorFlow、PyTorch、ONNX 等模型转换为 RK3588 NPU 可执行的 .rknn 格式。该工具包还提供 模拟器 功能,可在 x86 上模拟 NPU 推理,用于快速验证模型精度,但模拟器性能数据不能作为真实 NPU 性能参考。与之配套的 rknn-toolkit-lite2 则运行在 ARM 板卡上,提供 Python API 直接调用 NPU。
安装流程
- 创建虚拟环境:
python3 -m venv rknn_env && source rknn_env/bin/activate。 - 安装依赖:
pip install numpy==1.24.3 opencv-python==4.8.1.78(版本需与工具包要求一致)。 - 安装 RKNN-Toolkit2:
pip install rknn_toolkit2-1.6.0-cp38-cp38-linux_x86_64.whl。 - 验证安装:执行
python -c "from rknn.api import RKNN; print('OK')"。
案例拆解:ONNX 模型转换与板卡部署
以 YOLOv5s 为例,转换脚本核心代码如下:
from rknn.api import RKNN
rknn = RKNN()
# 配置 NPU 目标平台
rknn.config(target_platform='rk3588', optimization_level=3)
# 加载 ONNX 模型
rknn.load_onnx(model='yolov5s.onnx')
# 构建 RKNN 模型(可在此阶段进行量化)
rknn.build(do_quantization=False)
# 导出模型
rknn.export_rknn('yolov5s.rknn')
# 在模拟器上验证(可选)
rknn.init_runtime(target=None)
# 释放资源
rknn.release()
转换完成后,将 .rknn 文件与 rknn-toolkit-lite2 的 librknnrt.so 一并部署至板卡。在板卡上使用 lite2 加载模型:
from rknnlite.api import RKNNLite
rknn_lite = RKNNLite()
rknn_lite.load_rknn('yolov5s.rknn')
rknn_lite.init_runtime()
# 执行推理
outputs = rknn_lite.inference(inputs=[img])
optimization_level 影响模型优化程度,级别越高,NPU 算子融合越激进,但可能增加转换时间。性能测试时建议固定该参数,以保证结果可复现。
4.4 基本运行验证:确保软硬件链路畅通
验证策略
在正式进行延迟与吞吐测试前,必须完成三项基础验证:NPU 设备可见性、模型加载成功率、单次推理正确性。这三项验证能快速定位环境问题,避免后续测试数据无效。
操作流程
- 设备可见性:在板卡上运行
python3 -c "from rknnlite.api import RKNNLite; r = RKNNLite(); print(r.list_devices())",应输出['/dev/rknpu']。 - 模型加载:编写脚本加载
yolov5s.rknn,若抛出E_RKNN_INVALID_MODEL,则检查模型文件是否完整或版本是否匹配。 - 推理正确性:使用一张固定测试图片,对比输出张量的 shape 与数值范围。例如,YOLOv5 输出应为
[1, 25200, 85]的浮点数组。
案例拆解:一次典型的驱动加载失败排障
背景:某开发板使用内核 5.10.110,尝试加载 rknpu2 0.9.2 驱动。
现象:insmod rknn.ko 报错 insmod: ERROR: could not insert module rknn.ko: Unknown symbol in module。
分析:通过 dmesg 查看详细日志,发现 Unknown symbol: rknn_create_workqueue。该符号在 5.10 内核中已被移除,驱动版本过旧。
解决:升级至 rknpu2 0.9.3 版本,该版本适配了 5.10+ 内核。重新加载后,dmesg 输出正常。
复盘:驱动与内核的版本匹配是环境搭建中最常见的坑。建议在项目初期就锁定内核版本,并记录驱动版本哈希值,便于复现。
常见误区与总结
- 忽略板卡 Python 版本:rknn-toolkit-lite2 仅支持 Python 3.8-3.10,若板卡默认 Python 为 3.11,需自行编译或使用 conda。
- 模拟器性能误导:模拟器仅用于功能验证,其延迟数据与真实 NPU 相差 10-100 倍,切勿作为性能基准。
- 库文件冲突:若板卡上存在多个版本的
librknnrt.so,务必通过ldd检查测试程序实际链接的路径。
environment.txt,作为性能测试报告的附件,确保测试结果可追溯。