RK平台YOLO商品识别部署全流程:训练到RKNN转换实战

发布时间:2026/10/21 17:57:02

RK平台YOLO商品识别部署全流程:训练到RKNN转换实战 做无人售货柜项目绕不开的一个核心问题怎么稳定识别用户从柜子里拿走的到底是哪件商品。我前面两篇聊过硬件选型和整体系统框架这篇终于到硬核环节——在RK平台上跑通YOLO商品识别的完整链路环境搭建、数据集整理、模型训练、转RKNN部署一条线走下来。这篇我尽量把每一条命令都写清楚不玩虚的适合正在做边缘视觉项目、尤其是不太熟悉RK平台NPU开发流程的朋友照着敲。先说清楚这篇解决什么问题把“摄像头拍到商品图”变成“程序直接告诉你这是可乐还是薯片”这套流程落地。R系列开发板负责算YOLO模型负责认。后面所有内容都是围绕这个目标展开的。1. 先搞清楚方案为什么长这样1.1 商品识别为什么比想象中难很多第一次做售货柜的朋友会觉得识别商品不就是普通的目标检测吗拿个开源模型就能跑。真上线之后你会发现事情没那么简单。无人售货柜里的商品有这几个天然debuff塑料瓶和易拉罐反光严重PET材质瓶身几乎是透明的袋装零食包装上的图案和文字会随着摆放角度发生折叠变形柜内光照不均匀某个角落可能长期处于暗区或者强曝光最麻烦的是用户拿取商品时手会遮挡住目标可能连续好几帧都看不到完整瓶身。再加上货道上的商品排列密集同类商品摆在一起边界框很容易重叠。所以这个场景不能靠简单的分类网络解决必须用目标检测把“哪个位置是什么商品”一次性找出来。这也是为什么我用YOLO系列而不是ImageNet分类模型的原因——既要定位又要分类YOLO这类单阶段检测器在边缘设备上部署最成熟。1.2 为什么是RK平台加YOLO而不是别的组合先放一段方案对比都是我实际调研过的路方案成本识别精度维护性适合场景重力/重量传感器低差相似重量商品完全无法区分需要频繁校准单货道形态单一的小柜子RFID标签标签成本高柜子改造成本高只认标签不认商品标签脱落就没辙每个商品都要贴标高端短保商品SKU少的场景云端视觉识别算法迭代快精度高但依赖网络需购GPU资源延迟不可控对延迟不敏感的场景边缘视觉RK YOLO板卡几百块无功耗压力精度够用离线可用模型可本地更新售货柜、自助终端这类边缘设备我当时选RK平台核心原因是两点一是板卡上集成了NPU跑量化后的YOLO模型完全没问题整机功耗能压住二是产品部署在现场断网或者网络抖动时识别绝不能停所有推理必须在本地完成。如果某天云端临时不可用整个柜子就瘫痪了这在商场上可没法交代。1.3 整体流程只有这么长不搞复杂架构一条线走通即可摄像头画面 - 抽帧 - 图像预处理 - RK板NPU推理YOLO检测 - 后处理NMS - 识别结果与货道映射 - 生成扣费订单后两级关于业务逻辑的部分我之前那篇已经聊过这篇集中在红框部分环境、训练、转换、部署。搞清楚这个边界后面看流程不会迷路。2. 环境搭建先把训练侧和板端侧两套环境洗干净标题写着“一行行代码带敲”那这一节就实打实来。环境分两套一套是训练模型用的PC环境另一套是RK板上跑推理的环境千万别混在一起。2.1 训练侧Ubuntu CUDA PyTorch环境我首选Ubuntu 20.04或者22.04Windows也不是不行但在CUDA环境和后续RKNN转换时总有一些莫名其妙的坑老老实实Ubuntu省心。装好系统之后第一步确认显卡驱动nvidia-smi看到类似CUDA Version: 12.4的输出就行。驱动版本会影响你装CUDA工具链但实际训练时PyTorch自带的CUDA runtime和你系统装的CUDA工具链是解耦的主要看驱动支持的上限版本不用强行装最新的CUDA Toolkit。接下来创建独立环境别一上来就pip install到系统Python里后面版本冲突会让你怀疑人生conda create -n yolo python3.10 -y conda activate yoloPython版本我建议3.10YOLOv8和RKNN工具链在这个版本下兼容性最好3.12某些底层库还没跟上。安装PyTorchCUDA版本根据自己的驱动来选pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121然后安装YOLO训练框架pip install ultralytics验证环境是否可用python -c import torch; print(torch.cuda.is_available()); print(torch.__version__)输出True说明GPU这边通了。这里有个常见问题明明有NVIDIA显卡却输出False多半是驱动没装好或者PyTorch版本和CUDA不匹配下载的wheel跟你机器驱动不兼容。这个问题排查思路就一个nvidia-smi能看到驱动PyTorch才能用上CUDA逐层确认。2.2 RK侧环境主机端rknn-toolkit2RK平台的推理流程是先用RKNN-Toolkit2在PC上将训练好的模型转换成RKNN格式再拷贝到板子上用运行时库跑。这是典型的交叉开发模式——训练和转换在PC推理在板子。所以主机的另一个环境是rknn-toolkit2。我一般是单独建一个conda环境避免和训练环境打架conda create -n rknn python3.10 -y conda activate rknn pip install rknn-toolkit21.5.2版本号要看你的NPU驱动和板端runtime版本。这里有个硬性要求主机端的rknn-toolkit2版本和板端的rknpu2运行时库版本必须对应跨版本转换出来的模型在板子上可能直接崩溃。我建议你先确定板子的NPU驱动版本再倒推安装匹配的工具链。2.3 板载环境rknpu2运行时库板子端我用的系统是Ubuntu一个小众镜像自带NPU驱动和运行时库。如果板子是干净系统需要把rknpu2的运行时库拷进去git clone https://github.com/airockchip/rknpu2 cd rknpu2/runtime/Linux/librknn_api/aarch64 cp librknnrt.so /usr/lib/然后在板子上用Python调推理的话再把rknn-toolkit2里的rknn推理接口库拷到项目目录就行。注意板端不用装完整版rknn-toolkit2只需要运行时库和Python封装。提示rknpu2运行时库的版本必须和模型转换时用的rknn-toolkit2版本一致。这条规则优先级最高很多“模型在板子上跑不了”的问题都是这俩版本没对上。3. 数据准备商品识别训练的地基工程模型训练这事数据质量决定精度上限。YOLO再强标注错误的数据喂进去训练出来也是一团浆糊。3.1 数据采集别全拿网图糊弄我踩过一个大坑一开始为了省事大量使用商品官网图、白底图训练结果放到现场识别率打对折。原因是现场柜内的光照、角度、背景和官网图差距太大模型学到的特征根本没法迁移。正确的采集方式是在实际的货柜内部或者模拟柜体内拍多角度正视、俯视、侧视45度、用户拿取时的斜角度多光照白天自然光、夜间LED灯带、曝光不足的暗角情况多放置状态正放、倒放、横放、半遮挡、多件商品紧挨我在项目里是拿一台USB摄像头架在柜内固定位置把商品摆在不同货道连续录制视频然后抽帧能高效产生大量带真实场景噪声的样本。一帧一帧拍摄太慢了视频抽帧能让你半天搞定上千张图。3.2 标注格式与工具标注工具我用LabelImg偏多因为它导出YOLO格式很直接界面也简单。框选目标后直接保存会生成一个同名的txt文件内容格式如下0 0.523437 0.482638 0.226562 0.319444 1 0.761718 0.206018 0.140625 0.277778这五个数字依次是类别ID、边界框中心点x坐标归一化、中心点y坐标归一化、框宽度归一化、框高度归一化。归一化是相对于图片宽高而言的。一个容易忽略的点类别ID顺序在训练集和数据集配置文件中必须严格一致最好一开始就用一个类别清单固定住。我项目里维护了一份classes.txt比如0 可乐 1 雪碧 2 某品牌薯片 3 某品牌苏打水 ...加新商品时只追加不修改已有ID否则以前标注的txt全部要重做。3.3 目录结构与划分YOLO训练框架对目录结构有约定我用的是最常见的布局dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── dataset.yaml批量划分可以用一个简单脚本import os, random, shutil random.seed(42) data_dir all_imgs train_dir dataset/images/train val_dir dataset/images/val os.makedirs(train_dir, exist_okTrue) os.makedirs(val_dir, exist_okTrue) imgs [f for f in os.listdir(data_dir) if f.endswith(.jpg)] val_batch random.sample(imgs, int(len(imgs) * 0.2)) for img in imgs: src_img os.path.join(data_dir, img) src_label os.path.join(all_labels, img.replace(.jpg, .txt)) if img in val_batch: shutil.copy(src_img, val_dir) shutil.copy(src_label, dataset/labels/val) else: shutil.copy(src_img, train_dir) shutil.copy(src_label, dataset/labels/train)比例我习惯8:2。这里有一个想法要说清楚验证集不只是随便留出20%就完事验证集里的图片场景分布要尽量贴近真实部署环境别训练集全是白天光线验证集全是暗光那样loss曲线会很有欺骗性。3.4 数据增强和负样本YOLOv8内置了mosaic、翻转、色域变换这些增强手段默认开不用多操心。但有一个东西必须自己加负样本。什么叫负样本就是完全不包含任何商品的图片比如柜内空无一物的背景、手伸进去但没抓东西的瞬间。这些图对应的txt文件是空的。加入负样本是为了降低误检率防止模型在处理空货道时乱报目标。我建议负样本比例控制在总样本量的10%左右过多会稀释正样本的学习。4. 一行行跑通YOLO训练全流程4.1 模型选型YOLOv8n还是YOLOv8sYOLOv8有几个规格nano、small、medium参数量和计算量递增。边缘部署不是越大越好关键看NPU算力和延迟预算。我实测下来在RK平台上模型规格参数量mAP50-95典型商品集单帧延迟NPUINT8量化后YOLOv8n约3.2M0.55-0.62约20-35msYOLOv8s约11.2M0.62-0.70约40-60msYOLOv8m约25.9M0.68-0.75约80-120ms无人售货柜的识别帧率不需要太高拿到稳定的识别结果比追求高帧率更关键但延迟也不能超过200ms不然用户体验很割裂。我最终选了YOLOv8s做权衡如果柜内SKU不多目标种类就十来个直接用YOLOv8n也完全够用推理速度还能快一倍。4.2 修改数据集配置和超参数在项目目录下写一个dataset.yamlpath: /home/user/project/dataset train: images/train val: images/val names: 0: cola 1: sprite 2: chips 3: sodanames里的顺序和标注txt里的类别ID一致。这一步错位训练出来的模型预测结果就全是乱的。训练时我用的命令行参数如下yolo detect train \ datadataset.yaml \ modelyolov8s.pt \ epochs200 \ imgsz640 \ batch32 \ device0 \ lr00.01 \ patience50逐行说明data刚写的dataset.yaml路径model先用官方预训练权重做迁移学习而不是从随机初始化开始训练。迁移学习能显著缩短收敛时间商品数据本身就少用预训练权重是常规操作epochs200轮起步。如果你数据量只有几百张开太多轮容易过拟合配合下面的早停机制imgsz输入分辨率。商品识别里很多目标是中小尺寸640够用。如果发现小目标漏检严重可以提高到960但推理速度会明显下降batch取决于GPU显存32G显存跑YOLOv8s这个量级没压力显存不够就把batch降到16lr0初始学习率0.01是默认值迁移学习时不用改。如果训练时loss剧烈震荡可以降到0.005patience验证集指标连续50轮不提升就自动停止省时间4.3 训练中间看什么训练启动后别干等重点关注两个东西train/loss曲线和验证阶段的mAP指标。正常情况下loss曲线是平滑下降的如果出现loss先降后升八成是学习率过大或者过拟合。mAP50在商品识别里会比mAP50-95高得多因为商品类别的框基本都是方正的对IoU没那么敏感。训练结束后在runs/detect/train/weights/下会生成best.pt和last.pt。best.pt是验证集上表现最好的权重部署用这个。4.4 一次完整的验证训练完先别急着转RKNN在PC上用测试图看一下效果yolo predict modelruns/detect/train/weights/best.pt sourcetest_images/ imgsz640输出结果里会有识别出的框、类别和置信度。这一步看着简单却能提前发现一堆问题类别有没有错乱、框有没有偏移、是不是明显漏检。如果这一步效果就很差先回去查数据标注模型本身的问题反而少。5. 模型转换从PyTorch到RKNN这是RK平台项目里最核心的一步也是拦路虎最多的一步。很多人在这一步卡住看到各种算子不支持就慌了。5.1 PyTorch模型导出ONNXRKNN-Toolkit不能直接吃PyTorch的pt权重要先转成ONNX格式。还是用工具链yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 opset12opset12要特别注意。RKNN工具链对太新的ONNX算子支持有限opset超过12后某些算子转换时会炸。我自己就遇到过opset17导出后转换报“不支持某个Split变体”的错改成12就一切正常。导出的best.onnx可以用Netron打开可视化检查输出节点对不对。YOLOv8的ONNX输出格式和v5不同是一个1x84x8400的张量8400是不同尺度特征图上的候选框数量84是4个坐标、1个置信度加80个类别分数。做部署后处理时要按这个格式解析别套v5的旧代码。5.2 RKNN转换脚本新建一个convert.pyfrom rknn.api import RKNN rknn RKNN() rknn.config( mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588, quantized_dtypew8a8 ) ret rknn.load_onnx(modelbest.onnx) if ret ! 0: print(load onnx failed) exit(-1) ret rknn.build(do_quantizationTrue, datasetquant_dataset.txt) if ret ! 0: print(build failed) exit(-1) rknn.export_rknn(best.rknn) rknn.release()几个参数逐个说明mean_values和std_values做输入归一化用的。我训练时没做特殊归一化所以这里就是经典的0减去后除以255。如果你训练时用了自定义归一化这里必须和训练时完全一致否则推理结果会差到离谱target_platform指定NPU平台型号不同平台生成模型格式不能互通quantized_dtypew8a8权重和激活都量化为INT8。RK平台在INT8下推理速度远快于FP16前提是校准集质量要好5.3 量化校准集quant_dataset.txt文件里列的是用于量化的图片路径每行一张图。这个校准集是INT8量化误差的决定因素比模型结构本身还关键。我写的第一版校准集用的全是训练集图片量化后精度下降了几个点换成现场柜内实拍图之后精度几乎无损。因为量化的本质是用一组真实输入来统计每层的激活值分布校准集的分布越接近实际场景量化误差就越小。校准集我一般放200到300张图覆盖所有SKU、不同光照和角度。文件内容就是一行一个路径没有其他花头/home/user/quant_imgs/001.jpg /home/user/quant_imgs/002.jpg ...5.4 RK平台板端推理模型转换出来之后写一个板端推理脚本Python跑起来验证import numpy as np from rknnlite.api import RKNNLite rknn_lite RKNNLite() rknn_lite.load_rknn(best.rknn) rknn_lite.init_runtime() img cv2.imread(test.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img img.astype(np.float32) / 255.0 img np.expand_dims(img, axis0) outputs rknn_lite.inference(inputs[img])这一步很容易出事儿的地方在两处。第一缩放方式训练时YOLO默认用letterbox保持宽高比的填充式缩放板端推理如果直接resize拉伸框的位置会错位。要么按letterbox方式处理要么在解析坐标时补偿缩放比例。第二输入张量布局rknn推理接口默认接受HWC的numpy输入不需要自己转NCHW。outputs拿到的是一个1x84x8400的数组。解码坐标时要把x、y、w、h还原到原图尺度h, w orig_img.shape[:2] gain min(640 / w, 640 / h) pad_x (640 - w * gain) / 2 pad_y (640 - h * gain) / 2然后把每个候选框的坐标减去pad再除以gain就得到原图坐标。最后再做NMSYOLO默认的输出里一个目标会有多个候选框不滤掉重框没法用。6. 常见问题排查与避坑速查做成一张表都是我实际踩过的或者同行反复问过的现象可能原因排查顺序与解决办法训练时loss是NaN学习率过大、数据集有标注越界先看标注txt里有没有大于1或者小于0的坐标再降lr到0.001mAP很高但现场识别差训练集和现场场景分布差异大重新采集现场图加到训练集重点覆盖不同光照RKNN转换报算子错误ONNX版本过高、模型结构过新导出ONNX时固定opset12换YOLOv8这种原生支持的模型量化后精度掉3个点以上校准集太少或分布偏差大校准集增加到300张全部用现场实拍图板端推理结果全为零输入预处理和训练不一致检查letterbox、归一化方式、数据布局推理耗时高模型规格大、输入分辨率高换YOLOv8n、imgsz降到640、确认INT8量化生效重复框一大堆后处理NMS没做或阈值不对自写NMSIoU阈值设0.45-0.5置信度阈值0.25两个相似商品经常混淆类别内视觉差异太小增加该类样本量、单独补充难负样本、考虑把相似商品合并成一个SKU处理其中一个很有代表性的问题量化后精度看起来还行但部署到现场发现某个特定角度、特定光线下总是漏检。这种问题往往是量化校准集里正好缺少这个角度的图把对应图片补进校准集重新量化即可收费昂贵但见效快。还有一个容易被忽略的时延细节在板端如果每个摄像机帧都做一次完整推理NPU占用率会很高。无人售货柜场景下我采用“运动检测触发”策略——只有画面中检测到位移变化时才跑YOLO推理。实测下来整机功耗和发热都明显下降识别准确率也没受影响。最后分享两个我在实际项目里的体会这套流程走通一次之后再回头做其他边缘识别项目就轻车熟路了。我个人体会最深的几点数据质量真的决定精度天花板。训练模型本身只是流水线操作花大量时间在调参上不如多拍500张现场照片、多标注一轮来的收益大。我在这个项目里前前后后采集了三轮数据每一轮都让准确率上了一个台阶。RK平台的NPU量化是一把双刃剑INT8推理速度快但如果校准集没弄好精度损失会远超预期。我的习惯是每次转换前先拿100张验证集图做一次量化精度对比确定校准集没问题再往板子上部署。最后别追求一步到位。先拿YOLOv8n跑通全链路再根据实测延迟和精度换s或者调整分辨率。链路通了你才有底气做后续优化。祝各位售货柜项目早日落地稳定出单。
延伸阅读

