Bantuan melindungi Great Barrier Reef dengan TensorFlow pada Kaggle Bergabung Tantangan

Delegasi GPU TensorFlow Lite

TensorFlow Lite mendukung beberapa akselerator hardware. Dokumen ini menjelaskan cara menggunakan backend GPU menggunakan API delegasi TensorFlow Lite di Android dan iOS.

GPU dirancang untuk memiliki throughput tinggi untuk beban kerja yang dapat diparalelkan secara masif. Dengan demikian, mereka sangat cocok untuk jaring saraf dalam, yang terdiri dari sejumlah besar operator, masing-masing bekerja pada beberapa tensor input yang dapat dengan mudah dibagi menjadi beban kerja yang lebih kecil dan dilakukan secara paralel, biasanya menghasilkan latensi yang lebih rendah. Dalam skenario terbaik, inferensi pada GPU sekarang dapat berjalan cukup cepat untuk aplikasi waktu nyata yang sebelumnya tidak tersedia.

Tidak seperti CPU, GPU menghitung dengan angka floating point 16-bit atau 32-bit dan tidak memerlukan kuantisasi untuk kinerja yang optimal. Delegasi tidak menerima model terkuantisasi 8-bit, tetapi perhitungan akan dilakukan dalam angka floating point. Mengacu pada dokumentasi canggih untuk rincian.

Manfaat lain dengan inferensi GPU adalah efisiensi dayanya. GPU melakukan komputasi dengan cara yang sangat efisien dan optimal, sehingga mereka mengkonsumsi lebih sedikit daya dan menghasilkan lebih sedikit panas daripada saat tugas yang sama dijalankan pada CPU.

Tutorial aplikasi demo

Cara termudah untuk mencoba delegasi GPU adalah dengan mengikuti tutorial di bawah ini, yang melalui pembuatan aplikasi demo klasifikasi kami dengan dukungan GPU. Kode GPU hanya biner untuk saat ini; itu akan segera menjadi sumber terbuka. Setelah Anda memahami cara membuat demo kami berfungsi, Anda dapat mencobanya pada model kustom Anda sendiri.

Android (dengan Android Studio)

Untuk tutorial langkah-demi-langkah, menonton GPU Delegasi untuk Android video.

Langkah 1. Kloning kode sumber TensorFlow dan buka di Android Studio

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

Langkah 2. Ubah app/build.gradle menggunakan GPU AAR malam

Tambahkan tensorflow-lite-gpu paket samping ada tensorflow-lite paket dalam yang ada dependencies blok.

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

Langkah 3. Bangun dan jalankan

Jalankan → Jalankan 'aplikasi'. Saat Anda menjalankan aplikasi, Anda akan melihat tombol untuk mengaktifkan GPU. Ubah dari model terkuantisasi ke float lalu klik GPU untuk berjalan di GPU.

menjalankan demo gpu android dan beralih ke gpu

iOS (dengan XCode)

Untuk tutorial langkah-demi-langkah, menonton GPU Delegasi untuk iOS video.

Langkah 1. Dapatkan kode sumber demo dan pastikan itu dikompilasi.

Ikuti kami iOS Demo App tutorial . Ini akan membawa Anda ke titik di mana demo kamera iOS yang tidak dimodifikasi berfungsi di ponsel Anda.

Langkah 2. Ubah Podfile untuk menggunakan TensorFlow Lite GPU CocoaPod

Dari rilis 2.3.0, secara default delegasi GPU dikeluarkan dari pod untuk mengurangi ukuran biner. Anda dapat memasukkannya dengan menentukan subspec. Untuk TensorFlowLiteSwift pod:

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

ATAU

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

Anda dapat melakukan yang sama untuk TensorFlowLiteObjC atau TensorFlowLitC jika Anda ingin menggunakan Objective-C (dari 2.4.0 rilis) atau C API.

Sebelum rilis 2.3.0

Hingga TensorFlow Lite 2.0.0

Kami telah membangun CocoaPod biner yang menyertakan delegasi GPU. Untuk mengalihkan proyek agar menggunakannya, ubah file `tensorflow/tensorflow/lite/examples/ios/camera/Podfile` untuk menggunakan pod `TensorFlowLiteGpuExperimental` alih-alih `TensorFlowLite`.


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

Hingga TensorFlow Lite 2.2.0

