AI-深度学习

海思NPU模型转换 10 板端最小推理闭环

展开合集目录
  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模型转换 10 板端最小推理闭环的封面

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

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

板端最小闭环先验证“同一个模型、同一份字节输入、可解释的原始输出”,然后再接摄像头、ROI 和业务后处理。这样可以把媒体链路与 NPU 运行时问题分开定位。

文档与代码入口

读《应用开发指南》第 3 章的进程线程、Device、Context、Stream 和内存,第 4 章的 Runtime、模型加载、执行与释放。查找关键词 task_buf、work_buf、stride、缓存刷新和模型描述。

项目入口为 application/Board/HI3516CV610_00S/Src/BoardNpu.cpp,最小测试程序为 application/Dependent/shared/head_yunet_luvli/hi3516/benchmark.cpp。前者用于实际板级适配,后者用于单模型诊断,能力边界不同。

生命周期与资源所有权

初始化 ACL → 选择 Device → 创建并设置 Context
读取 OM → 按加载 API 要求分配并复制模型内存 → 加载模型
查询模型描述 → 创建输入输出 dataset 和 data buffer
填充输入与工作缓冲 → 处理缓存一致性 → 执行
同步完成 → 读取输出 → 保存描述和原始结果
卸载模型 → 释放对应资源 → 销毁 Context → 结束运行环境

每次 API 返回值都要检查,并让失败路径只释放已经成功获取的资源。封装对象和底层设备内存的所有权需要分别管理,销毁 dataset 不应被想当然地视为释放全部用户分配的内存。

当前 benchmark 对 load_from_mem 使用的模型内存保留到卸载后再释放。不要在未确认 API 生命周期要求时,加载返回就释放源 buffer。异步执行还要保证输入、输出和任务内存在同步完成前一直有效。

描述信息决定分配和复制

按 API 查询真实输入输出数量、shape、数据类型、buffer 大小和 stride。业务只看到一个图像输入,不代表运行时只有一个输入 buffer;模型可能还有 task 和 work 缓冲。

task 缓冲不能在同时执行的任务间共享。工作缓冲是否能复用,必须遵守手册的 Stream 和并发约束;文档允许的单 Stream 多模型复用场景,也需要按最大需求分配。不能把串行可复用推广成跨 Stream 并发共享。

图像逻辑文件每行 width*bytes_per_element 字节,设备每行可能有 padding。逐行拷贝时检查行数、row_bytes、stride 和总大小,不要把 W*H*C 直接当作分配大小。输出连续化规则见第 08 章。

使用可缓存内存时,CPU 写入后的设备可见性、设备写入后的 CPU 可见性必须按本 SDK 的缓存同步接口处理。缓存问题可能表现为重复旧结果、局部错误或偶现异常,不能仅靠多执行几次规避。

编译最小测试程序

在项目根目录、已安装本项目交叉编译工具链的主机执行:

mkdir -p application/.temp/npu-board-check
bash application/Dependent/shared/head_yunet_luvli/hi3516/build_benchmark.sh \
  > application/.temp/npu-board-check/build.log 2>&1

产物为 application/.temp/head-yunet-luvli/hi3516/npu-benchmark。脚本选择项目 musl ARM 编译器、板级 SDK 头文件与库;不要改用宿主机 g++ 生成 x86 文件后上传 ARM 板。

将程序、同哈希 OM 和 input_0.bgr 放到设备的独立测试目录。传输地址和路径由实际设备确定,保留已有业务模型;测试前确认设备资源占用和与在线业务的互斥安排。

执行并取回输出

下面命令在设备测试目录执行,要求三个文件已传入且设备 Runtime 可用:

sha256sum yunet320_original.om input_0.bgr
./npu-benchmark yunet320_original.om input_0.bgr \
  320 320 30 board-output > board-run.log 2>&1

取回 board-run.log 和全部 board-output_*.bin,使用同一个比较脚本与 CPU NPZ、PC 仿真分别比对。若模型描述和当前 benchmark 的三输入假设不一致,先适配程序,不要绕过检查。

benchmark 默认预热 3 次,随后统计指定次数的执行耗时,输出均值、p50、p95及内存信息。它的模型加载耗时与执行耗时分开,测得的 execute 时间不包含完整业务的图像采集、ROI、后处理和显示。

接入业务前的验收

验收顺序是文件哈希一致、描述一致、输入字节一致、原始输出可接受、后处理一致、真实样本任务指标达标。随后再加入多模型加载、卸载、长期循环和媒体并发测试。

板端内存同时包括模型、task/work、输入输出、媒体缓冲及其他模块。单模型执行成功不能保证级联系统常驻多个模型后仍有足够内存。记录加载前、加载后、执行峰值与卸载后的状态,区分合理缓存和持续增长。

上一篇 PC仿真与精度比对 · 系列目录 · 下一篇 转换失败与性能排查