专栏算法工具链从零开始:YOLOv5x 在 Horizon J6 平台的完整部署实战(下)

从零开始:YOLOv5x 在 Horizon J6 平台的完整部署实战(下)

XZH2026-07-20
61
0

YOLOv5x 在 Horizon J6 上的端到端部署实践(下):板端推理与精度评估

上篇完成了模型从 PyTorch 到 HBM 的转换。本篇继续介绍板端 C++ 推理部署,包括 NV12 输入构造、UCP/DNN API 调用、YOLOv5 输出解析、交叉编译、板端运行以及 mAP 精度评估。

前置产物:yolov5x_640x640_nv12.hbm
板端输入:NV12 双平面
输出:YOLOv5 三个检测头,注意 tensor stride 与 padding

1. 板端推理整体流程

板端 C++ 推理可以拆成以下几步:

部署时最容易出问题的地方主要有两个:

  • 输入必须是模型期望的 NV12 双平面格式。

  • 输出不能按紧密内存布局读取,必须按 stride 访问。


2. NV12 输入格式

HBM 的输入通常会被拆成两个 tensor:

Tensor

Shape

数据类型

说明

images_y

(1, 640, 640, 1)

U8

Y 亮度平面

images_uv

(1, 320, 320, 2)

U8

UV 交错色度平面

从 OpenCV 读取的 BGR 图片需要先做 letterbox,再转换为 NV12:

这里不需要在 C++ 侧手动做 /255,因为上篇编译配置中已经通过 scale_value: 1/255 交给模型运行时处理。

3. UCP/DNN API 调用流程

板端推理主流程可以简化为:

实际工程中还需要处理错误码、动态 stride、内存大小计算和多输入多输出遍历。


4. 输出解析:必须按 stride 访问

YOLOv5 的输出 tensor 中存在 padding,不能用普通的连续数组方式读取。例如:

最后一维 85 个 float 理论上是 85 * 4 = 340 bytes,但实际 col stride 是 384 bytes,中间多了 44 bytes padding。

正确访问方式是使用 byte stride 计算偏移:

不要这样做:

这是板端 YOLO 后处理最常见的坑之一。


5. YOLOv5 解码与 NMS

YOLOv5 每个检测头对应一个 stride 和一组 anchors:

解码公式:

后处理一般包含:

  1. 遍历三个检测头。

  2. 对 obj 和 class 做 sigmoid。

  3. 按置信度阈值过滤候选框。

  4. 将 letterbox 坐标映射回原图。

  5. 执行 NMS。

  6. 绘制检测框和类别标签。


6. 交叉编译

使用 SDK 自带的 aarch64 交叉编译器:

CMake 中需要链接 DNN、UCP、OpenCV 等运行依赖:

如果共享库中的部分符号由板端系统运行时提供,可以加入:


7. 部署到板端运行

将可执行文件、HBM 模型和测试图片拷贝到板端:

板端执行:

如果结果框明显异常,优先检查三件事:

  1. 输入 NV12 是否正确。

  2. 是否重复做了 /255。
  3. 输出是否按 tensor stride 读取。


8. mAP 精度评估

部署完成后,可以对比浮点模型和量化模型在 COCO val2017 上的 mAP:

示例结果:

Metric

Float ONNX

Quantized BC

Diff

mAP

0.4913

0.4826

-0.0087

mAP_50

0.6424

0.6509

+0.0085

mAP_75

0.5241

0.5054

-0.0187

mAP_small

0.3575

0.3196

-0.0379

mAP_med

0.5280

0.5066

-0.0214

mAP_large

0.6710

0.6771

+0.0061

量化后 mAP 有轻微下降属于正常现象。若下降过大,优先排查校准数据覆盖度、预处理一致性、输入归一化和后处理 decode 是否一致。


9. 关键点速查

环节

要点

输入格式

板端 HBM 输入为 NV12 双平面

归一化

由编译配置中的 scale_value 完成

校准数据

使用 RGB、NCHW、float32、[0,1]

预处理

Stage 2、Stage 4、Stage 5 的 letterbox 逻辑必须一致

输出解析

必须按 tensor byte stride 访问

后处理

YOLOv5 decode、坐标映射、NMS 要和浮点侧保持一致


小结

下篇完成了从 HBM 模型到板端 C++ 推理的部署闭环。相比工具链编译,板端实现更容易踩到数据格式和内存布局问题。只要保证 NV12 输入正确、运行时归一化不重复、输出按 stride 解析,YOLOv5x 在 J6 上的端到端部署就能稳定跑通。

算法工具链
官方教程征程6
评论0
0/600