נציג TensorFlow Lite GPU

TensorFlow Lite תומך במספר מאיצי חומרה. מסמך זה מתאר כיצד להשתמש ב-GPU backend באמצעות ממשקי API של נציג TensorFlow Lite ב-Android ו-iOS.

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

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

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

הדרכות לאפליקציה להדגמה

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

אנדרואיד (עם Android Studio)

למדריך שלב אחר שלב, צפה בסרטון ה- GPU Delegate לאנדרואיד .

שלב 1. שכבו את קוד המקור של TensorFlow ופתחו אותו ב-Android Studio

git clone https://github.com/tensorflow/tensorflow

שלב 2. ערוך את app/build.gradle כדי להשתמש ב-AAR GPU לילי

הוסף את tensorflow-lite-gpu לצד חבילת tensorflow-lite הקיימת בבלוק dependencies הקיים.

dependencies {
    ...
    implementation 'org.tensorflow:tensorflow-lite:2.3.0'
    implementation 'org.tensorflow:tensorflow-lite-gpu:2.3.0'
}

שלב 3. בנה והפעל

הפעל ← הפעל 'אפליקציה'. כאשר תפעיל את האפליקציה תראה כפתור להפעלת ה-GPU. שנה ממודל קוונטי למודל צף ולאחר מכן לחץ על GPU כדי להפעיל על ה-GPU.

הפעלת הדגמה של אנדרואיד gpu ועבור ל-gpu

iOS (עם XCode)

למדריך שלב אחר שלב, צפה בסרטון ה- GPU Delegate עבור iOS .

שלב 1. קבל את קוד המקור של ההדגמה וודא שהוא מתחבר.

עקוב אחר המדריך שלנו לאפליקציית הדגמה ל-iOS. זה יביא אותך לנקודה שבה הדגמת מצלמת iOS ללא שינוי עובדת על הטלפון שלך.

שלב 2. שנה את ה-Podfile לשימוש ב- TensorFlow Lite GPU CocoaPod

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

pod 'TensorFlowLiteSwift/Metal', '~> 0.0.1-nightly',

אוֹ

pod 'TensorFlowLiteSwift', '~> 0.0.1-nightly', :subspecs => ['Metal']

אתה יכול לעשות באופן דומה עבור TensorFlowLiteObjC או TensorFlowLitC אם אתה רוצה להשתמש ב-Objective-C (מגרסה 2.4.0) או ב-C API.

לפני שחרור 2.3.0

עד TensorFlow Lite 2.0.0

בנינו CocoaPod בינארי הכולל את נציג ה-GPU. כדי להחליף את הפרוייקט לשימוש בו, שנה את הקובץ `tensorflow/tensorflow/lite/examples/ios/camera/Podfile` כך שישתמש בפוד `TensorFlowLiteGpuExperimental` במקום `TensorFlowLite`.


    target 'YourProjectName'
      # pod 'TensorFlowLite', '1.12.0'
      pod 'TensorFlowLiteGpuExperimental'
    

עד TensorFlow Lite 2.2.0

מ-TensorFlow Lite 2.1.0 עד 2.2.0, נציג GPU כלול בפוד 'TensorFlowLiteC'. אתה יכול לבחור בין `TensorFlowLiteC` לבין `TensorFlowLiteSwift` בהתאם לשפה.

שלב 3. הפעל את נציג ה-GPU

כדי להפעיל את הקוד שישתמש בנציג ה-GPU, תצטרך לשנות את TFLITE_USE_GPU_DELEGATE מ-0 ל-1 ב- CameraExampleViewController.h .

#define TFLITE_USE_GPU_DELEGATE 1

שלב 4. בנה והפעל את אפליקציית ההדגמה

לאחר ביצוע השלב הקודם, אתה אמור להיות מסוגל להפעיל את האפליקציה.

שלב 5. מצב שחרור

