使用 Qualcomm Neural Processing Engine SDK 移植模型
模型转换
将来自 PyTorch、ONNX、TensorFlow 或 TFLite 的 32 位浮点精度预训练模型输入到 SNPE 转换器工具(snpe-<framework>-to-dlc),将模型转换为称为深度学习容器(DLC)的 Qualcomm 专用中间表示。除了来自源框架的输入模型外,转换器还需要有关输入模型的额外详情,例如输入节点名称、其对应的输入维度,以及任何输出张量名称(适用于具有多个输出的模型)。有关所有可配置参数,请参阅 converters,或运行以下命令查看命令行帮助:输出:如果您的工作环境中没有 yaml 包,请使用以下命令安装: 以下示例使用从 ONNX Model Zoo 下载的 ONNX 模型(inception_v3_opset16.onnx)。将模型以 inception_v3.onnx 为名下载到您的工作区。在本示例中,我们将模型下载到 ~/models 目录。运行以下命令以生成 inception_v3.dlc 模型。模型量化
要在 Hexagon Tensor Processor(HTP)上运行模型,必须对转换后的 DLC 进行量化。SNPE 提供了一个工具(snpe-dlc-quant),可使用其自有的量化算法将 DLC 模型量化为 INT8/INT16 DLC。有关 SNPE 量化的更多信息,请参阅 Quantized models。SNPE 的量化过程需要两个步骤:
-
量化模型内的权重和偏置。
权重和偏置的量化是一个静态步骤,即不需要用户提供额外的输入数据。
-
量化激活层(或没有权重的层)。
量化激活层需要一组来自训练数据集的输入图像作为校准数据。这些校准数据集图像以
.raw 格式的预处理图像文件列表形式输入。这些输入 .raw 文件的文件大小必须与模型的输入大小相匹配。
snpe-dlc-quant 的输入是转换后的 DLC 模型,以及一个包含校准数据集图像路径的纯文本文件。此输入列表包含以 .raw 格式保存为 NumPy 数组的预处理图像的路径。预处理图像的大小必须与模型的输入分辨率相匹配。snpe-dlc-quant 工具的输出是量化后的 DLC。使用 Netron 图可视化工具来识别模型的输入/输出层维度。 出于演示目的,我们可以使用随机输入文件来评估量化过程。可以使用下面为 inception_v3.onnx 模型编写的简单 Python 脚本生成输入文件。将该脚本以 generate_random_input.py 为名保存在您的工作区 ~/models/ 目录中,并在主机上使用 python ~/models/generate_random_input.py 运行它。以下示例 Python 代码创建一个 input_list,其中包含用于量化模型的校准数据集图像路径。上述脚本生成 10 个示例输入文件,保存在 /tmp/RandomInputsForInceptionV3/ 目录中,以及一个包含每个生成样本路径的 input_list.txt 文件。现在,snpe-dlc-quant 工具所需的所有输入都已就绪,可以对模型进行量化。这会生成一个量化的 inception_v3 DLC 模型(inception_v3_quantized.dlc)。默认情况下,模型按 INT8 位宽量化。通过为 snpe-dlc-quant 工具指定 --act_bitwidth 16 和/或 --weights_bitwidth 16 选项,可自定义量化,使用 16 位而不是默认的 INT8。请参阅 snpe-dlc-quant 工具文档,或运行 snpe-dlc-quant --help 查看所有可用的自定义项,包括量化模式、优化等。模型优化
量化后的模型 DLC 需要一个图准备步骤,以针对在 HTP 上执行优化模型。为了让模型 DLC 能够在 HTP 上执行,SNPE 提供了 snpe-dlc-graph-prepare 工具,该工具以量化模型和硬件特定详情(例如芯片组)作为输入。针对 HTP 等硬件的优化取决于芯片组上存在的特定 HTP 版本。为确保将正确的优化集应用于执行图,以最优地利用 HTP,向 snpe-dlc-graph-prepare 工具提供正确的芯片组 ID 非常重要。
根据 HTP 版本和芯片组 ID,该工具会创建一个缓存,其中包含在 HTP 硬件上执行模型 DLC 的执行策略。如果没有这一步,网络初始化期间会产生额外开销,因为 SNPE 运行时必须实时创建执行策略。HTP 缓存信息
snpe-dlc-graph-prepare 步骤完成后,HTP 缓存记录就会添加到 DLC 中。可以使用 snpe-dlc-info 工具查看该缓存信息。使用 AI Engine Direct 移植模型
模型转换和量化
将来自 PyTorch、ONNX、TensorFlow 或 TFLite 的预训练 FP32 模型输入到 QNN 转换器工具(qnn-<framework>-converter),转换为以高级可读 C++ 图形式表示的 QNN 图。在 HTP 上加速模型时,必须对模型进行量化。模型量化可以与转换在同一步骤中完成。执行此量化步骤进行静态量化时,必须提供校准数据集。要在转换的同时启用量化,请使用 --input_list INPUT_LIST 选项进行静态量化。有关更多信息,请参阅 quantization support。以下示例使用从 ONNX Model Zoo 下载的 ONNX 模型(inception_v3_opset16.onnx)。将模型以 inception_v3.onnx 为名下载到您的工作区。在本示例中,模型下载到 ~/models 目录。模型转换:CPU 后端
要将模型转换为在基于 x86/Arm 的 CPU 上运行,请运行以下命令以生成 inception_v3.cpp 和 inception_v3.bin。inception_v3.cpp 文件包含转换后模型的高级图表示。inception_v3.bin 文件包含模型的权重/偏置。模型转换和量化:HTP 后端
要在 HTP 上运行模型,需要进行量化步骤。在 AI Engine Direct(QNN)SDK 中进行量化时,需要向 QNN 转换器提供来自训练数据集的 50 到 200 张图像作为校准数据集。校准数据集中的图像经过预处理(缩放、归一化等)并以 .raw 格式保存为 NumPy 数组。这些输入 .raw 文件的大小必须与模型的输入大小相匹配。使用 Netron 图可视化工具来识别模型的输入/输出层维度。
出于演示目的,您可以使用随机输入文件来评估量化过程。可以使用下面为 inception_v3.onnx 模型编写的 Python 脚本生成输入文件。将该脚本以 generate_random_input.py 为名保存在 ~/models/ 目录中,并使用 python ~/models/generate_random_input.py 运行它。以下 Python 代码创建一个 input_list,其中包含用于量化模型的校准数据集。运行以下命令进行转换和量化。默认情况下,模型按 INT8 位宽量化。您可以指定 --act_bitwidth 16 和/或 --weights_bitwidth 16 以使用 INT16 量化。这会在 ~/models/ 目录中生成 inception_v3_quantized.cpp 和 inception_v3_quantized.bin 文件。请参阅 qnn-<framework>-converter 或运行 qnn-<framework>-converter --help,查看量化的所有可用自定义项,包括量化模式、优化等。模型编译
转换/量化步骤完成后,使用 qnn-model-lib-generator 将生成的 C++ 图编译为共享对象(.so),使应用能够动态加载模型以执行推理。对于 x86,使用 Clang 编译器工具链将 C++ 图编译为 .so 库。对于 Linux 嵌入式设备(例如 Qualcomm Dragonwing™ RB3 Gen 2 和 IQ-9075),必须使用相应的编译器工具链(aarch64-oe-linux-gcc11.2)。编译模型以在 x86 上运行
-
安装 GCC 12 版本的 GNU 标准 C++ 库开发包。
该软件包包含编译和链接 C++ 程序所需的标准库头文件(例如
<limits>、<vector> 和 <string>)、静态库和支持文件。
-
生成用于在基于 x86 的 Linux 机器上运行的共享对象模型。
这会使用 Clang-14 编译器工具链将 C++ 图编译为与 x86 主机兼容的 QNN 模型
.so,并生成 inception_v3.so。
编译模型以在目标设备上运行
在为设备端执行(aarch64 架构)编译模型时,务必使用正确的交叉编译工具链,以确保编译出的共享对象(.so)与设备操作系统兼容。以下步骤安装将模型 cpp 文件编译为 .so 库所需的交叉编译工具链。有关安装相应交叉编译工具链的说明,请参阅 Download and install the Platform SDK。在新的命令行终端中安装平台 SDK 并设置好交叉编译环境之后。
-
检查环境是否已正确设置。
如果上述环境变量未被填充,请在新的命令行终端中重复步骤 1。
-
设置 QAIRT 环境。
编译模型以在基于 Arm 的 CPU 上运行
交叉编译器设置完成后,使用以下命令在 ~/model/libs/aarch64-oe-linux-gcc11.2 中生成 libinception_v3.so。通过命令行参数将此位置提供给 qnn-model-lib-generator 工具。此处使用的编译器工具链为 aarch64-oe-linux-gcc11.2。
编译模型以在 HTP 上运行
要在 HTP 上运行模型,以下命令会在 ~/models/libs/aarch64-oe-linux-gcc11.2 中生成 libinception_v3_quantized.so。此处使用的编译器工具链为 aarch64-oe-linux-gcc11.2。