NNAPI 执行提供程序
使用 ONNX Runtime 和 NNAPI 执行提供程序加速 Android 设备上的 ONNX 模型。Android Neural Networks API (NNAPI) 是 Android 上 CPU、GPU 和 NN 加速器的统一接口。
目录
要求
NNAPI 执行提供程序 (EP) 需要 Android 8.1 或更高版本的 Android 设备。建议使用 Android 9 或更高版本的 Android 设备以获得最佳性能。
安装
包含 NNAPI EP 的 ONNX Runtime 预构建 Android 包发布在 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 及更高版本。请注意,目前使用 NCHW 的 NNAPI 性能可能比使用 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。 输入 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 Resize。 |
ai.onnx:Sigmoid | |
ai.onnx:Sin | |
ai.onnx:Slice | |
ai.onnx:Softmax | |
ai.onnx:Split | 分割次数必须能整除分割轴的大小。如果提供输入 split,则应为常量。 |
ai.onnx:Sqrt | |
ai.onnx:Squeeze | 输入 axes 应为常量。 |
ai.onnx:Sub | |
ai.onnx:Tanh | |
ai.onnx:Transpose | |
ai.onnx:Unsqueeze | 输入 axes 应为常量。 |
com.microsoft:QLinearAdd | 所有量化比例和零点都应为常量。 |
com.microsoft:QLinearAveragePool | 仅支持 2D 池化。 所有量化比例和零点都应为常量。 |
com.microsoft:QLinearSigmoid | 所有量化比例和零点都应为常量。 |