נציגים של TensorFlow Lite

משתמשים מורשים מאפשרים את שיפור המהירות באמצעות חומרה של מודלים של TensorFlow Lite באמצעות שימוש באצים במכשיר כמו ה-GPU ומעבד האותות הדיגיטלי (DSP).

כברירת מחדל, ב-TensorFlow Lite נעשה שימוש בליבות של המעבד (CPU) שעברו אופטימיזציה לקבוצת ההוראות ARM Neon. עם זאת, המעבד (CPU) הוא מעבד רב-תכליתי שלא עבר אופטימיזציה לצורך החישוב הכבד, שבדרך כלל מופיע במודלים של למידת מכונה (לדוגמה, המטריצה המתמטית שמתבססת על קונבולציה ושכבות צפופות).

לעומת זאת, רוב הטלפונים הניידים המודרניים מכילים צ'יפים שמטפלים בצורה טובה יותר במשימות כבדות. השימוש בהן לתפעול של רשת נוירונים מספק יתרונות עצומים מבחינת זמן אחזור וחיסכון בחשמל. לדוגמה, מעבדי GPU יכולים לספק האצה של עד פי 5 בזמן האחזור.

לכל אחד מהמאיצים האלה משויכים ממשקי API שמאפשרים חישובים בהתאמה אישית, כמו OpenCL או OpenGL ES ל-GPU לנייד. בדרך כלל צריך לכתוב הרבה קוד מותאם אישית כדי להריץ רשת נוירונים דרך הממשקים האלה. המצב מסתבך עוד יותר כשחושבים שלכל מאיץ יש יתרונות וחסרונות, והוא לא יכול לבצע כל פעולה ברשת נוירונים. ממשק ה-API של TensorFlow ב-Lite פותר את הבעיה הזו ומשמש כגשר בין זמן הריצה של TFLite לבין ממשקי ה-API האלה ברמה נמוכה יותר.

זמן ריצה עם נציגים

בחירת נציג מורשה

ב-TensorFlow Lite יש תמיכה במספר משתמשים, שכל אחד מהם מותאם לפלטפורמות מסוימות ולסוגים מסוימים של מודלים. בדרך כלל יהיו מספר משתמשים מורשים שרלוונטיים לתרחיש לדוגמה שלכם, בהתאם לשני קריטריונים עיקריים: הפלטפורמה (Android או iOS?) שאליה מטרגטים וסוג המודל (נקודה צפה או כמותית?) שאתם מנסים להאיץ.

משתמשים עם הרשאות גישה לפי פלטפורמה

בפלטפורמות שונות (Android ו-iOS)

  • מקבל הגישה ל-GPU - אפשר להשתמש במקבל ההרשאה ל-GPU גם ב-Android וגם ב-iOS. הוא מותאם להרצת מודלים מבוססי-float של 32 ביט ו-16 ביט שבהם יש GPU. הוא תומך גם במודלים כמותיים ב-8 ביט ומספק ביצועי GPU בהשוואה לגרסאות הצפות שלהם. מידע נוסף על הקצאת ה-GPU זמין במאמר TensorFlow Lite ב-GPU.

iOS

  • בעל גישה ללמידת מכונה בליבה (Core ML) במכשירי iPhone ו-iPad חדשים יותר – במכשירי iPhone ו-iPad חדשים יותר שבהם Neural Engine זמין, אפשר להשתמש במתן גישה ל-Core ML כדי להאיץ את תהליך ההסקת מסקנות לגבי מודלים של נקודה צפה (floating-point) של 32 ביט או 16 ביט. Neural Engine זמין במכשירים ניידים של Apple עם A12 SoC ואילך. לסקירה כללית של מקבלי הגישה ל-Core ML והוראות מפורטות, ראו מקבל הגישה ל-TensorFlow Lite Core ML.

משתמשים עם הרשאות גישה לפי סוג מודל

