从 Android 11 开始,NNAPI 允许应用指示模型的相对优先级、准备给定模型的预计最长时间以及完成给定执行的预计最长时间,从而改进服务质量 (QoS)。此外,Android 11 还引入了更多 NNAPI 错误值,使服务能够更准确地指示发生故障时出现的问题,以便客户端应用更好地应对和恢复。
优先级
对于 Android 11 或更高版本,NN HAL 1.3 中准备的模型具有优先级。此优先级是相对于同一应用所拥有的其他准备好的模型而言的。与优先级较低的执行相比,优先级较高的执行可以使用更多计算资源,并可抢占或耗尽优先级较低的执行的资源。
包含 Priority
显式参数的 NN HAL 1.3 调用是 IDevice::prepareModel_1_3
。请注意,IDevice::prepareModelFromCache_1_3
在缓存参数中隐式包含 Priority
。
支持优先级的策略可能有许多,具体取决于驱动程序和加速器的功能。以下列举了几项策略:
- 对于具有内置优先级支持的驱动程序,可直接将
Priority
字段传播到加速器。 - 甚至在执行到达加速器之前,就可使用单独针对每个应用的优先级队列来支持不同的优先级。
暂停或取消正在执行的低优先级模型,以释放加速器,使其执行高优先级模型。为此,您可以将检查点插入低优先级模型,这样,在到达检查点时,就可以通过查询标志确定是否应提前暂停当前执行;或者,您也可以将模型划分为子模型,并在子模型执行之间查询相应标志。请注意,在准备好的具有优先级的模型中使用检查点或子模型可能会引入额外的开销,而在低于 NN HAL 1.3 的版本中,没有优先级的模型不存在这种开销。
- 如需支持抢占,请保留执行上下文,包括要执行的下一个运算或子模型以及所有相关的中间运算数数据。过后可使用此执行上下文恢复执行。
- 完全抢占支持没有必要,因此不需要保留执行上下文。由于 NNAPI 模型的执行具有确定性,因此您可于稍后从头开始重启执行。
Android 允许服务通过使用 AID (Android UID) 区分发起调用的不同应用。HIDL 具有内置检索机制,可通过 ::android::hardware::IPCThreadState::getCallingUid
方法检索发起调用的应用的 UID。AID 列表可在 libcutils/include/cutils/android_filesystem_config.h
中找到。
时限
从 Android 11 开始,启动模型准备和执行时可以使用 OptionalTimePoint
时限参数。对于可估算任务所需时间的驱动程序,如果驱动程序根据此时限估计无法在时限前完成任务,就可以在任务启动前将其取消。同样,对于正在执行的任务,如果驱动程序根据时限估计无法在时限前完成任务,也可以将其取消。如果任务未在时限内完成或时限已过,时限参数并不会强制驱动程序取消任务。时限参数可用于释放驱动程序内的计算资源并将控制权交还给应用,其速度要快于没有时限的情况。
包含 OptionalTimePoint
时限参数的 NN HAL 1.3 调用如下:
IDevice::prepareModel_1_3
IDevice::prepareModelFromCache_1_3
IPreparedModel::execute_1_3
IPreparedModel::executeSynchronously_1_3
IPreparedModel::executeFenced
如需查看上述每种方法的时限功能的参考实现,请参阅位于 frameworks/ml/nn/driver/sample/SampleDriver.cpp
下的 NNAPI 示例驱动程序。
错误代码
Android 11 在 NN HAL 1.3 中包含四个错误代码值,旨在改进错误报告功能,使驱动程序能够更好地传达其状态,使应用能够更妥当地恢复。以下是 ErrorStatus
中的错误代码值。
MISSED_DEADLINE_TRANSIENT
MISSED_DEADLINE_PERSISTENT
RESOURCE_EXHAUSTED_TRANSIENT
RESOURCE_EXHAUSTED_PERSISTENT
在 Android 10 或更低版本中,驱动程序只能通过 GENERAL_FAILURE
错误代码表示故障。从 Android 11 开始,您可以使用两个 MISSED_DEADLINE
错误代码来指出工作负载因以下原因而被取消:时限已到,或因驱动程序预测工作负载无法在时限内完成。您还可以使用两个 RESOURCE_EXHAUSTED
错误代码来指示任务因驱动程序内的资源限制而失败,例如驱动程序没有足够的内存来完成调用。
这两种错误的 TRANSIENT
版本均表示问题是暂时的,后续对同一任务的调用可能会在短暂延迟后成功。例如,如果驱动程序正忙于执行前面的长时间运行的工作或占用大量资源的工作,但是等到驱动程序不忙于执行前面的工作时,新任务就会成功完成,那么在这种情况下就应返回此错误代码。这两种错误的 PERSISTENT
版本均表示,后续对同一任务的调用预计会一直失败。例如,如果驱动程序估计即使在最理想的情况下任务也无法在时限内完成,或者模型本身过大以致于所需的资源超出了驱动程序可提供的资源水平,那么在这种情况下就应返回此错误代码。
验证
服务质量功能在 NNAPI VTS 测试 (VtsHalNeuralnetworksV1_3Target
) 中进行测试。其中包括一组进行验证的测试 (TestGenerated/ValidationTest#Test/
),用于确保驱动程序拒绝无效优先级;还有一组名为 DeadlineTest
的测试 (TestGenerated/DeadlineTest#Test/
),用于确保驱动程序能够正确处理时限。