模型精度数据对比:NVIDIA TensorRT ↔ Atlas 300V(Ascend 310P3)
两边都用 YOLOv5 v6.0
val.py同一套口径评测同一个业务模型shv54。
NVIDIA 侧产物是既有标准输出,Atlas 侧由AscendDemo/scripts/eval_yolov5_style.py生成,
6 个产物同名同规格,可以直接diff/ 并排看图。
| NVIDIA | Atlas 300V | |
|---|---|---|
| 产物目录 | docs/shv54精度数据/ | docs/shv54精度数据_atlas/ |
| 评测脚本 | YOLOv5 v6.0 val.py + utils/metrics.py | AscendDemo/scripts/eval_yolov5_style.py(复刻同一套逻辑) |
| 评测图数 / 实例数 | 4997 / 14975 | 4991 / 14949 |
1. 结论
| 结论 | 依据 |
|---|---|
| 昇腾链路与 NVIDIA 的精度基本等价,没有出现迁移掉点 | 逐类 P 差 ≤ 0.0030、R 差 ≤ 0.0050;mAP@0.5 反而高 +0.0080 |
| 唯一系统性差异是 mAP@0.5:.95 低 -0.0320,且只出现在高 IoU 段 | IoU ≤ 0.5 的所有指标(mAP@0.5、逐类 P/R、混淆矩阵)两边逐项吻合 |
| 这不是平台数值精度问题 | 同一 ONNX 在 ONNX Runtime(FP32) 与昇腾 NPU(FP16) 上,GT 的 best-IoU 均值 0.92662 vs 0.92724(差 +0.00062) |
| 评测口径已逐项对齐 | 见 §2;且自研实现与上游 utils/metrics.py 做过逐位对拍(max|diff| = 0.000e+00) |
一句话:这不是"昇腾比 NVIDIA 差",而是"两边在框坐标精度上差了约 3 个百分点的mAP@0.5:.95,检出/漏检/误检行为两边一致"。
2. 口径对齐(两边一致的部分)
| 环节 | 取值 | 说明 |
|---|---|---|
| 评测实现 | AscendDemo/scripts/eval_yolov5_style.py | 复刻 YOLOv5 v6.0 val.py + utils/metrics.py |
| 金标准对拍 | 上游 utils/metrics.py 逐位比对 | TP 矩阵、AP 矩阵、PR 曲线、混淆矩阵 全部 max|diff| = 0.000e+00 |
| 输入尺寸 | imgsz=960, rect=True | 本数据集 16:9 图的 rect 画布与我们的 .om 画布逐像素一致 |
| NMS | conf=0.001, iou=0.6, max_det=300(每类) | 与 val.py 的 non_max_suppression 一致 |
| NMS 语义 | per-class(multi_label=True) | 原仓库 val.py:217 明确传 multi_label=True,我们的图内 NMS 语义与之相同 |
| 匹配规则 | 同类 + IoU >= 0.5(0.5:0.95 共 10 档)+ IoU 降序贪心 | 与上游 process_batch 一致 |
| AP | np.trapz(np.interp(101 点)) | 与上游 compute_ap 一致 |
| 工作点 | smooth(f1.mean(0), 0.1).argmax() | YOLOv5 的 best-F1 点 |
| 混淆矩阵 | conf=0.25, iou=0.45, 列归一化, <0.005 置 NaN | 与上游 ConfusionMatrix 一致 |
| 指标汇总 | 宏平均 | resualt.txt 的 all 行是三类宏平均 |
3. 数据集差异(唯一的数据集层面的不对称)
Atlas 侧用的是本地 test_assets/ 4991 张带标注图;NVIDIA 侧参考产物是 4997 张。
差的 6 张图带走了 26 个标注框:
| class | NVIDIA 实例数 | Atlas 实例数 | 差 |
|---|---|---|---|
| person | 7805 | 7792 | -13 |
| helmet | 3872 | 3869 | -3 |
| head | 3298 | 3288 | -10 |
| all | 14975 | 14949 | -26 |
实例数差异 ≤ 0.7%。注意:这 6 张图是 NVIDIA 侧多出来的,两边的评测集并不完全相同,
逐类指标的差异里有一部分来自这里。
4. 主对比表(resualt.txt 全字段)
all 行(宏平均):
| 项 | NVIDIA | Atlas 300V | 差值 |
|---|---|---|---|
| all · Images | 4997 | 4991 | -6 |
| all · Instances | 14975 | 14949 | -26 |
| all · P | 0.958 | 0.959 | +0.0010 |
| all · R | 0.953 | 0.949 | -0.0040 |
| all · mAP@.5 | 0.971 | 0.979 | +0.0080 |
| all · mAP@.5:.95 | 0.86 | 0.828 | -0.0320 |
逐类:
| class | NVIDIA P | Atlas P | ΔP | NVIDIA R | Atlas R | ΔR | NVIDIA mAP@.5 | Atlas mAP@.5 | ΔmAP | NVIDIA mAP@.5:.95 | Atlas mAP@.5:.95 | ΔmAP |
|—|—|—|—|—|—|—|—|—|—|—|—|—|—|
| person | 0.969 | 0.969 | +0.0000 | 0.966 | 0.963 | -0.0030 | 0.98 | 0.987 | +0.0070 | 0.886 | 0.86 | -0.0260 |
| helmet | 0.926 | 0.929 | +0.0030 | 0.949 | 0.948 | -0.0010 | 0.964 | 0.972 | +0.0080 | 0.834 | 0.798 | -0.0360 |
| head | 0.98 | 0.979 | -0.0010 | 0.942 | 0.937 | -0.0050 | 0.969 | 0.979 | +0.0100 | 0.859 | 0.827 | -0.0320 |
表中的数值是
resualt.txt的原始字面值(上游%.3g,只有 3 位有效数字),
两边格式完全相同,可以直接diff。
差值列由这些 3 位有效数字算出;§5 给出metrics.json里的全精度值。
5. Atlas 侧工作点细节(best-F1,全精度)
本节数值来自
docs/shv54精度数据_atlas/metrics.json(全精度),
§4 里resualt.txt的 3 位有效数字就是这些值按上游%.3g取整后的结果。
| 项 | 值 |
|---|---|
| best-F1 置信度 | 0.5145 |
| 宏平均 precision | 0.9590 |
| 宏平均 recall | 0.9490 |
| 宏平均 F1 | 0.9539 |
| 参与匹配的图片数 | 4991 |
| 预测框总数(score ≥ 0.001) | 70729 |
逐类 TP/FP(best-F1 工作点):
| class | GT | TP | FP | P | R | F1 | AP@.5 | AP@.5:.95 |
|---|---|---|---|---|---|---|---|---|
| person | 7792 | 7501 | 242 | 0.9687 | 0.9627 | 0.9657 | 0.9866 | 0.8595 |
| helmet | 3869 | 3666 | 280 | 0.9290 | 0.9475 | 0.9382 | 0.9720 | 0.7982 |
| head | 3288 | 3081 | 65 | 0.9793 | 0.9369 | 0.9577 | 0.9793 | 0.8272 |
Atlas 侧逐 IoU 档的 mAP(说明高 IoU 段是怎么塌下去的):
| IoU | 0.50 | 0.55 | 0.60 | 0.65 | 0.70 | 0.75 | 0.80 | 0.85 | 0.90 | 0.95 |
|---|---|---|---|---|---|---|---|---|---|---|
| mAP | 0.9793 | 0.9758 | 0.9691 | 0.9582 | 0.9383 | 0.9067 | 0.8605 | 0.7836 | 0.6359 | 0.2757 |
6. 混淆矩阵(conf=0.25, iou=0.45,列归一化,列 = GT)
| GT \ 预测 | person | helmet | head | 背景 FP |
|---|---|---|---|---|
| person | 0.97 | 0.03 | 0.01 | 0.48 |
| helmet | 0.01 | 0.95 | 0.03 | 0.38 |
| head | 0.00 | 0.01 | 0.94 | 0.14 |
| background FN | 0.02 | 0.02 | 0.02 | — |
NVIDIA 侧同口径矩阵(从 docs/shv54精度数据/confusion_matrix.png 读出):
| GT \ 预测 | person | helmet | head | 背景 FP |
|---|---|---|---|---|
| person | 0.97 | — | — | 0.42 |
| helmet | — | 0.95 | 0.02 | 0.45 |
| head | — | — | 0.94 | 0.13 |
| background FN | 0.03 | 0.05 | 0.04 | — |
逐项吻合:对角线 person / helmet / head 的检出率两边都是 0.97 / 0.95 / 0.94;
漏检(background FN 行)NVIDIA 0.03 / 0.05 / 0.04,Atlas 0.02 / 0.02 / 0.02;
误检构成(background FP 列)NVIDIA 0.42 / 0.45 / 0.13,Atlas 0.48 / 0.38 / 0.14。
→ 两边的检测集(检出 / 漏检 / 误检)是等价的。
7. 差异归因
7.1 已排除的原因(都有实验数据)
| 候选原因 | 判别实验 | 结果 |
|---|---|---|
| 平台数值精度(NPU FP16 vs NVIDIA FP32) | 同一 ONNX 跑 ORT(FP32),与 .om(FP16) 在 200 张同图上比「每个 GT 的 best-IoU」 | ORT 0.92662 vs .om 0.92724(差 +0.00062);坐标偏差中位数 3.18 px vs 3.00 px → 逐框等效,不是原因 |
| NMS 的 multi-label 语义 | 把 70729 个框按「同坐标只留最高分」折成单标签后重评 | 丢 8382 框,mAP@0.5 0.9793→0.9786,mAP@0.5:.95 0.8283→0.8293 → Δ ≤ 0.001,不是原因 |
| max_det 分配规则(每类 300 vs 全局 300) | 统计单图检测数 | 单图总框数 > 300 的图 0 张,单类 > 300 的 0 次 → 完全没触发 |
| 输入画布(960×544 vs YOLOv5 rect 的 992×576) | 用 ORT 在 992×576 画布上跑同 200 张图 | mAP@0.5 0.9445→0.9547,但 mAP@0.5:.95 0.8254→0.8234 → 高 IoU 段没改善,不是原因 |
GT 标注口径(labels/*.txt vs Annotations/*.xml) | 同一份预测分别对两套 GT 评测 | txt 更优(mAP@0.5:.95 0.8283 vs XML 0.8037);两份 GT 存在系统性 1 像素偏移,但我们用的 txt 已是与模型对齐的那套 → 不是原因 |
NMS 的 iou_thres(0.6 vs 0.45) | 用 ORT 跑 iou=0.45 的 ONNX,比同 200 张图 | mAP@0.5:.95 0.8254→0.8237 → Δ ≤ 0.002,不是原因 |
| 评测流程本身引入的误差 | 把生产 .om 的预测也做同样的尺寸偏差统计 | 生产 .om 与评测 .om 的偏差数字完全一致(person 宽比中位 1.00545、高比 1.00470)→ 生产链路有同样的定位上限,不是评测流程的产物 |
7.2 仍未定位的差异
mAP@0.5:.95 低 0.0320,表现为 IoU 档越高差得越多:
| IoU 档 | 0.50 | 0.55 | 0.60 | 0.65 | 0.70 | 0.75 | 0.80 | 0.85 | 0.90 | 0.95 |
|---|---|---|---|---|---|---|---|---|---|---|
| Atlas mAP | 0.9793 | 0.9758 | 0.9691 | 0.9582 | 0.9383 | 0.9067 | 0.8605 | 0.7836 | 0.6359 | 0.2757 |
Atlas 侧「每个 GT 能达到的 best-IoU」分布(这是高 IoU 段的天花板):
| class | best-IoU 中位数 | best-IoU 均值 | IoU≥0.95 的 GT 占比 |
|---|---|---|---|
| person | 0.9428 | 0.9128 | 44.2% |
| helmet | 0.9214 | 0.8833 | 29.8% |
| head | 0.9290 | 0.8963 | 29.3% |
即:绝大多数 GT 只能匹配到 IoU 0.92~0.94 的框,高 IoU 档的 AP 因此天然偏低。
而 NVIDIA 侧 mAP@0.5:.95 更高,说明其框坐标精度上限更高。
重要:这不是评测链路的缺陷——生产 .om(shv54.om)的预测做同样统计,
尺寸偏差数字与评测 .om 完全一致,也就是说线上的定位精度上限是同一个。
剩下的可能来源,都在「两边跑的到底是不是同一个程序」这一层,
无法从 NVIDIA 侧的产物反推:
- NVIDIA 侧是逐 batch 变画布的。YOLOv5 rect 模式按每个 batch 的宽高比算
batch_shapes(utils/dataloaders.py:501),同一份数据不同 batch 的画布可以不同;
我们只有一个固定画布 960×544。上表已验证「换成 992×576 画布」并不能改善高 IoU 段,
但逐 batch 混合画布没有单独复现。 - NVIDIA 侧的具体命令行参数无法从产物反推(
--iou-thres/--conf-thres/--batch-size/--rect)。产物只能反映最终数值,反映不了运行参数。 - 评测集不完全相同(4997 vs 4991)。但多出的 6 张图只占 0.12%,
不足以解释 0.03 的聚合差。
结论口径:以上三点都属于「两边不是同一次运行的完全复刻」,
而不是昇腾链路的精度缺陷——从 §6 的混淆矩阵和 §4 的 P/R 看,
检测能力(检出/漏检/误检)两边等价,差异集中在框坐标精度这一层。若要彻底闭合,需要拿到 NVIDIA 侧那次
val.py的完整命令行与运行日志。
8. 复现步骤
# 1) 导出评测专用 ONNX(图内 NMS:conf=0.001 / iou=0.6 / 每类 300)
source .venv/bin/activate
python AscendDemo/scripts/export_yolo_onnx.py \
--weights model/shv54_head.ts.pt --output model/shv54_val001.onnx \
--num-classes 3 --conf-thres 0.001 --iou-thres 0.6 --max-dets-per-class 300
# 2) atc(必须 deactivate venv,用系统 python3)
deactivate
source /usr/local/Ascend/ascend-toolkit/set_env.sh
atc --model=model/shv54_val001.onnx --framework=5 --output=model/shv54_val001 \
--soc_version=Ascend310P3 --input_format=NCHW --input_shape="image:1,3,544,960" --log=info
# 3) 全量推理(4991 张)
source .venv/bin/activate
export PYTHONPATH=$PWD/AscendDemo/build
python AscendDemo/scripts/run_batch_infer.py --om model/shv54_val001.om \
--images-root test_assets --out eval/pred_full_val001.jsonl --conf 0.001
# 4) YOLOv5 口径评测 → 6 个产物
python AscendDemo/scripts/eval_yolov5_style.py --gt-root test_assets \
--pred eval/pred_full_val001.jsonl --out-dir eval/yolov5_style \
--out-json eval/yolov5_style/metrics.json
9. 产物清单
| 文件 | NVIDIA 侧 | Atlas 300V 侧 |
|---|---|---|
resualt.txt | docs/shv54精度数据/resualt.txt | docs/shv54精度数据_atlas/resualt.txt |
PR_curve.png | docs/shv54精度数据/PR_curve.png | docs/shv54精度数据_atlas/PR_curve.png |
F1_curve.png | docs/shv54精度数据/F1_curve.png | docs/shv54精度数据_atlas/F1_curve.png |
P_curve.png | docs/shv54精度数据/P_curve.png | docs/shv54精度数据_atlas/P_curve.png |
R_curve.png | docs/shv54精度数据/R_curve.png | docs/shv54精度数据_atlas/R_curve.png |
confusion_matrix.png | docs/shv54精度数据/confusion_matrix.png | docs/shv54精度数据_atlas/confusion_matrix.png |
metrics.json | — | docs/shv54精度数据_atlas/metrics.json(机器可读) |
规格:4 张曲线图 2250×1500(figsize=(9,6) + dpi=250),
混淆矩阵 3000×2250(figsize=(12,9) + dpi=250),
resualt.txt 459 字节 / LF / 无 BOM。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐



所有评论(0)