תוספי ספקים של Neural Networks API (NNAPI), הוצגו ב- Android 10 הוא אוספים של פעולות וסוגי נתונים שהוגדרו על ידי הספק. במכשירים עם NN עם תקן HAL 1.2 ואילך, מנהלי התקנים יכולים לספק פעולה עם האצת חומרה בהתאמה אישית באמצעות שתומכים בתוספי ספקים תואמים. תוספי הספקים לא משנים את ההתנהגות של הפעולות הקיימות.
תוספי ספקים מספקים חלופה מובנית יותר לתפעול ה-OEM, בסוגי הנתונים שהוצאו משימוש ב-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 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
ביטים הוא התוסף
קידומת וטמפרטורת המינימום
Model::ExtensionTypeEncoding::LOW_BITS_TYPE
ביטים מייצג את הסוג או הפעולה
של התוסף.
במהלך טיפול בפעולה או בסוג אופרנד, על הנהג לבדוק את התוסף
. אם לקידומת התוסף יש ערך שאינו אפס, הפעולה או האופרנד
הוא סוג תוסף. אם הערך הוא 0
, הפעולה או סוג האופרנד
אינו סוג תוסף.
כדי למפות את התחילית לשם של תוסף, צריך לחפש אותה ב
model.extensionNameToPrefix
המיפוי מהקידומת לשם התוסף הוא התאמה של אחד לאחד
(bijection) למודל נתון. ערכי קידומת שונים עשויים להתאים
אותו שם תוסף בדגמים שונים.
מנהל ההתקן צריך לאמת פעולות של תוסף וסוגי נתונים מפני שה-NNAPI סביבת זמן הריצה לא יכולה לאמת פעולות מסוימות של תוסף וסוגי נתונים מסוימים.
לאופרנדים של תוספים יכולים להיות נתונים משויכים
operand.extraParams.extension
סביבת זמן הריצה מתייחסת אליו כאל blob של נתונים גולמיים בגודל שרירותי.
פעולות OEM (יצרן ציוד מקורי) וסוגי נתונים
ל-NNAPI יש פעולת OEM (יצרן ציוד מקורי) וסוגי נתונים של OEM (יצרן ציוד מקורי) כדי לאפשר
ליצרני מכשירים כדי לספק פונקציונליות מותאמת אישית ספציפית לנהג. האלה
סוגי הפעולות והנתונים משמשים רק לאפליקציות של OEM (יצרן ציוד מקורי). הסמנטיקה של OEM (יצרן ציוד מקורי)
סוגי הפעולות והנתונים הם ספציפיים ל-OEM (יצרן הציוד המקורי) ועשויים להשתנות בכל שלב. ה-OEM (יצרן הציוד המקורי)
סוגי הפעולות והנתונים מקודדים באמצעות OperationType::OEM_OPERATION
,
OperandType::OEM
ו-OperandType::TENSOR_OEM_BYTE
.