Dari TensorFlow Lite 2.1.0 hingga 2.2.0, delegasi GPU disertakan dalam pod `TensorFlowLiteC`. Anda dapat memilih antara `TensorFlowLiteC` dan `TensorFlowLiteSwift` tergantung pada bahasanya.

Langkah 3. Aktifkan delegasi GPU

Untuk mengaktifkan kode yang akan menggunakan delegasi GPU, Anda akan perlu mengubah TFLITE_USE_GPU_DELEGATE dari 0 ke 1 di CameraExampleViewController.h .

#define TFLITE_USE_GPU_DELEGATE 1

Langkah 4. Bangun dan jalankan aplikasi demo

Setelah mengikuti langkah sebelumnya, Anda seharusnya dapat menjalankan aplikasi.

Langkah 5. Mode rilis

Sementara di Langkah 4 Anda menjalankan dalam mode debug, untuk mendapatkan kinerja yang lebih baik, Anda harus mengubah ke build rilis dengan pengaturan Metal optimal yang sesuai. Secara khusus, Untuk mengedit pengaturan ini pergi ke Product > Scheme > Edit Scheme... . Pilih Run . Pada Info tab, perubahan Build Configuration , dari Debug ke Release , hapus centang Debug executable .

mengatur rilis

Kemudian klik Options tab dan perubahan GPU Frame Capture untuk Disabled dan Metal API Validation ke Disabled .

menyiapkan opsi logam

Terakhir pastikan untuk memilih Release-only builds on 64-bit architecture. Di bawah Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings mengatur Build Active Architecture Only > Release ke Ya.

menyiapkan opsi rilis

Mencoba delegasi GPU pada model Anda sendiri

Android

Ada dua cara untuk memohon percepatan model yang tergantung pada apakah Anda menggunakan Android Studio ML Model Binding atau TensorFlow Lite Interpreter.

Penerjemah TensorFlow Lite

Lihat demo untuk melihat cara menambahkan delegasi. Dalam aplikasi Anda, tambahkan AAR seperti di atas, impor org.tensorflow.lite.gpu.GpuDelegate modul, dan menggunakan addDelegate fungsi untuk mendaftarkan delegasi GPU untuk penerjemah:

Kotlin

    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)
      

Jawa

    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

Cepat

    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 (Sampai 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.
```

Kami tidak menyediakan panggilan balik untuk kegagalan ini, karena ini bukan kegagalan run-time yang sebenarnya, tetapi sesuatu yang dapat diamati oleh pengembang saat mencoba menjalankan jaringan pada delegasi.

Kiat untuk pengoptimalan

Mengoptimalkan untuk perangkat seluler

Beberapa operasi yang sepele pada CPU mungkin memiliki biaya tinggi untuk GPU pada perangkat seluler. Operasi membentuk kembali sangat mahal untuk menjalankan, termasuk BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH , dan sebagainya. Anda harus memeriksa dengan cermat penggunaan operasi pembentukan kembali, dan mempertimbangkan bahwa mungkin telah diterapkan hanya untuk menjelajahi data atau untuk iterasi awal model Anda. Menghapusnya dapat meningkatkan kinerja secara signifikan.

Pada GPU, data tensor dipotong menjadi 4 saluran. Dengan demikian, perhitungan pada tensor bentuk [B,H,W,5] akan melakukan hampir sama pada tensor bentuk [B,H,W,8] tetapi secara signifikan lebih buruk dari [B,H,W,4] . Dalam hal ini, jika perangkat keras kamera mendukung bingkai gambar dalam RGBA, mengumpankan input 4 saluran tersebut secara signifikan lebih cepat karena salinan memori (dari RGB 3 saluran ke RGBX 4 saluran) dapat dihindari.

Untuk kinerja terbaik, Anda harus mempertimbangkan untuk melatih ulang pengklasifikasi dengan arsitektur jaringan yang dioptimalkan untuk seluler. Pengoptimalan untuk inferensi pada perangkat dapat secara dramatis mengurangi latensi dan konsumsi daya dengan memanfaatkan fitur perangkat keras seluler.

Mengurangi waktu inisialisasi dengan serialisasi

Fitur delegasi GPU memungkinkan Anda memuat dari kode kernel yang telah dikompilasi sebelumnya dan data model yang diserialisasikan dan disimpan di disk dari proses sebelumnya. Pendekatan ini menghindari kompilasi ulang dan mengurangi waktu startup hingga 90%. Untuk petunjuk tentang cara untuk menerapkan serialisasi untuk proyek Anda, lihat GPU Delegasi serialisasi .