TensorFlow Lite GPU temsilcisi

TensorFlow Lite , birkaç donanım hızlandırıcısını destekler. Bu belge, Android ve iOS'ta TensorFlow Lite temsilci API'lerini kullanarak GPU arka ucunun nasıl kullanılacağını açıklar.

GPU'lar, büyük ölçüde paralelleştirilebilir iş yükleri için yüksek aktarım hızına sahip olacak şekilde tasarlanmıştır. Bu nedenle, her biri daha küçük iş yüklerine kolayca bölünebilen ve paralel olarak yürütülebilen, tipik olarak daha düşük gecikme süresiyle sonuçlanan bazı girdi tensörleri üzerinde çalışan çok sayıda operatörden oluşan derin sinir ağları için çok uygundurlar. En iyi senaryoda, GPU üzerindeki çıkarım, daha önce mevcut olmayan gerçek zamanlı uygulamalar için artık yeterince hızlı çalışabilir.

CPU'ların aksine, GPU'lar 16 bit veya 32 bit kayan nokta sayılarıyla hesaplar ve optimum performans için niceleme gerektirmez. Temsilci, 8 bitlik nicelleştirilmiş modelleri kabul eder, ancak hesaplama kayan nokta sayılarında yapılacaktır. Ayrıntılar için gelişmiş belgelere bakın.

GPU çıkarımının bir başka avantajı da güç verimliliğidir. GPU'lar, hesaplamaları çok verimli ve optimize edilmiş bir şekilde gerçekleştirir, böylece aynı görev CPU'larda çalıştırıldığından daha az güç tüketir ve daha az ısı üretir.

Demo uygulama eğitimleri

GPU temsilcisini denemenin en kolay yolu, GPU destekli sınıflandırma demo uygulamalarımızı oluşturan aşağıdaki öğreticileri takip etmektir. GPU kodu şimdilik sadece ikili; yakında açık kaynaklı olacak. Demolarımızı nasıl çalıştıracağınızı anladıktan sonra, bunu kendi özel modellerinizde deneyebilirsiniz.

Android (Android Studio ile)

Adım adım eğitim için Android için GPU Delegesi videosunu izleyin.

Adım 1. TensorFlow kaynak kodunu klonlayın ve Android Studio'da açın

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

Adım 2. Her gece GPU AAR'ı kullanmak için app/build.gradle düzenleyin

Mevcut dependencies bloğundaki mevcut tensorflow-lite paketinin yanına tensorflow-lite-gpu paketini ekleyin.

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

Adım 3. Oluşturun ve çalıştırın

Çalıştır → 'Uygulamayı' çalıştır. Uygulamayı çalıştırdığınızda, GPU'yu etkinleştirmek için bir düğme göreceksiniz. Kuantize modelden kayan modele geçin ve ardından GPU'da çalıştırmak için GPU'ya tıklayın.

android gpu demosunu çalıştırma ve gpu'ya geçme

iOS (XCode ile)

Adım adım eğitim için iOS için GPU Delegesi videosunu izleyin.

Adım 1. Demo kaynak kodunu alın ve derlendiğinden emin olun.

iOS Demo Uygulaması eğitimimizi takip edin. Bu sizi, telefonunuzda değiştirilmemiş iOS kamera demosunun çalıştığı bir noktaya götürecektir.

Adım 2. TensorFlow Lite GPU CocoaPod'u kullanmak için Pod dosyasını değiştirin

2.3.0 sürümünden itibaren, ikili boyutu azaltmak için varsayılan olarak GPU temsilcisi bölmeden çıkarılır. Alt spesifikasyon belirterek bunları dahil edebilirsiniz. TensorFlowLiteSwift bölmesi için:

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

VEYA

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

Objective-C'yi (2.4.0 sürümünden itibaren) veya C API'sini kullanmak istiyorsanız, TensorFlowLiteObjC veya TensorFlowLitC için benzer şekilde yapabilirsiniz.

2.3.0 sürümünden önce

TensorFlow Lite 2.0.0'a kadar

GPU temsilcisini içeren bir ikili CocoaPod oluşturduk. Projeyi kullanmak üzere değiştirmek için, 'tensorflow/tensorflow/lite/examples/ios/camera/Podfile' dosyasını 'TensorFlowLite' yerine 'TensorFlowLiteGpuExperimental' bölmesini kullanacak şekilde değiştirin.


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

TensorFlow Lite 2.2.0'a kadar

TensorFlow Lite 2.1.0'dan 2.2.0'a kadar, GPU temsilcisi "TensorFlowLiteC" bölmesine dahil edilmiştir. Dile bağlı olarak `TensorFlowLiteC` ve `TensorFlowLiteSwift` arasında seçim yapabilirsiniz.

