如何把视觉模型部署到边缘设备
GPU 服务器上的检测模型 mAP 很漂亮,搬到边缘盒子(Jetson / NPU 工控机)上却可能又慢又掉点:**边缘部署的难点不在模型而在”对齐”**——前后处理对齐、精度对齐、性能与功耗对齐。本文以 YOLO 类检测模型为例,走通 ONNX 导出 → 边缘引擎构建 → 前后处理对齐 → 实测验收的完整链路。
graph TD
A[PyTorch 训练模型] --> B[导出 ONNX 固定输入尺寸]
B --> C[边缘引擎构建 TensorRT/ORT]
C --> D[前后处理对齐 letterbox+NMS]
D --> E{精度对齐 mAP 差 < 0.5}
E -- 否 --> F[排查量化/归一化差异]
F --> C
E -- 是 --> G[实测 FPS/功耗/温度验收]
前置准备
边缘目标设备以 Jetson Orin Nano 为例(x86 工控机流程相同,引擎换 OpenVINO/ORT):
pip install onnx onnxruntime ultralytics # 导出侧 |
- 导出侧与设备侧各留一套相同验证集图片(200 张即可)做对齐测试
- 明确输入契约:尺寸(如 640×640)、归一化方式(/255、BGR/RGB)
步骤一:导出 ONNX 并固定契约
动态轴在边缘引擎上支持差,导出时固定 batch 与尺寸:
yolo export model=best.pt format=onnx imgsz=640 batch=1 simplify=True |
import onnx |
simplify会用 onnx-simplifier 折叠常量节点,减少边缘引擎不支持的算子- 记录输入输出张量名与形状,写进部署文档——这是前后处理的唯一依据
步骤二:构建边缘推理引擎
Jetson 上用 TensorRT 做 FP16 引擎;x86 CPU 盒子用 ORT:
# Jetson: trtexec 构建引擎并序列化缓存 |
# x86 CPU 盒子: ORT + 线程绑定 |
引擎文件与设备型号、JetPack 版本绑定——换硬件必须重构建,不能拷贝复用。
步骤三:前后处理对齐
边缘端掉点八成出在这里:letterbox 填充值、归一化顺序、NMS 阈值与训练侧不一致:
import cv2, numpy as np |
- 坐标反算:
(x - pad) / r还原到原图——漏除 ratio 是框偏移的经典 bug - NMS 用与验证脚本相同的 IoU/conf 阈值;设备端实现不同就统一用 numpy 版
步骤四:精度与性能验收
同一验证集跑”PyTorch 原模型”与”边缘引擎”,双指标验收:
- 精度对齐:mAP@0.5 差 < 0.5 个百分点;FP16 通常无感,INT8 需逐类检查
- 性能验收:连续跑 30 分钟记录 FPS、功耗、核心温度——边缘设备降频是隐性杀手
# 设备侧压测: 记录频率与温度曲线 |
验收标准写进发布单:FPS ≥ 目标值、30 分钟无降频掉速、mAP 差在门禁内。
常见问题
- 框整体偏移:letterbox 的 pad/ratio 反算错误,或导出时内置了预处理又重复做了一遍
- FP16 某类召回崩了:小目标 score 下溢——该层关 FP16 或改 INT8 校准覆盖小目标样本
- 首帧极慢:引擎预热不足,上线前空跑 50 帧再接流
- 多路视频 FPS 不达标:单引擎串行是瓶颈——按路数开多 context 或多进程绑核
小结
边缘部署 = 契约工程:导出时固定输入契约,构建时绑定硬件契约,前后处理复刻训练契约,验收时用同一验证集对齐精度、用长时间压测对齐性能。四个契约任何一个”大概一致”,都会在设备上变成可见的掉点或掉帧——把”对齐”做成 checklist,边缘部署就从玄学变成流水线。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 非鱼小站!
评论
WalineDisqus






