骁龙神经处理引擎SDK参考指南(4)

骁龙神经处理引擎SDK参考指南(4)


4.4 用户定义的操作

4.4.1 UDO概述

介绍
SNPE 为用户提供了以用户定义操作(以下简称 UDO)的形式插入运行时引擎可能不支持的自定义神经网络操作的能力。这些可以是在 Tensorflow 等流行的训练框架中定义的操作,也可以是基于框架扩展构建但在 SNPE SDK 中不可用的自定义操作。它们可以在实现它们的任何支持的硬件加速器上本地执行。与执行内部支持的操作相比,SNPE 提供了以无缝方式执行这些操作的基础设施,几乎没有开销。

UDO 包剖析
SNPE 允许用户以动态库的形式提供 UDO 实现,动态库可以被查询、加载和运行,以使用其中定义的内核执行推理。SNPE 提倡“UDO 包”的概念,用户可以使用它轻松表达 UDO 不同组件之间的关联。这个概念是所有工具的核心,这些工具使用户能够创建要在网络推理中使用的 UDO 包。但是,需要注意的是,SNPE 仍然在运行时直接与各种 UDO 库交互,而不是与 UDO 包构造交互。因此,用户可以自由地构建独立的库,而不必严格遵守包的概念。

下图说明了 UDO 包的概念:

在这里插入图片描述
从图中可以看出,一个UDO包由一个注册组件和一个实现组件组成。它们通常分别表示为一个注册库和一组实现库,每个硬件加速器对应一个实现内核。如果愿意,用户可以选择将这两个组件构建到一个库中。
注册库由指定所有用户定义操作的方法和它们设计的硬件内核组成。它还包含允许在创建网络时验证操作是否正常的方法。注册库在ARM CPU上加载并执行。

特定于硬件的实现库公开了其他几种实现操作实例创建、执行、分析和销毁的方法。这些是通过相应软件平台支持的编程结构实现的,例如用于 GPU 的 OpenCL 和用于 DSP 的 Hexagon-NN SDK。虽然特定于内核的实现文件在源代码上可能完全不同,但它们都需要使用 $SDK_ROOT/share/SnpeUdo/include/SnpeUdo 中定义的一组 C API 与 SNPE 交互。可以从C++ API获得有关这些 API 的完整详细信息。

UDO 工作流程

SNPE 建议采用以下工作流程来开发 UDO 并将其集成到运行时中:

在这里插入图片描述
工作流的第一步是识别模型中需要表示为用户定义操作的操作,并通过配置文件描述它们的属性。该文件的格式和内容在定义 UDO中进行了描述。

下一组步骤通过为 UDO 内核创建源文件并根据适当的工具链编译它们以生成特定于硬件内核(如 GPU 和 DSP)的动态库来生成 UDO 包的组件。SNPE 提供了一个名为的工具,snpe-udo-package-generator该工具可帮助用户创建用于与 SNPE UDO API 接口的通用框架代码,并为用户留下占位符以填充内核实现。它还为 x86、Android 等常见目标以及配置文件中指定的每个目标的运行时生成 makefile。有关包生成的更多详细信息,请参阅创建 UDO 包。有关为特定运行时编译 UDO 包的详细信息,请参阅编译 UDO 包。

SNPE 模型转换工具还需要使用第一步中创建的配置文件以及实际训练的模型,以允许使用文件中的定义解释用户定义的操作。然后可以使用工具检查生成的 DLC 文件,例如snpe-dlc-info探测模型中 UDO 的属性。有关使用 UDO 创建(和可选量化)DLC 的详细信息,请参阅使用 UDO 准备模型. 或者,也可以使用 SNPE 量化工具对具有 UDO 的模型进行量化,以与 DSP 等定点运行时一起使用。量化器工具估计来自网络中所有层(包括 UDO)的激活的量化范围。由于该工具在 x86 主机上离线运行,因此需要有 UDO 的 CPU 实现,以便通过整个网络执行推理。这也在工作流程图中以虚线表示。有关量化过程的详细信息,请参阅使用 UDO 量化 DLC 。

此工作流程的最后一步是能够使用 UDO 实际执行网络模型。SNPE 应用程序使用 UDO 包在对选定网络模型运行推理的进程中注册 UDO 实现。应该注意的是,这些 UDO 可以在没有竞争条件的情况下由多个 SNPE 实例同时执行,这增加了网络推理的整体吞吐量。有关 UDO 包注册过程的更多详细信息,请参阅使用 UDO 运行模型。

如果 UDO 的 DSP 实现库未被签名以在签名过程域(SNPE 应用程序的默认设置)上执行,则需要请求使用未签名过程域。未签名的过程域仅适用于 DSP 目标,并允许 SNPE 使用未签名的 UDO 实现库。要查看如何将未签名的进程域与 SNPE 应用程序一起使用,请参阅使用 UDO 运行模型。

UDO 向后兼容性

