NNAPI 执行提供程序

使用 ONNX Runtime 和 NNAPI 执行提供程序在 Android 设备上加速 ONNX 模型。Android Neural Networks API (NNAPI) 是 Android 上 CPU、GPU 和 NN 加速器的统一接口。

目录

要求

NNAPI 执行提供程序 (EP) 需要运行 Android 8.1 或更高版本的 Android 设备。 建议使用运行 Android 9 或更高版本的 Android 设备以获得最佳性能。

安装

预构建的包含用于 Android 的 NNAPI EP 的 ONNX Runtime 包已发布在 Maven 上。

有关安装说明,请参阅此处

构建

有关构建包含 NNAPI EP 的软件包的说明,请参阅构建 Android EP

用法

ONNX Runtime API 详细信息请参阅此处

NNAPI EP 可以通过 C、C++ 或 Java API 使用

在创建推理会话时,必须显式注册 NNAPI EP。 例如

Ort::Env env = Ort::Env{ORT_LOGGING_LEVEL_ERROR, "Default"};
Ort::SessionOptions so;
uint32_t nnapi_flags = 0;
Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_Nnapi(so, nnapi_flags));
Ort::Session session(env, model_path, so);

配置选项

NNAPI EP 有几个运行时选项可用。

要使用 NNAPI EP 运行时选项,请创建一个表示选项的无符号整数,并使用按位 OR 运算符设置每个单独的选项。

uint32_t nnapi_flags = 0;
nnapi_flags |= NNAPI_FLAG_USE_FP16;

可用选项

NNAPI_FLAG_USE_FP16

在 NNAPI EP 中使用 fp16 放宽。

这可能会提高性能,但也可能由于精度较低而降低准确性。

NNAPI_FLAG_USE_NCHW

在 NNAPI EP 中使用 NCHW 布局。

这仅适用于 Android API 级别 29 及更高版本。 请注意,目前,与使用 NHWC 相比,NNAPI 使用 NCHW 可能会有更差的性能。

NNAPI_FLAG_CPU_DISABLED

阻止 NNAPI 使用 CPU 设备。

NNAPI 在使用 GPU 或 NPU 进行执行时效率更高,但是对于 GPU/NPU 不支持的操作,NNAPI 可能会回退到其 CPU 实现。 NNAPI 的 CPU 实现(称为 nnapi-reference)通常不如 ORT 操作的优化版本效率高。 因此,禁用 NNAPI CPU 回退并使用 ORT 内核处理执行可能是有利的。

对于某些模型,如果 NNAPI 将使用 CPU 执行操作,并且设置了此标志,则模型的执行可能会回退到 ORT 内核。

此选项仅适用于 Android API 级别 29 及更高版本,对于 Android API 级别 28 及更低版本将被忽略。

有关 NNAPI 设备分配,请参阅https://developer.android.com.cn/ndk/guides/neuralnetworks#device-assignment

有关 NNAPI CPU 回退,请参阅https://developer.android.com.cn/ndk/guides/neuralnetworks#cpu-fallback

NNAPI_FLAG_CPU_ONLY

在 NNAPI EP 中仅使用 CPU,这可能会降低性能,但会提供没有精度损失的参考输出值,这对于验证很有用。

此选项仅适用于 Android API 级别 29 及更高版本,对于 Android API 级别 28 及更低版本将被忽略。

支持的操作

以下操作受 NNAPI 执行提供程序支持:

运算符 注意
ai.onnx:Abs  
ai.onnx:Add  
ai.onnx:AveragePool 仅支持 2D 池化。
ai.onnx:BatchNormalization  
ai.onnx:Cast  
ai.onnx:Clip  
ai.onnx:Concat  
ai.onnx:Conv 仅支持 2D 卷积。
权重和偏置应为常量。
ai.onnx:DepthToSpace 仅支持 DCR 模式 DepthToSpace。
ai.onnx:DequantizeLinear 所有量化比例和零点应为常量。
ai.onnx:Div  
ai.onnx:Elu  
ai.onnx:Exp  
ai.onnx:Flatten  
ai.onnx:Floor  
ai.onnx:Gather 如果输入索引不是 int32 类型,则应为常量。
ai.onnx:Gemm 如果输入 B 不是常量,则 transB 应为 1。
ai.onnx:GlobalAveragePool 仅支持 2D 池化。
ai.onnx:GlobalMaxPool 仅支持 2D 池化。
ai.onnx:Identity  
ai.onnx:LeakyRelu  
ai.onnx:Log  
ai.onnx:LRN  
ai.onnx:MatMul  
ai.onnx:MaxPool 仅支持 2D 池化。
ai.onnx:Max  
ai.onnx:Min  
ai.onnx:Mul  
ai.onnx:Neg  
ai.onnx:Pad 仅支持常量模式 Pad。
输入 pads 和 constant_value 应为常量。
输入 pads 值应为非负数。
ai.onnx:Pow  
ai.onnx:PRelu  
ai.onnx:QLinearConv 仅支持 2D 卷积。
权重和偏置应为常量。
所有量化比例和零点应为常量。
ai.onnx:QLinearMatMul 所有量化比例和零点应为常量。
ai.onnx:QuantizeLinear 所有量化比例和零点应为常量。
ai.onnx:ReduceMean  
ai.onnx:Relu  
ai.onnx:Reshape  
ai.onnx:Resize 仅支持 2D 调整大小。
ai.onnx:Sigmoid  
ai.onnx:Sin  
ai.onnx:Slice  
ai.onnx:Softmax  
ai.onnx:Split 拆分数必须均匀地划分拆分轴大小。 如果提供,则输入拆分应为常量。
ai.onnx:Sqrt  
ai.onnx:Squeeze 输入轴应为常量。
ai.onnx:Sub  
ai.onnx:Tanh  
ai.onnx:Transpose  
ai.onnx:Unsqueeze 输入轴应为常量。
com.microsoft:QLinearAdd 所有量化比例和零点应为常量。
com.microsoft:QLinearAveragePool 仅支持 2D 池化。
所有量化比例和零点应为常量。
com.microsoft:QLinearSigmoid 所有量化比例和零点应为常量。