בעלי גישה ל-GPU ב-TensorFlow Lite

השימוש ביחידות עיבוד גרפיות (GPU) להפעלת מודלים של למידת מכונה (ML) יכול לשפר משמעותית את ביצועי המודל ואת חוויית המשתמש באפליקציות שתומכות ב-ML. TensorFlow Lite מאפשר להשתמש במעבדי GPU ובמעבדים מיוחדים אחרים באמצעות מנהלי התקן של חומרה שנקראים נציגים. הפעלת השימוש ב-GPU באפליקציות TensorFlow Lite ML יכולה לספק את היתרונות הבאים:

  • מהירות – יחידות GPU מותאמות לתפוקה גבוהה של עומסי עבודה מקבילים מאוד. בזכות העיצוב הזה הם מתאימים במיוחד לרשתות נוירונים עמוקות, שכוללות מספר גדול של אופרטורים, שכל אחד מהם עובד על גופי קלט שניתן לעבד במקביל, מה שמוביל בדרך כלל לזמן אחזור קצר יותר. בתרחיש הטוב ביותר, הפעלת המודל ב-GPU עשויה לפעול מהר מספיק כדי להפעיל אפליקציות בזמן אמת שלא היו אפשריות קודם לכן.
  • יעילות בצריכת חשמל – יחידות GPU מבצעות חישובי למידת מכונה (ML) באופן יעיל ומשופר, בדרך כלל צורכות פחות חשמל ומפיקות פחות חום מאשר אותה משימה שפועלת במעבדים.

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

תמיכה בפעולות GPU ML

יש כמה מגבלות על הפעולות ש-TensorFlow Lite GPU יכול להאיץ, או פעולות, על ידי נציג של TensorFlow Lite GPU. בעל הגישה תומך בפעולות הבאות ברמת צף של 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). בגלל העלות הגבוהה של סנכרון בין המעבד (CPU) לבין ה-GPU, מצב ביצוע מפוצל כזה בדרך כלל מוביל לביצועים איטיים יותר מאשר כאשר כל הרשת פועלת על המעבד (CPU) בלבד. במקרה כזה, האפליקציה יוצרת אזהרה, למשל:

WARNING: op code #42 cannot be handled by this delegate.

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

מודלים לדוגמה

הדוגמאות הבאות מיועדות לנצל את ההאצה של ה-GPU באמצעות TensorFlow Lite, וניתנות לעיון ולבדיקה:

אופטימיזציה ל-GPU

אפשר להיעזר בשיטות הבאות כדי לשפר את הביצועים כשמפעילים מודלים בחומרת GPU באמצעות נציג של TensorFlow Lite GPU:

  • ביצוע מחדש של פעולות – פעולות מסוימות שמבוצעות במהירות במעבד (CPU) עשויות להיות בעלות גבוהה ל-GPU במכשירים ניידים. פעולות שינוי גודל יקרות במיוחד, כולל BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH וכן הלאה. יש לבחון בקפידה את השימוש בפעולות שינוי צורה, ולשקול שייתכן שהשתמשתם רק לצורך בחינת נתונים או באיטרציות מוקדמות של המודל. הסרתן יכולה לשפר משמעותית את הביצועים.

  • ערוצי נתונים של תמונות – ב-GPU, נתוני tensor פרוסים ל-4 ערוצים, ולכן חישוב של טנזור בצורה [B,H,W,5] פועל בערך באותו אופן על טנזור בצורה [B,H,W,8], אבל גרוע משמעותית מ-[B,H,W,4]. אם חומרת המצלמה שבה אתם משתמשים תומכת בפריימים של תמונות ב-RGBA, ההזנה של הקלט בן 4 הערוצים מהירה יותר משמעותית, כי הוא חוסך העתקת זיכרון מ-RGB ב-3 ערוצים ל-RGBX ב-4 ערוצים.

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

תמיכה מתקדמת ב-GPU

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

שימוש במודלים קוונטיים

בקטע הזה מוסבר איך להעניק גישה ל-GPU מאיצים מודלים קוונטיים ב-8 ביט, כולל:

כדי לבצע אופטימיזציה של הביצועים, צריך להשתמש במודלים שיש בהם גם גורמי קלט בנקודה צפה (floating-point) וגם טנזורי פלט.

איך זה עובד?

מכיוון שהקצה העורפי של ה-GPU תומך רק בביצוע נקודה צפה (floating-point), אנחנו מריצים מודלים מכניים על ידי הענקת 'תצוגת נקודה צפה' של המודל המקורי. ברמה גבוהה, זה כולל את השלבים הבאים:

  • ערכי tensor קבועים (כמו משקולות או הטיות) מבוטלים כשהם עוברים לזיכרון ה-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.