本页概述了如何实现神经网络 API (NNAPI) 驱动程序。如需了解更多详情,请参阅 hardware/interfaces/neuralnetworks
中的 HAL 定义文件中的文档。示例驱动程序实现在 frameworks/ml/nn/driver/sample
中。
如需详细了解神经网络 API,请参阅神经网络 API。
神经网络 HAL
神经网络 (NN) HAL 定义了产品(例如,手机或平板电脑)中各种设备(如图形处理器 (GPU) 和数字信号处理器 (DSP))的抽象。这些设备的驱动程序必须符合 NN HAL。该接口在 hardware/interfaces/neuralnetworks
中的 HAL 定义文件中指定。
框架和驱动程序之间接口的一般流程如图 1 所示。
图 1. 神经网络流程
初始化
在初始化时,框架会查询驱动程序的功能,方法是使用 IDevice::getCapabilities_1_3
。@1.3::Capabilities
结构包含所有数据类型,并使用向量表示非宽松性能。
为了确定如何将计算分配给可用的设备,框架会使用各项功能来了解每个驱动程序执行操作的速度和能效。为了提供此信息,驱动程序必须根据参考工作负载的执行情况提供标准化的性能数值。
要确定驱动程序响应 IDevice::getCapabilities_1_3
而返回的值,请使用 NNAPI 基准测试应用来衡量相应数据类型的性能。建议使用 MobileNet v1 和 v2、asr_float
以及 tts_float
模型来衡量 32 位浮点值的性能,建议使用 MobileNet v1 和 v2 量化模型来衡量 8 位量化值的性能。如需了解详情,请参阅 Android 机器学习测试套件。
在 Android 9 及更低版本中,Capabilities
结构仅包含浮点和量化张量的驱动程序性能信息,不包含标量数据类型。
作为初始化过程的一部分,框架可能会使用 IDevice::getType
、IDevice::getVersionString
、IDevice:getSupportedExtensions
和 IDevice::getNumberOfCacheFilesNeeded
查询更多信息。
在产品重启之间,框架希望本节中描述的所有查询始终为给定的驱动程序报告相同的值。否则,使用该驱动程序的应用可能会表现出性能降低或行为不正确的情况。
编译
当框架收到来自应用的请求时,会确定要使用的设备。在 Android 10 中,应用可以发现和指定框架从中选择的设备。如需了解详情,请参阅设备发现和分配。
在模型编译时,框架通过调用 IDevice::getSupportedOperations_1_3
将模型发送到每个候选驱动程序。每个驱动程序都会返回一个布尔值数组,指示模型支持哪些运算。驱动程序可能会因多种原因确定它无法支持给定的运算。例如:
- 驱动程序不支持数据类型。
- 驱动程序仅支持具有特定输入参数的运算。例如,驱动程序可能支持 3x3 和 5x5 卷积运算,但不支持 7x7 卷积运算。
- 驱动程序的内存限制阻止其处理大型图或输入。
在编译期间,如 OperandLifeTime
中所述,模型的输入、输出和内部操作数可能具有未知的维度或秩。如需了解详情,请参阅输出形状。
框架指示每个选定的驱动程序通过调用 IDevice::prepareModel_1_3
来准备执行模型子集。然后,每个驱动程序都会编译其子集。例如,驱动程序可能会生成代码或创建权重的重新排序副本。由于模型的编译与请求的执行之间可能存在大量时间,因此不应在编译期间分配设备内存的大块资源。
如果成功,驱动程序会返回 @1.3::IPreparedModel
句柄。如果驱动程序在准备模型子集时返回失败代码,则框架会在 CPU 上运行整个模型。
为了减少应用启动时用于编译的时间,驱动程序可以缓存编译工件。如需了解详情,请参阅编译缓存。
执行
当应用请求框架执行请求时,框架默认调用 IPreparedModel::executeSynchronously_1_3
HAL 方法,以在准备好的模型上执行同步执行。请求也可以使用 execute_1_3
方法、executeFenced
方法(请参阅栅栏执行)异步执行,或者使用突发执行来执行。
与异步调用相比,同步执行调用可以提高性能并减少线程开销,因为只有在执行完成后,控制权才会返回到应用进程。这意味着驱动程序不需要单独的机制来通知应用进程执行已完成。
使用异步 execute_1_3
方法,控制权会在执行开始后返回到应用进程,并且驱动程序必须使用 @1.3::IExecutionCallback
在执行完成时通知框架。
传递给 execute 方法的 Request
参数列出了用于执行的输入和输出操作数。存储操作数数据的内存必须使用行优先顺序,且第一个维度迭代速度最慢,并且在任何行的末尾都没有填充。如需详细了解操作数的类型,请参阅操作数。
对于 NN HAL 1.2 或更高版本的驱动程序,当请求完成时,错误状态、输出形状和定时信息会返回到框架。在执行期间,模型的输出或内部操作数可能具有一个或多个未知维度或未知秩。当至少一个输出操作数具有未知维度或秩时,驱动程序必须返回动态调整大小的输出信息。
对于 NN HAL 1.1 或更低版本的驱动程序,仅当请求完成时才会返回错误状态。输入和输出操作数的维度必须完全指定,执行才能成功完成。内部操作数可以具有一个或多个未知维度,但它们必须具有指定的秩。
对于跨多个驱动程序的用户请求,框架负责预留中间内存以及对每个驱动程序的调用进行排序。
可以在同一 @1.3::IPreparedModel
上并行启动多个请求。驱动程序可以并行执行请求或序列化执行。
框架可以要求驱动程序保留多个准备好的模型。例如,准备模型 m1
,准备 m2
,在 m1
上执行请求 r1
,在 m2
上执行 r2
,在 m1
上执行 r3
,在 m2
上执行 r4
,释放(在清理中描述)m1
,并释放 m2
。
为避免首次执行速度过慢而导致不良用户体验(例如,首帧卡顿),驱动程序应在编译阶段执行大多数初始化。首次执行时的初始化应仅限于在早期执行时会对系统健康状况产生负面影响的操作,例如预留大型临时缓冲区或提高设备的时钟频率。只能准备有限数量的并发模型的驱动程序可能必须在首次执行时进行初始化。
在 Android 10 或更高版本中,如果使用同一准备好的模型在快速连续执行多个执行,客户端可以选择使用执行突发对象在应用和驱动程序进程之间进行通信。如需了解详情,请参阅突发执行和快速消息队列。
为了提高快速连续多次执行的性能,驱动程序可以保留临时缓冲区或提高时钟频率。建议创建一个监视程序线程,以便在固定时间段后未创建新请求时释放资源。
输出形状
对于一个或多个输出操作数未指定所有维度的请求,驱动程序必须在执行后提供输出形状列表,其中包含每个输出操作数的维度信息。如需详细了解维度,请参阅 OutputShape
。
如果执行因输出缓冲区过小而失败,驱动程序必须在输出形状列表中指示哪些输出操作数的缓冲区大小不足,并且应尽可能多地报告维度信息,对于未知的维度,应使用零。
定时
在 Android 10 中,如果应用已指定在编译过程中使用的单个设备,则应用可以请求执行时间。如需了解详情,请参阅 MeasureTiming
和 设备发现和分配。在这种情况下,NN HAL 1.2 驱动程序必须测量执行时长,或者在执行请求时报告 UINT64_MAX
(以指示时长不可用)。驱动程序应尽量减少因测量执行时长而导致的任何性能损失。
驱动程序会在 Timing
结构中报告以下以微秒为单位的时长:
- 设备上的执行时间:不包括驱动程序在主机处理器上运行的执行时间。
- 驱动程序中的执行时间:包括设备上的执行时间。
这些时长必须包括执行暂停的时间,例如,当执行已被其他任务抢占或正在等待资源可用时。
当驱动程序未被要求测量执行时长,或者存在执行错误时,驱动程序必须将时长报告为 UINT64_MAX
。即使驱动程序被要求测量执行时长,它也可以改为报告 UINT64_MAX
作为设备上的时间、驱动程序中的时间或两者。当驱动程序将两个时长都报告为 UINT64_MAX
以外的值时,驱动程序中的执行时间必须等于或超过设备上的时间。
栅栏执行
在 Android 11 中,NNAPI 允许执行等待 sync_fence
句柄列表,并可以选择返回 sync_fence
对象,该对象在执行完成时发出信号。这减少了小型序列模型和流式用例的开销。栅栏执行还允许与其他可以发出信号或等待 sync_fence
的组件进行更高效的互操作。如需详细了解 sync_fence
,请参阅同步框架。
在栅栏执行中,框架调用 IPreparedModel::executeFenced
方法,以使用要等待的同步栅栏向量在准备好的模型上启动栅栏异步执行。如果异步任务在调用返回之前完成,则可以为 sync_fence
返回空句柄。还必须返回 IFencedExecutionCallback
对象,以允许框架查询错误状态和时长信息。
执行完成后,可以通过 IFencedExecutionCallback::getExecutionInfo
查询以下两个测量执行时长的定时值。
timingLaunched
:从调用executeFenced
到executeFenced
发出返回的syncFence
信号的时长。timingFenced
:从执行等待的所有同步栅栏发出信号到executeFenced
发出返回的syncFence
信号的时长。
控制流
对于运行 Android 11 或更高版本的设备,NNAPI 包括两个控制流运算 IF
和 WHILE
,它们将其他模型作为参数,并有条件 (IF
) 或重复 (WHILE
) 执行这些模型。如需详细了解如何实现此功能,请参阅控制流。
服务质量
在 Android 11 中,NNAPI 通过允许应用指示其模型的相对优先级、模型准备的最大预期时间以及执行完成的最大预期时间,从而改进了服务质量 (QoS)。如需了解详情,请参阅服务质量。
清理
当应用完成使用准备好的模型时,框架会释放其对 @1.3::IPreparedModel
对象的引用。当不再引用 IPreparedModel
对象时,它会在创建它的驱动程序服务中自动销毁。模型特定的资源可以在此时在驱动程序的析构函数实现中回收。如果驱动程序服务希望在客户端不再需要 IPreparedModel
对象时自动销毁它,则在通过 IPreparedModelCallback::notify_1_3
返回 IPreparedeModel
对象后,它不得保留对 IPreparedModel
对象的任何引用。
CPU 使用率
驱动程序应使用 CPU 来设置计算。驱动程序不应使用 CPU 来执行图计算,因为这会干扰框架正确分配工作的能力。驱动程序应向框架报告其无法处理的部分,并让框架处理其余部分。
框架为除供应商定义运算之外的所有 NNAPI 运算提供 CPU 实现。如需了解详情,请参阅供应商扩展。
Android 10 中引入的运算(API 级别 29)仅具有参考 CPU 实现,用于验证 CTS 和 VTS 测试是否正确。与 NNAPI CPU 实现相比,移动机器学习框架中包含的优化实现更受欢迎。
实用程序函数
NNAPI 代码库包含可供驱动程序服务使用的实用程序函数。
frameworks/ml/nn/common/include/Utils.h
文件包含各种实用程序函数,例如用于日志记录和在不同 NN HAL 版本之间进行转换的函数。
VLogging:
VLOG
是 AndroidLOG
周围的包装宏,仅当在debug.nn.vlog
属性中设置了适当的标记时才记录消息。initVLogMask()
必须在任何对VLOG
的调用之前调用。VLOG_IS_ON
宏可用于检查当前是否启用了VLOG
,从而允许在不需要时跳过复杂的日志记录代码。属性的值必须是以下值之一:- 空字符串,表示不执行任何日志记录。
- 令牌
1
或all
,表示要完成所有日志记录。 - 标记列表,以空格、逗号或冒号分隔,指示要完成哪些日志记录。标记为
compilation
、cpuexe
、driver
、execution
、manager
和model
。
compliantWithV1_*
:如果 NN HAL 对象可以转换为不同 HAL 版本的相同类型而不会丢失信息,则返回true
。例如,如果模型包含 NN HAL 1.1 或 NN HAL 1.2 中引入的运算类型,则在V1_2::Model
上调用compliantWithV1_0
会返回false
。convertToV1_*
:将 NN HAL 对象从一个版本转换为另一个版本。如果转换导致信息丢失(即,如果新版本的类型无法完全表示该值),则会记录警告。功能:
nonExtensionOperandPerformance
和update
函数可用于帮助构建Capabilities::operandPerformance
字段。查询类型属性:
isExtensionOperandType
、isExtensionOperationType
、nonExtensionSizeOfData
、nonExtensionOperandSizeOfData
、nonExtensionOperandTypeIsScalar
、tensorHasUnspecifiedDimensions
。
frameworks/ml/nn/common/include/ValidateHal.h
文件包含实用程序函数,用于验证 NN HAL 对象是否根据其 HAL 版本规范有效。
validate*
:如果 NN HAL 对象根据其 HAL 版本规范有效,则返回true
。OEM 类型和扩展类型未经过验证。例如,如果模型包含引用不存在的操作数索引的运算,或者模型包含该 HAL 版本不支持的运算,则validateModel
会返回false
。
frameworks/ml/nn/common/include/Tracing.h
文件包含用于简化向神经网络代码添加 systracing 信息的宏。有关示例,请参阅 示例驱动程序中的 NNTRACE_*
宏调用。
frameworks/ml/nn/common/include/GraphDump.h
文件包含一个实用程序函数,用于以图形形式转储 Model
的内容,以进行调试。
graphDump
:以 Graphviz (.dot
) 格式将模型的表示形式写入指定的流(如果已提供),或者写入 logcat(如果未提供流)。
验证
要测试 NNAPI 的实现,请使用 Android 框架中包含的 VTS 和 CTS 测试。VTS 直接(不使用框架)练习驱动程序,而 CTS 通过框架间接练习驱动程序。这些测试每个 API 方法,并验证驱动程序支持的所有运算是否正常工作并提供满足精度要求的结果。
CTS 和 VTS 中针对 NNAPI 的精度要求如下:
浮点:abs(预期值 - 实际值) <= atol + rtol * abs(预期值);其中:
- 对于 fp32,atol = 1e-5f,rtol = 5.0f * 1.1920928955078125e-7
- 对于 fp16,atol = rtol = 5.0f * 0.0009765625f
量化:相差一位(
mobilenet_quantized
除外,相差三位)布尔:完全匹配
CTS 测试 NNAPI 的一种方法是生成固定的伪随机图,用于测试和比较每个驱动程序的执行结果与 NNAPI 参考实现。对于 NN HAL 1.2 或更高版本的驱动程序,如果结果不符合精度标准,则 CTS 会报告错误,并在 /data/local/tmp
下转储失败模型的规范文件以进行调试。如需详细了解精度标准,请参阅 TestRandomGraph.cpp
和 TestHarness.h
。
模糊测试
模糊测试的目的是查找测试代码中由于意外输入等因素而导致崩溃、断言、内存违规或常规未定义行为的情况。对于 NNAPI 模糊测试,Android 使用基于 libFuzzer 的测试,这些测试在模糊测试方面效率很高,因为它们使用先前测试用例的行覆盖率来生成新的随机输入。例如,libFuzzer 偏爱在新代码行上运行的测试用例。这大大减少了测试查找有问题代码所需的时间。
要执行模糊测试以验证驱动程序实现,请修改 AOSP 中 libneuralnetworks_driver_fuzzer
测试实用程序中的 frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
,以包含驱动程序代码。如需详细了解 NNAPI 模糊测试,请参阅 frameworks/ml/nn/runtime/test/android_fuzzing/README.md
。
安全性
由于应用进程直接与驱动程序的进程通信,因此驱动程序必须验证其接收的调用的参数。此验证由 VTS 验证。验证代码位于 frameworks/ml/nn/common/include/ValidateHal.h
中。
驱动程序还应确保应用在使用同一设备时不会相互干扰。
Android 机器学习测试套件
Android 机器学习测试套件 (MLTS) 是 CTS 和 VTS 中包含的 NNAPI 基准测试,用于验证供应商设备上真实模型的准确性。该基准测试评估延迟时间和准确性,并将驱动程序的结果与在 CPU 上运行的 TF Lite 的结果进行比较,以用于相同的模型和数据集。这确保了驱动程序的准确性不低于 CPU 参考实现。
Android 平台开发者还使用 MLTS 来评估驱动程序的延迟时间和准确性。
NNAPI 基准测试可以在 AOSP 的两个项目中找到:
platform/test/mlts/benchmark
(基准测试应用)platform/test/mlts/models
(模型和数据集)
模型和数据集
NNAPI 基准测试使用以下模型和数据集。
- MobileNetV1 浮点和 u8 量化,具有不同大小,针对 Open Images Dataset v4 的小子集(1500 张图片)运行。
- MobileNetV2 浮点和 u8 量化,具有不同大小,针对 Open Images Dataset v4 的小子集(1500 张图片)运行。
- 基于长短期记忆 (LSTM) 的声学模型,用于文本到语音转换,针对 CMU Arctic 集的小子集运行。
- 基于 LSTM 的声学模型,用于自动语音识别,针对 LibriSpeech 数据集的小子集运行。
如需了解详情,请参阅 platform/test/mlts/models
。
压力测试
Android 机器学习测试套件包含一系列崩溃测试,用于验证驱动程序在重度使用情况下或在客户端行为的极端情况下的弹性。
所有崩溃测试都提供以下功能:
- 挂起检测:如果 NNAPI 客户端在测试期间挂起,则测试将失败,失败原因为
HANG
,并且测试套件会移至下一个测试。 - NNAPI 客户端崩溃检测:测试在客户端崩溃后仍然存在,并且测试失败,失败原因为
CRASH
。 - 驱动程序崩溃检测:测试可以检测到导致 NNAPI 调用失败的驱动程序崩溃。请注意,驱动程序进程中可能存在不会导致 NNAPI 失败且不会导致测试失败的崩溃。为了涵盖此类失败,建议在系统日志上运行
tail
命令以查找与驱动程序相关的错误或崩溃。 - 针对所有可用的加速器:测试针对所有可用的驱动程序运行。
所有崩溃测试都有以下四种可能的结果:
SUCCESS
:执行已完成,没有错误。FAILURE
:执行失败。通常是由测试模型时发生故障引起的,表明驱动程序未能编译或执行模型。HANG
:测试进程变得无响应。CRASH
:测试进程崩溃。
如需详细了解压力测试和崩溃测试的完整列表,请参阅 platform/test/mlts/benchmark/README.txt
。
使用 MLTS
要使用 MLTS:
- 将目标设备连接到工作站,并确保可以通过 adb 访问该设备。如果连接了多个设备,请导出目标设备
ANDROID_SERIAL
环境变量。 cd
进入 Android 顶级源代码目录。source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
在基准测试运行结束时,结果将以 HTML 页面的形式呈现,并传递给
xdg-open
。
如需了解详情,请参阅 platform/test/mlts/benchmark/README.txt
。
神经网络 HAL 版本
本节介绍 Android 和神经网络 HAL 版本中引入的更改。
Android 11
Android 11 引入了 NN HAL 1.3,其中包括以下值得注意的更改。
- NNAPI 中对有符号 8 位量化的支持。 添加了
TENSOR_QUANT8_ASYMM_SIGNED
操作数类型。 具有 NN HAL 1.3 且支持无符号量化操作的驱动程序也必须支持这些操作的有符号变体。 在运行大多数量化操作的有符号和无符号版本时,驱动程序必须产生相同的结果,误差在 128 以内。 此要求有五个例外情况:CAST
、HASHTABLE_LOOKUP
、LSH_PROJECTION
、PAD_V2
和QUANTIZED_16BIT_LSTM
。QUANTIZED_16BIT_LSTM
操作不支持有符号操作数,而其他四个操作支持有符号量化,但不要求结果相同。 - 对围栏执行的支持,框架在其中调用
IPreparedModel::executeFenced
方法,以便在准备好的模型上启动围栏式异步执行,并使用同步围栏向量等待。 有关详细信息,请参阅围栏执行。 - 对控制流的支持。 添加了
IF
和WHILE
操作,这些操作将其他模型作为参数,并有条件地 (IF
) 或重复地 (WHILE
) 执行它们。 有关详细信息,请参阅控制流。 - 改进的服务质量 (QoS),因为应用可以指示其模型的相对优先级、模型准备所需的最长时间以及执行完成所需的最长时间。 有关详细信息,请参阅服务质量。
- 对内存域的支持,该内存域为驱动程序管理的缓冲区提供分配器接口。 这允许跨执行传递设备原生内存,从而消除同一驱动程序上连续执行之间不必要的数据复制和转换。 有关详细信息,请参阅内存域。
Android 10
Android 10 引入了 NN HAL 1.2,其中包括以下显著更改。
Capabilities
结构体包含所有数据类型(包括标量数据类型),并使用向量而不是命名字段来表示非宽松性能。getVersionString
和getType
方法允许框架检索设备类型 (DeviceType
) 和版本信息。 请参阅设备发现和分配。- 默认情况下调用
executeSynchronously
方法以同步执行。execute_1_2
方法告知框架异步执行。 请参阅执行。 MeasureTiming
参数(用于executeSynchronously
、execute_1_2
和突发执行)指定驱动程序是否要测量执行持续时间。 结果在Timing
结构中报告。 请参阅计时。- 支持一个或多个输出操作数具有未知维度或秩的执行。 请参阅输出形状。
- 支持供应商扩展,这些扩展是供应商定义的操作和数据类型的集合。 驱动程序通过
IDevice::getSupportedExtensions
方法报告支持的扩展。 请参阅供应商扩展。 - 突发对象能够使用快速消息队列 (FMQ) 控制一组突发执行,以在应用和驱动程序进程之间进行通信,从而减少延迟。 请参阅突发执行和快速消息队列。
- 支持 AHardwareBuffer,允许驱动程序在不复制数据的情况下执行操作。 请参阅AHardwareBuffer。
- 改进了编译工件的缓存支持,以减少应用启动时用于编译的时间。 请参阅编译缓存。
Android 10 引入了以下操作数类型和操作。
-
ANEURALNETWORKS_BOOL
ANEURALNETWORKS_FLOAT16
ANEURALNETWORKS_TENSOR_BOOL8
ANEURALNETWORKS_TENSOR_FLOAT16
ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
ANEURALNETWORKS_TENSOR_QUANT16_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
-
ANEURALNETWORKS_ABS
ANEURALNETWORKS_ARGMAX
ANEURALNETWORKS_ARGMIN
ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
ANEURALNETWORKS_CAST
ANEURALNETWORKS_CHANNEL_SHUFFLE
ANEURALNETWORKS_DETECTION_POSTPROCESSING
ANEURALNETWORKS_EQUAL
ANEURALNETWORKS_EXP
ANEURALNETWORKS_EXPAND_DIMS
ANEURALNETWORKS_GATHER
ANEURALNETWORKS_GENERATE_PROPOSALS
ANEURALNETWORKS_GREATER
ANEURALNETWORKS_GREATER_EQUAL
ANEURALNETWORKS_GROUPED_CONV_2D
ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
ANEURALNETWORKS_INSTANCE_NORMALIZATION
ANEURALNETWORKS_LESS
ANEURALNETWORKS_LESS_EQUAL
ANEURALNETWORKS_LOG
ANEURALNETWORKS_LOGICAL_AND
ANEURALNETWORKS_LOGICAL_NOT
ANEURALNETWORKS_LOGICAL_OR
ANEURALNETWORKS_LOG_SOFTMAX
ANEURALNETWORKS_MAXIMUM
ANEURALNETWORKS_MINIMUM
ANEURALNETWORKS_NEG
ANEURALNETWORKS_NOT_EQUAL
ANEURALNETWORKS_PAD_V2
ANEURALNETWORKS_POW
ANEURALNETWORKS_PRELU
ANEURALNETWORKS_QUANTIZE
ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
ANEURALNETWORKS_RANDOM_MULTINOMIAL
ANEURALNETWORKS_REDUCE_ALL
ANEURALNETWORKS_REDUCE_ANY
ANEURALNETWORKS_REDUCE_MAX
ANEURALNETWORKS_REDUCE_MIN
ANEURALNETWORKS_REDUCE_PROD
ANEURALNETWORKS_REDUCE_SUM
ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_ROI_POOLING
ANEURALNETWORKS_RSQRT
ANEURALNETWORKS_SELECT
ANEURALNETWORKS_SIN
ANEURALNETWORKS_SLICE
ANEURALNETWORKS_SPLIT
ANEURALNETWORKS_SQRT
ANEURALNETWORKS_TILE
ANEURALNETWORKS_TOPK_V2
ANEURALNETWORKS_TRANSPOSE_CONV_2D
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN
Android 10 引入了对许多现有操作的更新。 这些更新主要与以下方面相关:
- 支持 NCHW 内存布局
- 支持 softmax 和归一化操作中秩不为 4 的张量
- 支持扩张卷积
- 支持
ANEURALNETWORKS_CONCATENATION
中具有混合量化的输入
下面的列表显示了在 Android 10 中修改的操作。 有关更改的完整详细信息,请参阅 NNAPI 参考文档中的 OperationCode。
ANEURALNETWORKS_ADD
ANEURALNETWORKS_AVERAGE_POOL_2D
ANEURALNETWORKS_BATCH_TO_SPACE_ND
ANEURALNETWORKS_CONCATENATION
ANEURALNETWORKS_CONV_2D
ANEURALNETWORKS_DEPTHWISE_CONV_2D
ANEURALNETWORKS_DEPTH_TO_SPACE
ANEURALNETWORKS_DEQUANTIZE
ANEURALNETWORKS_DIV
ANEURALNETWORKS_FLOOR
ANEURALNETWORKS_FULLY_CONNECTED
ANEURALNETWORKS_L2_NORMALIZATION
ANEURALNETWORKS_L2_POOL_2D
ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
ANEURALNETWORKS_LOGISTIC
ANEURALNETWORKS_LSH_PROJECTION
ANEURALNETWORKS_LSTM
ANEURALNETWORKS_MAX_POOL_2D
ANEURALNETWORKS_MEAN
ANEURALNETWORKS_MUL
ANEURALNETWORKS_PAD
ANEURALNETWORKS_RELU
ANEURALNETWORKS_RELU1
ANEURALNETWORKS_RELU6
ANEURALNETWORKS_RESHAPE
ANEURALNETWORKS_RESIZE_BILINEAR
ANEURALNETWORKS_RNN
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_SOFTMAX
ANEURALNETWORKS_SPACE_TO_BATCH_ND
ANEURALNETWORKS_SPACE_TO_DEPTH
ANEURALNETWORKS_SQUEEZE
ANEURALNETWORKS_STRIDED_SLICE
ANEURALNETWORKS_SUB
ANEURALNETWORKS_SVDF
ANEURALNETWORKS_TANH
ANEURALNETWORKS_TRANSPOSE
Android 9
NN HAL 1.1 在 Android 9 中引入,包括以下显著更改。
IDevice::prepareModel_1_1
包括ExecutionPreference
参数。 驱动程序可以使用此参数来调整其准备工作,因为它知道应用倾向于节省电池电量,或者将在快速连续的调用中执行模型。- 添加了九个新操作:
BATCH_TO_SPACE_ND
、DIV
、MEAN
、PAD
、SPACE_TO_BATCH_ND
、SQUEEZE
、STRIDED_SLICE
、SUB
、TRANSPOSE
。 - 应用可以指定可以使用 16 位浮点范围和/或精度运行 32 位浮点计算,方法是将
Model.relaxComputationFloat32toFloat16
设置为true
。Capabilities
结构具有附加字段relaxedFloat32toFloat16Performance
,以便驱动程序可以向框架报告其宽松性能。
Android 8.1
初始 Neural Networks HAL (1.0) 在 Android 8.1 中发布。 有关详细信息,请参阅 /neuralnetworks/1.0/
。