إضافات المورّد لواجهة برمجة التطبيقات Neural Networks API (NNAPI)، التي تم طرحها في Android 10، هي مجموعات من العمليات وأنواع البيانات التي يحدّدها المورّد. على الأجهزة التي تعمل بالإصدار 1.2 من NN HAL أو إصدار أحدث، يمكن أن توفّر برامج التشغيل عمليات مخصّصة يتم تسريعها باستخدام الأجهزة من خلال إتاحة استخدام إضافات البائعين ذات الصلة. لا تؤدي إضافات المورّدين إلى تعديل سلوك العمليات الحالية.
توفّر إضافات المورّد بديلاً أكثر تنظيمًا لعمليات المصنّع الأصلي للجهاز وأنواع البيانات التي تم إيقافها نهائيًا في Android 10. لمزيد من المعلومات، يُرجى الاطّلاع على عمليات الشركات المصنّعة الأصلية وأنواع البيانات.
قائمة الإضافات المسموح باستخدامها
لا يمكن استخدام إضافات المورّد إلا من خلال تطبيقات Android المحدّدة بشكل صريح والملفات الثنائية الأصلية في الأقسام /product
و/vendor
و/odm
و/data
.
لا يمكن للتطبيقات والثنائيات الأصلية الموجودة في القسم /system
استخدام إضافات المورّد.
يتم تخزين قائمة بتطبيقات Android والملفات الثنائية المسموح لها باستخدام إضافات المورّد في NNAPI في /vendor/etc/nnapi_extensions_app_allowlist
. يحتوي كل سطر من الملف على إدخال جديد. يمكن أن يكون الإدخال مسارًا ثنائيًا أصليًا مسبوقًا بشَرطة مائلة (/)، مثل /data/foo
، أو اسم حزمة تطبيق Android، مثل com.foo.bar
.
يتم فرض قائمة السماح من المكتبة المشتركة لوقت التشغيل في NNAPI. وتوفّر هذه المكتبة الحماية من الاستخدام غير المقصود، ولكنها لا توفّر الحماية من التحايل المتعمد من خلال تطبيق يستخدم مباشرةً واجهة HAL لبرنامج تشغيل NNAPI.
تعريف إضافة المورّد
ينشئ البائع ملف رأس ويحتفظ به مع تعريف الامتداد. يمكنك الاطّلاع على مثال كامل لتعريف إضافة في
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.
للتحقّق مما إذا كان الجهاز يتيح استخدام إضافة، استخدِم 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
العالية هي
بادئة
الامتداد، وتمثّل البتات
Model::ExtensionTypeEncoding::LOW_BITS_TYPE
المنخفضة نوع الامتداد أو العملية.
عند التعامل مع نوع عملية أو نوع معامل، يجب أن يتحقّق برنامج التشغيل من البادئة
للامتداد. إذا كانت بادئة الامتداد تتضمّن قيمة غير صفرية، يكون نوع العملية أو المعامِل هو نوع امتداد. إذا كانت القيمة 0
، يعني ذلك أنّ نوع العملية أو المعامل ليس نوع إضافة.
لربط البادئة باسم إضافة، ابحث عنها في
model.extensionNameToPrefix
.
إنّ عملية الربط من البادئة إلى اسم الامتداد هي عملية تطابق فردي (اقتران ثنائي) لنموذج معيّن. قد تتوافق قيم البادئات المختلفة مع اسم الإضافة نفسه في نماذج مختلفة.
يجب أن يتحقّق برنامج التشغيل من صحة عمليات الإضافة وأنواع البيانات لأنّ وقت تشغيل NNAPI لا يمكنه التحقّق من صحة عمليات الإضافة وأنواع البيانات المحدّدة.
يمكن أن تتضمّن معاملات الإضافة بيانات مرتبطة بها في
operand.extraParams.extension
،
ويتعامل وقت التشغيل معها ككائن ثنائي كبير الحجم للبيانات الأولية بحجم عشوائي.
عمليات الشركة المصنّعة الأصلية وأنواع البيانات
تتضمّن واجهة برمجة التطبيقات NNAPI عملية خاصة بالمصنّعين الأصليين للأجهزة وأنواع بيانات خاصة بهم للسماح لمصنّعي الأجهزة بتوفير وظائف مخصّصة خاصة ببرامج التشغيل. لا تستخدم تطبيقات المصنّع الأصلي للجهاز سوى أنواع العمليات والبيانات هذه. إنّ دلالات عمليات OEM وأنواع البيانات خاصة بمصنّع المعدات الأصلية ويمكن أن تتغير في أي وقت. يتم ترميز عمليات ومصادر بيانات الشركة المصنّعة الأصلية باستخدام OperationType::OEM_OPERATION
وOperandType::OEM
وOperandType::TENSOR_OEM_BYTE
.