Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

TensorFlow Lite GPU-Delegat

TensorFlow Lite unterstützt mehrere Hardwarebeschleuniger. In diesem Dokument wird beschrieben, wie Sie das GPU-Backend mithilfe der TensorFlow Lite-Delegaten-APIs unter Android und iOS verwenden.

GPUs sind für einen hohen Durchsatz bei massiv parallelisierbaren Workloads ausgelegt. Daher eignen sie sich gut für tiefe neuronale Netze, die aus einer großen Anzahl von Operatoren bestehen, die jeweils an einem oder mehreren Eingangstensoren arbeiten, die leicht in kleinere Arbeitslasten unterteilt und parallel ausgeführt werden können, was typischerweise zu einer geringeren Latenz führt. Im besten Fall kann die Inferenz auf der GPU jetzt schnell genug für zuvor nicht verfügbare Echtzeitanwendungen ausgeführt werden.

Im Gegensatz zu CPUs berechnen GPUs mit 16-Bit- oder 32-Bit-Gleitkommazahlen und erfordern für eine optimale Leistung keine Quantisierung.

Ein weiterer Vorteil der GPU-Inferenz ist die Energieeffizienz. GPUs führen die Berechnungen sehr effizient und optimiert durch, sodass sie weniger Strom verbrauchen und weniger Wärme erzeugen als wenn dieselbe Aufgabe auf CPUs ausgeführt wird.

Demo-App-Tutorials

Der einfachste Weg, den GPU-Delegierten auszuprobieren, besteht darin, die folgenden Tutorials zu befolgen, in denen unsere Klassifizierungs-Demo-Anwendungen mit GPU-Unterstützung erstellt werden. Der GPU-Code ist derzeit nur binär. es wird bald Open-Source sein. Sobald Sie verstanden haben, wie unsere Demos funktionieren, können Sie dies an Ihren eigenen benutzerdefinierten Modellen ausprobieren.

Android (mit Android Studio)

Eine schrittweise Anleitung finden Sie im Video zum GPU-Delegierten für Android .

Schritt 1. Klonen Sie den TensorFlow-Quellcode und öffnen Sie ihn in Android Studio

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

Schritt 2. Bearbeiten Sie app/build.gradle , um den nächtlichen GPU-AAR zu verwenden

Fügen Sie das tensorflow-lite-gpu Paket neben dem vorhandenen tensorflow-lite Paket im vorhandenen dependencies .

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

Schritt 3. Erstellen und ausführen

Ausführen → 'App' ausführen. Wenn Sie die Anwendung ausführen, wird eine Schaltfläche zum Aktivieren der GPU angezeigt. Wechseln Sie von einem quantisierten zu einem Float-Modell und klicken Sie dann auf GPU, um es auf der GPU auszuführen.

Laufen Android GPU Demo und wechseln Sie zu GPU

iOS (mit XCode)

Sehen Sie sich das GPU Delegate für iOS- Video an, um eine schrittweise Anleitung zu erhalten.

Schritt 1. Holen Sie sich den Demo-Quellcode und stellen Sie sicher, dass er kompiliert wird.

Folgen Sie unserem iOS Demo App Tutorial . Dies bringt Sie zu einem Punkt, an dem die unveränderte iOS-Kamera-Demo auf Ihrem Telefon funktioniert.

Schritt 2. Ändern Sie die Poddatei, um den TensorFlow Lite GPU CocoaPod zu verwenden