更多相关文章

2026/10/21 17:57:02

AI Agent长任务跑偏的根因与4个上下文工程解法

1. 为什么“长任务跑偏”不是模型能力问题,而是上下文设计失效 “AI Agent 长任务总跑偏”——这句话最近在多个技术社群里高频出现,几乎成了某类项目复盘会上的固定开场白。我见过某高校实验室开发的智能科研助手,在执行“从100篇PDF中提取方…

2026/10/21 17:57:02

基于Matlab的多能源微网双层调度模型:建模、求解与调参

多能源微网这个话题,这几年在电力系统领域的热度一直不减。我自己从做第一个微网算例开始,到后面接触各类园区级项目,最大的感受是:如果只用一个简单的单层优化模型去描述整个多能源微网,不是不行,而是到了…

2026/10/21 17:57:02

wire_api选chat还是responses?API语义边界决策指南

1. 标题背后的真实战场:不是语法选择,而是API语义边界的认知重构看到这个标题——“Codex 接中转站,wire_api 填 chat 还是 responses?”——我第一反应不是查文档,而是放下手头正在调试的接口,把笔记本翻到…

2026/10/21 19:08:13

图表设计方法论与实战:从信息架构梳理到工具选型

前几天整理技术方案文档的时候,我翻到了一张三个月前自己画的项目架构图。盯了十分钟,愣是没看懂当时为什么把用户模块放在右侧、为什么订单和支付之间有两条交叉线、那一大片淡黄色的分组到底想表达什么。真正让我沉默的是——这张图还挂在那份所有人都…

