AI-深度学习

海思NPU模型转换 12 项目案例与交付清单

展开合集目录
  1. 海思NPU模型转换 01 平台工具与文档地图
  2. 海思NPU模型转换 02 搭建转换环境
  3. 海思NPU模型转换 03 拿到模型后的检查
  4. 海思NPU模型转换 04 导出和整理ONNX
  5. 海思NPU模型转换 05 预处理与AIPP
  6. 海思NPU模型转换 06 校准数据与量化
  7. 海思NPU模型转换 07 执行ATC转换
  8. 海思NPU模型转换 08 输出与后处理约定
  9. 海思NPU模型转换 09 PC仿真与精度比对
  10. 海思NPU模型转换 10 板端最小推理闭环
  11. 海思NPU模型转换 11 转换失败与性能排查
  12. 海思NPU模型转换 12 项目案例与交付清单
  13. 海思NPU模型转换 A 附录A文档检索表
  14. 海思NPU模型转换 B 附录BATC与AIPP参数表
  15. 海思NPU模型转换 C 附录C错误现象与排查表
  16. 海思NPU模型转换 D 附录D项目目录及交付模板
海思NPU模型转换 12 项目案例与交付清单的封面

系列编排日期为 2026 年 8 月;技术基线核对与教学代码 CPU 验证日期为 2026-10-12。适用 Hi3516CV610 与本系列注明的 SDK/工具版本,实测范围见第 12 章。

返回系列目录 · 本篇属于 12 章与 4 份附录。

这一章把 YuNet 2023mar 从模型检查、320 输入整理、CPU 等价性验证、ATC 编译一路连接到功能仿真和板端验收。配套代码负责数据准备和张量比较;转换工具、SDK、原始模型及真实样本由项目环境提供。

样例范围与输入约定

使用项目 SDK/Tools/Npu/YuNet/face_detection_yunet_2023mar.onnx,主文件 SHA-256 为:

8f2383e4dd3cfbb4553ea8718107fc0423210dc964f9f4280604804ed2552fa4

源图接收 BGR 0~255 FLOAT,原输入为 640。教学脚本固定到 320,对预先提取的头部 ROI 进行左上对齐、黑色填边、双线性缩放;再生成首层权重乘 255 的变体,让外部 UINT8 经 AIPP 除以 255 后保持同样语义。

脚本接受已经裁好的头 ROI,不包含头部检测器,也不自动从整帧找脸。完整级联的裁剪与坐标关系可结合口鼻遮挡系列阅读。

配套文件

文件 用途
README.md 环境要求、执行顺序和验证边界
audit_onnx.py 检查模型结构并输出模型卡信息
prepare_yunet.py 固定模型、生成输入并比较 CPU 输出
aipp_yunet.cfg 320 BGR planar 静态 AIPP
convert_yunet.sh 保存配置并执行本项目 ATC
compare_outputs.py 按日志去除 stride padding,比较 NPZ

下载全部教学代码后,把这些文件放到项目内 application/.temp/npu-handbook-tools/。不要直接依赖博客目录;容器只挂载项目根目录。Python 环境需要 NumPy、OpenCV、ONNX 和 ONNX Runtime,使用独立环境并记录实际版本。

第一步检查源模型

在项目根目录执行,所有日志留在项目目录:

mkdir -p application/.temp/yunet320-logs
python3 application/.temp/npu-handbook-tools/audit_onnx.py \
  SDK/Tools/Npu/YuNet/face_detection_yunet_2023mar.onnx \
  --output application/.temp/yunet320-logs/source-audit.json \
  > application/.temp/yunet320-logs/audit.log 2>&1

核对输入名 input、opset 11 和 12 个输出。若模型哈希或结构不同,先确认来源,不应继续假设它符合脚本针对的 YuNet 结构。

第二步准备模型和同源输入

先用合成图跑通文件与 CPU 数值流程,输出目录必须不存在:

python3 application/.temp/npu-handbook-tools/prepare_yunet.py \
  --model SDK/Tools/Npu/YuNet/face_detection_yunet_2023mar.onnx \
  --output application/.temp/yunet320-smoke \
  --container-output /workspace/application/.temp/yunet320-smoke \
  --synthetic \
  > application/.temp/yunet320-logs/smoke.log 2>&1

合成图是确定性的彩色图案,只验证几何、字节布局和首层缩放等价性。正式转换另建目录,替换为真实头 ROI;下面的两个文件名是自备样本示例,需要实际存在:

python3 application/.temp/npu-handbook-tools/prepare_yunet.py \
  --model SDK/Tools/Npu/YuNet/face_detection_yunet_2023mar.onnx \
  --output application/.temp/yunet320-run \
  --container-output /workspace/application/.temp/yunet320-run \
  --images application/.temp/head-roi/day.png application/.temp/head-roi/dim.png \
  > application/.temp/yunet320-logs/prepare.log 2>&1

两张图仅展示命令格式,实际集合按第 06 章补齐场景。脚本生成以下内容:

