בדף הזה מופיעה סקירה כללית של אופן ההטמעה של מנהל התקן של ממשק ה-API של רשתות נוירונים (NNAPI). פרטים נוספים זמינים במסמכי העזרה בקובצי ההגדרה של HAL ב-hardware/interfaces/neuralnetworks
.
הטמעה לדוגמה של מנהל התקן נמצאת ב-frameworks/ml/nn/driver/sample
.
למידע נוסף על Neural Networks API, ראו Neural Networks API.
HAL של רשתות נוירונים
HAL של רשתות הנוירונים (NN) מגדיר הפשטה של המכשירים השונים, כמו יחידות עיבוד גרפיות (GPU) ומעבדי אותות דיגיטליים (DSP), שנמצאים במוצר (לדוגמה, טלפון או טאבלט). מנהלי ההתקנים של המכשירים האלה חייבים לעמוד בתקן NN HAL. הממשק מצוין בקובצי הגדרת ה-HAL ב-hardware/interfaces/neuralnetworks
.
המעבר הכללי של הממשק בין המסגרת לנהג מתואר באיור 1.
איור 1. תהליך העבודה של רשתות נוירונים
אתחול
במהלך האימות, המסגרת שולחת לשאילתה לנהג לגבי היכולות שלו באמצעות IDevice::getCapabilities_1_3
.
המבנה @1.3::Capabilities
כולל את כל סוגי הנתונים ומייצג ביצועים לא קשורים באמצעות וקטור.
כדי לקבוע איך להקצות חישובים למכשירים הזמינים, המסגרת הרעיונית משתמשת ביכולות כדי להבין באיזו מהירות ובאיזו מהירות אנרגיה יכולה להיות יעילה כל נהג יכול לבצע פעולה. כדי לספק את המידע הזה, מנהל ההתקן צריך לספק נתוני ביצועים סטנדרטיים על סמך ביצוע עומסי עבודה לדוגמה.
כדי לקבוע את הערכים שמנהל התקן מחזיר בתגובה ל-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
כולל מידע על ביצועי הנהגים רק עבור נקודה צפה (floating-point) וטנצ'רים כמותיים, ולא כולל סוגי נתונים סקלריים.
כחלק מתהליך האתחול, המערכת עשויה לשלוח שאילתות לגבי מידע נוסף באמצעות IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
ו-IDevice::getNumberOfCacheFilesNeeded
.
בין הפעלות מחדש של המוצר, לפי המסגרת, כל השאילתות המתוארות בקטע הזה אמורות תמיד לדווח על אותם ערכים עבור מנהל התקן נתון. אחרת, אפליקציה שמשתמשת במנהל התקן הזה עלולה להפגת ביצועים נמוכים או התנהגות שגויה.
קומפילציה
תוכנת ה-framework קובעת באילו מכשירים להשתמש כשהיא מקבלת בקשה מאפליקציה. ב-Android 10, אפליקציות יכולות לגלות ולציין את המכשירים שמהם היא בוחרת. למידע נוסף, ראו זיהוי והקצאה של מכשירים.
בזמן הידור המודל, המסגרת שולחת את המודל לכל נהג מתאים באמצעות קריאה ל-IDevice::getSupportedOperations_1_3
.
כל מנהל מחזיר מערך של ערכים בוליאניים שמציינים אילו פעולות של המודל נתמכות. נהג יכול לקבוע שהוא לא יכול לתמוך בפעולה מסוימת מכמה סיבות. לדוגמה:
- הנהג לא תומך בסוג הנתונים הזה.
- מנהל ההתקן תומך רק בפעולות עם פרמטרים ספציפיים של קלט. לדוגמה, מנהל התקן עשוי לתמוך בפעולות קונבולוציה בגודל 3x3 ו-5x5, אבל לא בפעולות קונבולוציה בגודל 7x7.
- לנהג יש מגבלות זיכרון שמונעות ממנו לטפל בגרפים או בקלט גדולים.
במהלך ההידור, יכולים להיות ממדים או דירוג לא ידועים לקלט, לפלט ולאופרנדים הפנימיים של המודל, כפי שמתואר ב-OperandLifeTime
. למידע נוסף, ראו צורת פלט.
המסגרת מורה לכל מנהל שנבחר להתכונן להרצה של קבוצת משנה של המודל באמצעות קריאה ל-IDevice::prepareModel_1_3
.
לאחר מכן, כל מנהל התקן יוצר את קבוצת המשנה שלו. לדוגמה, מנהל יכול ליצור קוד או ליצור עותק של המשקלים בסדר מחדש. מכיוון שיכול להיות פרק זמן משמעותי בין הידור המודל לבין ביצוע בקשות, לא כדאי להקצות משאבים כמו מקטעים גדולים של זיכרון המכשיר במהלך הידור.
אם הפעולה מסתיימת בהצלחה, מנהל ההתקן מחזיר אחיזה מסוג @1.3::IPreparedModel
. אם הנהג מחזיר קוד כשל בהכנת קבוצת המשנה של המודל, ה-framework מריץ את המודל כולו במעבד.
כדי לקצר את הזמן הנדרש ל-compilation כשאפליקציה מופעלת, הנהג יכול לשמור את פריטי ה-compilation במטמון. למידע נוסף, ראו שמירה במטמון של הידור.
ביצוע
כשאפליקציה מבקשת מה-framework לבצע בקשה, ה-framework קורא ל-method IPreparedModel::executeSynchronously_1_3
כברירת מחדל כדי לבצע הרצה סינכרונית במודל מוכן.
אפשר גם להריץ בקשה באופן אסינכררוני באמצעות השיטה execute_1_3
, השיטה executeFenced
(ראו ביצוע מוגבל) או באמצעות ביצוע רצף פעולות.
קריאות ביצוע סינכרוניות משפרות את הביצועים ומצמצמות את תקורת השרשורים בהשוואה לקריאות אסינכרוניות, כי השליטה מוחזרת לתהליך האפליקציה רק אחרי הביצוע. המשמעות היא שהדרייבר לא צריך מנגנון נפרד כדי להודיע לתהליך האפליקציה שההפעלה הושלמה.
כשמשתמשים בשיטה האסינכרונית execute_1_3
, השליטה חוזרת לתהליך האפליקציה אחרי שההפעלה מתחילה, והנהג צריך להודיע למסגרת כשההפעלה מסתיימת באמצעות @1.3::IExecutionCallback
.
הפרמטר Request
שמועבר לשיטת ההרצה מפרט את האופרנדים של הקלט והפלט שמשמשים לביצוע. בזיכרון שמאחסן את נתוני האופרנד צריך להשתמש בסדר שורה-ראשי, כאשר המאפיין הראשון חוזר על עצמו, ובלי מרווח פנימי בסוף כל שורה. למידע נוסף על סוגי המשתנים, תוכלו לקרוא את המאמר Operands.
במנהלי NN HAL 1.2 ואילך, כשבקשה תושלם, סטטוס השגיאה, צורת הפלט ופרטי התזמון יחזרו למסגרת. במהלך ההפעלה, לפלט או לאופרטורים הפנימיים של המודל יכולים להיות מאפיין אחד או יותר לא ידוע או דרגה לא ידועה. אם למשתנה פלט אחד לפחות יש מאפיין או דירוג לא ידועים, הנהג צריך להחזיר מידע על פלט בגודל דינמי.
לנהגים עם NN HAL 1.1 ומטה, מוחזר רק סטטוס השגיאה כשנשלחת בקשה. כדי שההרצה תושלם בהצלחה, צריך לציין את המאפיינים של אופרטורי הקלט והפלט באופן מלא. לאפשרויות הפעלה פנימיות יכול להיות מאפיין אחד או יותר לא ידוע, אבל הן חייבות להיות בעלות דירוג מסוים.
בבקשות של משתמשים שכוללות מספר נהגים, ה-framework אחראי על שמירת זיכרון הביניים ולסדר את הקריאות לכל נהג.
אפשר לשלוח כמה בקשות במקביל באותו @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
ראו מסגרת סנכרון.
בביצוע מוגדר, ה-framework קורא ל-method IPreparedModel::executeFenced
כדי להפעיל הפעלה אסינכרונית מגודרת במודל מוכן, עם וקטור של גדרות סנכרון שצריך להמתין לו. אם המשימה האסינכרונית תסתיים לפני שהשיחה חוזרת, אפשר להחזיר כינוי ריק בשביל sync_fence
. צריך להחזיר גם אובייקט IFencedExecutionCallback
כדי לאפשר ל-framework להריץ שאילתות על מידע על סטטוס השגיאה ועל משך הזמן.
אחרי שמשלימים את הביצוע, אפשר לשלוח שאילתה על שני ערכי התזמון הבאים, שמודדים את משך הביצוע, דרך IFencedExecutionCallback::getExecutionInfo
.
timingLaunched
: משך הזמן מרגע הקריאה שלexecuteFenced
ועד ל-executeFenced
מסמנת את הערךsyncFence
שמוחזר.timingFenced
: משך הזמן מרגע שכל גדרות הסנכרון שנמצאות בהמתנה מופיעות כאשרexecuteFenced
מסמן את הערךsyncFence
שמוחזר.
בקרת זרימה
במכשירים עם Android מגרסה 11 ואילך, NNAPI כולל שתי פעולות של בקרת תהליך, IF
ו-WHILE
, שמקבלות מודלים אחרים כארגומנטים ומבצעות אותם באופן מותנה (IF
) או חוזר (WHILE
). למידע נוסף על הטמעה של הפעולות האלה, ראו בקרת תהליך.
איכות השירות
ב-Android 11, NNAPI כולל איכות שירות משופרת (QoS) כי הוא מאפשר לאפליקציה לציין את סדר העדיפויות היחסי של המודלים שלה, את הזמן המקסימלי הצפוי להכנת מודל ואת משך הזמן המקסימלי הצפוי להשלמת הביצוע. למידע נוסף, ראו איכות שירות.
ניקוי
כשהאפליקציה מסיימת להשתמש במודל מוכן, המסגרת משחררת את ההפניה שלה לאובייקט @1.3::IPreparedModel
. כשההפניה לאובייקט IPreparedModel
לא קיימת יותר, הוא נהרס באופן אוטומטי בשירות הנהג שיצר אותו. בשלב הזה אפשר להשתמש במשאבים ספציפיים לדגם בהטמעה של כלי ההסבה לנהג. אם שירות מנהל ההתקן רוצה שהאובייקט IPreparedModel
יושמד באופן אוטומטי כשהלקוח לא צריך אותו יותר, הוא לא יכול לשמור הפניות לאובייקט IPreparedModel
אחרי שהאובייקט IPreparedeModel
הוחזר דרך IPreparedModelCallback::notify_1_3
.
שימוש במעבד
על מנהלי ההתקנים להשתמש במעבד (CPU) כדי להגדיר חישובים. אסור להשתמש ב-CPU לביצוע חישובים של גרפים, כי זה מפריע ליכולת של המסגרת להקצות את העבודה בצורה נכונה. מנהל ההתקן צריך לדווח למסגרת על החלקים שהוא לא יכול לטפל בהם, ולאפשר למסגרת לטפל בשאר החלקים.
ה-framework מספק הטמעה של מעבד (CPU) לכל הפעולות של NNAPI, מלבד פעולות שהוגדרו על ידי הספק. למידע נוסף, ראו תוספי ספקים.
לפעולות שבוצעו ב-Android 10 (רמת API 29) יש רק הטמעה של מעבד (CPU) להתייחסות, כדי לוודא שהבדיקות של ה-CTS וה-VTS נכונות. מומלץ להשתמש בהטמעות האופטימיות שכלולות במסגרות של למידת מכונה לנייד, במקום בהטמעה של NNAPI ל-CPU.
פונקציות שירות
קוד המקור של NNAPI כולל פונקציות שירות ששירותי הנהגים יכולים להשתמש בהן.
הקובץ frameworks/ml/nn/common/include/Utils.h
מכיל פונקציות שירות שונות, כמו פונקציות לצורכי רישום ביומן ולצורך המרה בין גרסאות שונות של NN HAL.
VLogging:
VLOG
הוא מאקרו wrapper מסביב ל-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
אם אובייקט ה-NN HAL תקין בהתאם למפרט של גרסת ה-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 מפעיל את הנהגים באופן ישיר (בלי להשתמש ב-framework), ואילו CTS מיישם את הנהגים באופן עקיף דרך המסגרת. הבדיקות האלה בודקות את כל ה-methods של ה-API, ומוודאים שכל הפעולות שנתמכות על ידי מנהלי ההתקנים פועלות כראוי ומספקות תוצאות שעומדות בדרישות הדיוק.
דרישות הדיוק ב-CTS וב-VTS ל-NNAPI הן:
Floating-point: b(expected - Actual) <= atol + rtol * b(expected); כאשר:
- ל-fp32, atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
- ל-fp16, atol = rtol = 5.0f * 0.0009765625f
כמותית: כל אחד בנפרד (חוץ מהשנייה
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 Machine Learning Test Suite (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 של רשתות נוירונים
בקטע הזה מתוארים השינויים שבוצעו בגרסאות HAL של רשתות נוירונים ו-Android.
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
כולל את כל סוגי הנתונים, כולל סוגי נתונים סקלריים, ומייצג ביצועים לא קשורים באמצעות וקטור במקום שדות עם שם. - ה-methods
getVersionString
ו-getType
מאפשרות ל-framework לאחזר את סוג המכשיר (DeviceType
) ואת פרטי הגרסה. למידע נוסף, ראו גילוי והקצאה של מכשירים. - השיטה
executeSynchronously
נקראת כברירת מחדל כדי לבצע ביצוע באופן סינכרוני. ה-methodexecute_1_2
מנחה את ה-framework לבצע הפעלה באופן אסינכרוני. ביצוע - הפרמטר
MeasureTiming
לשיטותexecuteSynchronously
,execute_1_2
והפעלה ברצף מציין אם הנהג מודד את משך ההפעלה. התוצאות מדווחות במבנהTiming
. למידע נוסף, ראו תזמון. - תמיכה בפעולות שבהן אופרנד אחד או יותר של פלט הוא בעל מאפיין או דירוג לא ידועים. מידע נוסף זמין במאמר צורת הפלט.
- תמיכה בתוספי ספקים, שהם אוספים של פעולות וסוגי נתונים שהוגדרו על ידי הספק. הנהג מדווח על תוספים נתמכים באמצעות method
IDevice::getSupportedExtensions
. תוספים של ספקים - היכולת של אובייקט זרימה רציפה לשלוט בקבוצה של פעולות זרימה רציפה באמצעות תורים מהירים להעברת הודעות (FMQ) כדי לתקשר בין תהליכי האפליקציה לבין תהליכי הנהג, וכך לצמצם את זמן האחזור. ביצועים רצופי ומהיר של הודעות
- תמיכה ב-AHardwareBuffer כדי לאפשר למנהל ההתקן לבצע פעולות ללא העתקת נתונים. מידע נוסף זמין במאמר AHardwareBuffer.
- תמיכה משופרת בשמירת ארטיפקטים של הידור במטמון כדי לקצר את זמן הידור האפליקציה בזמן ההפעלה. למידע נוסף, ראו שמירה במטמון של הידור במטמון.
ב-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
- תמיכה ב-tensors עם דרגה שונה מ-4 בפעולות softmax ו-normalization
- תמיכה בקיפולים מורחבים
- תמיכה בקלט עם קצוב מעורב ב-
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/
.