Bis TensorFlow Lite 2.0.0 haben wir einen binären CocoaPod erstellt, der den GPU-Delegaten enthält. Um das Projekt auf die Verwendung umzustellen, ändern Sie die Datei "tensorflow / tensorflow / lite / examples / ios / camera / Podfile", um den Pod "TensorFlowLiteGpuExperimental" anstelle von "TensorFlowLite" zu verwenden. `` `Ziel 'YourProjectName' # pod 'TensorFlowLite', '1.12.0' pod 'TensorFlowLiteGpuExperimental'` `

Ab TensorFlow Lite 2.1.0 ist der GPU-Delegat im TensorFlowLiteC Pod enthalten. Sie können je nach Sprache zwischen TensorFlowLiteC und TensorFlowLiteSwift wählen.

Für die nächtliche Version und die kommende Version 2.3.0 wird der GPU-Delegat standardmäßig aus dem Pod ausgeschlossen, um die Binärgröße zu verringern. Sie können sie einschließen, indem Sie eine Unterspezifikation angeben. Für TensorFlowLiteSwift Pod:

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

ODER

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

Sie können dies auch für TensorFlowLiteC tun, wenn Sie die C-API verwenden möchten.

Schritt 3. Aktivieren Sie den GPU-Delegaten

Um den Code zu aktivieren, der den GPU-Delegaten verwendet, müssen Sie TFLITE_USE_GPU_DELEGATE in TFLITE_USE_GPU_DELEGATE von 0 auf 1 CameraExampleViewController.h .

#define TFLITE_USE_GPU_DELEGATE 1

Schritt 4. Erstellen Sie die Demo-App und führen Sie sie aus

Nachdem Sie den vorherigen Schritt ausgeführt haben, sollten Sie die App ausführen können.

Schritt 5. Freigabemodus

Während Sie in Schritt 4 im Debug-Modus ausgeführt wurden, sollten Sie zu einem Release-Build mit den entsprechenden optimalen Metal-Einstellungen wechseln, um eine bessere Leistung zu erzielen. Um diese Einstellungen zu bearbeiten, gehen Sie insbesondere zu Product > Scheme > Edit Scheme... Wählen Sie Run . Ändern Sie auf der Registerkarte " Info Option " Build Configuration von " Debug in " Release und deaktivieren Sie die Option " Debug executable .

Release einrichten

Klicken Sie dann auf die Registerkarte Options und ändern Sie GPU Frame Capture in Disabled und Metal API Validation in Disabled .

Einrichten von Metalloptionen

Stellen Sie schließlich sicher, dass Sie Nur-Release-Builds auf 64-Bit-Architektur auswählen. Unter Project navigator -> tflite_camera_example -> PROJECT -> tflite_camera_example -> Build Settings setzen Sie Build Active Architecture Only > Release auf Yes.

Freigabeoptionen einrichten

Versuchen Sie den GPU-Delegaten auf Ihrem eigenen Modell

Android

Sehen Sie sich die Demo an, um zu sehen, wie Sie den Delegaten hinzufügen. org.tensorflow.lite.gpu.GpuDelegate in Ihrer Anwendung den AAR wie oben hinzu, importieren org.tensorflow.lite.gpu.GpuDelegate Modul addDelegate und registrieren Sie den GPU-Delegaten mit der Funktion addDelegate beim Interpreter:

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

Schnell

Initialisieren Sie den TensorFlow Lite-Interpreter mit dem GPU-Delegaten.

import TensorFlowLite

// Load model ...

let delegate = MetalDelegate()

if let interpreter = try Interpreter(modelPath: modelPath,
                                     delegates: [delegate]) {
  // Run inference ...
}

Ziel c

Interpreter::ModifyGraphWithDelegate in Ihren Anwendungscode den GPU-Delegatenkopf ein und rufen Sie die Funktion Interpreter::ModifyGraphWithDelegate auf, um den GPU-Delegaten beim Interpreter zu registrieren:

#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);

Unterstützte Modelle und Operationen

Mit der Veröffentlichung des GPU-Delegaten haben wir eine Handvoll Modelle hinzugefügt, die im Backend ausgeführt werden können:

Eine vollständige Liste der unterstützten Operationen finden Sie in der erweiterten Dokumentation .

Nicht unterstützte Modelle und Operationen

Wenn einige der Operationen vom GPU-Delegaten nicht unterstützt werden, führt das Framework nur einen Teil des Diagramms auf der GPU und den verbleibenden Teil auf der CPU aus. Aufgrund der hohen Kosten für die CPU / GPU-Synchronisation führt ein geteilter Ausführungsmodus wie dieser häufig zu einer langsameren Leistung als wenn das gesamte Netzwerk nur auf der CPU ausgeführt wird. In diesem Fall erhält der Benutzer eine Warnung wie:

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

Wir haben keinen Rückruf für diesen Fehler bereitgestellt, da dies kein echter Laufzeitfehler ist, sondern etwas, das der Entwickler beobachten kann, wenn er versucht, das Netzwerk auf dem Delegaten zum Laufen zu bringen.

Tipps zur Optimierung

Einige Operationen, die auf der CPU trivial sind, können hohe Kosten für die GPU verursachen. Eine Klasse einer solchen Operation sind verschiedene Formen von BATCH_TO_SPACE , einschließlich BATCH_TO_SPACE , SPACE_TO_BATCH , SPACE_TO_DEPTH usw. Wenn diese Operationen nur aus logischen Gründen des Netzwerkarchitekten in das Netzwerk eingefügt werden, lohnt es sich, sie aus Gründen der Leistung zu entfernen.

Auf der GPU werden Tensordaten in 4 Kanäle aufgeteilt. Somit wird eine Berechnung auf einem Tensor der Form [B,H,W,5] ungefähr gleich auf einem Tensor der Form [B,H,W,8] jedoch signifikant schlechter als [B,H,W,4] .

In diesem Sinne kann, wenn die Kamerahardware Bilderrahmen in RGBA unterstützt, das Zuführen dieses 4-Kanal-Eingangs erheblich schneller erfolgen, da eine Speicherkopie (von 3-Kanal-RGB zu 4-Kanal-RGBX) vermieden werden kann.

Zögern Sie nicht, Ihren Klassifikator mit einer für Mobilgeräte optimierten Netzwerkarchitektur neu zu trainieren, um eine optimale Leistung zu erzielen. Dies ist ein wesentlicher Teil der Optimierung für die Inferenz auf dem Gerät.