Google I/O הוא עטיפה! התעדכן בהפעלות של TensorFlow. צפה בהפעלות

נציג TensorFlow Lite GPU

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

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

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

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

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

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

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

לקבלת הדרכה צעד-אחר-צעד, לצפות האצלה GPU עבור אנדרואיד וידאו.

שלב 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 עבור iOS וידאו.

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

עקוב App הדגמת 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 בדגם שלך

דְמוּי אָדָם

ישנן שתי דרכים להפעיל האצת המודל תלוי אם אתה משתמש דגם ML סטודיו אנדרואיד כריכה או מתורגמן לייט TensorFlow.

מתורגמן 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%. לקבלת הוראות כיצד ליישם בהמשכים לפרויקט שלך, לראות בהמשכי האצלת GPU .