专栏算法工具链Horizon J6m 部署 YOLOv8s INT8 精度下降问题排查记录

Horizon J6m 部署 YOLOv8s INT8 精度下降问题排查记录

O2026-07-20
55
0

1. 问题背景

在 Horizon J6 Open Explorer 工具链中部署 YOLOv8s 时,最初采用 Ultralytics 标准导出的 ONNX 模型。

标准 YOLOv8 ONNX 的输出通常为:

其中:

该输出已经在 ONNX 图内完成了:

使用 Horizon 工具链对该完整模型进行 INT8 量化后,检测精度出现严重下降。


2. 初始实验现象

在同一批 COCO val2017 前 50 张图片、相同预处理和相同评测逻辑下,原完整输出 YOLOv8s 的结果为:

模型阶段

mAP50-95

mAP50

Optimized Float

0.537

0.696

INT8 Calibrated

0.107

0.216

INT8 PTQ

约 0.116

约 0.230

INT16 Calibrated

0.532

0.689

INT16 PTQ

0.532

0.686

可以看到:

该现象说明模型并不是不能量化,而是对 INT8 位宽非常敏感。


3. 初期排查方向

最开始主要怀疑以下问题:

  1. RGB 和 BGR 顺序不一致;

  2. 输入是否重复除以 255;

  3. 校准数据范围是否错误;

  4. NCHW 和 NHWC 布局不一致;

  5. LetterBox 预处理不一致;

  6. COCO 类别编号或坐标恢复错误;

  7. ONNX 导出本身存在问题;

  8. Horizon 图优化阶段改变模型计算结果;

  9. 校准图片数量不足;

  10. INT8 对 YOLOv8 检测头不友好。

经过多轮对照后,前面的大部分原因都被排除。


4. 为什么可以排除输入和校准数据问题

校准数据采用:

YAML 中运行时输入配置为:

这里并不是重复除以 255:

  • 校准数据已经是 ONNX 输入域的 float32,范围为 0~1;

  • 板端 NV12 输入仍然是 uint8,范围为 0~255;

  • YAML 中的 scale_value 用于将板端输入转换到模型输入域。

更关键的是,同一套校准数据下,INT16 模型可以恢复到接近浮点精度。

如果 RGB/BGR、输入范围或校准数据存在严重错误,INT16 通常也不会恢复到:

因此,主要问题不在输入预处理和校准数据。


5. 根本原因分析

问题的核心在于:

Ultralytics 标准导出的 YOLOv8 ONNX 将 DFL、Softmax、Sigmoid 和边框解码全部包含在模型图中,Horizon 对整个检测图执行 INT8 量化时,这些数值敏感运算也进入了量化范围。

5.1 DFL 对 INT8 量化误差敏感

YOLOv8 的边框回归不是直接预测四个边框坐标,而是为每个方向预测 16 个离散值:

随后执行:

INT8 量化会对 logits 进行缩放、截断和取整。

即使单个 logits 的误差较小,也可能改变 16 个 bin 之间的相对关系。误差经过 Softmax 和加权求期望后,会转化为边框距离误差。

5.2 stride 会进一步放大边框误差

DFL 得到的距离还会乘以不同特征层的 stride:

例如某个方向的 DFL 距离只偏差 0.2 个网格,在 P5 上就可能产生:

四个方向都可能存在偏差,最终导致边框 IoU 明显下降。

5.3 mAP50-95 比 mAP50 下降更多

在 YOLOv8x 的对照实验中,完整输出 INT8 的结果表现为:

这说明模型仍然能够找到目标,但边框定位变得不够准确。

目标在 IoU=0.5 时可能仍然匹配,但在 IoU=0.75、0.85 或 0.95 等高阈值下无法匹配,因此 mAP50-95 下降更明显。

这与 DFL 和坐标解码误差的表现高度一致。


6. Raw6 解决方案

为避免将敏感后处理纳入 INT8 量化图,重新导出了 YOLOv8s Raw6 ONNX。

模型固定输出六路原始特征:

其中:

新的部署边界为:

