骁龙神经处理引擎SDK参考指南(11)
4.5.8 离线图缓存
HTP 上 DSP 运行时的离线图形缓存
具有Hexagon 张量处理器 (HTP) 的目标上的 SNPE DSP 运行时支持离线图形缓存功能,这有助于在 Linux x86-64 平台上准备后端图形。这有助于减少初始化时间并在执行模型时直接加载设备上的缓存。
SNPE 用户的工作流程更改:
- 使用 snpe-caffe/caffe2/tensorflow-to-dlc 进行模型转换
- 使用 snpe-dlc-quant 进行模型量化
- 使用 snpe-dlc-graph-prepare 对离线图形缓存准备进行建模
- 使用 snpe-net-run 或自定义应用程序在目标上执行模型
上图中的 DLC Quantize 包含 2 个步骤,即首先量化模型,然后生成离线缓存。snpe-dlc-graph-prepare工具用于在 DLC 被snpe-dlc-quant工具量化后为 SNPE HTP 运行时生成 DLC 缓存 blob。snpe-dlc-graph-prepare工具也可以与浮动模型一起使用,为 HTP FP16 运行时生成缓存。
例如,以下命令将 Inception v3 DLC 文件转换为量化的 Inception v3 DLC 文件,并生成 HTP 图形缓存并存储在 DLC 中。
snpe-dlc-quant --input_dlc inception_v3.dlc --input_list image_file_list.txt --output_dlc inception_v3_quantized.dlc
snpe-dlc-graph-prepare --input_dlc inception_v3_quantized.dlc --output_dlc inception_v3_quantized_cache.dlc --htp_socs sm855 0
运行snpe-dlc-graph-prepare触发在提供的模型上生成 HTP 图,并将生成的缓存添加到 HTP 记录到 DLC 中。如果 HTP 编译器无法处理/编译网络的任何部分,snpe-dlc-graph-prepare 会发出一条错误消息。
snpe-dlc-graph-prepare可以帮助使用相同/不同版本的 SNPE 快速为图形重新准备离线缓存,而无需重新执行量化步骤,如果输入数据集很大,量化步骤可能会花费大量时间。
同样,作为量化过程的一部分,snpe-dlc-quantize工具使用 –enable_htp 选项为 SNPE HTP 运行时生成 DLC 缓存 blob。
例如,以下命令将 Inception v3 DLC 文件转换为量化的 Inception v3 DLC 文件,并生成 HTP 图形缓存并存储在 DLC 中。
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list image_file_list.txt --output_dlc inception_v3_quantized.dlc
--enable_htp --htp_socs sm8550
笔记:
- 离线准备的图缓存和运行时的 SNPE 对象必须指定相同的图输出。如果在运行时未请求与准备好的图形中指定的相同的图形输出,则准备好的图形被视为无效并将被忽略。然后,图形准备将在运行时完成(称为在线准备),从而拒绝 DLC 中的缓存 blob,导致在这种情况下明显增加初始化时间。
- 为了启用离线准备的 CPU 回退,位于 CPU 子网之前的 DSP 子网需要将输入到后续子网的所有输出张量标记为图形输出。
- 使用snpe-dlc-quantize 的离线图形准备将在未来被弃用。目前,snpe-dlc-quantize用于支持遗留工作流程。建议迁移到snpe-dlc-graph-prepare用于离线 htp graph cache blob 准备
4.5.9 添加 HTA 部分
在 Hexagon Tensor Accelerator (HTA) 上运行模型需要对模型进行量化,并为在 HTA 上运行的部分生成二进制文件。两者都是使用snpe-dlc-quantize工具完成的,该工具经过扩展以包含内部的 HTA 编译器。
例如,以下命令将 Inception v3 DLC 文件转换为量化的 Inception v3 DLC 文件,并生成 HTA 部分以在 HTA 上运行整个模型。
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list image_file_list.txt
--output_dlc inception_v3_quantized.dlc --enable_hta
除了最后一个 (enable_hta) 之外的所有参数都与常规量化相同,并在量化模型中进行了解释。添加此参数会触发在提供的模型上生成 HTA 部分,并将编译的部分添加到 AIP 记录到 DLC 中。如果 HTA 编译器无法处理/编译网络的任何部分,snpe-dlc-quantize会发出一条错误消息。但是,DLC 仍将创建 - 只是没有 HTA 部分。
模型划分
默认情况下,HTA 编译器会自动对网络进行分区,以最大化在 HTA 上运行的部分。
在这种情况下,加载模型时,AIP 运行时使用 Hexagon NN 在 HVX 上运行非 HTA 部分。
如果启用了 CPU 回退,则 AIP 运行时未处理的任何部分都可能回退到 CPU 运行时执行。
在某些情况下,可能需要手动对网络进行分区,并选择可能与编译器自动生成的分区点不同的分区点。当事先知道网络的某个部分不支持在 HTA 上运行时,这可能是一个可预知的选项,请求只为 HTA 编译剩余部分,或者为了性能优势。
在所有情况下,SNPE snpe-dlc-quantize 工具都会创建记录,这些记录存储有关 HTA 子网的元数据以及 HTA 编译器为指定部分生成的编译二进制文件。
此外,它还为 HNN 子网检测并创建记录以覆盖模型的其余部分,并存储关于它们的元数据,这些元数据指定与分区确定的其他 HTA 子网的缓冲区连接。
所有这些记录都以加载模型时在运行时解析的格式存储在 DL 容器中。
要在对模型进行分区时手动指定使用的 HTA 部分,除了“enable_hta”之外,还应将附加参数“hta_partitions”传递给snpe-dlc-quantize 。
分区边界指定为逗号分隔(开始-结束)对,它们引用必须属于分区的层的 ID。
例如,以下命令将 Inception v3 DLC 文件转换为量化的 Inception v3 DLC 文件,并为层 0-11 生成单个 HTA 部分。
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list image_file_list.txt
--output_dlc inception_v3_quantized.dlc --enable_hta --hta_partitions 0-11
以下命令将分区扩展到多个 HTA 分区,在本例中为 0-11 和 177-215。
snpe-dlc-quantize --input_dlc inception_v3.dlc --input_list image_file_list.txt
--output_dlc inception_v3_quantized.dlc --enable_hta --hta_partitions 0-11,177-215
笔记:
- HTA 编译过程会删除之前使用 --enable_hta 运行的 snpe-dlc-quantize 中可能已经存在于 DLC 中的任何旧 AIP 记录。
建议用户从原始 DLC 开始进行 HTA 编译,以免无意中丢失之前生成的 AIP 记录。 - 由于 HVX 和 HNN 子网之间发生的重复重新量化和格式转换,在 AIP 子网内创建大量分区可能会导致运行时性能不佳和精度下降。
- 在这种情况下优化 AIP 性能的一种方法是重新排序与源网络中每个层关联的唯一 ID(在转换为 DLC 之前),以便离线编译在网络中产生更有意义的分区和更少的碎片。