Adım 3. GPU temsilcisini etkinleştirin

GPU temsilcisini kullanacak kodu etkinleştirmek için CameraExampleViewController.h içinde TFLITE_USE_GPU_DELEGATE 0'dan 1'e değiştirmeniz gerekir.

#define TFLITE_USE_GPU_DELEGATE 1

Adım 4. Demo uygulamasını oluşturun ve çalıştırın

Önceki adımı uyguladıktan sonra uygulamayı çalıştırabilmeniz gerekir.

Adım 5. Serbest bırakma modu

4. Adımda hata ayıklama modunda çalışırken daha iyi performans elde etmek için uygun optimum Metal ayarlarına sahip bir sürüm yapısına geçmelisiniz. Özellikle, bu ayarları düzenlemek için Product > Scheme > Edit Scheme... seçeneğine gidin. Run seçin. Info sekmesinde, Build Configuration Debug'dan Release değiştirin, Debug Debug executable işaretini kaldırın.

sürüm kurma

Ardından Options sekmesine tıklayın ve GPU Frame Capture Disabled ve Metal API Validation Disabled olarak değiştirin.

metal seçenekleri ayarlama

Son olarak, 64 bit mimaride yalnızca sürüme yönelik derlemeleri seçtiğinizden emin olun. Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings altında Build Active Architecture Only > Release seçeneğini Evet olarak ayarlayın.

sürüm seçeneklerini ayarlama

GPU temsilcisini kendi modelinizde denemek

Android

Android Studio ML Model Binding veya TensorFlow Lite Interpreter kullanmanıza bağlı olarak model hızlandırmayı çağırmanın iki yolu vardır.

TensorFlow Lite Yorumlayıcı

Temsilciyi nasıl ekleyeceğinizi görmek için demoya bakın. Uygulamanızda, AAR'ı yukarıdaki gibi ekleyin, org.tensorflow.lite.gpu.GpuDelegate modülünü içe aktarın ve GPU temsilcisini yorumlayıcıya kaydetmek için addDelegate işlevini kullanın:

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)
      

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

Süratli

    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 ...
    }
      

Amaç-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'a kadar)

        #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.
```

Bu gerçek bir çalışma zamanı hatası değil, geliştiricinin ağı temsilci üzerinde çalıştırmaya çalışırken gözlemleyebileceği bir şey olduğundan, bu hata için bir geri arama sağlamadık.

Optimizasyon için ipuçları

Mobil cihazlar için optimizasyon

CPU üzerinde önemsiz olan bazı işlemler, mobil cihazlarda GPU için yüksek maliyetli olabilir. BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH vb. dahil olmak üzere yeniden şekillendirme işlemlerinin çalıştırılması özellikle pahalıdır. Yeniden şekillendirme işlemlerinin kullanımını yakından incelemelisiniz ve bunun yalnızca verileri keşfetmek veya modelinizin erken yinelemeleri için uygulanmış olabileceğini göz önünde bulundurmalısınız. Bunları kaldırmak performansı önemli ölçüde artırabilir.

GPU'da tensör verileri 4 kanala bölünür. Bu nedenle, [B,H,W,5] şeklindeki bir tensör üzerinde bir hesaplama, [B,H,W,8] şeklindeki bir tensör üzerinde yaklaşık olarak aynı performansı gösterecek, ancak [B,H,W,4] ten önemli ölçüde daha kötü olacaktır. . Bu anlamda, kamera donanımı RGBA'da görüntü çerçevelerini destekliyorsa, bir bellek kopyası (3 kanallı RGB'den 4 kanallı RGBX'e) önlenebileceğinden, bu 4 kanallı girişin beslenmesi önemli ölçüde daha hızlıdır.

En iyi performans için, sınıflandırıcıyı mobil cihazlar için optimize edilmiş bir ağ mimarisiyle yeniden eğitmeyi düşünmelisiniz. Cihaz üzerinde çıkarım için optimizasyon, mobil donanım özelliklerinden yararlanarak gecikmeyi ve güç tüketimini önemli ölçüde azaltabilir.

Serileştirme ile başlatma süresinin azaltılması

GPU temsilci özelliği, önceden derlenmiş çekirdek kodundan yükleme yapmanıza ve önceki çalıştırmalardan seri hale getirilmiş ve diske kaydedilmiş model verilerinden yüklemenize olanak tanır. Bu yaklaşım yeniden derlemeyi önler ve başlatma süresini %90'a kadar azaltır. Projenize serileştirmeyi nasıl uygulayacağınıza ilişkin talimatlar için bkz. GPU Temsilci Serileştirme .