CPU 后处理实现包括:

  • 六路输出顺序检查;

  • NCHW/NHWC 输出适配;

  • DFL Softmax;

  • 16 个 bin 的距离期望;

  • 三尺度 anchor point 解码;

  • 分类 Sigmoid;

  • class-aware NMS;

  • 原图坐标恢复;

  • COCO 评测结果格式转换。


7. Raw6 实验结果

在相同的 COCO val2017 前 50 张图片上,Raw6 得到以下结果:

模型阶段

mAP50-95

mAP50

Raw6 Original Float

0.537

0.696

Raw6 Optimized Float

0.537

0.696

Raw6 INT8 Calibrated

0.529

0.685

Raw6 INT8 PTQ

0.529

0.685

完整输出模型与 Raw6 模型的对比如下:

模型形式

阶段

mAP50-95

mAP50

完整输出 [1,84,8400]

Float

0.537

0.696

完整输出 [1,84,8400]

INT8 Calibrated

0.107

0.216

Raw6 六路输出

Float

0.537

0.696

Raw6 六路输出

INT8 Calibrated

0.529

0.685


8. 实验结果说明

8.1 Raw6 导出和 CPU 后处理正确

Raw6 Original Float 的结果为:

与原完整输出浮点模型完全一致。

这证明以下实现均正确:

  • 六路输出顺序;

  • DFL channel reshape;

  • DFL Softmax;

  • bin 加权求期望;

  • stride 配置;

  • anchor center 使用 x+0.5、y+0.5;
  • 分类 Sigmoid;

  • class-aware NMS;

  • LetterBox 坐标恢复;

  • COCO 类别编号映射;

  • 评测代码接口。

8.2 Horizon 图优化没有影响精度

Raw6 Original Float 与 Optimized Float 完全一致:

因此 Horizon 的普通 ONNX 图优化阶段没有破坏模型计算结果。

8.3 Raw6 INT8 量化损失很小

Raw6 从浮点到 INT8:

该下降幅度较小,属于正常的 INT8 PTQ 精度损失。

8.4 检测头卷积本身不是主要问题

Raw6 模型中仍然被量化的部分包括:

但最终精度只下降 0.008。

因此可以判断:

YOLOv8 的 Detect Head 卷积本身并不是导致精度崩溃的主要原因。

真正的严重掉点发生在原始 box/cls logits 之后,即:

8.5 Raw6 INT8 接近完整输出 INT16

对比:

二者仅相差:

说明通过重新划分模型部署边界,Raw6 INT8 基本达到了完整模型 INT16 的精度,同时保留了大部分卷积算子的 INT8 执行效率。


9. 最终结论

本次精度问题不是由以下因素导致:

  • ONNX 模型导出错误;

  • Horizon 图优化错误;

  • RGB/BGR 配置错误;

  • 输入重复除以 255;

  • 校准数据格式错误;

  • COCO 标注或类别编号错误;

  • LetterBox 和 NMS 整体实现错误;

  • YOLOv8 Detect Head 卷积完全不支持 INT8。

真正的原因是:

标准 YOLOv8 ONNX 将 DFL、Softmax、Sigmoid、anchor point 解码和坐标计算放在模型图内。Horizon J6 对完整检测图执行 INT8 PTQ 时,这些数值敏感操作受到量化误差影响,微小的 logits 误差经过 DFL、距离期望和 stride 解码后被放大,导致边框定位偏移和 IoU 下降,最终造成 mAP50-95 严重下降。

将模型改为 Raw6 六路原始输出,并在 CPU 使用 float32 完成 DFL、Sigmoid、解码和 NMS 后:

因此,Raw6 方案已经验证为当前 Horizon J6 工具链上部署 YOLOv8 INT8 的有效方案。


10. 后续模型导出建议

对于 Horizon J6 上的 YOLOv8 INT8 部署,建议 ONNX 保留:

建议从 ONNX 中移出:

推荐输出形式:

不建议直接使用标准 Ultralytics 最终输出:

但这不是所有硬件平台的统一限制。

在 GPU、TensorRT、FP16、混合精度或对相关算子量化支持较好的平台上,完整输出模型仍然可能正常工作。

该结论仅针对:

这一具体部署环境。


算法工具链
社区征文征程6
评论0
0/600