2026/10/21 19:08:13

图表设计工作流全解析:从信息架构到视觉落地

diagram-design 这种项目,乍一听像个工具库,实际上是把零零散散的信息梳理成别人一眼就能看懂的东西。不管是系统架构图、业务流程图,还是数据看板里的趋势图,本质都是在做同一件事:把复杂度打包,降低读者的…

2026/10/21 19:08:13

AI专著生成方法论:从大纲到终稿的五阶段流水线

去年底帮一位搞行业研究的同事收拾一套书稿,他把三年的调研资料和几十篇内部报告扔给大语言模型,指望一键生成一本专著,结果模型吐出来的东西乍看像模像样,细看全是“正确的废话”:目录结构完整、章节标题工整&#xf…

2026/10/21 19:08:13

C++入门学习避坑指南:从编译环境到内存管理核心要点

C入门学习这件事,我见过太多人兴冲冲地买了书、收藏了教程,结果在指针和内存那里卡了一个月,最后灰溜溜地转投其他阵营。说实话,C确实比大多数语言更“难啃”,但这个“难”很多时候不是智力问题,而是入门姿…

2026/10/21 19:08:13

手写C++解析X.509证书:从DER字节流到TLV树

证书文件我们每天都在打交道,但真正扒开DER字节流看底层的时刻并不多。做TLS握手、写嵌入式安全模块、搭证书管理平台的时候,总绕不开ASN.1编码和X.509结构;很多项目直接引第三方库,但一旦需要裁剪体积、适配特殊硬件,…

2026/10/21 19:03:08

PySide2嵌入Matplotlib实时图表:FigureCanvas与动态刷新全指南

做Qt桌面工具这几年,凡是涉及“加个图表”的需求,我第一反应都不是 plt.show() ,而是想清楚一个问题:matplotlib画出来的图,到底凭什么能被塞进PySide2的窗口里。很多刚开始做PySide2嵌入matplotlib的朋友&#xff0…

2026/10/21 4:53:08

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/21 0:00:35

交通流仿真实战:IDM跟驰与MOBIL换道模型参数调优与避坑指南

简介:这份资源是面向交通工程学习者与Python开发者的微观交通流仿真项目,核心实现智能驾驶模型(IDM)下的车辆跟驰与换道行为,可用于理解速度、密度与流量之间的动态关系,适合具备Python基础、希望深入交通模…

2026/10/21 0:00:35

揭穿智能体表面顺从:用追踪代码重建任务执行确定性

1. 表面顺从不是智能体的“礼貌”,而是任务执行链路上的隐性断点最近在调试一个跨平台长周期任务调度系统时,我反复遇到一种令人困惑的现象:智能体在用户指令发出后,几乎秒级响应“已收到”“正在处理”“请稍候”,UI上…

2026/10/21 0:00:35

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