RKNN 模型转换
本章讲如何将 PyTorch / ONNX / TensorFlow 模型转换为 RK182X NPU 可执行的 .rknn 模型。
整体框图
训练框架模型(PyTorch / TensorFlow / ...)
↓
导出为中间格式(.onnx / .pb / .tflite)
↓
RKNN Toolkit 转换
├─ 图优化
├─ 算子融合
├─ 量化校准
└─ 目标平台编译
↓
.rknn 模型文件
↓
部署到 RK182X 板端执行1. RKNN Toolkit 安装
实际 Wheel 文件名(来自 /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-toolkit/rknn3-toolkit/packages/):
ls -la /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-toolkit/rknn3-toolkit/packages/输出:
总计 367580
drwxr-xr-x 2 linaro linaro 4096 2026年 1月28日 .
drwxr-xr-x 5 linaro linaro 4096 2026年 1月28日 ..
-rw-r--r-- 1 linaro linaro 226 2026年 1月28日 md5sum.txt
-rw-r--r-- 1 linaro linaro 421 2026年 1月28日 requirements_cp310-1.0.0.txt
-rw-r--r-- 1 linaro linaro 413 2026年 1月28日 requirements_cp312-1.0.0.txt
-rw-r--r-- 1 linaro linaro 188832423 2026年 1月28日 rknn3_toolkit-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
-rw-r--r-- 1 linaro linaro 187542742 2026年 1月28日 rknn3_toolkit-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whlMD5:
cat /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-toolkit/rknn3-toolkit/packages/md5sum.txt输出:
7c7c7366ad7ae483142dbd4ea9b6b1f0 rknn3_toolkit-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
54554b352e8b7fdf5efd09227871123b rknn3_toolkit-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl架构限制:RKNN3 Toolkit 仅提供 x86_64 架构 wheel,只能在 PC(x86_64)上运行。开发板(aarch64)只能装
rknn3-toolkit-lite。
安装(仅 x86_64 PC 可执行):
python3 -m venv ~/rknn-env
source ~/rknn-env/bin/activate
# 原 wheel 名为 rknn3_toolkit-1.0.0-...x86_64.whl(不是 rknn_toolkit2)
pip install /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-toolkit/rknn3-toolkit/packages/rknn3_toolkit-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
# 验证
python3 -c "from rknn.api import RKNN; print('RKNN Toolkit OK')"板端实测(aarch64):
python3 -c "from rknn.api import RKNN; print('RKNN Toolkit OK')"输出:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'rknn'x86_64 wheel 无法在 aarch64 板端 pip install。板端只能装
rknn3-toolkit-lite(推理,不能转换)。
2. PyTorch → ONNX → RKNN 完整步骤
带 ResNet50 端到端示例。
2.1 PyTorch 导出 ONNX
import torch
import torchvision.models as models
model = models.resnet50(pretrained=False)
model.load_state_dict(torch.load('resnet50_best.pth'))
model.eval()
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
model, dummy_input, 'resnet50.onnx',
input_names=['input'],
output_names=['output'],
dynamic_axes={'input': {0: 'batch'}, 'output': {0: 'batch'}},
opset_version=11,
)
print('ONNX exported: resnet50.onnx')2.2 RKNN Toolkit 转换
from rknn.api import RKNN
rknn = RKNN(verbose=True)
# 配置转换参数
# 实际合法值(rknn.py:177-178):
# target_platform = rv1103 / rv1103b / rv1106 / rv1106b / rk2118 /
# rk3562 / rk3566 / rk3568 / rk3576 / rk3588 / rk1820
# 实际合法值(rknn.py:173):
# quantized_dtype = w8a8 / w4a16(默认 w16a16)
rknn.config(
mean_values=[[123.675, 116.28, 103.53]],
std_values=[[58.395, 57.12, 57.375]],
target_platform='rk1820',
quantized_dtype='w8a8',
)
# 加载 ONNX
rknn.load_onnx(model='resnet50.onnx')
# 构建(含量化校准)
# 实际签名 (rknn.py:291): build(do_quantization, dataset, rknn_batch_size, auto_hybrid)
rknn.build(
do_quantization=True,
dataset='./calib_images.txt',
)
# 精度评估(可选)
# 实际签名 (rknn.py:417): accuracy_analysis(inputs, output_dir, core_mask, target, device_id)
rknn.accuracy_analysis(
inputs=['./test_images/'],
output_dir='./accuracy_report/',
)
# 导出
rknn.export_rknn('resnet50.rknn')
# 释放
rknn.release()
print('RKNN model exported: resnet50.rknn')2.3 校准数据集准备
# calib_images.txt 格式:每行一个图片路径
# ./calib/IMG_001.jpg
# ./calib/IMG_002.jpg
# ./calib/IMG_003.jpg
import os, random
image_dir = '/path/to/dataset/train/images'
all_images = [os.path.join(image_dir, f) for f in os.listdir(image_dir)
if f.endswith(('.jpg', '.png'))]
random.seed(42)
calib = random.sample(all_images, 100)
with open('calib_images.txt', 'w') as f:
for img in calib:
f.write(img + '\n')
print(f'Calibration set: {len(calib)} images')3. YOLOv8 目标检测转换
设置 custom_string='yolov8' 启用 YOLOv8 自定义后处理,mean / std 设为 0 / 255(像素值归一化),其余流程与标准转换一致。
from rknn.api import RKNN
rknn = RKNN(verbose=True)
rknn.config(
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]],
target_platform='rk1820',
quantized_dtype='w8a8',
custom_string='yolov8',
)
rknn.load_onnx(model='yolov8n.onnx')
rknn.build(do_quantization=True, dataset='./coco_calib.txt')
rknn.export_rknn('yolov8n_rk1820.rknn')
rknn.release()4. 量化精度优化
| 问题 | 排查方向 |
|---|---|
| Top-1 下降 >1% | 校准集覆盖不足 |
| 检测 mAP 暴跌 | 敏感层被量化 |
| 特定类别精度差 | 类别样本不均衡 |
可调旋钮:
config(quantized_method='layer' / 'channel' / 'group32')— 量化粒度build(auto_hybrid=True)— 自动混合精度
5. 关键参数
| 参数 | 说明 | 取值 |
|---|---|---|
target_platform | 目标平台 | 'rk1820' |
mean_values | 输入减均值 | ImageNet [255*0.485, 255*0.456, 255*0.406];已归一化 [0, 0, 0] |
std_values | 输入除以标准差 | ImageNet [255*0.229, 255*0.224, 255*0.225] |
input_attrs | 输入 tensor 类型 | {'input': {'dtype': 'uint8', 'layout': 'NHWC'}} |
quantized_dtype | 量化类型 | 'w8a8' / 'w4a16' / 'w4a8' |
do_quantization | 是否做 INT8 量化 | True |
dataset | 校准数据集 | .txt(CNN) / .json(LLM) |
6. 量化校准数据集
| 模型类型 | 数据集路径 | 数量 |
|---|---|---|
| CNN(MobileNet V2) | datasets/imagenet/.../dataset_20.txt | 20 张 |
| LLM(Qwen3) | datasets/CMMLU/dataset.json | 数十条(中文问答) |
| 目标检测(yolov5) | dataset.txt | 通常 20-50 张 |
# 1. 收集代表性图片
mkdir -p calib_images
cp /path/to/representative_*.jpg calib_images/
# 2. 生成路径列表
ls calib_images/*.jpg > dataset.txt
# 3. 转换脚本引用
rknn.build(do_quantization=True, dataset='./dataset.txt')7. 精度验证
RKNN3 没有内置精度对比工具,需要编写验证脚本:
python3 -c "from rknn3lite.api import RKNN3Lite; print('RKNN3Lite available')"输出:
RKNN3Lite availablefrom rknn3lite.api import RKNN3Lite # 板端用 lite
rknn_lite = RKNN3Lite()
rknn_lite.load_rknn('model.rknn', 'model.weight')
rknn_lite.init_runtime()
# 跑同一输入,对比 RKNN3 输出 vs PyTorch 输出
outputs = rknn_lite.inference(inputs=[img])
# 计算差异
import numpy as np
mse = np.mean((outputs[0] - pytorch_output) ** 2)| 任务 | 指标 |
|---|---|
| 分类 | Top-1 / Top-5 Accuracy |
| 检测 | mAP / IoU |
| 超分 / 重建 | MSE / PSNR |
| LLM | 困惑度(Perplexity) |
8. SDK 内示例
Model Zoo 示例:
ls /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-model-zoo/examples/输出:
FastVLM glm_edge GME-Qwen2-VL HY_MT_1_5
InternVLM Janus_Pro MiniCPM_V_4 mobilenet_v1
mobilenet_v2 Qwen2_5 Qwen2_5_Omni Qwen2_5_VL
Qwen3 Qwen3_Embedding Qwen3_VL resnet
SmolVLM yolov5 yolov6 yolov8MobileNet V2 转换脚本:
ls /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-model-zoo/examples/mobilenet_v2/python/输出:
convert.py
dataset_eval.pyexamples/mobilenet_v2/python/convert.py— MobileNet V2 转 RKNN3examples/mobilenet_v2/python/dataset_eval.py— MobileNet V2 数据集评估
Qwen3 转换脚本:
ls /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-model-zoo/examples/Qwen3/python/输出:
export_llm.py
export_rknn.pyexamples/Qwen3/python/export_llm.py— Qwen3 导出 ONNXexamples/Qwen3/python/export_rknn.py— ONNX 转 RKNN
跑示例前需要先准备好数据集(ImageNet / CMMLU)。
9. 常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
ModuleNotFoundError: No module named 'rknn' | 装到板端了(aarch64) | 移到 PC(x86_64)安装 |
target_platform 'rk1828' 不支持 | 写错 | 改成 'rk1820' |
| Python 3.11 装不上 Toolkit | 仅支持 3.10 / 3.12 | 装 Python 3.10 或 3.12 |
do_quantization=True 报缺 dataset | 没下数据集 | 准备 20+ 样本 |
| 量化后精度掉点 | 校准集覆盖不足 | 扩校准集 + 改 quantized_method |
10. 下一步
11. 参考文档
RK1820_RK1828_AI_Release-Note_CN.md(SDK 内)— RKNN3 V1.0.0 完整更新说明Rockchip_RK1820_RK1828_AI_SDK_RELEASE_CN.pdf(SDK 内)— Release Note PDFRockchip_RK1820_RK1828_AI_SDK_Quick_Start_CN.pdf(SDK 内)— 快速开始
