在上一篇博客中,探讨了如何使用 Python 和 中预编译的模型来实现目标检测。本篇博客将深入介绍如何将用户自定义训练的模型转换并优化为能够在 Hailo NPU 上高效运行的 模型。
为了将自定义模型编译为 模型,需要安装 Hailo Dataflow Compiler(DFC) 工具。登录 Hailo 的网站 https://hailo.ai/developer-zone/software-downloads,找到对应 Python 版本的 文件,并按照下面的步骤创建虚拟环境并安装必要的软件包:
将自定义模型转换为 模型需要三步:
- 将 Tensorflow 或 ONNX 模型转换成 Hailo Archive 模型()。
- 将 模型进行量化。
- 编译为 Hailo Executable File 模型()。
Tensorflow 与 ONNX 模型都可以进行转换,这里以 的 ONNX 模型为例,首先引入软件包并定义相关变量。
接着实例化 类,并调用 方法进行转换。
在模型结构较为简单时,通常不会报错。当模型结构较为复杂时,会存在 Hailo NPU 不支持的算子,从而报错导致转换失败。NPU 支持的算子可以查询官网的数据手册,或者查看下文参考中的链接。例如在转换 YOLOv8 模型时会提示以下错误信息:
出现错误时有两种解决方案。一是根据报错信息,使用 Netron https://netron.app 查看模型结构,并修改原始模型,移除或替换 Hailo NPU 不支持的算子。二是报错信息中会推荐解决方法,在转换时绕过不支持的算子,那么 方法则需要传递额外的参数:
- :原始模型中开始转换的节点(对应新模型的输入)的名称。
- :原始模型中停止转换的节点(对应新模型的输出)的名称。
- : 输入的尺寸,如常见的 。
节点的名称可以使用 Netron 查看,或者使用下面的程序遍历打印节点的名称。
根据上面的错误信息提示,要将停止转换的节点修改为 ,修改后的程序如下。
程序执行后并未报错,但在最后一步编译时会出现 Hailo NPU 内存不够的情况,我们再观察一下转换时输出的日志:
日志建议将停止转换的节点修改为 。即在 NMS 处理前将模型切割,查阅 Hailo 开发者论坛得知,Hailo NPU 不具备进行 NMS 运算的能力,这一部分将在 CPU 上运行。Hailo 的 GitHub 仓库提供了主流模型转换时结束节点的名称,具体请查看下文参考中的链接。最终,程序修改为:
模型量化(Quantization)是将深度学习模型中的权重和激活值(输出)从高精度的浮点数(如 float32)转换为低精度的数据类型(如 int8),以减少模型的存储需求、加快推理速度并降低功耗,这一过程对于将深度学习模型部署到边缘设备中特别重要。这里使用的是训练后量化,即在已经训练好的模型上直接进行量化,无需重新训练或微调,但可能会导致一些准确性的损失。
首先需要准备好量化时使用的校准数据集。校准数据集主要用于帮助确定量化参数,以尽量减少量化过程对模型性能的影响。校准数据集的质量直接影响到量化模型的最终性能,应该尽可能涵盖所有的数据变化,以确保量化后的模型在不同条件下都能有良好的泛化能力。校准数据集不需要标签,其主要用于收集每一层激活值的统计数据,例如最小值、最大值、平均值和标准差等。这些统计信息用于确定如何最佳地映射浮点数到整数,从而保持模型性能,这个过程不需要知道输入数据对应的标签,只需要了解数据的分布特性。
本篇博客用到的 YOLOv8 模型是使用 COCO 数据集训练的,下面就以此为例进行校准数据集的准备。
接着实例化 类,并调用 方法进行量化。
在量化过程中还可以添加一些脚本对参数进行设置,例如 设置量化的级别、 设置模型能够使用的资源量等。 仓库提供了主流模型的参数设置脚本,具体请查看下文参考中的链接。程序示例如下。
最后使用 方法完成模型的编译。