כל מאיץ מתוכנן מתוך מחשבה על רוחב סיביות מסוים של נתונים. אם תספקו למקבל הגישה מודל נקודה צפה (floating-point) שתומך רק בפעולות כמותיות ב-8 ביט, כל הפעולות שלו יידחו והמודל יפעל במלואו על המעבד (CPU). כדי להימנע מהפתעות כאלה, בטבלה הבאה יש סקירה כללית של התמיכה בהענקת גישה לפי סוג המודל:

סוג הדגם GPU CoreML
נקודה צפה (32 ביט) כן כן
קוונטיזציה של float16 אחרי האימון כן כן
קוונטיזציה של טווח דינמי אחרי האימון כן לא
כימות מספרים שלמים אחרי האימון כן לא
הדרכה מבוססת-כמות כן לא

מתבצע אימות של הביצועים

המידע בקטע הזה משמש כקו מנחה כללי ליצירת רשימת משתמשים מקוצרת שיכולה לשפר את הבקשה שלכם. עם זאת, חשוב לציין שלכל משתמש מורשה יש קבוצה מוגדרת מראש של פעולות שהוא תומך בהן, ושהביצועים שלהן עשויים להשתנות בהתאם לדגם ולמכשיר. לכן מומלץ בדרך כלל לבצע השוואה לשוק כדי להעריך את מידת התועלת של נציג מורשה לצרכים שלכם. הפעולה הזו גם עוזרת להצדיק את הגדלת הגודל הבינארי שקשורה לצירוף משתמש בעל הרשאות גישה לסביבת זמן הריצה של TensorFlow Lite.

ב-TensorFlow Lite יש כלים רבים להערכת ביצועים ולהערכת רמת הדיוק, שעוזרים למפתחים להיות בטוחים בשימוש של המשתמשים באפליקציה שלהם. הכלים האלה מוזכרים בקטע הבא.

כלים להערכה

זמן אחזור וטביעת הרגל הפחמנית

אפשר להשתמש בכלי בנצ'מרק של TensorFlow Lite כדי להעריך את ביצועי המודל, כולל זמן אחזור ממוצע של ההסקה, תקורת האתחול, טביעת הרגל הפחמנית וכו'. הכלי הזה תומך במספר דגלים כדי לקבוע מהי ההגדרה הטובה ביותר להענקת גישה למודל שלכם. במכונה, אפשר לציין את --gpu_backend=gl באמצעות --use_gpu כדי למדוד הרצת GPU באמצעות OpenGL. הרשימה המלאה של הפרמטרים הנתמכים להענקת גישה מוגדרת במסמכי התיעוד המפורטים.

הנה דוגמה להרצה של מודל כמותי עם GPU דרך adb:

adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/mobilenet_v1_224_quant.tflite \
  --use_gpu=true

ניתן להוריד כאן את הגרסה המובנית מראש של הכלי לארכיטקטורת ARM 64 ביט (למידע נוסף).

דיוק ונכון

בדרך כלל משתמשים עם הרשאות גישה מבצעים חישובים ברמת דיוק שונה מזו של המעבדים המקבילים להם. כתוצאה מכך, יש פגיעה (בדרך כלל משנית) לדיוק שמשויכת לשימוש בהאצלת חומרה לצורך האצת חומרה. שימו לב שזה לא נכון תמיד. לדוגמה, מכיוון שה-GPU משתמש ברמת דיוק בנקודה צפה (floating-point) כדי להריץ מודלים כמותיים, יכול להיות שיהיה שיפור קל ברמת הדיוק (למשל, יש שיפור של פחות מ-1% בסיווג התמונות של ILSVRC – 5% המובילים).

