【无人售货柜・RK+YOLO】篇 5:RK3576 部署第一步!YOLO 模型转 RKNN 全流程,新手必避的量化大坑

目录

[一、先给新手扫盲:什么是 RKNN?为什么必须转这个格式?](#一、先给新手扫盲:什么是 RKNN?为什么必须转这个格式?)

新手必守的部署红线(提前避坑,一步都不能破)

[二、第一步:YOLOv5 pt 模型 → 导出 ONNX 格式(最关键,90% 的坑都在这)](#二、第一步:YOLOv5 pt 模型 → 导出 ONNX 格式(最关键,90% 的坑都在这))

准备工作

导出命令(直接复制就能用,全平台通用)

[每个参数的意义 & 避坑解释](#每个参数的意义 & 避坑解释)

[导出后必做的 3 项检查(少一项都可能踩坑)](#导出后必做的 3 项检查(少一项都可能踩坑))

[三、第二步:RKNN-Toolkit2 环境搭建,新手零报错版](#三、第二步:RKNN-Toolkit2 环境搭建,新手零报错版)

环境锁死(一个都不能改)

搭建步骤

[四、第三步:ONNX 转 RKNN 完整脚本,直接复制就能用](#四、第三步:ONNX 转 RKNN 完整脚本,直接复制就能用)

完整转换脚本

必须准备的量化校准数据集quant_dataset.txt

商用级量化数据集制作规范(严格照着做,精度损失≤1%)

运行脚本

[五、新手必踩:INT8 量化后精度暴跌?4 招彻底解决](#五、新手必踩:INT8 量化后精度暴跌?4 招彻底解决)

[六、PC 端仿真精度验证,确保模型没问题](#六、PC 端仿真精度验证,确保模型没问题)


大家好,我是黒漂技术佬。上一篇我们把售货柜专用的 YOLO 模型优化到了商用级精度,mAP@0.5 稳在 99% 以上,相似商品误检、小目标漏检这些核心痛点基本全解决了。

但我太懂新手了,到这一步大概率会直接踩进部署的大坑:训好的模型在电脑上跑得好好的,一转到 RK3576 的 NPU 上,要么算子不支持转不成功,要么 INT8 量化后精度直接腰斩,要么跑是能跑,一帧要 200ms,完全没法用。

毫不夸张地说,端侧部署的坑,比训练多 10 倍都不止。但别慌,这一篇我就给你一套零踩坑、保姆级、经过 RK3576 安卓量产验证的 YOLO 转 RKNN 全流程,从 ONNX 导出到 RKNN 转换、量化避坑、精度验证,一步不落,新手跟着走,100% 能转出能跑、精度不掉、速度够快的 RKNN 模型。


一、先给新手扫盲:什么是 RKNN?为什么必须转这个格式?

【新手概念科普】我们训好的.pt/.onnx模型是通用格式,只能在电脑的 CPU/GPU 上跑,RK3576 的 NPU 根本不认。而RKNN ,是瑞芯微专为自家 NPU 芯片设计的专属模型格式,只有转成 RKNN 格式,才能调用 RK3576 的 6TOPS NPU 算力,实现硬件加速推理。

举个通俗的例子:onnx 模型就像一份普通话演讲稿,电脑能看懂,但 RK3576 的 NPU 只会说专属方言,你必须把演讲稿翻译成它能听懂的方言(RKNN),它才能说得又快又准。

新手必守的部署红线(提前避坑,一步都不能破)

  1. 工具版本锁死 :RKNN-Toolkit2 必须用v1.6.0稳定版,别追最新版,最新版对 YOLOv5 的算子支持反而有坑,v1.6.0 是目前 RK3576 适配最稳、坑最少的版本
  2. 输入规格锁死 :固定batch=1,固定输入尺寸 640×640,绝对不要用动态 batch、动态尺寸,RK3576 的 NPU 对动态输入支持极差,必踩坑
  3. 量化方式锁死:INT8 不对称量化,别用 FP16,FP16 速度慢一倍、内存占用高一倍,售货柜场景 INT8 完全够用,精度损失能控制在 1% 以内
  4. 算子红线:绝对不要用 YOLOv5 官方不支持的魔改算子(比如自定义注意力模块、魔改卷积),大概率 RKNN 不支持,转模型直接报错

二、第一步:YOLOv5 pt 模型 → 导出 ONNX 格式(最关键,90% 的坑都在这)

很多新手转 RKNN 失败,根本不是转换的问题,是 ONNX 导出就错了。这里给你零坑导出命令 + 每一步的解释,还有必做的检查项。

准备工作

把你上一篇训好的best.pt权重文件,放到 YOLOv5 源码的根目录里,确保你的 YOLOv5 环境是正常可用的。

导出命令(直接复制就能用,全平台通用)

bash

运行

复制代码
python export.py \
--weights best.pt \
--img 640 \
--batch 1 \
--device cpu \
--include onnx \
--simplify \
--opset 12 \
--dynamic False

每个参数的意义 & 避坑解释

  • --weights best.pt:你训好的售货柜商品识别模型权重,别写错文件名
  • --img 640:和训练时的输入分辨率完全一致,训练用 640 这里就必须 640,绝对不能改
  • --batch 1:固定批次为 1,RK3576 的 NPU 推理只支持固定 batch=1,动态 batch 直接不支持
  • --device cpu:用 CPU 导出,避免 GPU 导出带来的算子兼容问题,新手必加
  • --include onnx:只导出 ONNX 格式,别导出其他无关格式
  • --simplify:【核心必加】用 onnx-simplifier 简化 ONNX 模型,去掉冗余算子、合并常量,大幅提升 RKNN 兼容性,90% 的算子不支持报错,都是因为没加这个参数
  • --opset 12:【核心必锁】ONNX 的算子版本,必须设 12,RKNN-Toolkit2 对 13 以上的高版本 opset 支持极差,必报错
  • --dynamic False:关闭动态输入,固定输入尺寸,RK3576 对动态输入支持极差,必踩坑

导出后必做的 3 项检查(少一项都可能踩坑)

导出成功后,你会在根目录得到best.onnx文件,别着急转 RKNN,先做这 3 项检查:

  1. 输入输出维度检查 用 Netron(新手必装的 ONNX 可视化工具,免费开源)打开best.onnx,确认输入维度是[1,3,640,640],输出维度是[1,25200,nc+5](nc 是你的商品类别数,比如 10 类商品,输出就是[1,25200,15]),完全正确才能继续。

  2. 算子结构检查 看 Netron 里的模型结构,有没有if/loop这类控制流算子,或者不认识的自定义算子。正常简化后的 YOLOv5s 模型结构非常干净,全是卷积、激活这些基础算子,有多余算子必须重新导出,一定要加--simplify

  3. 推理有效性检查 写一段极简代码,验证 ONNX 模型能正常推理,输出结果和 pt 模型一致,确保 ONNX 本身没问题:

    python

    运行

    复制代码
    import onnxruntime as ort
    import cv2
    import numpy as np
    
    # 加载ONNX模型
    session = ort.InferenceSession("best.onnx", providers=["CPUExecutionProvider"])
    input_name = session.get_inputs()[0].name
    
    # 预处理图片
    img = cv2.imread("test.jpg")
    img = cv2.resize(img, (640, 640))
    img = img.transpose(2, 0, 1)
    img = np.expand_dims(img, axis=0).astype(np.float32) / 255.0
    
    # 推理
    output = session.run([], {input_name: img})
    print("ONNX推理成功,输出形状:", output[0].shape)

    能正常输出形状,说明 ONNX 模型完全没问题,可以进入下一步。


三、第二步:RKNN-Toolkit2 环境搭建,新手零报错版

很多新手第一步就栽在环境搭建上,Python 版本不对、依赖冲突,各种报错。这里给你一套经过无数次验证的零报错环境搭建流程,严格按步骤来,绝对不会出问题。

环境锁死(一个都不能改)

  • 系统:优先 Ubuntu 20.04(最稳,官方原生支持),Windows10/11 也可以用 Anaconda 装环境,MacOS 不支持
  • Python 版本:必须 3.8,别用 3.9 及以上,RKNN-Toolkit2 对高版本 Python 完全不兼容
  • RKNN-Toolkit2 版本:v1.6.0,别用最新版,坑巨多

搭建步骤

  1. 先装 Anaconda(新手必用,避免环境冲突),官网下载 Python3.8 对应的版本,一键安装,记得勾选Add to PATH

  2. 打开 Anaconda Prompt,创建专属虚拟环境,输入命令: bash

    运行

    复制代码
    conda create -n rknn python=3.8
    conda activate rknn
  3. 安装 RKNN-Toolkit2 和配套依赖,一行命令搞定: bash

    运行

    复制代码
    pip install rknn-toolkit2==1.6.0 onnx==1.12.0 onnxruntime==1.13.1 opencv-python numpy==1.23.5 -i https://pypi.tuna.tsinghua.edu.cn/simple
  4. 验证安装是否成功,在虚拟环境里输入 python,执行: python

    运行

    复制代码
    from rknn.api import RKNN
    print("RKNN环境安装成功!")

    不报错,就说明环境完全搭好了,恭喜你避开了 80% 的环境坑。


四、第三步:ONNX 转 RKNN 完整脚本,直接复制就能用

环境搭好了,ONNX 也没问题了,现在到了核心的转换环节。我给你写好了完整可运行、经过量产验证的转换脚本 ,文件名就叫onnx2rknn.py,放到和best.onnx同一个文件夹里,你只需要改 2 个地方,就能直接运行。

完整转换脚本

python

运行

复制代码
from rknn.api import RKNN
import cv2
import numpy as np

if __name__ == '__main__':
    # ========== 新手只需要改这里的2个参数 ==========
    ONNX_MODEL = "best.onnx"        # 你的ONNX模型文件名
    RKNN_MODEL = "best.rknn"        # 输出的RKNN模型文件名
    DATASET_TXT = "quant_dataset.txt"  # 量化用的数据集txt文件
    # ================================================

    # 1. 初始化RKNN对象
    rknn = RKNN(verbose=False)  # verbose=True可以看详细日志,排错用

    # 2. 【核心配置】RKNN模型预处理&量化配置,新手别瞎改
    rknn.config(
        # 预处理归一化:对应YOLO的 像素/255,所以mean是0,std是255
        mean_values=[[0, 0, 0]],
        std_values=[[255, 255, 255]],
        # 目标平台,必须写rk3576,别写错
        target_platform="rk3576",
        # 量化方式:INT8不对称量化,售货柜场景最优,精度损失最小
        quantized_dtype="asymmetric_quantized-u8",
        # 优化级别,最高级,提升推理速度
        optimization_level=3,
    )

    # 3. 加载ONNX模型
    print(f"正在加载ONNX模型:{ONNX_MODEL}")
    ret = rknn.load_onnx(model=ONNX_MODEL)
    if ret != 0:
        print("❌ 加载ONNX模型失败!")
        exit(ret)
    print("✅ ONNX模型加载成功")

    # 4. 构建RKNN模型,开启量化
    print("正在构建RKNN模型,开启INT8量化...")
    ret = rknn.build(
        do_quantization=True,  # 必须开启量化,不然没法用NPU加速
        dataset=DATASET_TXT     # 量化校准数据集,核心中的核心
    )
    if ret != 0:
        print("❌ 构建RKNN模型失败!")
        exit(ret)
    print("✅ RKNN模型构建成功")

    # 5. 导出RKNN模型文件
    print(f"正在导出RKNN模型:{RKNN_MODEL}")
    ret = rknn.export_rknn(RKNN_MODEL)
    if ret != 0:
        print("❌ 导出RKNN模型失败!")
        exit(ret)
    print(f"✅ RKNN模型导出成功!文件:{RKNN_MODEL}")

    # 6. 【可选】PC端仿真推理,验证模型能不能正常跑
    print("正在执行PC端仿真推理验证...")
    # 随便拿一张测试图做预处理
    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)

    # 初始化仿真runtime
    ret = rknn.init_runtime(target="rk3576", device_simulator=True)
    if ret != 0:
        print("❌ 初始化仿真环境失败!")
        exit(ret)

    # 推理
    outputs = rknn.inference(inputs=[img])
    print(f"✅ 仿真推理成功!输出形状:{outputs[0].shape}")

    # 释放资源
    rknn.release()
    print("🎉 全流程执行完成!RKNN模型转换&验证成功!")

必须准备的量化校准数据集quant_dataset.txt

这是决定量化后精度掉不掉的核心,90% 的新手量化后精度暴跌,都是因为这个文件没做好。

【新手概念科普】量化校准数据集,就是给 RKNN 工具提供一批真实场景的图片,工具会用这些图片统计模型每一层的数值分布,来做量化校准。校准用的图片越贴合真实场景,量化后的精度损失就越小。

商用级量化数据集制作规范(严格照着做,精度损失≤1%)
  1. 图片数量:10~20 张,别太少(少于 5 张校准不准),别太多(多于 50 张没必要,还慢)

  2. 图片要求:必须是你的售货柜摄像头拍的真实场景图,覆盖不同光线、不同角度、不同商品、不同摆放方式,绝对不能用网图、精修图、纯白背景图,不然校准出来的模型放到真实场景里直接精度暴跌

  3. txt 文件写法:每一行写一张图片的相对路径,比如: plaintext

    复制代码
    quant_img/1.jpg
    quant_img/2.jpg
    quant_img/3.jpg
    ...
    quant_img/20.jpg
  4. 图片格式:jpg/png 都可以,分辨率和训练时一致,640×640 最好

运行脚本

在 Anaconda Prompt 里,激活 rknn 虚拟环境,进入脚本所在的文件夹,输入命令:

bash

运行

复制代码
python onnx2rknn.py

等待运行完成,没有报错,你就会在文件夹里得到best.rknn文件 ------ 这就是能在 RK3576 NPU 上跑的模型了!


五、新手必踩:INT8 量化后精度暴跌?4 招彻底解决

很多新手跑通了转换,结果一测试,INT8 量化后的模型精度比 FP32 的 ONNX 模型掉了 10% 以上,商品全认错,心态直接崩了。别慌,我给你总结了 4 个必做的修复步骤,按顺序来,基本能把精度损失控制在 1% 以内:

  1. 最高优先级:重做量化校准数据集90% 的精度暴跌,都是校准数据集不行。必须用售货柜真实场景的图,覆盖所有商品、所有光线、所有摆放方式,别用网图、别用纯白背景图,重新做 txt 文件,重新转换。
  2. 检查 ONNX 导出是否正确 必须加--simplify,必须固定opset=12,必须固定batch=1,必须关闭动态输入,少一个都可能导致量化后精度异常。
  3. 调整量化配置 如果还是有精度损失,把 config 里的quantized_dtype改成"dynamic_fixed_point-i8",动态定点量化对 YOLO 的适配更好,精度损失更小。
  4. 逐层量化校准如果某一层的精度损失特别大,可以用 RKNN-Toolkit2 的逐层量化功能,给精度敏感的层设置 FP16 精度,其他层用 INT8,兼顾速度和精度。

六、PC 端仿真精度验证,确保模型没问题

转换完成后,别着急烧到板子上,先在 PC 端做仿真精度验证,对比 RKNN 模型和 ONNX 模型的输出差异,确保精度没问题。我给你写了一段极简的验证代码,直接就能用:

python

运行

复制代码
from rknn.api import RKNN
import onnxruntime as ort
import cv2
import numpy as np

# 加载RKNN模型
rknn = RKNN(verbose=False)
rknn.load_rknn("best.rknn")
rknn.init_runtime(target="rk3576", device_simulator=True)

# 加载ONNX模型
session = ort.InferenceSession("best.onnx", providers=["CPUExecutionProvider"])
input_name = session.get_inputs()[0].name

# 预处理测试图
img = cv2.imread("test.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_resize = cv2.resize(img_rgb, (640, 640))
img_input = np.expand_dims(img_resize, axis=0)
onnx_input = np.expand_dims(img_resize.transpose(2,0,1), axis=0).astype(np.float32)/255.0

# 分别推理
rknn_output = rknn.inference(inputs=[img_input])[0]
onnx_output = session.run([], {input_name: onnx_input})[0]

# 计算输出差异
diff = np.mean(np.abs(rknn_output - onnx_output))
print(f"RKNN与ONNX模型输出平均差异:{diff:.6f}")
if diff < 0.001:
    print("✅ 差异小于0.001,精度损失极小,完全可用")
else:
    print("⚠️  差异过大,需要重新校准量化")

rknn.release()

输出差异小于 0.001,就说明你的 RKNN 模型完全没问题,精度损失可以忽略不计,放心放到 RK3576 板子上用。

相关推荐
君不见~2 小时前
在YOLO11中引入LWGA轻量分组注意力模块(AAAI 2026),实现涨点,保姆级别教程
yolo·yolo11·yolo改进·yolo涨点
duyinbi75173 小时前
感受野坐标注意力卷积改进YOLOv26双向空间加权与自适应通道建模协同突破
人工智能·yolo·目标跟踪
阿拉斯攀登3 小时前
【无人售货柜・RK+YOLO】篇 6:安卓端落地!RK3576 + 安卓系统,YOLO RKNN 模型实时推理保姆级教程
android·人工智能·yolo·目标跟踪·瑞芯微·嵌入式驱动
Cpsu4 小时前
EdgeCrafter:实时目标检测任务新SOTA
人工智能·yolo·目标检测·计算机视觉
JicasdC123asd20 小时前
密集残差瓶颈网络改进YOLOv26特征复用与梯度传播双重优化
网络·yolo·目标跟踪
JicasdC123asd1 天前
密集连接瓶颈模块改进YOLOv26特征复用与梯度流动双重优化
人工智能·yolo·目标跟踪
duyinbi75171 天前
局部特征提取改进YOLOv26空间移位卷积与轻量化设计双重突破
人工智能·yolo·目标跟踪
张道宁1 天前
基于Spring Boot与Docker的YOLOv8检测服务实战
spring boot·yolo·docker
duyinbi75171 天前
大核瓶颈架构改进YOLOv26扩大感受野与多尺度特征提取双重突破
yolo·架构