L'utilizzo di unità di elaborazione grafica (GPU) per eseguire i modelli di machine learning (ML) può migliorare notevolmente le prestazioni del modello e l'esperienza utente delle 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 applicazioni TensorFlow Lite ML può offrire i seguenti vantaggi:
- Velocità : le GPU sono progettate per un throughput elevato di carichi di lavoro estremamente paralleli. Questo design li rende adatti per reti neurali profonde, che consistono in 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à eseguita sulle CPU.
Questo documento fornisce una panoramica del supporto delle GPU in TensorFlow Lite e alcuni usi avanzati dei processori GPU. Per informazioni più specifiche sull'implementazione del supporto GPU su piattaforme specifiche, vedere le guide seguenti:
Supporto per operazioni di GPU ML
Esistono alcune limitazioni alle operazioni o operazioni di TensorFlow ML che possono essere accelerate dal delegato GPU TensorFlow Lite. Il delegato supporta le seguenti operazioni con precisione float a 16 bit e 32 bit:
-
ADD
-
AVERAGE_POOL_2D
-
CONCATENATION
-
CONV_2D
-
DEPTHWISE_CONV_2D v1-2
-
EXP
-
FULLY_CONNECTED
-
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 per la quantizzazione abilita le versioni appropriate, ad esempio ADD v2.
Risoluzione dei problemi di supporto GPU
Se alcune delle operazioni non sono supportate dal delegato GPU, il framework eseguirà solo una parte del grafico sulla GPU e la parte rimanente sulla CPU. A causa dell'alto 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 un avviso, ad esempio:
WARNING: op code #42 cannot be handled by this delegate.
Non è disponibile alcuna richiamata per gli errori di questo tipo, poiché non si tratta di un errore di runtime effettivo. Quando si verifica l'esecuzione del modello con il delegato GPU, prestare attenzione a questi avvisi. Un numero elevato di questi avvisi può indicare che il tuo modello non è adatto all'uso per l'accelerazione GPU e potrebbe richiedere il refactoring del modello.
Modelli di esempio
I seguenti modelli di esempio sono costruiti per sfruttare l'accelerazione GPU con TensorFlow Lite e sono forniti come 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, come un cane, un gatto, un'auto, a ogni pixel dell'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 sui dispositivi mobili. Le operazioni di rimodellamento sono particolarmente costose da eseguire, inclusi
BATCH_TO_SPACE
,SPACE_TO_BATCH
,SPACE_TO_DEPTH
e così via. È necessario esaminare attentamente l'uso delle operazioni di rimodellamento e considerare che potrebbe essere stato applicato solo per esplorare i dati o per le prime iterazioni del modello. La loro rimozione può migliorare notevolmente le prestazioni.Canali dei dati dell'immagine - Sulla GPU, i dati del tensore sono suddivisi in 4 canali, quindi un calcolo su un tensore con la forma
[B,H,W,5]
esegue all'incirca lo stesso su un tensore di forma[B,H,W,8]
, ma significativamente peggiore di[B,H,W,4]
. Se l'hardware della fotocamera in uso supporta i fotogrammi dell'immagine in RGBA, l'alimentazione di quell'input a 4 canali è significativamente più veloce, poiché evita una copia della memoria da RGB a 3 canali a RGBX a 4 canali.Modelli ottimizzati per dispositivi mobili : per prestazioni ottimali, dovresti considerare di riqualificare il tuo 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 avanzate aggiuntive con l'elaborazione GPU per consentire prestazioni ancora migliori per i tuoi modelli, tra cui quantizzazione e serializzazione. Le sezioni seguenti descrivono queste tecniche in modo più dettagliato.
Utilizzo di modelli quantizzati
Questa sezione spiega come il delegato GPU accelera i modelli quantizzati a 8 bit, inclusi i seguenti:
- Modelli addestrati con formazione consapevole della quantizzazione
- Quantizzazione della gamma dinamica post-allenamento
- Quantizzazione di numeri interi post-allenamento
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 dandogli una "vista 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 del programma GPU, se quantizzati a 8 bit, vengono dequantizzati e quantizzati (rispettivamente) per ciascuna inferenza. Questa operazione viene eseguita sulla CPU utilizzando i kernel ottimizzati di TensorFlow Lite.
I simulatori di quantizzazione vengono inseriti tra le operazioni per simulare il comportamento quantizzato. Questo approccio è necessario per i modelli in cui gli operatori si aspettano che le attivazioni seguano i limiti appresi durante la quantizzazione.
Per informazioni sull'abilitazione di questa funzionalità con il delegato GPU, vedere quanto segue:
Riduzione del tempo di inizializzazione con la serializzazione
La funzione di delegato GPU consente di caricare dal codice del kernel precompilato e i dati del modello serializzati e salvati su disco da esecuzioni precedenti. Questo approccio evita la ricompilazione e può ridurre i tempi 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 funzione 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, usa
getCodeCacheDir()
che punta a una posizione privata per l'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 usando librerie come
farmhash::Fingerprint64
.