售货柜实战:端到端优化落地全记录
最后一篇实战,把前面 11 篇的知识全部串起来。从模型选型、训练优化、量化转换、推理加速、多路架构到工程化部署,完整讲一遍售货柜商品识别系统是怎么从 0 到 1 落地的,踩过哪些坑、每一步优化了多少。
大家好,我是黒漂技术佬。
这是边缘AI部署系列的最后一篇,也是实战篇。售货柜商品识别这个项目我做了挺久,从最开始的 demo 到量产落地,前前后后优化了四五版。
这篇把整个过程完整记录下来:模型怎么选的、训练怎么调的、量化掉点怎么解决的、推理速度怎么一步步提上来的、工程化踩了哪些坑。
一、项目背景
需求
智能售货柜,用户开门拿商品,关门自动结算。靠摄像头视觉识别拿了什么商品。
硬件
- 主控:RK3588(8G 内存版)
- 摄像头:2 路 1080p IPC 摄像头(主货架 + 副货架)
- 网络:4G + WiFi
性能要求
- 单路推理:≥ 20fps
- 商品识别准确率:≥ 95%
- 关门结算时间:≤ 2 秒
- 7×24 小时稳定运行
- 支持远程模型升级
商品数量
初期 30 种 SKU,后续扩展到 60+ 种。
二、第一版:基线版本
模型选型
一开始选了 YOLOv5s,理由:
- 社区成熟,资料多
- 精度不错
- 60 类以内应该够用
训练
- 数据集:每种商品 200 张左右,共约 6000 张
- 增强:默认 Mosaic + 翻转 + 颜色抖动
- 训练:300 epochs,默认参数
部署
- 导出 ONNX → onnxsim 简化 → 转 RKNN INT8
- 单线程同步推理
- OpenCV 做预处理
效果
| 单路推理速度 | ~12fps | 不够,要求 20fps |
| mAP(测试集) | 91.3% | 一般 |
| 端到端延迟 | ~120ms | 慢 |
| CPU 占用 | ~60% | 偏高 |
| 稳定性 | 偶尔断流崩溃 | 不行 |
问题总结:
三、第二版:模型与训练优化
优化 1:换 YOLOv8n
把 v5s 换成 v8n,参数量更小,架构更新。
- 模型大小:14M → 3.2M
- 推理速度:12fps → 22fps
- mAP:91.3% → 90.8%(几乎没掉)
速度几乎翻倍,精度基本持平。架构升级的收益比加大模型更划算。
优化 2:数据增强加强
- 加了高斯噪声、运动模糊(模拟摄像头模糊)
- 加了随机遮挡(模拟手挡、商品叠放)
- Mosaic 全程开启
- 亮度对比度抖动幅度加大
mAP:90.8% → 92.5%(+1.7%)
优化 3:知识蒸馏
用 YOLOv8m 当教师模型蒸馏 v8n:
- 温度 T=4
- 蒸馏损失比例 0.5
mAP:92.5% → 93.8%(+1.3%)
白嫖的精度,必做。
优化 4:难例补充
收集了一波 bad case:
- 底部货架角度偏的
- 反光场景的
- 商品部分露出的
每个难例场景补充 50-100 张。
mAP:93.8% → 95.1%(+1.3%)
第二版小结
| 推理速度 | 12fps | 22fps | +83% |
| mAP | 91.3% | 95.1% | +3.8% |
| 模型大小 | 14MB | 3.2MB | -77% |
模型层面的优化效果显著。
四、第三版:量化与推理优化
优化 1:量化调优
默认量化掉点有点多(95.1% → 92.7%,掉 2.4%)。
调优过程:
最终 INT8 mAP:94.4%(掉 0.7%,可接受)
推理速度:22fps → 38fps(FP16 → INT8,快了 70%+)
优化 2:RGA 硬件预处理
把 OpenCV 软件缩放换成 RGA 硬件加速:
- 预处理耗时:~15ms → ~2ms
- 端到端延迟大幅下降
优化 3:零拷贝输入
用 RKNN 零拷贝接口,少一次内存拷贝。
推理 + 拷贝:~26ms → ~22ms
优化 4:三阶段流水线
拉流解码 → 预处理 → 推理 → 后处理,每个阶段独立线程,队列串起来。
单路稳定 35fps+,端到端延迟 ~50ms。
优化 5:CPU 绑核
推理和预处理线程绑 A76 大核,拉流线程用小核。
帧率更稳定,不会被系统调度影响。
第三版小结
| 推理速度 | 22fps | 38fps | +73% |
| 端到端延迟 | ~120ms | ~50ms | -58% |
| INT8 mAP | 92.7% | 94.4% | +1.7% |
| CPU 占用 | ~60% | ~20% | -67% |
部署侧的优化收益也很大,而且精度还提升了(量化调优的功劳)。
五、第四版:多路架构与工程化
多路架构
两路摄像头,每路独立流水线:
- 主摄像头(1080p,商品识别):NPU 两核,30fps
- 副摄像头(720p,辅助检测):NPU 一核,15fps
NPU 独立模式分配,两路并行不打架。
稳定性优化
业务逻辑优化
工程化
第四版最终效果
| 单路推理速度 | ≥20fps | 38fps |
| 识别准确率 | ≥95% | 96.2%(多帧投票后) |
| 结算时间 | ≤2秒 | ~1秒 |
| CPU 占用 | – | ~20% |
| 稳定性 | 7×24h | 连续运行 30 天无崩溃 |
全部满足需求,还有不少余量。
六、整体优化路线回顾
从第一版到第四版,整体提升:
| 推理速度 | 12fps | 38fps | 3.2 倍 |
| mAP | 91.3% | 94.4%(单帧)/ 96.2%(多帧) | +3~5% |
| 端到端延迟 | ~120ms | ~50ms | 快 2.4 倍 |
| CPU 占用 | ~60% | ~20% | 降 2/3 |
| 模型大小 | 14MB | 3.2MB | 小 77% |
优化是一层层叠加的:
- 模型选型:速度 ×1.8
- 量化:速度 ×1.7
- 预处理加速:延迟 -50%
- 流水线:吞吐 ×1.5
- 训练优化:精度 +4%
没有哪一步是「银弹」,每一步优化一点,加起来就很多了。
七、踩过的坑 Top 10
坑 1:ONNX 导出 opset 太高
一开始用 opset 17,转 RKNN 各种算子不支持。换回 opset 12 就好了。
坑 2:RGB/BGR 搞反
RKNN 默认 RGB,OpenCV 默认 BGR,推理结果全错。排查了半天才发现。
坑 3:量化校准集太单一
一开始校准集全是正常光照的图,暗光场景量化误差大,漏检多。补充各种场景后好了。
坑 4:多线程共用一个 RKNN context
一开始图省事多路共用一个 context,偶发崩溃。改成每个线程一个 context 就稳了。
坑 5:RTSP 断流程序卡死
没加超时,断流了就一直卡着。加了 stimeout 和外层重连循环解决。
坑 6:预处理 letterbox 不对齐
训练时的 letterbox 和推理时的实现不一样,偏移差了几个像素,小目标检测影响大。
坑 7:NPU 降频
设备散热不好,跑久了 NPU 降频,速度越来越慢。加了散热片、设了温度策略。
坑 8:模型更新后格式不兼容
改了输出格式,老版本代码解析崩了。后来加了版本校验和向前兼容。
坑 9:内存泄漏
C++ 代码里几处忘记释放 RKNN 内存,跑几天内存满了。加了内存池和 valgrind 检查。
坑 10:4G 流量超标
一开始全量下载模型,一次几十 MB,设备多了流量费爆炸。改成差分更新 + 闲时下载。
八、经验总结
1. 先跑通再优化
别一开始就追求极致性能,先把基础功能跑通,再一步步优化。
2. 优化前先测瓶颈
不知道慢在哪就瞎优化,纯属浪费时间。每个阶段打点,找到最慢的地方针对性优化。
3. 小模型 + 好训练 > 大模型 + 随便训
模型大小的收益,很多时候不如数据和训练策略的优化大。
4. 工程化和算法一样重要
算法精度再高,服务天天崩也没用。稳定性、可维护性、可升级性,都是产品级必须的。
5. 边缘部署是系统工程
不是模型转完就完事了,摄像头、解码、预处理、推理、后处理、业务逻辑、网络、运维,每一环都影响最终效果。
九、系列总结
12 篇边缘AI部署系列到此结束,回顾一下覆盖的内容:
基础篇(1-2):边缘部署概述、模型选型与轻量化
训练优化篇(3-4):训练调优、知识蒸馏、模型剪枝
量化篇(5-7):量化原理、RKNN 转换、量化调优实战
推理优化篇(8-9):RK3588 推理优化、多路并发架构
落地篇(10-11):精度评估与 bad case、部署工程化
实战篇(12):售货柜端到端落地全记录
从模型选型到训练优化,从量化转换到推理加速,从架构设计到工程落地,整个边缘AI部署的链路都覆盖了。
边缘部署的核心不是某一个技术点,而是「在有限资源下平衡精度、速度、功耗、稳定性」的系统工程。理解了这个思路,换什么平台、什么模型都能快速上手。
我是黒漂技术佬,这个系列就到这里。下个系列见。



