服务质量

从 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。可以在libcutils/include/cutils/android_filesystem_config.h中找到 AID 列表。

截止日期

从 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/ ) 的测试以确保驱动程序正确处理截止日期。