yunet320-run/
  yunet320_reference.onnx   固定 320 的原数值语义模型
  yunet320_input255.onnx    首层权重乘 255 的模型
  prepared_0.png           几何处理完成的无损图
  input_0.bgr              三通道 UINT8 planar,307200 字节
  reference_0.npz          原数值语义的 CPU 输出
  input255_0.npz           缩放后模型的 CPU 输出
  calibration.txt         容器内 PNG 路径清单
  manifest.json           环境、输入哈希和各输出误差

--container-output 只决定清单里写入的路径,不会上传或复制文件。它必须与 Docker 挂载后的真实位置一致。多张图生成多个编号样本,文件后缀不表示量化精度。

第三步检查 CPU 等价性

脚本对全部 12 个输出执行有限值检查及 allclose(atol=1e-3, rtol=1e-3),失败直接终止。这个门槛用于验证指定的浮点等价改写,不是量化验收门槛。

本次在 2026-10-12 使用上述源模型和合成图实际执行,12 个输出均通过;最大绝对差约为 1.103e-6,出现在 bbox_8。验证环境为 NumPy 2.3.5、OpenCV 5.0.0、ONNX 1.22.0、ONNX Runtime 1.28.0。

这项结果支持“本次输入下首层缩放前后数值一致”,不支持真实人脸召回或量化精度结论。正式样本也应运行同样检查,并保留 manifest。

第四步执行 ATC

打开本项目转换容器后运行:

bash /workspace/application/.temp/npu-handbook-tools/convert_yunet.sh \
  /workspace/application/.temp/yunet320-run

脚本显式 source 环境,复制 AIPP 与命令,记录 ATC 版本,以 A16W8、quant_mode=0、FP32 输出、保留输出顺序进行转换,最后确认 om/yunet320_original.om 非空并保存哈希。所有 ATC 日志在 om/convert.log。

若 om 已存在,脚本会拒绝覆盖。重新实验应新建 case 目录并记录变更,不要删除日志后重复覆盖。参数解释和完整展开命令见第 07 章。

第五步功能仿真与原始输出比对

执行第 09 章的编译与仿真命令,输入必须使用本目录的 input_0.bgr。随后运行:

python3 application/.temp/npu-handbook-tools/compare_outputs.py \
  --reference application/.temp/yunet320-run/input255_0.npz \
  --log application/.temp/yunet320-run/sim/run.log \
  --prefix application/.temp/yunet320-run/sim/output \
  --output application/.temp/yunet320-run/sim/compare.json \
  > application/.temp/yunet320-run/sim/compare.log 2>&1

检查所有输出名称、shape、MAE、RMSE、最大误差,再使用业务 YuNet 解码检查框和关键点。当前比较器未实现 NMS 和任务评估,不会把数值报告包装成最终准确率。

第六步板端验证与归档

按第 10 章编译并运行 benchmark,传入同一 OM 和同一输入文件。取回输出后把比较器的 --log 与 --prefix 指向板端日志和文件,并使用新的报告路径。

CPU 与仿真比较用于观察编译量化,仿真与板端比较用于观察执行一致性,真实数据集用于观察任务效果。三者分别通过后,再把模型接回头 ROI 级联和实际配置。

本次教学代码已实际验证源模型检查、合成输入的 CPU 等价性,以及输出比较器对 stride padding 和错误输入的处理;ATC、功能仿真和设备推理仍需要在相应环境执行。本章没有新产生板端耗时或量化精度数据。

其他项目模型如何复用流程

模型路线 项目入口 最需要额外固定的内容
PIPNet98 SDK/Tools/Npu/PipNet/BuildOm.sh RGB ImageNet 归一化、五个输出、邻居与点位定义
YOLOv5s P34 application/Dependent/shared/head_detection_yolov5s/ 检测分支调整、步长、输出解码、小目标评估
YOLOv8n Pose SDK/Tools/Npu/Yolov8nPose/ RGB、56 通道输出、布局和关键点解释
FaceOcc U-Net application/Dependent/shared/unet_occlusion/hi3516/ 人脸裁剪、分割概率语义、输出缩放与阈值
YOLO-World application/Dependent/shared/yoloworld_occluder/ 固定词表、类别元数据、DFL 解码、后处理
LUVLi application/Dependent/shared/head_yunet_luvli/hi3516/ 复杂算子、探针、关键点输出和性能范围

Pose 的历史配置使用接近 1/256 的 0.0039062,不能无条件换成 1/255 再沿用旧验收结论;应将其当成既有版本的一部分,通过同图比较决定是否修改。

部署需要核对实际生效路径

当前模型资源位于 application/Platform/Module/HI3516CV610_00S/,配置入口需核对 application/Platform/Params/HI3516CV610_00S/config_table.json 和实际运行时配置。打包目录中的模型副本也需与发布版本一致。

旧 DeployPoseOm.sh 涉及的部分 Platform/MediaConfig 路径在当前树中不存在,不能把旧部署脚本原样执行当作通用最后一步。部署前检查脚本的每个目标,保留旧 OM、旧配置和旧程序配套版本;替换后通过设备加载日志与哈希确认实际生效文件。

交付包至少包含模型、输入输出约定、转换命令、工具版本、校准清单索引、验收报告、后处理版本和回滚方案。具体模板见附录 D。

上一篇 转换失败与性能排查 · 系列目录 · 下一篇 附录A文档检索表