בעוד שבשלב 4 רצתם במצב ניפוי באגים, כדי לקבל ביצועים טובים יותר, עליכם לשנות לגרסה גרסה עם הגדרות Metal האופטימליות המתאימות. בפרט, כדי לערוך הגדרות אלו עבור אל Product > Scheme > Edit Scheme... . בחר Run . בכרטיסייה Info , שנה את Build Configuration , מ- Debug ל- Release , בטל את הסימון של Debug executable .

הגדרת שחרור

לאחר מכן לחץ על הכרטיסייה Options ושנה GPU Frame Capture ל- Disabled ו- Metal API Validation ל- Disabled .

הגדרת אפשרויות מתכת

לבסוף, הקפד לבחור ב-Release-Only builds על ארכיטקטורת 64-bit. תחת Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings הגדר Build Active Architecture Only > Release ל-כן.

הגדרת אפשרויות שחרור

נסה את נציג ה-GPU בדגם משלך

דְמוּי אָדָם

ישנן שתי דרכים להפעיל האצת מודל, תלוי אם אתה משתמש ב- Android Studio ML Model Binding או TensorFlow Lite Interpreter.

מתורגמן TensorFlow Lite

עיין בהדגמה כדי לראות כיצד להוסיף את הנציג. ביישום שלך, הוסף את ה-AAR כמתואר לעיל, ייבא את מודול org.tensorflow.lite.gpu.GpuDelegate והשתמש בפונקציה addDelegate כדי לרשום את נציג ה-GPU למתורגמן:

קוטלין

    import org.tensorflow.lite.Interpreter
    import org.tensorflow.lite.gpu.CompatibilityList
    import org.tensorflow.lite.gpu.GpuDelegate

    val compatList = CompatibilityList()

    val options = Interpreter.Options().apply{
        if(compatList.isDelegateSupportedOnThisDevice){
            // if the device has a supported GPU, add the GPU delegate
            val delegateOptions = compatList.bestOptionsForThisDevice
            this.addDelegate(GpuDelegate(delegateOptions))
        } else {
            // if the GPU is not supported, run on 4 threads
            this.setNumThreads(4)
        }
    }

    val interpreter = Interpreter(model, options)

    // Run inference
    writeToInput(input)
    interpreter.run(input, output)
    readFromOutput(output)
      

Java

    import org.tensorflow.lite.Interpreter;
    import org.tensorflow.lite.gpu.CompatibilityList;
    import org.tensorflow.lite.gpu.GpuDelegate;

    // Initialize interpreter with GPU delegate
    Interpreter.Options options = new Interpreter.Options();
    CompatibilityList compatList = CompatibilityList();

    if(compatList.isDelegateSupportedOnThisDevice()){
        // if the device has a supported GPU, add the GPU delegate
        GpuDelegate.Options delegateOptions = compatList.getBestOptionsForThisDevice();
        GpuDelegate gpuDelegate = new GpuDelegate(delegateOptions);
        options.addDelegate(gpuDelegate);
    } else {
        // if the GPU is not supported, run on 4 threads
        options.setNumThreads(4);
    }

    Interpreter interpreter = new Interpreter(model, options);

    // Run inference
    writeToInput(input);
    interpreter.run(input, output);
    readFromOutput(output);
      

iOS

מָהִיר

    import TensorFlowLite

    // Load model ...

    // Initialize TensorFlow Lite interpreter with the GPU delegate.
    let delegate = MetalDelegate()
    if let interpreter = try Interpreter(modelPath: modelPath,
                                         delegates: [delegate]) {
      // Run inference ...
    }
      

