背景与来源
- 原文:《边缘算力设备模型部署,5个巨坑心得分享:Nvidia、算能、瑞芯微全踩过!》
- 本 Issue 是基于原文整理出的可复用工程经验、技术勘误与验收清单,非全文转载。
- 适用:PyTorch / YOLO → ONNX → TensorRT、RKNN、算能 BMRuntime;Jetson、RK3588、BM1684 等边缘视觉设备。
- 原文中的 mAP、FPS、延迟和“加速 3–5 倍”等数字属于作者示例,不能直接视作目标设备的可靠性能承诺。
关键结论
模型部署 ≠ 格式转换。精度分阶段验证、性能分模块测量、兼容性在选型前确认。
| 五大坑 | 典型现象 | 可复用排查策略 |
|---|---|---|
| ONNX 导出不一致 | 框偏移、置信度异常 | 统一预处理、输入形状、输出布局、NMS、坐标还原;固定样本逐层比较 |
| INT8 量化掉点 | mAP / 某类别召回明显下降 | 选择覆盖现场分布的校准集,按类别验证,敏感层混合精度,必要时 QAT |
| TensorRT 反而更慢 | 端到端耗时比 ONNX Runtime 高 | 核对硬件/版本/引擎构建参数,拆分 H2D、推理、D2H、后处理并做同步计时 |
| 跨 NPU 算子差异 | 转换失败、精度下降或 CPU fallback | 检查 RKNN/BMRuntime 兼容矩阵、转换日志,先做代表性算子与模型小样测试 |
| 多路视频瓶颈 | 推理单帧很快,整体 FPS 很低 | 硬件解码 + 批处理 + 预处理/推理流水线 + 减少内存拷贝,测每路实际时延 |
经验一:ONNX 结果不一致,先分清楚比较层次
- 固定一张输入图与输入张量,统一 RGB/BGR、归一化、letterbox、padding、通道顺序和尺寸。
- 分别比较模型原始输出张量与最终框结果;YOLO 的 NMS 通常不是模型原始输出本身。
- 坐标还原使用真实缩放比例和 pad 偏移,确保映射回原图坐标系。
- 对齐 opset 和目标 ONNX Runtime 支持情况;先跑 FP32,确认正确后再开启 FP16/INT8。
- 不宜用“最大差异超过 0.05 必须重导出”当通用规则;应结合输出量纲、相对/绝对误差和最终 mAP、漏检率进行判断。
经验二:INT8 量化的校准集重在代表性
- 校准样本需要覆盖白天、黄昏、夜间红外、雨雾、逆光、不同相机及真实部署时的曝光与分辨率。
- 不要把“至少 500 张”当成固定门槛;用校准规模曲线及独立验证集判断是否足够。
- 除整体 mAP,还要单独看烟雾、小目标、弱对比度类别的 AP、召回率与误检率。
- 尝试敏感层保留 FP16/FP32 的混合精度,但须确认对应芯片编译器是否支持;QAT 也必须与目标工具链匹配。
- 对照:FP32 → FP16 → INT8/混合量化,记录质量、时延、吞吐、峰值内存。
经验三:TensorRT 加速不保证端到端更快
- Jetson Orin NX 属 Ampere 平台,不能仅凭原文某条 FP16 warning 就断言其不支持原生 FP16;要复核实际模型、库版本及构建日志。
- TensorRT 10.x 等新版 API 与文中旧代码不同,
config.max_workspace_size/builder.build_engine等不可不经修改直接照抄。 - 固定 shape / 动态 shape、batch、精度、workspace/memory pool、计时同步、引擎预热都需要记录。
- 性能测量至少分为:解码、预处理、H2D、GPU 推理、D2H、NMS、显示/输出;再给出端到端 P50/P95。
- 优先用
trtexec验证 engine;部署时再确认线程、调度和运行时开销。
经验四:RKNN/算能等 NPU 依赖具体工具链版本
- 不应笼统认定“RK3588 不支持 SiLU”:相关算子支持会随 RKNN-Toolkit2 版本和模型图结构变化。
- 优先检查转换日志与不支持算子清单,再用逐层比较定位精度差异;CPU fallback 若存在,还需独立测其耗时。
- 不要直接把网络激活函数 SiLU 换为 ReLU 并继续沿用旧权重;改变架构需要重新训练和验证。
- 原文
custom_string='detect:fp16'不能作为可直接复用的 RKNN 混合量化配置;需采用目标 RKNN 版本支持的官方 hybrid-quantization 流程。 - 采购芯片之前,先实际转换一版目标模型并在板子上进行精度与时延验证。
经验五:多路视频要测完整流水线
典型管道:
RTSP/视频输入 → 硬件解码 → 颜色/尺寸处理 → Batch
→ TensorRT/RKNN 推理 → NMS/追踪/业务逻辑 → 输出
- 不要把单路模型 FPS × 路数直接当成真实视频系统吞吐;先确认解码能力、视频分辨率、帧率、batch 及延迟约束。
- GStreamer / DeepStream 能有效减少拷贝并整合流水线,但不意味着任何插件组合都是零拷贝;仍要检查缓冲类型与 CPU/GPU 边界。
- RTSP 设置
latency=0未必最稳,易受网络抖动影响;合理设置缓冲、丢帧策略与断线重连。 - 测每路 FPS、端到端 P95/P99、丢帧率、CPU/GPU/NPU/解码器占用、功耗与热降频。
标准部署验收清单
- 固定 PyTorch FP32 基准模型与独立数据集,保留 per-class AP/Recall。
- 校验 ONNX 与原模型的预处理、原始输出、NMS 和坐标还原。
- 记录导出与运行环境版本:PyTorch、ONNX、opset、ONNX Runtime、TensorRT/RKNN/算能运行时、驱动/固件。
- 对比 FP32/FP16/INT8 精度、误检漏检、延迟、内存。
- 核查 NPU 算子、编译器转换警告与潜在 fallback。
- 分段测量解码、预处理、推理、后处理、内存拷贝与端到端耗时。
- 多路视频进行真实长时间压力测试:每路 FPS、延迟分位数、丢帧率、温度、功耗、恢复能力。
- 将所有关键测试配置、输入样本、量化校准集版本与结果保存为可复现实验记录。
与图像/PDF/Mask 项目的直接关联
预处理任何缩放、padding、旋转或 DPI 改变都可能引发检测坐标映射错误;分割/检测输出须明确原图坐标系与变换参数。像素尺寸一致也不代表 Mask 标签值完全一致。
关联:另一个 Issue 归档了用于保持像素坐标网格的 image_pdf_roundtrip_multi_dirs_p2i_mask_safe.py。
可参考的官方文档
备注:本文为工程笔记/验收规范,并非在这些设备上重新复测原文章中所有性能数字。