Wenn Sie GPUs (Graphics Processing Units) zum Ausführen Ihrer Machine-Learning-Modelle (ML) verwenden, kann dies die Leistung Ihres Modells und die Nutzerfreundlichkeit Ihrer ML-fähigen Anwendungen erheblich verbessern. LiteRT ermöglicht die Verwendung von GPUs und anderen spezialisierten Prozessoren über einen Hardwaretreiber namens Delegates. Die Verwendung von GPUs mit Ihren LiteRT ML-Anwendungen bietet folgende Vorteile:
- Geschwindigkeit: GPUs sind für den hohen Durchsatz von extrem parallelen Arbeitslasten konzipiert. Dieses Design macht sie gut geeignet für Deep Neural Networks, die aus einer großen Anzahl von Operatoren bestehen, die jeweils an Eingabetensoren arbeiten, die parallel verarbeitet werden können, was in der Regel zu einer geringeren Latenz führt. Im besten Fall ist die Ausführung Ihres Modells auf einer GPU schnell genug, um Echtzeitanwendungen zu ermöglichen, die zuvor nicht möglich waren.
- Energieeffizienz: GPUs führen ML-Berechnungen sehr effizient und optimiert aus. Dabei wird in der Regel weniger Strom verbraucht und weniger Wärme erzeugt als bei derselben Aufgabe, die auf CPUs ausgeführt wird.
Dieses Dokument bietet einen Überblick über die GPU-Unterstützung in LiteRT und einige erweiterte Anwendungsfälle für GPU-Prozessoren. Weitere Informationen zur Implementierung der GPU-Unterstützung auf bestimmten Plattformen finden Sie in den folgenden Anleitungen:
Unterstützung von GPU-ML-Vorgängen
Es gibt einige Einschränkungen, welche TensorFlow-ML-Operationen oder Ops durch den LiteRT-GPU-Delegate beschleunigt werden können. Der Delegate unterstützt die folgenden Vorgänge mit 16-Bit- und 32-Bit-Gleitkommazahlen:
ADDAVERAGE_POOL_2DCONCATENATIONCONV_2DDEPTHWISE_CONV_2D v1-2EXPFULLY_CONNECTEDLOGICAL_ANDLOGISTICLSTM v2 (Basic LSTM only)MAX_POOL_2DMAXIMUMMINIMUMMULPADPRELURELURELU6RESHAPERESIZE_BILINEAR v1-3SOFTMAXSTRIDED_SLICESUBTRANSPOSE_CONV
Standardmäßig werden alle Vorgänge nur in Version 1 unterstützt. Wenn Sie die Quantisierungsunterstützung aktivieren, werden die entsprechenden Versionen aktiviert, z. B. ADDv2.
Fehlerbehebung bei der GPU-Unterstützung
Wenn einige der Vorgänge nicht vom GPU-Delegate unterstützt werden, führt das Framework nur einen Teil des Diagramms auf der GPU und den restlichen Teil auf der CPU aus. Aufgrund der hohen Kosten für die CPU/GPU-Synchronisierung führt ein solcher geteilter Ausführungsmodus oft zu einer langsameren Leistung als wenn das gesamte Netzwerk nur auf der CPU ausgeführt wird. In diesem Fall gibt die Anwendung eine Warnung aus, z. B.:
WARNING: op code #42 cannot be handled by this delegate.
Für Fehler dieses Typs gibt es keinen Callback, da es sich nicht um einen tatsächlichen Laufzeitfehler handelt. Achten Sie beim Testen der Ausführung Ihres Modells mit dem GPU-Delegate auf diese Warnungen. Eine hohe Anzahl dieser Warnungen kann darauf hindeuten, dass Ihr Modell nicht optimal für die GPU-Beschleunigung geeignet ist und möglicherweise umgestaltet werden muss.
Beispielmodelle
Die folgenden Beispielmodelle sind für die GPU-Beschleunigung mit LiteRT optimiert und dienen als Referenz und zum Testen:
- MobileNet v1 (224 × 224) – Bildklassifizierung
- Ein Bildklassifizierungsmodell, das für mobile und eingebettete Vision-Anwendungen entwickelt wurde.
(model)
* DeepLab-Segmentierung (257 × 257)
- Bildsegmentierungsmodell, das jedem Pixel im Eingabebild semantische Labels wie „Hund“, „Katze“ oder „Auto“ zuweist.
(Modell)
* MobileNet SSD-Objekterkennung
- Ein Bildklassifikationsmodell, das mehrere Objekte mit Begrenzungsrahmen erkennt.
(Modell)
* PoseNet für die Schätzung der Körperhaltung
- Ein Vision-Modell, das die Posen von Personen in Bildern oder Videos schätzt. (Modell)
- Ein Bildklassifikationsmodell, das mehrere Objekte mit Begrenzungsrahmen erkennt.
(Modell)
* PoseNet für die Schätzung der Körperhaltung
- Bildsegmentierungsmodell, das jedem Pixel im Eingabebild semantische Labels wie „Hund“, „Katze“ oder „Auto“ zuweist.
(Modell)
* MobileNet SSD-Objekterkennung
- Ein Bildklassifizierungsmodell, das für mobile und eingebettete Vision-Anwendungen entwickelt wurde.
(model)
* DeepLab-Segmentierung (257 × 257)
Für GPUs optimieren
Mit den folgenden Techniken können Sie die Leistung beim Ausführen von Modellen auf GPU-Hardware mit dem LiteRT-GPU-Delegate verbessern:
Vorgänge zum Umformen: Einige Vorgänge, die auf einer CPU schnell ausgeführt werden, können auf der GPU von Mobilgeräten sehr aufwendig sein. Vorgänge zum Umformen sind besonders rechenintensiv, z. B.
BATCH_TO_SPACE,SPACE_TO_BATCHundSPACE_TO_DEPTH. Sie sollten die Verwendung von „reshape“-Vorgängen genau prüfen und berücksichtigen, dass sie möglicherweise nur zum Untersuchen von Daten oder für frühe Iterationen Ihres Modells angewendet wurden. Wenn Sie sie entfernen, kann sich die Leistung erheblich verbessern.Bilddatenkanäle: Auf der GPU werden Tensordaten in 4‑Kanäle unterteilt. Eine Berechnung für einen Tensor mit der Form
[B,H,W,5]ist daher in etwa gleich wie für einen Tensor mit der Form[B,H,W,8], aber deutlich schlechter als für[B,H,W,4]. Wenn die von Ihnen verwendete Kamerahardware Bild-Frames im RGBA-Format unterstützt, ist die Verarbeitung dieses 4-Kanal-Eingabesignals deutlich schneller, da ein Speicherkopiervorgang von 3-Kanal-RGB zu 4-Kanal-RGBX vermieden wird.Für Mobilgeräte optimierte Modelle: Für eine optimale Leistung sollten Sie den Klassifikator mit einer für Mobilgeräte optimierten Netzwerkarchitektur neu trainieren. Die Optimierung für die Inferenz auf dem Gerät kann die Latenz und den Stromverbrauch durch die Nutzung von Funktionen der mobilen Hardware erheblich reduzieren.
Erweiterte GPU-Unterstützung
Sie können zusätzliche, erweiterte Techniken mit GPU-Verarbeitung verwenden, um die Leistung Ihrer Modelle noch weiter zu verbessern, z. B. Quantisierung und Serialisierung. In den folgenden Abschnitten werden diese Techniken näher beschrieben.
Quantisierte Modelle verwenden
In diesem Abschnitt wird erläutert, wie der GPU-Delegate die Beschleunigung von 8-Bit-quantisierten Modellen ermöglicht, einschließlich der folgenden:
- Mit quantisierungsbewusstem Training trainierte Modelle
- Quantisierung des dynamischen Bereichs nach dem Training
- Vollständige Ganzzahlquantisierung nach dem Training
Um die Leistung zu optimieren, sollten Sie Modelle verwenden, die sowohl Gleitkomma-Eingabe- als auch ‑Ausgabetensoren haben.
So funktioniert's
Da das GPU-Backend nur die Ausführung von Gleitkommazahlen unterstützt, führen wir quantisierte Modelle aus, indem wir ihm eine „Gleitkommaansicht“ des ursprünglichen Modells geben. Auf übergeordneter Ebene umfasst dies die folgenden Schritte:
Konstante Tensoren (z. B. Gewichte/Bias) werden einmal in den GPU-Speicher dequantisiert. Dieser Vorgang erfolgt, wenn der Delegat für LiteRT aktiviert ist.
Ein- und Ausgaben des GPU-Programms werden, sofern sie 8-Bit-quantisiert sind, für jeden Inferenzvorgang dequantisiert bzw. quantisiert. Dieser Vorgang wird auf der CPU mit den optimierten LiteRT-Kernels ausgeführt.
Quantisierungssimulatoren werden zwischen Operationen eingefügt, um das Verhalten nach der Quantisierung zu simulieren. Dieser Ansatz ist für Modelle erforderlich, bei denen die Operationen erwarten, dass die Aktivierungen den während der Quantisierung gelernten Grenzen folgen.
Informationen zum Aktivieren dieser Funktion mit dem GPU-Delegate finden Sie unter:
- Quantisierte Modelle mit GPU auf Android-Geräten verwenden
- Quantisierte Modelle mit GPU auf iOS-Geräten verwenden
Initialisierungszeit durch Serialisierung verkürzen
Mit der GPU-Delegatfunktion können Sie vorkompilierten Kernelcode und Modelldaten laden, die aus vorherigen Ausführungen serialisiert und auf der Festplatte gespeichert wurden. So wird eine erneute Kompilierung vermieden und die Startzeit kann um bis zu 90 % verkürzt werden. Diese Verbesserung wird durch den Austausch von Speicherplatz gegen Zeitersparnis erreicht. Sie können diese Funktion mit einigen Konfigurationsoptionen aktivieren, wie in den folgenden Codebeispielen gezeigt:
C++
TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default(); options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION; options.serialization_dir = kTmpDir; options.model_token = kModelToken; auto* delegate = TfLiteGpuDelegateV2Create(options); if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
Java
GpuDelegate delegate = new GpuDelegate( new GpuDelegate.Options().setSerializationParams( /* serializationDir= */ serializationDir, /* modelToken= */ modelToken)); Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
Achten Sie bei der Verwendung der Serialisierungsfunktion darauf, dass Ihr Code diesen Implementierungsregeln entspricht:
- Speichern Sie die Serialisierungsdaten in einem Verzeichnis, auf das andere Apps nicht zugreifen können. Verwenden Sie auf Android-Geräten
getCodeCacheDir(), das auf einen Speicherort verweist, der für die aktuelle Anwendung privat ist. - Das Modell-Token muss für das jeweilige Modell auf dem Gerät eindeutig sein. Sie können ein Modell-Token berechnen, indem Sie mit Bibliotheken wie
farmhash::Fingerprint64einen Fingerabdruck aus den Modelldaten generieren.