Neural Networks API (NNAPI) 供應商擴充功能, Android 10, 一組供應商定義的作業和資料類型。執行 NN 的裝置 HAL 1.2 以上版本,驅動程式可透過 支援相應的供應商擴充功能供應商額外資訊不會修改 現有作業的行為。
供應商擴充功能可為原始設備製造商 (OEM) 作業提供更結構化的替代方案, 資料類型,已在 Android 10 中淘汰。 若需更多資訊,請參閲 原始設備製造商 (OEM) 作業和資料類型:
擴充功能用量許可清單
供應商擴充功能只能由明確指定的 Android 應用程式和
/product
、/vendor
、/odm
和 /data
分區上的原生二進位檔。
位於「/system
」分區的應用程式和原生二進位檔無法使用廠商
。
以下清單列出了可使用 NNAPI 供應商擴充功能的 Android 應用程式和二進位檔
儲存在「/vendor/etc/nnapi_extensions_app_allowlist
」中。檔案中的每一行
包含新項目。項目可以是前置字串為
斜線 (/),例如 /data/foo
或 Android 應用程式套件的名稱
例如:com.foo.bar
。
系統會強制執行 NNAPI 執行階段共用資料庫的許可清單。這個圖書館 可防止意外使用,但目的並非違反 直接使用 NNAPI 驅動程式 HAL 介面啟動應用程式
供應商擴充功能定義
供應商會建立並維護包含擴充功能定義的標頭檔案。A 罩杯
您可前往以下網址,取得擴充功能定義的完整範例:
example/fibonacci/FibonacciExtension.h
。
每個擴充功能的名稱都必須以反向網域名稱開頭 即可。
const char EXAMPLE_EXTENSION_NAME[] = "com.example.my_extension";
這個名稱可做為作業和資料類型的命名空間。NNAPI 會使用此 名稱,藉此區分供應商額外資訊。
作業和資料類型的宣告方式與
runtime/include/NeuralNetworks.h
。
enum {
/**
* A custom scalar type.
*/
EXAMPLE_SCALAR = 0,
/**
* A custom tensor type.
*
* Attached to this tensor is {@link ExampleTensorParams}.
*/
EXAMPLE_TENSOR = 1,
};
enum {
/**
* Computes example function.
*
* Inputs:
* * 0: A scalar of {@link EXAMPLE_SCALAR}.
*
* Outputs:
* * 0: A tensor of {@link EXAMPLE_TENSOR}.
*/
EXAMPLE_FUNCTION = 0,
};
擴充功能作業可以使用任何運算元類型,包括非擴充功能運算元 類型,以及運算元型別。使用 另一個擴充功能,則驅動程式必須支援其他擴充功能。
擴充功能也可以為隨附的擴充功能運算元宣告自訂結構。
/**
* Quantization parameters for {@link EXAMPLE_TENSOR}.
*/
typedef struct ExampleTensorParams {
double scale;
int64_t zeroPoint;
} ExampleTensorParams;
在 NNAPI 用戶端中使用擴充功能
runtime/include/NeuralNetworksExtensions.h
敬上
(C API) 檔案提供執行階段擴充功能支援。本節將介紹
C API 簡介
如要確認裝置是否支援擴充功能,請使用
ANeuralNetworksDevice_getExtensionSupport
。
bool isExtensionSupported;
CHECK_EQ(ANeuralNetworksDevice_getExtensionSupport(device, EXAMPLE_EXTENSION_NAME,
&isExtensionSupported),
ANEURALNETWORKS_NO_ERROR);
if (isExtensionSupported) {
// The device supports the extension.
...
}
如要使用擴充運算元建構模型,請使用
ANeuralNetworksModel_getExtensionOperandType
敬上
即可取得運算元類型,並呼叫
ANeuralNetworksModel_addOperand
。
int32_t type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperandType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_TENSOR, &type),
ANEURALNETWORKS_NO_ERROR);
ANeuralNetworksOperandType operandType{
.type = type,
.dimensionCount = dimensionCount,
.dimensions = dimensions,
};
CHECK_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
視需要使用
ANeuralNetworksModel_setOperandExtensionData
敬上
連結其他資料與擴充運算元。
ExampleTensorParams params{
.scale = 0.5,
.zeroPoint = 128,
};
CHECK_EQ(ANeuralNetworksModel_setOperandExtensionData(model, operandIndex, ¶ms, sizeof(params)),
ANEURALNETWORKS_NO_ERROR);
如要建構具有擴充功能作業的模型,請使用
ANeuralNetworksModel_getExtensionOperationType
敬上
才能取得作業類型並呼叫
ANeuralNetworksModel_addOperation
。
ANeuralNetworksOperationType type;
CHECK_EQ(ANeuralNetworksModel_getExtensionOperationType(model, EXAMPLE_EXTENSION_NAME, EXAMPLE_FUNCTION,
&type),
ANEURALNETWORKS_NO_ERROR);
CHECK_EQ(ANeuralNetworksModel_addOperation(model, type, inputCount, inputs, outputCount, outputs),
ANEURALNETWORKS_NO_ERROR);
為 NNAPI 驅動程式新增擴充功能支援
駕駛人會透過
IDevice::getSupportedExtensions
敬上
方法。傳回的清單中必須包含個別支援的項目
。
Extension {
.name = EXAMPLE_EXTENSION_NAME,
.operandTypes = {
{
.type = EXAMPLE_SCALAR,
.isTensor = false,
.byteSize = 8,
},
{
.type = EXAMPLE_TENSOR,
.isTensor = true,
.byteSize = 8,
},
},
}
在用於識別類型和運算的 32 位元中,高分
Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX
敬上
位元是副檔名
prefix 和 Low
Model::ExtensionTypeEncoding::LOW_BITS_TYPE
位元代表類型或作業
。
處理作業或運算元類型時,驅動程式必須檢查擴充功能
前置字串。如果擴充內容前置字串的值不是零,表示作業或運算元
則是擴充功能類型如果值為 0
,則代表作業或運算元類型
不是擴充功能類型
如要將前置字串對應至擴充功能名稱,請前往
model.extensionNameToPrefix
。
前置字串與擴充功能名稱的對應,是一對一通訊
(注射) 模型。不同的前置字元值可能會對應到
相同副檔名的名稱。
驅動程式必須驗證擴充功能作業和資料類型,因為 NNAPI 執行階段無法驗證特定擴充功能作業和資料類型。
擴充功能運算元可在
operand.extraParams.extension
、
執行階段會視為任意大小的原始資料 blob。
原始設備製造商 (OEM) 作業和資料類型
NNAPI 具備 OEM 作業和 OEM 資料類型
裝置製造商提供自訂的驅動程式專屬功能。這些
作業和資料類型僅適用於原始設備製造商 (OEM) 應用程式。原始設備製造商 (OEM) 的語意
作業和資料類型僅適用於原始設備製造商 (OEM),且可能隨時變更。原始設備製造商 (OEM)
運算和資料類型使用 OperationType::OEM_OPERATION
進行編碼
OperandType::OEM
和OperandType::TENSOR_OEM_BYTE
。