ב-TensorFlow Lite יש שני סוגים של כלים למדידת רמת הדיוק של התנהגות מקבלי הגישה במודל נתון: מבוסס-משימות ו-Task-Agnostic. כל הכלים שמתוארים בקטע הזה תומכים בפרמטרים מתקדמים של הענקת גישה, ששימשו את כלי ההשוואה לשוק מהקטע הקודם. שימו לב שסעיפי המשנה שבהמשך מתמקדים בהערכה להענקת גישה (האם בעל הגישה פועל באופן זהה למעבד (CPU?) ולא בהערכת המודל (האם המודל עצמו מתאים למשימה?).

הערכה מבוססת-משימה

ב-TensorFlow Lite יש כלים להערכת הנכונות של שתי משימות מבוססות-תמונה:

קבצים בינאריים מוכנים מראש של הכלים האלה (Android, ארכיטקטורת ARM של 64 ביט), יחד עם מסמכי התיעוד, זמינים כאן:

הדוגמה הבאה מציגה הערכת סיווג תמונות באמצעות GPU ב-Pixel 4:

adb shell /data/local/tmp/run_eval \
  --model_file=/data/local/tmp/mobilenet_quant_v1_224.tflite \
  --ground_truth_images_path=/data/local/tmp/ilsvrc_images \
  --ground_truth_labels=/data/local/tmp/ilsvrc_validation_labels.txt \
  --model_output_labels=/data/local/tmp/model_output_labels.txt \
  --output_file_path=/data/local/tmp/accuracy_output.txt \
  --num_images=0 # Run on all images. \
  --use_gpu=true

הפלט הצפוי הוא רשימה של המדדים המובילים מ-1 עד 10:

Top-1 Accuracy: 0.733333
Top-2 Accuracy: 0.826667
Top-3 Accuracy: 0.856667
Top-4 Accuracy: 0.87
Top-5 Accuracy: 0.89
Top-6 Accuracy: 0.903333
Top-7 Accuracy: 0.906667
Top-8 Accuracy: 0.913333
Top-9 Accuracy: 0.92
Top-10 Accuracy: 0.923333

הערכה אגנוסטית של המשימה

למשימות שאין בהן כלי הערכה מוגדר במכשיר או ניסויים במודלים בהתאמה אישית, TensorFlow Lite כולל את הכלי הסקת מסקנות. (כאן) הארכיטקטורה הבינארית של ARM 64 ביט

ההבדל בין ההסקה משווה בין ביצוע של TensorFlow Lite (מבחינת זמן אחזור וסטיית ערך פלט) בשתי הגדרות:

  • מסקנות מעבד (CPU) עם שרשור יחיד
  • מסקנות בהגדרת המשתמש – מוגדרת על ידי הפרמטרים האלה

לשם כך, הכלי יוצר נתונים גאוסיאניים אקראיים ומעביר אותם דרך שני מתורגמים של TFLite – אחד מפעיל ליבה (kernel) של מעבד (CPU) עם שרשור יחיד והשני מוגדר לפי פרמטרים של הארגומנטים של המשתמש.

היא מודדת את זמן האחזור של שניהם, וגם את ההבדל המוחלט בין גורמי פלט מכל מתרגם, לפי רכיב.

במודל עם משתנה פלט יחיד, הפלט עשוי להיראות כך:

Num evaluation runs: 50
Reference run latency: avg=84364.2(us), std_dev=12525(us)
Test run latency: avg=7281.64(us), std_dev=2089(us)
OutputDiff[0]: avg_error=1.96277e-05, std_dev=6.95767e-06

כלומר, ביחס למשתנה הפלט באינדקס 0, הרכיבים מהפלט של המעבד (CPU) שונים מהפלט של בעל הגישה ב-1.96e-05 בממוצע.

שימו לב שהבנת המספרים האלה דורשת ידע מעמיק יותר לגבי המודל, והמשמעות של כל טינזור של הפלט. אם מדובר רגרסיה פשוטה שקובעת סוג מסוים של ניקוד או הטמעה, ההבדל צריך להיות נמוך (אחרת מדובר בשגיאה אצל בעל הגישה). עם זאת, קשה יותר לפרש פלטים כמו 'סיווג זיהוי' ממודלים של SSD. לדוגמה, יכול להיות שזה יראה הבדל בשימוש בכלי הזה, אבל יכול להיות שזה לא אומר שיש בעיה כלשהי בבעל הגישה: נשקול להשתמש בשתי מחלקות (מזויפות): "TV (מזהה: 10)", "Monitor (מזהה:20)" - אם משתמש מסוים נמצא מחוץ לאמת המוזגבת והוא מציג מוניטור במקום טלוויזיה, הפרש הפלט 1 = 1 בערך הזה יכול להיות, 10-10.