背景

RK3576 是瑞芯微推出的一款 8nm 中高端 AIoT 芯片,内置 6 TOPS NPU,非常适合做端侧目标检测。本文记录将 YOLOv8 部署到 RK3576 的完整流程:PyTorch → ONNX → RKNN(int8 量化)→ C++/Python 端侧推理

整体流程

阶段 工具 产物
训练/获取权重 PyTorch / Ultralytics yolov8n.pt
导出 ONNX Ultralytics export yolov8n.onnx
转 RKNN + 量化 RKNN-Toolkit2 yolov8n.rknn
端侧推理 RKNN Runtime (librknnrt) C++ / Python 推理程序

1. 导出 ONNX

使用 Ultralytics 导出 ONNX,注意关闭动态 shape(RKNN 需要固定尺寸):

1
2
pip install ultralytics
yolo export model=yolov8n.pt format=onnx opset=12 imgsz=640

导出后可用 netron 可视化网络结构,确认输出节点为 output0(1×84×8400 的检测头)。

2. RKNN-Toolkit2 转换与量化

RKNN-Toolkit2 需要运行在 x86_64 Linux(Ubuntu 18.04/20.04/22.04)。核心转换脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from rknn.api import RKNN

QUANT_IMG = "./dataset.txt" # 每行一张量化校准图片路径

rknn = RKNN(verbose=True)

# 预处理配置
rknn.config(
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]],
target_platform="rk3576",
quantized_dtype="asymmetric_quantized-8", # int8 量化
)

# 加载 ONNX
rknn.load_onnx(model="./yolov8n.onnx")

# 构建模型
rknn.build(
do_quantization=True,
dataset=QUANT_IMG,
rknn_batch_size=1,
)

# 导出 RKNN
rknn.export_rknn("./yolov8n.rknn")

# 在 PC 上模拟推理,验证精度
rknn.init_runtime()
outputs = rknn.inference(inputs=[img])
print("outputs shape:", outputs[0].shape)

rknn.release()

量化校准集建议

指标 建议
图片数量 200~500 张
来源 目标场景真实数据(比 ImageNet 更有效)
尺寸 与推理尺寸一致(如 640×640)
预处理 与推理阶段严格一致(BGR/RGB、归一化)

int8 量化后若精度下降明显,可尝试 quantized_dtype="asymmetric_quantized-8" 改为 "dynamic_fixed_point-8" 或增加校准集数量。

3. 端侧推理

在 RK3576 板卡上,通过 librknnrt 运行时加载模型。Python 侧示例:

1
2
3
4
5
6
7
8
9
10
11
from rknnlite.api import RKNNLite

rknn_lite = RKNNLite()
rknn_lite.load_rknn("./yolov8n.rknn")
rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_0)

outputs = rknn_lite.inference(inputs=[img])
# outputs[0] shape: (1, 84, 8400)
# 需自行做 NMS 解码,或参考 rknn_model_zoo 的 postprocess

rknn_lite.release()

4. 常见坑

  1. 动态 shape 报错:ONNX 导出务必 imgsz 固定、关闭 dynamic。
  2. 输出为 None:检查 NPU 驱动版本是否与 RKNN-Toolkit2 版本匹配。
  3. 精度大幅下降:检查校准集与推理预处理是否一致(RGB 顺序、是否减均值)。

参考