משתמשים עם הרשאה ל-GPU ב-LiteRT

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

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

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

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

יש כמה מגבלות לפעולות של למידת מכונה של TensorFlow, או תפעול, מואצת על ידי נציג של LiteRT 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. הפעלת הכימות support מפעילה את הגרסאות המתאימות, לדוגמה, ADD גרסה 2.

פתרון בעיות בתמיכה ב-GPU

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

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

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

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

המודלים הבאים לדוגמה מיועדים לנצל את האצת ה-GPU LiteRT ומסופקים לעיון ולבדיקה:

אופטימיזציה למעבדי GPU

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

  • עיצוב מחדש של פעולות – פעולות מסוימות שמבוצעות במהירות במעבד עשויות לכלול עלות גבוהה ל-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) וגם את img_tensors.

איך זה עובד?

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

  • עוברים לקטעים של טנזטורים קבועים (כמו משקולות/הטיות) הם מוסרים מהכמות. זיכרון GPU. הפעולה הזו מתרחשת כשאפשרות הענקת הגישה מופעלת עבור LiteRT.

  • קלט ופלט לתוכנת ה-GPU, אם נעשה בהם קומנציה של 8 ביט מנומקים מהכמות ובהתאמה (בהתאמה) לכל הסקת מסקנות. הפעולה הזו נעשה במעבד באמצעות הליבות (kernel) שעברו אופטימיזציה של LiteRT.

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

לקבלת מידע על הפעלת התכונה הזו באמצעות מקבל הגישה ל-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