השימוש ביחידות עיבוד גרפיות (GPU) להפעלת מודלים של למידת מכונה (ML) יכול לשפר משמעותית את ביצועי המודל ואת חוויית המשתמש באפליקציות שתומכות בלמידת מכונה. TensorFlow Lite מאפשר להשתמש במעבדי GPU ובמעבדים מיוחדים אחרים באמצעות מנהל התקן חומרה שנקרא נציגים. הפעלת השימוש במעבדי GPU באפליקציות למידת מכונה TensorFlow Lite יכולה לספק את היתרונות הבאים:
- מהירות – מעבדי ה-GPU מתאימים לתפוקה גבוהה של עומסי עבודה מקבילים ומעצימים. בזכות התכנון הזה, הן מתאימות במיוחד לרשתות נוירונים עמוקות, שכוללות מספר עצום של אופרטורים, שכל אחד מהם עובד על מזיני קלט שאפשר לעבד במקביל, ולכן בדרך כלל התוצאה היא זמן אחזור קצר. בתרחיש הטוב ביותר, הרצת המודל ב-GPU עשויה לרוץ מהר מספיק כדי לאפשר אפליקציות בזמן אמת שלא היו אפשריות קודם לכן.
- חיסכון בצריכת החשמל – מעבדי GPU מבצעים חישובים של למידת מכונה באופן יעיל ואופטימלי, ולרוב צורכים פחות חשמל ומפיקים פחות חום בהשוואה לאותה משימה שפועלת במעבדי CPU.
במסמך הזה מפורטת סקירה כללית על התמיכה במעבדי GPU ב-TensorFlow Lite, ושימושים מתקדמים מסוימים במעבדי GPU. למידע ספציפי יותר על הטמעת תמיכה ב-GPU בפלטפורמות ספציפיות, עיינו במדריכים הבאים:
תמיכה בפעולות של GPU ML
יש כמה מגבלות על הפעולות שמשתמשים ב-TensorFlow ML, או פעולות, יכולים להאיץ. בעל הגישה תומך בפעולות הבאות ברמת דיוק של ציפה של 16 ביט ו-32 ביט:
ADD
AVERAGE_POOL_2D
CONCATENATION
CONV_2D
DEPTHWISE_CONV_2D v1-2
EXP
FULLY_CONNECTED
LOGICAL_AND
LOGISTIC
LSTM v2 (Basic LSTM only)
MAX_POOL_2D
MAXIMUM
MINIMUM
MUL
PAD
PRELU
RELU
RELU6
RESHAPE
RESIZE_BILINEAR v1-3
SOFTMAX
STRIDED_SLICE
SUB
TRANSPOSE_CONV
כברירת מחדל, כל הפעולות נתמכות רק בגרסה 1. הפעלת התמיכה בכימות מפעילה את הגרסאות המתאימות, למשל ADD v2.
פתרון בעיות בתמיכה ב-GPU
אם חלק מהפעולות לא נתמכות על ידי מקבל הגישה ל-GPU, ה-framework יריץ רק חלק מהתרשים ב-GPU ואת החלק הנותר במעבד. בגלל העלות הגבוהה של סנכרון המעבד (CPU) ל-GPU, מצב ביצוע מפוצל כמו זה בדרך כלל גורם לביצועים איטיים יותר מאשר כשהרשת כולה פועלת במעבד (CPU) בלבד. במקרה כזה, האפליקציה יוצרת אזהרה, למשל:
WARNING: op code #42 cannot be handled by this delegate.
אין קריאה חוזרת לכשלים מהסוג הזה, כי זה לא כשל בזמן הריצה בפועל. כשבודקים את הביצוע של המודל באמצעות מקבל הגישה ל-GPU, חשוב לקבל התראה על האזהרות האלה. מספר גבוה של האזהרות האלה יכול להצביע על כך שהמודל לא מתאים לשימוש ביותר לצורך האצת GPU, ויכול להיות שיידרש ארגון מחדש (Refactoring) של המודל.
מודלים לדוגמה
המודלים הבאים לדוגמה נועדו לנצל את האצת ה-GPU עםTensorFlow Lite, והם ניתנים לעיון ולבדיקה:
- סיווג תמונות MobileNet v1 (224x224)
- מודל לסיווג תמונות שמיועד לאפליקציות לנייד ולאפליקציות ראייה מוטמעות. (model)
- פילוח DeepLab (257x257)
- שמקצה תוויות סמנטיות כמו כלב, חתול, מכונית לכל פיקסל בתמונת הקלט. (model)
- זיהוי אובייקטים של MobileNet SSD
- מודל לסיווג תמונות שמזהה מספר אובייקטים עם תיבות תוחמות. (model)
- PoseNet להערכת התנוחה
- מודל ראייה שמעריך את התנוחה של אנשים בתמונה או בסרטון. (model)
אופטימיזציה למעבדי GPU
הטכניקות הבאות יכולות לעזור לכם לשפר את הביצועים כשמריצים מודלים בחומרת GPU באמצעות מקבל הגישה ל-GPU של TensorFlow Lite:
שינוי פעולות – פעולות מסוימות, שמבוצעות במהירות במעבד (CPU), עשויות להיות בעלות גבוהה על ה-GPU במכשירים ניידים. פעולות של עיצוב מחדש יקרות במיוחד, כולל
BATCH_TO_SPACE
,SPACE_TO_BATCH
,SPACE_TO_DEPTH
וכן הלאה. צריך לבחון היטב את השימוש בפעולות עיצוב מחדש, ולשקול אם הוא יושם רק לצורך גילוי נתונים או איטרציות מוקדמות של המודל. הסרתן יכולה לשפר משמעותית את הביצועים.ערוצי נתונים של תמונות – ב-GPU, נתוני הטנזור מחולקים ל-4 ערוצים, כך שהחישוב של טנזור עם הצורה
[B,H,W,5]
מניב ביצועים זהים ב-Tensor בצורת[B,H,W,8]
, אבל פחות משמעותית מ-[B,H,W,4]
. אם חומרת המצלמה שבה אתם משתמשים תומכת בפריימים של תמונות ב-RGBA, הזנת הקלט ב-4 הערוצים מהירה יותר בצורה משמעותית כי נמנעת מהעתקת זיכרון מ-RGB בשלוש ערוצים ל-RGBX ב-4 ערוצים.מודלים מותאמים לניידים – לקבלת הביצועים הטובים ביותר, מומלץ לאמן מחדש את המסווג באמצעות ארכיטקטורת רשת שמותאמת לניידים. אופטימיזציה של הסקת המסקנות במכשיר יכולה לצמצם משמעותית את זמן האחזור ואת צריכת החשמל, על ידי ניצול של תכונות החומרה בנייד.
תמיכה מתקדמת ב-GPU
תוכלו להשתמש בשיטות מתקדמות נוספות עם עיבוד GPU כדי לשפר את הביצועים של המודלים שלכם, כולל כימות ויצירה בהמשכיות. בקטעים הבאים נרחיב על הטכניקות האלה.
שימוש במודלים כמותיים
בקטע הזה מוסבר איך הקצאת הגישה ל-GPU מאיצה מודלים כמותיים של 8 ביט, כולל הדברים הבאים:
- מודלים שעברו הכשרה באמצעות הדרכה מבוססת-כמות
- קוונטיזציה בטווח דינמי אחרי האימון
- קוונטיזציה של מספרים שלמים מלאים אחרי האימון
כדי לשפר את הביצועים, כדאי להשתמש במודלים שיש להם גם רכיבי קלט מסוג נקודה צפה וגם פלט.
איך זה עובד?
מכיוון שהקצה העורפי של ה-GPU תומך רק בהפעלה בנקודה צפה (floating-point), אנחנו מפעילים מודלים כמותיים על ידי יצירת 'תצוגה נקודה צפה (floating-point)' של המודל המקורי. ברמה הכללית, התהליך כולל את השלבים הבאים:
כמות מסוימת של רכיבי Tensors קבועים (כמו משקולות/הטיות) מוסרת מהזיכרון פעם אחת בזיכרון ה-GPU. הפעולה הזו מתבצעת כשמקבל הגישה מופעל ב-TensorFlow Lite.
קלט ופלט לתוכנת ה-GPU, אם נעשה בהם קומנציה ב-8 ביט, הם יוסרו מהכמות וכאלה שהם מכוסים (בהתאמה) לכל מסקנות. הפעולה הזו מתבצעת במעבד (CPU) באמצעות הליבות שעברו אופטימיזציה של TensorFlow Lite.
מוסיפים סימולטורים של כמויות בין פעולות כדי לחקות התנהגות כמותית. הגישה הזו נחוצה למודלים שבהם הפעולות מצפות שההפעלות יהיו בהתאם לגבולות שנלמדו במהלך הקוונטיזציה.
למידע נוסף על הפעלת התכונה הזו באמצעות מקבל הגישה ל-GPU:
צמצום זמן האתחול באמצעות סריאליזציה
התכונה 'הענקת גישה ל-GPU' מאפשרת לטעון מקוד ליבה שעבר הידור מראש ונתוני מודל שעברו סריאליזציה ונשמרו בדיסק מהפעלות קודמות. הגישה הזו מונעת הידור מחדש ויכולה לקצר את זמן ההפעלה בשיעור של עד 90%. את השיפור הזה אפשר להשיג באמצעות החלפת מקום בכונן לחיסכון בזמן. אפשר להפעיל את התכונה הזו באמצעות כמה אפשרויות של הגדרות אישיות, כפי שמתואר בדוגמאות הבאות:
C++
TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default(); options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION; options.serialization_dir = kTmpDir; options.model_token = kModelToken; auto* delegate = TfLiteGpuDelegateV2Create(options); if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
Java
GpuDelegate delegate = new GpuDelegate( new GpuDelegate.Options().setSerializationParams( /* serializationDir= */ serializationDir, /* modelToken= */ modelToken)); Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
כשמשתמשים בתכונת העריכה הסדרתית, חשוב לוודא שהקוד תואם לכללי ההטמעה הבאים:
- שומרים את נתוני העריכה בסדרה בספרייה שאי אפשר לגשת אליה לאפליקציות אחרות. במכשירי Android, צריך להשתמש ב-
getCodeCacheDir()
שמצביע למיקום פרטי לאפליקציה הנוכחית. - אסימון הדגם חייב להיות ייחודי למכשיר לדגם הספציפי. אפשר לחשב אסימון מודל על ידי יצירת טביעת אצבע מנתוני המודל באמצעות ספריות כמו
farmhash::Fingerprint64
.