Objective-C

    // Import module when using CocoaPods with module support
    @import TFLTensorFlowLite;

    // Or import following headers manually
    #import "tensorflow/lite/objc/apis/TFLMetalDelegate.h"
    #import "tensorflow/lite/objc/apis/TFLTensorFlowLite.h"

    // Initialize GPU delegate
    TFLMetalDelegate* metalDelegate = [[TFLMetalDelegate alloc] init];

    // Initialize interpreter with model path and GPU delegate
    TFLInterpreterOptions* options = [[TFLInterpreterOptions alloc] init];
    NSError* error = nil;
    TFLInterpreter* interpreter = [[TFLInterpreter alloc]
                                    initWithModelPath:modelPath
                                              options:options
                                            delegates:@[ metalDelegate ]
                                                error:&error];
    if (error != nil) { /* Error handling... */ }

    if (![interpreter allocateTensorsWithError:&error]) { /* Error handling... */ }
    if (error != nil) { /* Error handling... */ }

    // Run inference ...

        ```
          

C (עד 2.3.0)

        #include "tensorflow/lite/c/c_api.h"
        #include "tensorflow/lite/delegates/gpu/metal_delegate.h"

        // Initialize model
        TfLiteModel* model = TfLiteModelCreateFromFile(model_path);

        // Initialize interpreter with GPU delegate
        TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
        TfLiteDelegate* delegate = TFLGPUDelegateCreate(nil);  // default config
        TfLiteInterpreterOptionsAddDelegate(options, metal_delegate);
        TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
        TfLiteInterpreterOptionsDelete(options);

        TfLiteInterpreterAllocateTensors(interpreter);

        NSMutableData *input_data = [NSMutableData dataWithLength:input_size * sizeof(float)];
        NSMutableData *output_data = [NSMutableData dataWithLength:output_size * sizeof(float)];
        TfLiteTensor* input = TfLiteInterpreterGetInputTensor(interpreter, 0);
        const TfLiteTensor* output = TfLiteInterpreterGetOutputTensor(interpreter, 0);

        // Run inference
        TfLiteTensorCopyFromBuffer(input, inputData.bytes, inputData.length);
        TfLiteInterpreterInvoke(interpreter);
        TfLiteTensorCopyToBuffer(output, outputData.mutableBytes, outputData.length);

        // Clean up
        TfLiteInterpreterDelete(interpreter);
        TFLGpuDelegateDelete(metal_delegate);
        TfLiteModelDelete(model);
          

## Supported Models and Ops

With the release of the GPU delegate, we included a handful of models that can
be run on the backend:

*   [MobileNet v1 (224x224) image classification](https://ai.googleblog.com/2017/06/mobilenets-open-source-models-for.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobilenet_v1_1.0_224.tflite)
    <br /><i>(image classification model designed for mobile and embedded based vision applications)</i>
*   [DeepLab segmentation (257x257)](https://ai.googleblog.com/2018/03/semantic-image-segmentation-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/deeplabv3_257_mv_gpu.tflite)
    <br /><i>(image segmentation model that assigns semantic labels (e.g., dog, cat, car) to every pixel in the input image)</i>
*   [MobileNet SSD object detection](https://ai.googleblog.com/2018/07/accelerated-training-and-inference-with.html) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/mobile_ssd_v2_float_coco.tflite)
    <br /><i>(image classification model that detects multiple objects with bounding boxes)</i>
*   [PoseNet for pose estimation](https://github.com/tensorflow/tfjs-models/tree/master/posenet) [[download]](https://storage.googleapis.com/download.tensorflow.org/models/tflite/gpu/multi_person_mobilenet_v1_075_float.tflite)
    <br /><i>(vision model that estimates the poses of a person(s) in image or video)</i>

To see a full list of supported ops, please see the
[advanced documentation](gpu_advanced).

## Non-supported models and ops

If some of the ops are not supported by the GPU delegate, the framework will
only run a part of the graph on the GPU and the remaining part on the CPU. Due
to the high cost of CPU/GPU synchronization, a split execution mode like this
will often result in slower performance than when the whole network is run on
the CPU alone. In this case, the user will get a warning like:

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

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

טיפים לאופטימיזציה

אופטימיזציה עבור מכשירים ניידים

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

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

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

צמצום זמן האתחול בעזרת סדרה

תכונת ה-GPU Delegate מאפשרת לטעון מקוד ליבה שהורכב מראש ונתוני מודל שנקבעו בסידרה ונשמרו בדיסק מהרצות קודמות. גישה זו מונעת קומפילציה מחדש ומפחיתה את זמן האתחול בעד 90%. להנחיות כיצד להחיל סדרה על הפרויקט שלך, ראה גרפיקה Delegate Serialization .