בדף הזה מוסבר איך להטמיע מנהל של Neural Networks API (NNAPI). פרטים נוספים זמינים במסמכי העזרה בקובצי ההגדרה של HAL ב-hardware/interfaces/neuralnetworks
.
הטמעה לדוגמה של מנהל התקן מופיעה בקובץ frameworks/ml/nn/driver/sample
.
למידע נוסף על Neural Networks API, ראו Neural Networks API.
Neural Networks HAL
HAL של רשתות נוירונליות (NN) מגדיר הפשטה של המכשירים השונים, כמו יחידות עיבוד גרפי (GPU) ומעבדי אותות דיגיטליים (DSP), שנמצאים במוצר (לדוגמה, טלפון או טאבלט). מנהלי ההתקנים של המכשירים האלה חייבים לעמוד בתקן NN HAL. הממשק מוגדר בקובצי ההגדרה של HAL ב-hardware/interfaces/neuralnetworks
.
התהליך הכללי של הממשק בין המסגרת לבין הנהג מתואר באיור 1.
איור 1. תהליך העבודה של רשתות נוירונים
אתחול
במהלך האינטליקציה, המסגרת שולחת לשאילתה לנהג לגבי היכולות שלו באמצעות IDevice::getCapabilities_1_3
.
המבנה @1.3::Capabilities
כולל את כל סוגי הנתונים, ומציג את הביצועים ללא הרפיה באמצעות וקטור.
כדי לקבוע איך להקצות את החישובים למכשירים הזמינים, המסגרת משתמשת ביכולות כדי להבין כמה מהר וכל אחד מהדרייברים יכול לבצע את הביצועים, וכמה אנרגיה הוא צורך. כדי לספק את המידע הזה, ה-driver צריך לספק נתוני ביצועים סטנדרטיים על סמך ביצוע עומסי עבודה לדוגמה.
כדי לקבוע את הערכים שהדרייבר מחזיר בתגובה ל-IDevice::getCapabilities_1_3
, משתמשים באפליקציית NNAPI למדדי ביצועים כדי למדוד את הביצועים של סוגי הנתונים התואמים. מומלץ להשתמש במודלים MobileNet v1 ו-v2, asr_float
ו-tts_float
למדידת הביצועים של ערכים של נקודה צפה באורך 32 ביט, ובמודלים המצטברים של MobileNet v1 ו-v2 למדידת הביצועים של ערכים מצטברים באורך 8 ביט. מידע נוסף זמין במאמר Android Machine Learning Test Suite.
ב-Android 9 ובגרסאות ישנות יותר, המבנה Capabilities
כולל מידע על ביצועי מנהל ההתקן רק לגבי טינסורים של נקודות צפות וטנסורים מקוטנים, ולא כולל סוגי נתונים סקלריים.
כחלק מתהליך האתחול, המסגרת עשויה לשלוח שאילתות לקבלת מידע נוסף באמצעות IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
ו-IDevice::getNumberOfCacheFilesNeeded
.
בין הפעלות מחדש של המוצר, ההגדרות של המסגרת מצפות שכל השאילתות המתוארות בקטע הזה תמיד ידווחו על אותם ערכים עבור מנהל התקן נתון. אחרת, יכול להיות שבאפליקציה שמשתמשת באותו מנהל התקן יהיו ביצועים נמוכים יותר או התנהגות שגויה.
קומפילציה
המסגרת קובעת באילו מכשירים להשתמש כשהיא מקבלת בקשה מאפליקציה. ב-Android 10, אפליקציות יכולות לזהות את המכשירים שמסגרת ה-API בוחרת מהם, ולציין אותם. למידע נוסף, ראו זיהוי והקצאה של מכשירים.
בזמן הידור המודל, המסגרת שולחת את המודל לכל נהג מתאים באמצעות קריאה ל-IDevice::getSupportedOperations_1_3
.
כל מנהל מחזיר מערך של ערכים בוליאניים שמציינים אילו פעולות של המודל נתמכות. יכולות להיות כמה סיבות לכך שמנהל התקן לא יכול לתמוך בפעולה מסוימת. לדוגמה:
- אין תמיכה בסוג הנתונים במנהל.
- הנהג תומך רק בפעולות עם פרמטרים ספציפיים של קלט. לדוגמה, יכול להיות שמנהל התקן תומך בפעולות 3x3 ו-5x5, אבל לא בפעולות 7x7.
- לנהג יש מגבלות זיכרון שמונעות ממנו לטפל בגרפים או בקלט גדולים.
במהלך הידור, למשתני הקלט, הפלט והאופרטורים הפנימיים של המודל, כפי שמתואר ב-OperandLifeTime
, יכולים להיות מאפיינים או דרגה לא ידועים. מידע נוסף זמין במאמר צורת הפלט.
המסגרת מורה לכל מנהל שנבחר להתכונן להרצה של קבוצת משנה של המודל באמצעות קריאה ל-IDevice::prepareModel_1_3
.
לאחר מכן, כל מנהל רכיבים יוצר את קבוצת המשנה שלו. לדוגמה, מנהל יכול ליצור קוד או ליצור עותק של המשקלים בסדר מחדש. יכול להיות שיחלוף זמן רב בין הידור המודל לבין ביצוע הבקשות, לכן לא כדאי להקצות משאבים כמו קטעים גדולים של זיכרון המכשיר במהלך הידור.
אם הפעולה מסתיימת בהצלחה, מנהל ההתקן מחזיר אחיזה מסוג @1.3::IPreparedModel
. אם מנהל ההתקן מחזיר קוד שגיאה בזמן הכנת קבוצת המשנה שלו מהמודל, המסגרת מפעילה את כל המודל ב-CPU.
כדי לקצר את הזמן שנדרש ל-compilation כשאפליקציה מופעלת, הנהג יכול לשמור את פריטי ה-compilation במטמון. מידע נוסף זמין במאמר אחסון במטמון של קובצי הידור.
ביצוע
כשאפליקציה מבקשת מהמסגרת לבצע בקשה, המסגרת קורא כברירת מחדל ל-method HAL IPreparedModel::executeSynchronously_1_3
כדי לבצע ביצוע סינכרוני במודל מוכן.
אפשר גם להריץ בקשה באופן אסינכרוני באמצעות השיטה execute_1_3
, השיטה executeFenced
(ראו ביצוע מוגבל) או באמצעות ביצוע רצף פעולות.
קריאות לביצוע סינכרוני משפרות את הביצועים ומפחיתות את זמן הטיפול הנוסף בשרשור בהשוואה לקריאות אסינכרוניות, כי השליטה מוחזרת לתהליך האפליקציה רק אחרי שהביצוע מסתיים. המשמעות היא שהדרייבר לא צריך מנגנון נפרד כדי להודיע לתהליך האפליקציה שההפעלה הושלמה.
כשמשתמשים בשיטה האסינכרונית execute_1_3
, השליטה חוזרת לתהליך האפליקציה אחרי שההפעלה מתחילה, והנהג צריך להודיע למסגרת כשההפעלה מסתיימת באמצעות @1.3::IExecutionCallback
.
הפרמטר Request
שמוענק לשיטת execute מציג את אופרטורי הקלט והפלט ששימשו לביצוע. הזיכרון שמאחסן את נתוני המשתנים חייב להשתמש בסדר של שורות ראשיות, כאשר המאפיין הראשון הוא האיטי ביותר, ואין בו מילוי בסופו של כל שורה. למידע נוסף על סוגי המשתנים, ראו Operands.
במנהלי NN HAL 1.2 ואילך, כשבקשה תושלם, סטטוס השגיאה, צורת הפלט ופרטי התזמון יחזרו למסגרת. במהלך ההפעלה, לפלט או לאופרטורים הפנימיים של המודל יכולים להיות מאפיין אחד או יותר לא ידוע או דרגה לא ידועה. אם למשתנה פלט אחד לפחות יש מאפיין או דירוג לא ידועים, הנהג צריך להחזיר מידע על פלט בגודל דינמי.
עבור מנהלי התקנים עם NN HAL 1.1 ואילך, רק סטטוס השגיאה מוחזר כשהבקשה תושלם. כדי שההרצה תושלם בהצלחה, צריך לציין את המאפיינים של אופרטורי הקלט והפלט באופן מלא. לאפשרויות הפעלה פנימיות יכול להיות מאפיין לא ידוע אחד או יותר, אבל הן חייבות להיות בעלות דירוג מסוים.
בבקשות של משתמשים שמתפרשות על פני כמה מנהלי התקנים, המסגרת אחראית להקצאת זיכרון ביניים ולסדר הקריאות לכל מנהל התקנים.
אפשר להפעיל כמה בקשות במקביל באותו @1.3::IPreparedModel
.
הנהג יכול להריץ בקשות במקביל או לבצע את ההרצות בסדר.
המסגרת יכולה לבקש מהנהג לשמור יותר מדגם אחד מוכן. לדוגמה, מכינים את המודל m1
, מכינים את m2
, מריצים את הבקשה r1
ב-m1
, מריצים את r2
ב-m2
, מריצים את r3
ב-m1
, מריצים את r4
ב-m2
, מריצים את m1
(כפי שמתואר בקטע ניקוי) ומריצים את m2
.
כדי למנוע ביצוע איטי בפעם הראשונה שעלול לגרום לחוויית משתמש גרועה (לדוגמה, רעידות בפריים הראשון), רוב ההפעלות הראשוניות צריכות להתבצע בשלב הידור הקוד. כדאי להגביל את האתחול בזמן ההפעלה הראשונה לפעולות שמשפיעות לרעה על תקינות המערכת כשהן מתבצעות בשלב מוקדם, כמו הקצאת מאגרים זמניים גדולים או הגדלת קצב השעון של המכשיר. יכול להיות שדרייברים שיכולים להכין רק מספר מוגבל של מודלים בו-זמנית יצטרכו לבצע את האיניציאליזציה שלהם בזמן הביצוע הראשון.
ב-Android מגרסה 10 ואילך, במקרים שבהם מתבצעות כמה פעולות ברצף מהיר עם אותו מודל מוכן, הלקוח יכול להשתמש באובייקט של רצף פעולות מהיר כדי לתקשר בין תהליכי האפליקציה לבין תהליכי הנהג. למידע נוסף, ראו ביצועים מרובים בבת אחת ורשימות הודעות מהירות.
כדי לשפר את הביצועים של מספר פעולות ברצף מהיר, הנהג יכול לשמור מאגרים זמניים או להגדיל את שיעורי השעון. מומלץ ליצור חוט של כלב שמירה כדי לשחרר משאבים אם לא נוצרות בקשות חדשות אחרי פרק זמן קבוע.
צורת הפלט
בבקשות שבהן לא צוינו כל המאפיינים של אופרטורים של פלט אחד או יותר, הנהג צריך לספק רשימה של צורות פלט שמכילות את פרטי המאפיינים של כל אופרטור פלט אחרי הביצוע. למידע נוסף על מאפיינים, ראו OutputShape
.
אם ביצוע נכשל בגלל מאגר פלט בגודל לא מספיק, הנהג צריך לציין ברשימת הצורות של הפלט לאילו אופרטורים של פלט יש מאגר בגודל לא מספיק, ולדווח על כמה שיותר מידע על המאפיינים, ולהשתמש באפס למאפיינים לא ידועים.
תזמון
ב-Android 10, אפליקציה יכולה לבקש את זמן הביצוע אם היא ציינה מכשיר יחיד לשימוש בתהליך הידור. מידע נוסף זמין במאמרים MeasureTiming
וזיהוי והקצאה של מכשירים.
במקרה כזה, נהג NN HAL 1.2 צריך למדוד את משך הביצוע או לדווח על UINT64_MAX
(כדי לציין שהמשך לא זמין) בזמן ביצוע הבקשה. מנהל ההתקן צריך לצמצם את הפגיעה בביצועים כתוצאה ממדידת משך הביצוע.
הנהג מדווח על משכי הזמן הבאים במיקרו-שניות במבנה Timing
:
- זמן הביצוע במכשיר: לא כולל את זמן הביצוע בתוכנת ההתקן, שפועלת במעבד המארח.
- זמן הביצוע ב-driver: כולל זמן הביצוע במכשיר.
משכי הזמן האלה חייבים לכלול את הזמן שבו הביצוע הושעה, למשל כשמשימות אחרות עקפו את הביצוע או כשהמשימות ממתינות למשאב שיהיה זמין.
אם לא ביקשו מהדרייבר למדוד את משך הביצוע, או אם יש שגיאת ביצוע, הוא צריך לדווח על משכי הזמן כ-UINT64_MAX
. גם אם נשלחה בקשה למנהל ההתקנה למדוד את משך הביצוע, הוא יכול לדווח במקום זאת על UINT64_MAX
עבור הזמן במכשיר, הזמן בהתקנה או שניהם. כשהמנהל מדווח על שני משכי הזמן כערך שאינו UINT64_MAX
, זמן הביצוע במנהל צריך להיות שווה לזמן במכשיר או גדול ממנו.
ביצוע מוגבל
ב-Android 11, NNAPI מאפשר להפעלות להמתין לרשימה של מחזיקי sync_fence
, ולבחור אם להחזיר אובייקט sync_fence
, שיישלח אות כשהפעולה תושלם. כך אפשר לצמצם את התקורה במודלים של רצפים קטנים ובתרחישי שימוש בסטרימינג. בנוסף, ביצוע מגודר מאפשר יכולת פעולה הדדית יעילה יותר עם רכיבים אחרים שיכולים לשלוח אות או להמתין ל-sync_fence
. מידע נוסף על sync_fence
זמין במאמר מסגרת סנכרון.
בהפעלה מוקפת גדר, המסגרת קוראת ל-method IPreparedModel::executeFenced
כדי להפעיל הפעלה אסינכררונית מוקפת גדר במודל מוכן עם וקטור של גדרות סנכרון להמתנה. אם המשימה האסינכרונית מסתיימת לפני שהקריאה חוזרת, אפשר להחזיר למשתנה sync_fence
ערך של טיפול (handle) ריק. צריך להחזיר גם אובייקט IFencedExecutionCallback
כדי לאפשר למסגרת להריץ שאילתה לגבי סטטוס השגיאה ופרטי משך הזמן.
אחרי השלמת הביצוע, אפשר לשלוח שאילתה דרך IFencedExecutionCallback::getExecutionInfo
כדי לקבל את שני ערכי התזמון הבאים, שמשמשים למדידת משך הביצוע.
timingLaunched
: משך הזמן מהקריאה ל-executeFenced
ועד שה-executeFenced
מאותת על ה-syncFence
המוחזר.timingFenced
: משך הזמן מהרגע שבו מתקבל האות מכל מחסומי הסנכרון שההפעלה ממתינה להם, עד שהאות מ-executeFenced
מחזיר את הערךsyncFence
.
בקרת זרימה
במכשירים עם Android מגרסה 11 ואילך, NNAPI כולל שתי פעולות של בקרת תהליך, IF
ו-WHILE
, שמקבלות מודלים אחרים כארגומנטים ומבצעות אותם באופן מותנה (IF
) או חוזר (WHILE
). למידע נוסף על הטמעה של הפעולות האלה, ראו בקרת תהליך.
איכות השירות
ב-Android 11, NNAPI כולל שיפורים באיכות השירות (QoS) על ידי מתן אפשרות לאפליקציה לציין את העדיפויות היחסיות של המודלים שלה, את משך הזמן המרבי הצפוי להכנת מודל ואת משך הזמן המרבי הצפוי להשלמת ביצוע. למידע נוסף, ראו איכות שירות.
ניקוי
כשהאפליקציה מסיימת להשתמש במודל מוכן, המסגרת משחררת את ההפניה שלה לאובייקט @1.3::IPreparedModel
. כשההפניה לאובייקט IPreparedModel
לא קיימת יותר, הוא נהרס באופן אוטומטי בשירות הנהג שיצר אותו. בשלב הזה אפשר למחזר משאבים ספציפיים למודל בהטמעה של ה-destructor בנהג. אם שירות מנהל ההתקן רוצה שהאובייקט IPreparedModel
יושמד באופן אוטומטי כשהלקוח לא צריך אותו יותר, הוא לא יכול לשמור הפניות לאובייקט IPreparedModel
אחרי שהאובייקט IPreparedeModel
הוחזר דרך IPreparedModelCallback::notify_1_3
.
שימוש במעבד
נהגים אמורים להשתמש במעבד (CPU) כדי להגדיר חישובים. אסור להשתמש ב-CPU לביצוע חישובים של גרפים, כי זה מפריע ליכולת של המסגרת להקצות את העבודה בצורה נכונה. מנהל ההתקן צריך לדווח למסגרת על החלקים שהוא לא יכול לטפל בהם, ולאפשר למסגרת לטפל בשאר החלקים.
המסגרת מספקת הטמעה של מעבד לכל פעולות ה-NNAPI, מלבד פעולות שהוגדרו על ידי הספק. מידע נוסף זמין במאמר תוספים של ספקים.
לפעולות שהוצגו ב-Android 10 (רמת API 29) יש רק הטמעה של מעבדי הפניה כדי לוודא שבדיקות CTS ו-VTS תקינות. מומלץ להשתמש בהטמעות האופטימיות שכלולות במסגרות של למידת מכונה לנייד, במקום בהטמעה של NNAPI ל-CPU.
פונקציות שירות
קוד המקור של NNAPI כולל פונקציות שירות ששירותי הנהגים יכולים להשתמש בהן.
הקובץ frameworks/ml/nn/common/include/Utils.h
מכיל פונקציות שירות שונות, כמו פונקציות לצורכי רישום ביומן ולצורך המרה בין גרסאות שונות של NN HAL.
תיעוד וידאו:
VLOG
הוא מאקרו של מעטפת סביבLOG
של Android, שמתעדה את ההודעה רק אם התג המתאים מוגדר במאפייןdebug.nn.vlog
. צריך לקרוא לפונקציהinitVLogMask()
לפני כל קריאה לפונקציהVLOG
. אפשר להשתמש במאקרוVLOG_IS_ON
כדי לבדוק אםVLOG
מופעל כרגע, וכך לדלג על קוד מורכב של רישום ביומן אם הוא לא נדרש. הערך של המאפיין חייב להיות אחד מהערכים הבאים:- מחרוזת ריקה, שמציינת שאין לבצע רישום ביומן.
- האסימון
1
אוall
, שמציין שצריך לבצע את כל הרישום ביומן. - רשימה של תגים, מופרדים באמצעות רווחים, פסיקים או נקודתיים, שמציינת אילו אירועים צריך לתעד ביומן. התגים הם
compilation
,cpuexe
,driver
,execution
,manager
ו-model
.
compliantWithV1_*
: הפונקציה מחזירה את הערךtrue
אם אפשר להמיר אובייקט NN HAL לאותו סוג בגרסה אחרת של HAL בלי לאבד מידע. לדוגמה, קריאה ל-compliantWithV1_0
ב-V1_2::Model
מחזירה את הערךfalse
אם המודל כולל סוגי פעולות שהוצגו ב-NN HAL 1.1 או ב-NN HAL 1.2.convertToV1_*
: המרת אובייקט NN HAL מגרסה אחת לגרסה אחרת. אם ההמרה גורמת לאובדן מידע (כלומר, אם הגרסה החדשה של הסוג לא יכולה לייצג את הערך באופן מלא), מתועדת אזהרה ביומן.יכולות: אפשר להשתמש בפונקציות
nonExtensionOperandPerformance
ו-update
כדי לעזור ביצירת השדהCapabilities::operandPerformance
.שליחת שאילתות לגבי נכסים מסוגים:
isExtensionOperandType
,isExtensionOperationType
, nonExtensionSizeOfData
,nonExtensionOperandSizeOfData
, nonExtensionOperandTypeIsScalar
,tensorHasUnspecifiedDimensions
.
הקובץ frameworks/ml/nn/common/include/ValidateHal.h
מכיל פונקציות שירות לאימות של אובייקט NN HAL תקין בהתאם למפרט של גרסת ה-HAL שלו.
validate*
: הפונקציה מחזירה את הערךtrue
אם אובייקט ה-HAL של NN תקין בהתאם למפרט של גרסת ה-HAL שלו. סוגי ה-OEM וסוגים של תוספים לא מאומתים. לדוגמה, הפונקציהvalidateModel
מחזירה את הערךfalse
אם הדגם מכיל פעולה שמפנה למפתח של אופרנד שאינו קיים, או פעולה שאינה נתמכת בגרסה הזו של HAL.
הקובץ frameworks/ml/nn/common/include/Tracing.h
מכיל מאקרוסים שמפשטים את הוספת המידע של systracing לקוד של רשתות נוירונליות.
לדוגמה, אפשר לעיין בהפעלות המאקרו של NNTRACE_*
במנהל ההתקן לדוגמה.
הקובץ frameworks/ml/nn/common/include/GraphDump.h
מכיל פונקציית שירות לדמפ של התוכן של Model
בצורה גרפית למטרות ניפוי באגים.
graphDump
: כתיבת ייצוג של המודל בפורמט Graphviz (.dot
) בסטרימינג שצוין (אם הוא סופק) או ב-logcat (אם לא סופק סטרימינג).
אימות
כדי לבדוק את ההטמעה של NNAPI, משתמשים בבדיקות VTS ו-CTS שכלולות במסגרת Android. VTS מפעיל את מנהלי ההתקנים ישירות (בלי להשתמש במסגרת), ואילו CTS מפעיל אותם באופן עקיף דרך המסגרת. הבדיקה הזו כוללת בדיקה של כל method ב-API, ולוודא שכל הפעולות הנתמכות על ידי הנהגים פועלות בצורה תקינה ומספקות תוצאות שעומדות בדרישות הדיוק.
הדרישות לדיוק ב-CTS וב-VTS ל-NNAPI הן:
נקודת צפה: abs(expected - actual) <= atol + rtol * abs(expected); כאשר:
- עבור fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
- עבור fp16, atol = rtol = 5.0f * 0.0009765625f
Quantized: שגיאה של יחידה אחת (חוץ מ-
mobilenet_quantized
, שגיאה של שלוש יחידות)בוליאני: התאמה מדויקת
אחת מהדרכים שבהן CTS בודק את NNAPI היא באמצעות יצירת גרפים פסאודו-אקראיים קבועים, המשמשים לבדיקת תוצאות הביצועים של כל מנהל ולביצוע השוואה ביניהן לבין ההטמעה של NNAPI. עבור מנהלי התקנים עם NN HAL 1.2 ואילך, אם התוצאות לא עומדות בקריטריונים של הדיוק, המערכת של CTS תדווח על שגיאה ותשמיט קובץ מפרט של המודל שנכשל בקטע /data/local/tmp
לצורך ניפוי באגים.
פרטים נוספים על קריטריונים הדיוק מופיעים במאמרים TestRandomGraph.cpp
וTestHarness.h
.
בדיקת fuzz
מטרת בדיקת fuzz היא למצוא קריסות, טענות נכוֹנוּת (assertions), הפרות של זיכרון או התנהגות לא מוגדרת באופן כללי בקוד שנבדק, עקב גורמים כמו קלט בלתי צפוי. ב-Android נעשה שימוש בבדיקות מבוססות libFuzzer לבדיקת fuzz של NNAPI. הבדיקות האלה יעילות ב-fuzzing כי הן משתמשות בכיסוי שורות של תרחישי בדיקה קודמים כדי ליצור קלט אקראי חדש. לדוגמה, libFuzzer מעדיף תרחישי בדיקה שפועלים בשורות קוד חדשות. כך ניתן לקצר משמעותית את משך הזמן של הבדיקה עד שמוצאים את הקוד הבעייתי.
כדי לבצע בדיקת fuzz לאימות ההטמעה של מנהל ההתקן, משנים את frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
בכלי הבדיקה libneuralnetworks_driver_fuzzer
שנמצא ב-AOSP כך שיכלול את קוד מנהל ההתקן. למידע נוסף על בדיקת fuzz של NNAPI, ראו frameworks/ml/nn/runtime/test/android_fuzzing/README.md
.
אבטחה
תהליכי האפליקציות מתקשרים ישירות עם תהליך של מנהל התקן, ולכן מנהלי ההתקנים חייבים לאמת את הארגומנטים של הקריאות שהם מקבלים. מערכת VTS מאמתת את התיקוף הזה. קוד האימות מופיע ב-frameworks/ml/nn/common/include/ValidateHal.h
.
בנוסף, הנהגים צריכים לוודא שאפליקציות לא יכולות להפריע לאפליקציות אחרות בזמן השימוש באותו מכשיר.
חבילה לבדיקת למידת מכונה ב-Android
ערכת הבדיקות של למידת המכונה ב-Android (MLTS) היא מדד NNAPI שכלול ב-CTS וב-VTS, ומטרתו לאמת את הדיוק של מודלים אמיתיים במכשירי ספקים. בבדיקה נמדדים זמן האחזור והדיוק, והתוצאות של הדרייברים משווים לתוצאות של TF Lite שפועל ב-CPU, עבור אותו מודל ומערך נתונים. כך אפשר להבטיח שהדיוק של מנהל ההתקן לא יהיה גרוע יותר מההטמעה של קובץ העזר של המעבד.
מפתחי פלטפורמת Android משתמשים ב-MLTs גם כדי להעריך את זמן האחזור ואת הדיוק של מנהלי ההתקנים.
מדד הביצועים של NNAPI נמצא בשני פרויקטים ב-AOSP:
platform/test/mlts/benchmark
(אפליקציית אמת מידה)platform/test/mlts/models
(מודלים ומערכי נתונים)
מודלים ומערכי נתונים
בבדיקה של NNAPI נעשה שימוש במודלים ובמערכי הנתונים הבאים.
- MobileNetV1 float ו-u8 quantized בגדלים שונים, שפועלים על קבוצת משנה קטנה (1,500 תמונות) של Open Images Dataset v4.
- MobileNetV2 float ו-u8 quantized בגדלים שונים, שפועלים על קבוצת משנה קטנה (1,500 תמונות) של Open Images Dataset v4.
- מודל אקוסטי מבוסס זיכרון לטווח קצר (LSTM) להמרת טקסט לדיבור, שפועל על קבוצת משנה קטנה של קבוצת CMU Arctic.
- מודל אקוסטי מבוסס-LSTM לזיהוי דיבור אוטומטי, שפועל על קבוצת משנה קטנה של מערך הנתונים LibriSpeech.
מידע נוסף זמין במאמר platform/test/mlts/models
.
בדיקת לחץ
חבילת הבדיקות של למידת המכונה של Android כוללת סדרה של בדיקות התרסקות כדי לאמת את עמידות הנהגים בתנאים של שימוש כבד או בתרחישים קיצוניים של התנהגות הלקוחות.
בכל בדיקות ההתנגשויות מוצגות התכונות הבאות:
- זיהוי תקיעות: אם לקוח NNAPI נתקע במהלך בדיקה, הבדיקה נכשלת עם הסיבה לכישלון
HANG
וחבילה הבדיקות עוברת לבדיקה הבאה. - זיהוי קריסה של לקוח NNAPI: הבדיקות עוברות קריסות של לקוחות והן נכשלות עם הסיבה לכישלון
CRASH
. - זיהוי קריסה של מנהל התקן: הבדיקות יכולות לזהות קריסה של מנהל התקן שגורמת לכשל בקריאה ל-NNAPI. חשוב לזכור שיכולות להיות קריסות בתהליכי הנהג שלא גורמות לכשל ב-NNAPI ולא גורמות לכישלון הבדיקה. כדי לכסות כשל מסוג זה, מומלץ להריץ את הפקודה
tail
ביומן המערכת כדי למצוא שגיאות או קריסות שקשורות לדרייבר. - טירגוט לכל המאיצים הזמינים: הבדיקה מתבצעת לכל מנהלי ההתקנים הזמינים.
לכל בדיקות התאונות יש ארבע תוצאות אפשריות:
SUCCESS
: ההפעלה הושלמה ללא שגיאה.FAILURE
: ההפעלה נכשלה. בדרך כלל נגרמת בגלל כשל בבדיקת מודל, שמציין שמנהל ההתקן לא הצליח לקמפל או להריץ את המודל.HANG
: תהליך הבדיקה הפסיק להגיב.CRASH
: תהליך הבדיקה קרס.
מידע נוסף על בדיקות עומס ורשימה מלאה של בדיקות קריסה זמינים במאמר platform/test/mlts/benchmark/README.txt
.
שימוש ב-MLTS
כדי להשתמש ב-MLTs:
- מחברים מכשיר יעד לתחנת העבודה ומוודאים שאפשר לגשת אליו דרך adb.
אם יש יותר ממכשיר אחד שמחובר, מייצאים את משתנה הסביבה
ANDROID_SERIAL
של מכשיר היעד. cd
לספריית המקור ברמה העליונה של Android.source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
בסיום הרצה של מדד ביצועים, התוצאות מוצגות כדף HTML ומועברות אל
xdg-open
.
מידע נוסף זמין במאמר platform/test/mlts/benchmark/README.txt
.
גרסאות HAL של Neural Networks
בקטע הזה מתוארים השינויים בגרסאות HAL של Android ושל Neural Networks.
Android 11
ב-Android 11 מוצגת NN HAL 1.3, שכוללת את השינויים הבולטים הבאים.
- תמיכה בקידוד 8 ביט חתום ב-NNAPI. הוספת סוג המשתנה
TENSOR_QUANT8_ASYMM_SIGNED
. מנהלי התקנים עם NN HAL 1.3 שתומכים בפעולות עם קצוב ללא סימן חייבים לתמוך גם בוריאנטים החתומים של הפעולות האלה. כשמריצים גרסאות חתומות ולא חתומות של רוב הפעולות המקווננות, הנהגים חייבים לספק את אותן תוצאות עד להיסט של 128. יש חמישה יוצאים מן הכלל לדרישה הזו:CAST
,HASHTABLE_LOOKUP
,LSH_PROJECTION
,PAD_V2
וגםQUANTIZED_16BIT_LSTM
. הפעולהQUANTIZED_16BIT_LSTM
לא תומכת באופרטורים עם סימן, ואילו ארבע הפעולות האחרות תומכות בקידוד מדויק עם סימן, אבל לא מחייבות שהתוצאות יהיו זהות. - תמיכה בהפעלות מוקפות שבהן המסגרת קוראת לשיטה
IPreparedModel::executeFenced
כדי להפעיל הפעלה אסינכרונית מוקפת במודל מוכן עם וקטור של מחסומי סנכרון להמתנה. מידע נוסף זמין במאמר ביצוע מוגבל. - תמיכה בזרימת בקרה. הוספת הפעולות
IF
ו-WHILE
, שמקבלות מודלים אחרים כארגומנטים ומבצעות אותם באופן מותנה (IF
) או שוב ושוב (WHILE
). מידע נוסף זמין במאמר זרימת בקרה. - שיפור באיכות השירות (QoS), כי האפליקציות יכולות לציין את העדיפויות היחסיות של המודלים שלהן, את משך הזמן המקסימלי הצפוי להכנת מודל ואת משך הזמן המקסימלי הצפוי להשלמת ביצוע. מידע נוסף זמין במאמר איכות שירות.
- תמיכה בדומיינים של זיכרון שמספקים ממשקי הקצאה למאגרים בניהול הנהג. כך אפשר להעביר זיכרונות מקומיים של המכשיר בין פעולות, וכך למנוע העתקה וטרנספורמציה מיותרים של נתונים בין פעולות רצופות באותו מנהל. מידע נוסף זמין במאמר דומיינים של זיכרון.
Android 10
ב-Android 10 מוצגת NN HAL 1.2, שכוללת את השינויים הבולטים הבאים.
- המבנה
Capabilities
כולל את כל סוגי הנתונים, כולל סוגי נתונים סקלריים, ומייצג ביצועים ללא הרפיה באמצעות וקטור במקום שדות עם שמות. - השיטות
getVersionString
ו-getType
מאפשרות למסגרת לאחזר את סוג המכשיר (DeviceType
) ואת פרטי הגרסה. גילוי והקצאה של מכשירים - השיטה
executeSynchronously
נקראת כברירת מחדל כדי לבצע ביצוע באופן סינכרוני. השיטהexecute_1_2
מורה למסגרת לבצע את ההפעלה באופן אסינכרוני. ביצוע - הפרמטר
MeasureTiming
לשיטותexecuteSynchronously
,execute_1_2
והפעלה רציפה מציין אם הנהג מודד את משך ההפעלה. התוצאות מדווחות במבנהTiming
. מידע נוסף זמין בקטע תזמון. - תמיכה בהרצות שבהן למשתני הפלט יש מימד או דירוג לא ידועים. מידע נוסף זמין במאמר צורת הפלט.
- תמיכה בתוספים של ספקים, שהם אוספים של פעולות וסוגי נתונים שהוגדרו על ידי הספק. הנהג מדווח על התוספים הנתמכים באמצעות השיטה
IDevice::getSupportedExtensions
. תוספים של ספקים - היכולת של אובייקט זרימה רציפה לשלוט בקבוצה של פעולות זרימה רציפה באמצעות תורים מהירים להעברת הודעות (FMQ) כדי לתקשר בין תהליכי האפליקציה לבין תהליכי הנהג, וכך לצמצם את זמן האחזור. ביצועים רצופי והודעות מהירות
- תמיכה ב-AHardwareBuffer כדי לאפשר למנהל ההתקן לבצע פעולות ללא העתקת נתונים. מידע נוסף זמין במאמר AHardwareBuffer.
- תמיכה משופרת בשמירת ארטיפקטים של הידור במטמון כדי לקצר את זמן הידור האפליקציה בזמן ההפעלה. אחסון ב-cache של הידור
ב-Android 10 נוספו סוגי אופרטורים ופעולות הבאות.
-
ANEURALNETWORKS_BOOL
ANEURALNETWORKS_FLOAT16
ANEURALNETWORKS_TENSOR_BOOL8
ANEURALNETWORKS_TENSOR_FLOAT16
ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
ANEURALNETWORKS_TENSOR_QUANT16_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM
ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
-
ANEURALNETWORKS_ABS
ANEURALNETWORKS_ARGMAX
ANEURALNETWORKS_ARGMIN
ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
ANEURALNETWORKS_CAST
ANEURALNETWORKS_CHANNEL_SHUFFLE
ANEURALNETWORKS_DETECTION_POSTPROCESSING
ANEURALNETWORKS_EQUAL
ANEURALNETWORKS_EXP
ANEURALNETWORKS_EXPAND_DIMS
ANEURALNETWORKS_GATHER
ANEURALNETWORKS_GENERATE_PROPOSALS
ANEURALNETWORKS_GREATER
ANEURALNETWORKS_GREATER_EQUAL
ANEURALNETWORKS_GROUPED_CONV_2D
ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
ANEURALNETWORKS_INSTANCE_NORMALIZATION
ANEURALNETWORKS_LESS
ANEURALNETWORKS_LESS_EQUAL
ANEURALNETWORKS_LOG
ANEURALNETWORKS_LOGICAL_AND
ANEURALNETWORKS_LOGICAL_NOT
ANEURALNETWORKS_LOGICAL_OR
ANEURALNETWORKS_LOG_SOFTMAX
ANEURALNETWORKS_MAXIMUM
ANEURALNETWORKS_MINIMUM
ANEURALNETWORKS_NEG
ANEURALNETWORKS_NOT_EQUAL
ANEURALNETWORKS_PAD_V2
ANEURALNETWORKS_POW
ANEURALNETWORKS_PRELU
ANEURALNETWORKS_QUANTIZE
ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
ANEURALNETWORKS_RANDOM_MULTINOMIAL
ANEURALNETWORKS_REDUCE_ALL
ANEURALNETWORKS_REDUCE_ANY
ANEURALNETWORKS_REDUCE_MAX
ANEURALNETWORKS_REDUCE_MIN
ANEURALNETWORKS_REDUCE_PROD
ANEURALNETWORKS_REDUCE_SUM
ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_ROI_POOLING
ANEURALNETWORKS_RSQRT
ANEURALNETWORKS_SELECT
ANEURALNETWORKS_SIN
ANEURALNETWORKS_SLICE
ANEURALNETWORKS_SPLIT
ANEURALNETWORKS_SQRT
ANEURALNETWORKS_TILE
ANEURALNETWORKS_TOPK_V2
ANEURALNETWORKS_TRANSPOSE_CONV_2D
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN
ב-Android 10 יש עדכונים לרבות מהפעולות הקיימות. העדכונים קשורים בעיקר לנושאים הבאים:
- תמיכה בפריסה של זיכרון NCHW
- תמיכה בטנסורים עם דרגה שונה מ-4 בפעולות softmax ו-normalization
- תמיכה במודלים של עיבוד נתונים (convolution) מורחבים
- תמיכה בקלט עם קצירה משולבת ב-
ANEURALNETWORKS_CONCATENATION
ברשימה הבאה מפורטות הפעולות ששונו ב-Android 10. פרטים מלאים על השינויים מופיעים בקטע OperationCode במסמכי העזרה של NNAPI.
ANEURALNETWORKS_ADD
ANEURALNETWORKS_AVERAGE_POOL_2D
ANEURALNETWORKS_BATCH_TO_SPACE_ND
ANEURALNETWORKS_CONCATENATION
ANEURALNETWORKS_CONV_2D
ANEURALNETWORKS_DEPTHWISE_CONV_2D
ANEURALNETWORKS_DEPTH_TO_SPACE
ANEURALNETWORKS_DEQUANTIZE
ANEURALNETWORKS_DIV
ANEURALNETWORKS_FLOOR
ANEURALNETWORKS_FULLY_CONNECTED
ANEURALNETWORKS_L2_NORMALIZATION
ANEURALNETWORKS_L2_POOL_2D
ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
ANEURALNETWORKS_LOGISTIC
ANEURALNETWORKS_LSH_PROJECTION
ANEURALNETWORKS_LSTM
ANEURALNETWORKS_MAX_POOL_2D
ANEURALNETWORKS_MEAN
ANEURALNETWORKS_MUL
ANEURALNETWORKS_PAD
ANEURALNETWORKS_RELU
ANEURALNETWORKS_RELU1
ANEURALNETWORKS_RELU6
ANEURALNETWORKS_RESHAPE
ANEURALNETWORKS_RESIZE_BILINEAR
ANEURALNETWORKS_RNN
ANEURALNETWORKS_ROI_ALIGN
ANEURALNETWORKS_SOFTMAX
ANEURALNETWORKS_SPACE_TO_BATCH_ND
ANEURALNETWORKS_SPACE_TO_DEPTH
ANEURALNETWORKS_SQUEEZE
ANEURALNETWORKS_STRIDED_SLICE
ANEURALNETWORKS_SUB
ANEURALNETWORKS_SVDF
ANEURALNETWORKS_TANH
ANEURALNETWORKS_TRANSPOSE
Android 9
NN HAL 1.1 נוסף ל-Android 9 וכולל את השינויים הבולטים הבאים.
IDevice::prepareModel_1_1
כולל פרמטרExecutionPreference
. הנהג יכול להשתמש בנתונים האלה כדי לשנות את ההכנה, מתוך ידיעה שהאפליקציה מעדיפה לחסוך בסוללה או שתפעיל את המודל בקריאות מהירות רצופות.- נוספו תשע פעולות חדשות:
BATCH_TO_SPACE_ND
,DIV
,MEAN
,PAD
,SPACE_TO_BATCH_ND
,SQUEEZE
,STRIDED_SLICE
,SUB
,TRANSPOSE
. - כדי לציין שאפליקציה יכולה להריץ חישובים של 32 ביט של float באמצעות טווח או דיוק של 16 ביט של float, מגדירים את
Model.relaxComputationFloat32toFloat16
כ-true
. למבנהCapabilities
יש את השדה הנוסףrelaxedFloat32toFloat16Performance
כדי שהנהג יוכל לדווח על הביצועים המנוהלים שלו למסגרת.
Android 8.1
הגרסה הראשונית של Neural Networks HAL (1.0) שוחררה ב-Android 8.1. למידע נוסף, ראו /neuralnetworks/1.0/
.