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

【无人售货柜・RK+YOLO】篇 5:RK3576 部署第一步!YOLO 模型转 RKNN 全流程,新手必避的量化大坑 目录一、先给新手扫盲什么是 RKNN为什么必须转这个格式新手必守的部署红线提前避坑一步都不能破二、第一步YOLOv5 pt 模型 → 导出 ONNX 格式最关键90% 的坑都在这准备工作导出命令直接复制就能用全平台通用每个参数的意义 避坑解释导出后必做的 3 项检查少一项都可能踩坑三、第二步RKNN-Toolkit2 环境搭建新手零报错版环境锁死一个都不能改搭建步骤四、第三步ONNX 转 RKNN 完整脚本直接复制就能用完整转换脚本必须准备的量化校准数据集quant_dataset.txt商用级量化数据集制作规范严格照着做精度损失≤1%运行脚本五、新手必踩INT8 量化后精度暴跌4 招彻底解决六、PC 端仿真精度验证确保模型没问题大家好我是黒漂技术佬。上一篇我们把售货柜专用的 YOLO 模型优化到了商用级精度mAP0.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它才能说得又快又准。新手必守的部署红线提前避坑一步都不能破工具版本锁死RKNN-Toolkit2 必须用v1.6.0稳定版别追最新版最新版对 YOLOv5 的算子支持反而有坑v1.6.0 是目前 RK3576 适配最稳、坑最少的版本输入规格锁死固定batch1固定输入尺寸 640×640绝对不要用动态 batch、动态尺寸RK3576 的 NPU 对动态输入支持极差必踩坑量化方式锁死INT8 不对称量化别用 FP16FP16 速度慢一倍、内存占用高一倍售货柜场景 INT8 完全够用精度损失能控制在 1% 以内算子红线绝对不要用 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固定批次为 1RK3576 的 NPU 推理只支持固定 batch1动态 batch 直接不支持--device cpu用 CPU 导出避免 GPU 导出带来的算子兼容问题新手必加--include onnx只导出 ONNX 格式别导出其他无关格式--simplify【核心必加】用 onnx-simplifier 简化 ONNX 模型去掉冗余算子、合并常量大幅提升 RKNN 兼容性90% 的算子不支持报错都是因为没加这个参数--opset 12【核心必锁】ONNX 的算子版本必须设 12RKNN-Toolkit2 对 13 以上的高版本 opset 支持极差必报错--dynamic False关闭动态输入固定输入尺寸RK3576 对动态输入支持极差必踩坑导出后必做的 3 项检查少一项都可能踩坑导出成功后你会在根目录得到best.onnx文件别着急转 RKNN先做这 3 项检查输入输出维度检查用 Netron新手必装的 ONNX 可视化工具免费开源打开best.onnx确认输入维度是[1,3,640,640]输出维度是[1,25200,nc5]nc 是你的商品类别数比如 10 类商品输出就是[1,25200,15]完全正确才能继续。算子结构检查看 Netron 里的模型结构有没有if/loop这类控制流算子或者不认识的自定义算子。正常简化后的 YOLOv5s 模型结构非常干净全是卷积、激活这些基础算子有多余算子必须重新导出一定要加--simplify。推理有效性检查写一段极简代码验证 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, axis0).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别用最新版坑巨多搭建步骤先装 Anaconda新手必用避免环境冲突官网下载 Python3.8 对应的版本一键安装记得勾选Add to PATH。打开 Anaconda Prompt创建专属虚拟环境输入命令bash运行conda create -n rknn python3.8 conda activate rknn安装 RKNN-Toolkit2 和配套依赖一行命令搞定bash运行pip install rknn-toolkit21.6.0 onnx1.12.0 onnxruntime1.13.1 opencv-python numpy1.23.5 -i https://pypi.tuna.tsinghua.edu.cn/simple验证安装是否成功在虚拟环境里输入 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(verboseFalse) # verboseTrue可以看详细日志排错用 # 2. 【核心配置】RKNN模型预处理量化配置新手别瞎改 rknn.config( # 预处理归一化对应YOLO的 像素/255所以mean是0std是255 mean_values[[0, 0, 0]], std_values[[255, 255, 255]], # 目标平台必须写rk3576别写错 target_platformrk3576, # 量化方式INT8不对称量化售货柜场景最优精度损失最小 quantized_dtypeasymmetric_quantized-u8, # 优化级别最高级提升推理速度 optimization_level3, ) # 3. 加载ONNX模型 print(f正在加载ONNX模型{ONNX_MODEL}) ret rknn.load_onnx(modelONNX_MODEL) if ret ! 0: print(❌ 加载ONNX模型失败) exit(ret) print(✅ ONNX模型加载成功) # 4. 构建RKNN模型开启量化 print(正在构建RKNN模型开启INT8量化...) ret rknn.build( do_quantizationTrue, # 必须开启量化不然没法用NPU加速 datasetDATASET_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, axis0) # 初始化仿真runtime ret rknn.init_runtime(targetrk3576, device_simulatorTrue) 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%图片数量10~20 张别太少少于 5 张校准不准别太多多于 50 张没必要还慢图片要求必须是你的售货柜摄像头拍的真实场景图覆盖不同光线、不同角度、不同商品、不同摆放方式绝对不能用网图、精修图、纯白背景图不然校准出来的模型放到真实场景里直接精度暴跌txt 文件写法每一行写一张图片的相对路径比如plaintextquant_img/1.jpg quant_img/2.jpg quant_img/3.jpg ... quant_img/20.jpg图片格式jpg/png 都可以分辨率和训练时一致640×640 最好运行脚本在 Anaconda Prompt 里激活 rknn 虚拟环境进入脚本所在的文件夹输入命令bash运行python onnx2rknn.py等待运行完成没有报错你就会在文件夹里得到best.rknn文件 —— 这就是能在 RK3576 NPU 上跑的模型了五、新手必踩INT8 量化后精度暴跌4 招彻底解决很多新手跑通了转换结果一测试INT8 量化后的模型精度比 FP32 的 ONNX 模型掉了 10% 以上商品全认错心态直接崩了。别慌我给你总结了 4 个必做的修复步骤按顺序来基本能把精度损失控制在 1% 以内最高优先级重做量化校准数据集90% 的精度暴跌都是校准数据集不行。必须用售货柜真实场景的图覆盖所有商品、所有光线、所有摆放方式别用网图、别用纯白背景图重新做 txt 文件重新转换。检查 ONNX 导出是否正确必须加--simplify必须固定opset12必须固定batch1必须关闭动态输入少一个都可能导致量化后精度异常。调整量化配置如果还是有精度损失把 config 里的quantized_dtype改成dynamic_fixed_point-i8动态定点量化对 YOLO 的适配更好精度损失更小。逐层量化校准如果某一层的精度损失特别大可以用 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(verboseFalse) rknn.load_rknn(best.rknn) rknn.init_runtime(targetrk3576, device_simulatorTrue) # 加载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, axis0) onnx_input np.expand_dims(img_resize.transpose(2,0,1), axis0).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(fRKNN与ONNX模型输出平均差异{diff:.6f}) if diff 0.001: print(✅ 差异小于0.001精度损失极小完全可用) else: print(⚠️ 差异过大需要重新校准量化) rknn.release()输出差异小于 0.001就说明你的 RKNN 模型完全没问题精度损失可以忽略不计放心放到 RK3576 板子上用。