L'utilizzo di unità di elaborazione grafica (GPU) per eseguire i tuoi modelli di machine learning (ML) può migliorare notevolmente le prestazioni del tuo modello e l'esperienza utente delle tue applicazioni abilitate per ML. TensorFlow Lite consente l'uso di GPU e altri processori specializzati tramite driver hardware chiamati delegati . L'abilitazione dell'uso delle GPU con le tue applicazioni TensorFlow Lite ML può offrire i seguenti vantaggi:
- Velocità : le GPU sono progettate per un throughput elevato di carichi di lavoro massicciamente paralleli. Questo design li rende particolarmente adatti per le reti neurali profonde, costituite da un numero enorme di operatori, ognuno dei quali lavora su tensori di input che possono essere elaborati in parallelo, il che in genere si traduce in una latenza inferiore. Nella migliore delle ipotesi, l'esecuzione del modello su una GPU potrebbe essere abbastanza veloce da abilitare applicazioni in tempo reale che in precedenza non erano possibili.
- Efficienza energetica : le GPU eseguono calcoli ML in modo molto efficiente e ottimizzato, in genere consumando meno energia e generando meno calore rispetto alla stessa attività in esecuzione sulle CPU.
Questo documento fornisce una panoramica del supporto delle GPU in TensorFlow Lite e alcuni usi avanzati per i processori GPU. Per informazioni più specifiche sull'implementazione del supporto GPU su piattaforme specifiche, consulta le seguenti guide:
Supporto per operazioni GPU ML
Esistono alcune limitazioni a quali operazioni TensorFlow ML, o ops , possono essere accelerate dal delegato GPU TensorFlow Lite. Il delegato supporta le seguenti operazioni con precisione float a 16 e 32 bit:
-
ADD
-
AVERAGE_POOL_2D
-
CONCATENATION
-
CONV_2D
-
DEPTHWISE_CONV_2D v1-2
-
EXP
-
FULLY_CONNECTED
-
LOGICAL_AND
-
LOGISTIC
-
LSTM v2 (Basic LSTM only)
-
MAX_POOL_2D
-
MAXIMUM
-
MINIMUM
-
MUL
-
PAD
-
PRELU
-
RELU
-
RELU6
-
RESHAPE
-
RESIZE_BILINEAR v1-3
-
SOFTMAX
-
STRIDED_SLICE
-
SUB
-
TRANSPOSE_CONV
Per impostazione predefinita, tutte le operazioni sono supportate solo nella versione 1. L'abilitazione del supporto di quantizzazione abilita le versioni appropriate, ad esempio ADD v2.
Risoluzione dei problemi relativi al supporto della GPU
Se alcune delle operazioni non sono supportate dal delegato GPU, il framework eseguirà solo una parte del grafico sulla GPU e la parte restante sulla CPU. A causa dell'elevato costo della sincronizzazione CPU/GPU, una modalità di esecuzione divisa come questa spesso si traduce in prestazioni più lente rispetto a quando l'intera rete viene eseguita solo sulla CPU. In questo caso, l'applicazione genera avvisi, come:
WARNING: op code #42 cannot be handled by this delegate.
Non esiste alcuna richiamata per errori di questo tipo, poiché non si tratta di un vero errore di runtime. Quando si verifica l'esecuzione del modello con il delegato GPU, è necessario prestare attenzione a questi avvisi. Un numero elevato di questi avvisi può indicare che il modello non è la soluzione migliore per l'utilizzo dell'accelerazione GPU e potrebbe richiedere il refactoring del modello.
Esempi di modelli
I seguenti modelli di esempio sono creati per sfruttare l'accelerazione GPU con TensorFlow Lite e vengono forniti per riferimento e test:
- Classificazione delle immagini MobileNet v1 (224x224) : un modello di classificazione delle immagini progettato per applicazioni di visione mobili e integrate. ( modello )
- Segmentazione DeepLab (257x257) : modello di segmentazione dell'immagine che assegna etichette semantiche, ad esempio cane, gatto, auto, a ogni pixel nell'immagine di input. ( modello )
- Rilevamento di oggetti SSD MobileNet : un modello di classificazione delle immagini che rileva più oggetti con riquadri di delimitazione. ( modello )
- PoseNet per la stima della posa - Un modello di visione che stima le pose delle persone in immagini o video. ( modello )
Ottimizzazione per GPU
Le seguenti tecniche possono aiutarti a ottenere prestazioni migliori durante l'esecuzione di modelli su hardware GPU utilizzando il delegato GPU TensorFlow Lite:
Operazioni di rimodellamento : alcune operazioni rapide su una CPU possono avere un costo elevato per la GPU su dispositivi mobili. Le operazioni di risagoma sono particolarmente costose da eseguire, incluse
BATCH_TO_SPACE
,SPACE_TO_BATCH
,SPACE_TO_DEPTH
e così via. Dovresti esaminare attentamente l'uso delle operazioni di risagoma e considerare che potrebbero essere state applicate solo per esplorare i dati o per le prime iterazioni del tuo modello. La loro rimozione può migliorare significativamente le prestazioni.Canali dati immagine : sulla GPU, i dati del tensore vengono suddivisi in 4 canali, quindi un calcolo su un tensore con la forma
[B,H,W,5]
si comporta all'incirca allo stesso modo su un tensore di forma[B,H,W,8]
, ma significativamente peggiore di[B,H,W,4]
. Se l'hardware della fotocamera che stai utilizzando supporta i fotogrammi dell'immagine in RGBA, l'alimentazione dell'input a 4 canali è significativamente più veloce, poiché evita una copia di memoria da RGB a 3 canali a RGBX a 4 canali.Modelli ottimizzati per dispositivi mobili : per prestazioni ottimali, dovresti prendere in considerazione la possibilità di riaddestrare il classificatore con un'architettura di rete ottimizzata per dispositivi mobili. L'ottimizzazione per l'inferenza sul dispositivo può ridurre drasticamente la latenza e il consumo energetico sfruttando le funzionalità dell'hardware mobile.
Supporto GPU avanzato
Puoi utilizzare tecniche aggiuntive e avanzate con l'elaborazione GPU per consentire prestazioni ancora migliori per i tuoi modelli, incluse la quantizzazione e la serializzazione. Le sezioni seguenti descrivono queste tecniche in maggiore dettaglio.
Utilizzo di modelli quantizzati
Questa sezione spiega come il delegato GPU accelera i modelli quantizzati a 8 bit, inclusi i seguenti:
- Modelli addestrati con addestramento sensibile alla quantizzazione
- Quantizzazione della gamma dinamica post-addestramento
- Quantizzazione full-integer post-addestramento
Per ottimizzare le prestazioni, utilizzare modelli con tensori di input e output a virgola mobile.
Come funziona?
Poiché il backend della GPU supporta solo l'esecuzione in virgola mobile, eseguiamo modelli quantizzati fornendo una "visualizzazione in virgola mobile" del modello originale. Ad alto livello, ciò comporta i seguenti passaggi:
I tensori costanti (come pesi/distorsioni) vengono dequantizzati una volta nella memoria della GPU. Questa operazione si verifica quando il delegato è abilitato per TensorFlow Lite.
Gli input e gli output al programma GPU, se quantizzati a 8 bit, sono dequantizzati e quantizzati (rispettivamente) per ogni inferenza. Questa operazione viene eseguita sulla CPU utilizzando i kernel ottimizzati di TensorFlow Lite.
I simulatori di quantizzazione vengono inseriti tra le operazioni per imitare il comportamento quantizzato. Questo approccio è necessario per i modelli in cui le operazioni si aspettano che le attivazioni seguano i limiti appresi durante la quantizzazione.
Per informazioni sull'abilitazione di questa funzione con il delegato GPU, vedere quanto segue:
Riduzione del tempo di inizializzazione con la serializzazione
La funzione delega GPU consente di caricare dal codice del kernel precompilato e dai dati del modello serializzati e salvati su disco dalle esecuzioni precedenti. Questo approccio evita la ricompilazione e può ridurre il tempo di avvio fino al 90%. Questo miglioramento si ottiene scambiando spazio su disco per risparmiare tempo. Puoi abilitare questa funzione con alcune opzioni di configurazione, come mostrato nei seguenti esempi di codice:
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;
Giava
GpuDelegate delegate = new GpuDelegate( new GpuDelegate.Options().setSerializationParams( /* serializationDir= */ serializationDir, /* modelToken= */ modelToken)); Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
Quando utilizzi la funzionalità di serializzazione, assicurati che il tuo codice sia conforme a queste regole di implementazione:
- Archivia i dati di serializzazione in una directory non accessibile ad altre app. Sui dispositivi Android, utilizzare
getCodeCacheDir()
che punta a una posizione privata dell'applicazione corrente. - Il token del modello deve essere univoco per il dispositivo per il modello specifico. Puoi calcolare un token del modello generando un'impronta digitale dai dati del modello utilizzando librerie come
farmhash::Fingerprint64
.