本节指定 UDO 包的限制:

  • 针对特定SNPE 发布版本为DSP V68 编译的UDO,需要与相同的发布版本一起使用,不能与不同的发布版本一起使用。
  • 用户需要使用与特定 SNPE 版本兼容的正确 QNN SDK 重新编译为 DSP V68 生成的 UDO 包。
  • 由于 . 中的一些已知限制,用户需要使用适用于 DSP V68 的 SNPE 1.49 SDK 重新生成 UDO 包snpe-udo-package-generator。由于此限制,用户无法在 SNPE SDK 1.49 上使用 1.49 之前生成的 UDO 包。请注意此限制仅适用于 DSP V68 UDO 包。

4.4.2定义 UDO

用户定义的操作 (UDO) 允许用户将他们的自定义操作与 SNPE 集成,以便在任何支持的硬件加速器上执行。UDO 机制接受自定义操作(定义如下)的规范,并处理该信息以处理包含该自定义操作的模型。本节解释如何指定这样的 UDO。有关UDO 的更多详细信息,请参阅UDO 概述;有关如何将包含 UDO 的模型转换为受支持框架的 SNPE DLC 的详细信息,请参阅使用 UDO准备模型。

UDO 配置规范

如UDO 概述中所述部分,用户可以使用配置规范文件来表达他们的自定义操作的属性。此 UDO 配置(以下称为 UDO 配置)是对使用 Javascript 对象表示法 (JSON) 语法和格式创建的操作的描述。配置文件语法定义了可以键值对指定的字段,并按照JSON规则以树状结构排列。这些字段是预先确定的,最终将被解析为构成 UDO 的所需信息。提供的信息应该是通用的并且独立于特定模型,这意味着特定于模型的参数或名称不需要是配置的一部分。该信息将用于识别框架模型中的操作,然后最终序列化到 DLC 模型中。

UDO 配置字段说明

上述 UDO 配置文件的详细信息如下所述。

{
    “UdoPackage_0”:
    {
        “运营商”:[
            {
                “类型”: ””,
                “输入”:[
                    {“名称”:“”,“per_core_data_types”:{“CPU”:“FLOAT_32”,“GPU”:“FLOAT_32”,“DSP”:“UINT_8”}"static": true, "tensor_layout": "NHWC"},
                    {“名称”:“”,“数据类型”:“FLOAT_32”,
                    "static": true, "tensor_layout": "NHWC"},
                ],
                “输出”:[
                    {“名称”:“”,“per_core_data_types”:{“CPU”:“FLOAT_32”,“GPU”:“FLOAT_32”,“DSP”:“UINT_8”}}
                    {“名称”:“”,“data_type”:“FLOAT_32”}
                ],
                “标量参数”:[
                    {“名称”:“scalar_param_1”,“data_type”:“INT_32”}
                ],
                “张量参数”:[
                    {"name":"tensor_param_1",​​ "data_type": "FLOAT_32", "tensor_layout": "NHWC"},
                ],
                “核心类型”:[“CPU”,“GPU”,“DSP”],
                “dsp_arch_types”:[“v66”、“v68”、“v69”、“v73”
            }
        ],
        "UDO_PACKAGE_NAME": "MyCustomUdoPackage",
    }
}

上面的描述只是一个通用配置文件,用于帮助定义用户可以填写的字段。必填字段提供特定值,而可选字段用空字符串表示。请注意,可选字段仅意味着如果未提供则有默认值,或者将使用空字符串。下面按层次结构描述了每个可用字段的完整详细信息:

  • UdoPackage:每个 UDO 包都可以描述为“UdoPackage_i”,其中i表示生成包的顺序。用户也可以自由使用空字符串,但字典结构是必需的。
  • Operators:这是特定 UdoPackage 的子节点,指示存在的运算符数量。
    • type:定义操作的类型。
    • 输入:操作的输入张量列表。每个输入都是一个字典对象。2个
      • name:可选字段,描述输入张量的名称。由于输入张量的名称是可变的,因此用户无需提供此名称。
      • per_core_data_type:一个字典对象,指定每个核心中此输入张量的数据类型。或者,如果用户希望所有指定内核都具有相同的数据类型,则用户可以指定选项“data_type”,后跟数据类型。支持的数据类型是:
        • FLOAT_16
        • FLOAT_32
        • FIXED_4
        • FIXED_8
        • FIXED_16
        • UINT_8
        • UINT_16
        • UINT_32
        • 细绳
    • static:如果输入数据是静态的,即在模型中提供数据,则需要一个布尔字段。如果输入张量将包含数据,则需要设置此字段,否则输入将被动态处理,数据将不会被序列化。
    • tensor_layout:一个字符串字段,描述输入张量的规范维度格式。支持的值为:4
      - NCHW
      - 国家卫生健康委员会
    • 输出:操作的输出张量列表。2个
    • scalar_params:标量值属性的列表。3个
      - 名称:描述标量参数名称的必填字段。
      - data_type:描述此标量参数支持的数据类型的必填字段。
    • tensor_params:张量值属性列表。2 3
    • core_types:此特定操作的预期 IP 内核。支持的 core_types:
      - 中央处理器
      - 显卡
      - 数字信号处理器
    • dsp_arch_types: DSP 核心类型的预期 DSP 架构类型。支持的 dsp_arch_types:
      • v65
      • v66
      • v68
      • v69
      • v73
  • UDO_PACKAGE_NAME: UDO 包的名称,可以是任何有效的字符串。1个
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值