NNAPI 执行提供者

使用 ONNX Runtime 和 NNAPI 执行提供者在 Android 设备上加速 ONNX 模型。Android 神经网络 API (NNAPI) 是 Android 上 CPU、GPU 和神经网络加速器的统一接口。

目录

要求

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 运行时选项,请创建一个表示这些选项的无符号整数,并使用位或运算符设置每个单独的选项。

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 及更高版本。请注意,目前 NNAPI 使用 NCHW 的性能可能不如使用 NHWC。

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。
输入填充和 constant_value 应为常数。
输入填充值应为非负数。
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 所有量化尺度和零点应为常数。