2、RKNN基础:RKNN Toolkit版本、支持芯片、模型格式、转换流程概览
在开始动态batch size模型的RKNN转换与部署之前,必须先建立对RKNN工具链的整体认知。RKNN Toolkit是瑞芯微(Rockchip)提供的AI模型转换、量化、推理验证与部署工具集,它将TensorFlow、PyTorch、ONNX、Caffe等主流框架训练出的模型,转换为RKNN格式,使其能够在RK3566、RK3568、RK3588、RK3576等NPU上高效运行。本章将系统梳理RKNN Toolkit的版本演进、支持芯片范围、模型格式约束以及标准转换流程,为后续动态batch size的专项处理打下坚实基础。
上图展示了RKNN转换的整体链路:左侧为支持的输入模型格式,中间为RKNN Toolkit的核心API调用顺序,右侧为转换产出的RKNN模型特性,底部则列出了当前主流的芯片平台与工具版本配套。这张图是理解后续所有章节的“地图”,接下来我们将逐一拆解每个模块的细节。
2.1 RKNN Toolkit版本演进与选型
核心原理
RKNN Toolkit目前主要分为两大系列:RKNN-Toolkit1(对应旧版RKNN API,主要支持RK3399Pro、RK1808等早期芯片)和RKNN-Toolkit2(对应新版RKNN API,支持RK3566/RK3568/RK3588/RK3576等新一代芯片)。两者在模型格式、量化算法、API接口上均有较大差异,且不向后兼容。对于新项目,除非目标芯片是RK3399Pro或RK1808,否则一律选择RKNN-Toolkit2。
RKNN-Toolkit2本身也在持续迭代,例如v1.4.0、v1.5.0、v1.6.0、v2.0.0等版本。版本差异主要体现在:新增算子支持、量化精度优化(如混合量化、通道量化)、动态shape支持度完善、以及bug修复。选择版本时,应遵循“芯片SDK配套优先”原则——即查看目标平台(如RK3588)的SDK文档中推荐的RKNN-Toolkit2版本,而不是盲目追求最新版。
版本对比表
| 对比维度 | RKNN-Toolkit1 | RKNN-Toolkit2 |
|---|---|---|
| 支持芯片 | RK3399Pro、RK1808、RV1109/1126 | RK3566、RK3568、RK3576、RK3588/S、RV1103/1106 |
| Python版本 | Python 3.5~3.7 | Python 3.6~3.11 |
| 模型格式 | ONNX、Caffe、TensorFlow、PyTorch(实验) | ONNX、PyTorch、TensorFlow、TFLite、Caffe、PaddlePaddle |
| 动态shape支持 | 不支持或有限 | 支持动态batch、动态宽高(需指定范围) |
| 量化方式 | 非对称量化为主 | 支持非对称/对称量化、混合量化、通道量化 |
| API风格 | rknn.load_onnx()等 | rknn.load_onnx()等,但参数不同 |
选型判断方法
- 确认芯片型号:查看硬件原理图或CPU信息(
cat /proc/cpuinfo),确定是RK3588还是RK3568等。 - 查阅SDK文档:在瑞芯微官方文档中心(Tina Linux或Rockchip SDK)中查找对应芯片的NPU使用指南,其中会明确RKNN-Toolkit2的推荐版本。
- 检查Python环境:使用
python3 --version确认版本,若为3.8~3.10,可直接安装最新稳定版;若为3.11,需确认该版本是否被支持。 - 验证安装:安装后运行
from rknn.api import RKNN,无报错即成功。
常见误区
2.2 支持芯片与NPU算力差异
核心原理
不同芯片的NPU架构不同,导致支持的算子、量化精度、动态shape能力均有差异。例如,RK3588的NPU算力达6 TOPS,支持int4/int8/int16混合精度;而RK3568的NPU算力为0.8 TOPS,仅支持int8/int16。动态batch size模型在RK3588上可以较轻松地设置batch=1~4,但在RK3568上可能因内存带宽限制导致性能下降明显。
芯片对比表
| 芯片型号 | NPU算力 | 内存支持 | 动态batch建议 | 典型应用 |
|---|---|---|---|---|
| RK3566 | 0.8 TOPS | LPDDR4/4X | 1~2 | 智能门锁、低端IPC |
| RK3568 | 0.8 TOPS | LPDDR4/4X | 1~2 | 工业平板、NVR |
| RK3576 | 6 TOPS | LPDDR4/5 | 1~4 | AIoT、边缘计算 |
| RK3588 | 6 TOPS | LPDDR4/4X/5 | 1~8 | 智能座舱、机器人、边缘服务器 |
| RV1106 | 0.5 TOPS | 内置DDR | 1 | 摄像头、视觉模组 |
实战场景:根据芯片选择动态batch策略
假设我们在RK3588上部署一个目标检测模型,输入为640x640,期望支持batch=1和batch=4两种模式。RK3588的NPU支持多核并行,batch=4时可以将四个输入分配到不同NPU核心,充分利用算力。但在RK3568上,由于只有单核NPU,batch=4会导致内存访问冲突,实际吞吐量可能比batch=1连续推理4次还低。因此,在RK3568上应固定batch=1,通过多线程流水线提升整体帧率。
判断方法
- 查看芯片数据手册中的NPU算力与内存带宽。
- 使用
npu_info工具(部分SDK提供)查看NPU负载。 - 在板端运行
rknn.run()时,通过perf_debug=True获取单次推理耗时。
2.3 模型格式与转换前置要求
核心原理
RKNN-Toolkit2支持多种输入格式,但ONNX是官方推荐的首选格式,因为其算子覆盖最全、动态shape支持最好。PyTorch模型需先导出为ONNX(torch.onnx.export),TensorFlow模型需保存为冻结的.pb或TFLite格式。Caffe模型需提供.prototxt和.caffemodel。对于动态batch size,ONNX中需将batch维度标记为动态(dynamic_axes)。
操作流程:PyTorch模型导出为动态batch ONNX
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.conv = nn.Conv2d(3, 16, 3, padding=1)
def forward(self, x):
return self.conv(x)
model = MyModel().eval()
dummy_input = torch.randn(1, 3, 640, 640)
torch.onnx.export(
model,
dummy_input,
"model_dynamic.onnx",
opset_version=12,
input_names=["input"],
output_names=["output"],
dynamic_axes={
"input": {0: "batch_size"},
"output": {0: "batch_size"}
}
)
print("ONNX exported with dynamic batch axis")
导出后,可使用onnxruntime验证动态batch是否生效:
import onnxruntime as ort
import numpy as np
sess = ort.InferenceSession("model_dynamic.onnx")
# 测试batch=1
out1 = sess.run(None, {"input": np.random.randn(1,3,640,640).astype(np.float32)})
# 测试batch=4
out4 = sess.run(None, {"input": np.random.randn(4,3,640,640).astype(np.float32)})
print("batch=1 output shape:", out1[0].shape)
print("batch=4 output shape:", out4[0].shape)
常见误区
2.4 RKNN转换流程概览与关键参数
核心原理
标准转换流程分为五个步骤:配置(config)→ 加载(load)→ 构建(build)→ 导出(export)→ 验证(inference)。其中,config阶段需要指定目标平台、量化策略、动态shape范围等;build阶段会执行模型优化、算子映射、量化校准;export生成.rknn文件;inference可在PC端模拟NPU推理,验证精度。
完整转换代码模板
from rknn.api import RKNN
rknn = RKNN()
# 1. 配置
rknn.config(
target_platform='rk3588',
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]],
quantized_dtype='w8a8',
quantized_algorithm='normal',
optimization_level=3,
dynamic_input=True, # 启用动态输入
dynamic_batch_size=[1, 4] # 动态batch范围
)
# 2. 加载ONNX
ret = rknn.load_onnx(model='model_dynamic.onnx')
if ret != 0:
print("Load ONNX failed")
exit(-1)
# 3. 构建
ret = rknn.build(do_quantization=True, dataset='dataset.txt')
if ret != 0:
print("Build failed")
exit(-1)
# 4. 导出
ret = rknn.export_rknn('model_dynamic.rknn')
if ret != 0:
print("Export failed")
exit(-1)
# 5. 验证(PC模拟)
ret = rknn.init_runtime()
if ret != 0:
print("Init runtime failed")
exit(-1)
import numpy as np
input_data = np.random.randn(2, 3, 640, 640).astype(np.float32)
outputs = rknn.inference(inputs=[input_data])
print("Inference output shape:", outputs[0].shape)
rknn.release()
关键参数说明表
| 参数名 | 作用 | 动态batch注意事项 |
|---|---|---|
| target_platform | 指定目标芯片 | 必须与板端芯片一致,否则运行报错 |
| dynamic_input | 启用动态输入模式 | 设为True后,build阶段会生成动态shape的rknn模型 |
| dynamic_batch_size | 指定batch范围 | 例如[1,4]表示batch从1到4,必须是连续整数 |
| quantized_dtype | 量化精度 | w8a8表示权重和激活均为int8,动态batch下建议保持w8a8 |
| optimization_level | 优化等级0~3 | 等级越高优化越激进,但可能影响动态shape支持 |
案例拆解:动态batch转换失败排查
背景:某开发者使用RKNN-Toolkit2 v1.5.0在RK3588上转换一个YOLOv5s模型,ONNX已设置动态batch,但rknn.build()报错“E RKNN: Dynamic input is not supported in current version”。
分析过程:首先检查RKNN-Toolkit2版本,发现v1.5.0对动态shape支持尚不完善。查阅官方release notes,确认v1.6.0才正式支持动态batch。其次,检查ONNX模型,发现dynamic_axes只设置了输入,未设置输出,导致RKNN解析时无法确定输出shape。
解决步骤:
- 升级RKNN-Toolkit2至v1.6.0(
pip install rknn-toolkit2==1.6.0)。 - 重新导出ONNX,确保输入输出均设置
dynamic_axes。 - 在
rknn.config()中显式添加dynamic_batch_size=[1,4]。 - 重新build,成功生成.rknn文件。
结果对比:修复前build失败;修复后build成功,且在PC模拟推理中batch=1和batch=4均输出正确shape。
复盘经验:动态batch转换失败时,优先检查三处:工具链版本是否支持、ONNX动态轴是否完整、config中是否显式声明batch范围。三者缺一不可。
2.5 总结与最佳实践
本章梳理了RKNN基础三要素:版本选型、芯片匹配、格式规范。在实际项目中,建议遵循以下最佳实践:
- 统一使用RKNN-Toolkit2 v1.6.0及以上版本,并匹配芯片SDK推荐版本。
- 所有模型优先导出为ONNX(opset≥12),并完整设置动态轴。
- 在config中明确
dynamic_input=True和dynamic_batch_size范围,不要依赖默认值。 - 转换后务必在PC端用
rknn.inference()验证多个batch尺寸的精度与shape。 - 将转换脚本、ONNX模型、dataset.txt(量化校准集)一并纳入版本管理,便于复现。