RKNN Toolkit 使用方式与典型场景:两个可运行示例
四、使用方式与典型场景:两个可运行示例
示例一:ONNX 转 RKNN,INT8 量化 + 连板推理
先准备一小批量化图片,放到 dataset.txt 中,每行一个图片路径(相对路径相对于 txt 所在目录):
./images/0001.jpg
./images/0002.jpg
./images/0003.jpg
转换脚本:
from rknn.api import RKNN
rknn = RKNN(verbose=True)
rknn.config(
mean_values=[[123.675, 116.28, 103.53]],
std_values=[[58.395, 57.12, 57.375]],
target_platform="rk3588",
quantized_dtype="asymmetric_quantized-8",
quantized_algorithm="normal",
quantized_method="channel",
optimization_level=3,
)
ret = rknn.load_onnx(model="yolov8n.onnx")
assert ret == 0, "load_onnx failed"
ret = rknn.build(do_quantization=True, dataset="dataset.txt")
assert ret == 0, "build failed"
ret = rknn.export_rknn("yolov8n_int8.rknn")
assert ret == 0, "export failed"
ret = rknn.init_runtime(target="rk3588")
inputs = rknn.inference(inputs=["images/0001.jpg"])
print(inputs[0].shape)
rknn.release()
要点:mean_values 与 std_values 必须与训练时预处理完全一致,否则量化校准统计的分布就是错的,精度必然崩;target_platform 写错会得到一个看似正常但板端跑不起来的模型。
示例二:板端 rknnlite 多线程推理
from rknnlite.api import RKNNLite
rknn = RKNNLite()
rknn.load_rknn("yolov8n_int8.rknn")
rknn.init_runtime(core_mask=RKNNLite.NPU_CORE_AUTO)
# 零拷贝:把图像直接写入输入张量占用的内存
import cv2, numpy as np
img = cv2.imread("test.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (640, 640))
img = np.expand_dims(img, axis=0)
outputs = rknn.inference(inputs=[img], data_format="nhwc")
print(len(outputs))
rknn.release()
多路视频场景下,把 core_mask 手动分配到不同核(例如第一路固定到某个核、第二路分配到另一个核),比让运行时自动抢占更稳定。多线程共享一个 RKNNLite 实例通常不安全,正确做法是每线程各持一个实例并绑定不同核。
适合与不适合的场景
- 适合:目标硬件确定是 Rockchip 芯片、模型以 CNN 为主、需要 INT8 提速、需要多路视频并行推理的边缘盒子。
- 不太适合:模型里有大量 NPU 未支持的算子、需要 FP32 高精度数值、目标平台不是 Rockchip、或者团队希望「一套模型到处跑」的场景。
- 要谨慎:Transformer 类模型在部分平台的算子覆盖仍有限,先做算子探查再定方案。

