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 all'ML. LiteRT consente l'utilizzo di GPU e altri processori specializzati tramite un driver hardware chiamato delegati. L'attivazione dell'utilizzo delle GPU con le applicazioni LiteRT ML può offrire i seguenti vantaggi:
- Velocità: le GPU sono progettate per un'elevata velocità effettiva di workload massicciamente paralleli. Questo design li rende adatti alle reti neurali profonde, che sono costituite da un numero enorme di operatori, ognuno dei quali opera su tensori di input che possono essere elaborati in parallelo, il che in genere si traduce in una latenza inferiore. Nello scenario migliore, l'esecuzione del modello su una GPU potrebbe essere abbastanza veloce da consentire applicazioni in tempo reale che prima non erano possibili.
- Efficienza energetica: le GPU eseguono i 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 LiteRT e alcuni utilizzi avanzati dei processori GPU. Per informazioni più specifiche sull'implementazione del supporto delle GPU su piattaforme specifiche, consulta le seguenti guide:
Supporto delle operazioni di ML con GPU
Esistono alcune limitazioni alle operazioni di machine learning di TensorFlow, o ops, che possono essere accelerate dal delegato GPU LiteRT. Il delegato supporta le seguenti operazioni con precisione in virgola mobile a 16 e 32 bit:
ADDAVERAGE_POOL_2DCONCATENATIONCONV_2DDEPTHWISE_CONV_2D v1-2EXPFULLY_CONNECTEDLOGICAL_ANDLOGISTICLSTM v2 (Basic LSTM only)MAX_POOL_2DMAXIMUMMINIMUMMULPADPRELURELURELU6RESHAPERESIZE_BILINEAR v1-3SOFTMAXSTRIDED_SLICESUBTRANSPOSE_CONV
Per impostazione predefinita, tutte le operazioni sono supportate solo nella versione 1. L'attivazione del supporto alla quantizzazione abilita le versioni appropriate, ad esempio ADD v2.
Risoluzione dei problemi relativi al supporto GPU
Se alcune 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'elevato costo della sincronizzazione CPU/GPU, una modalità di esecuzione suddivisa come questa spesso comporta 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 è previsto alcun callback per gli errori di questo tipo, poiché non si tratta di un errore di runtime effettivo. Quando testi l'esecuzione del modello con il delegato GPU, devi prestare attenzione a questi avvisi. Un numero elevato di questi avvisi può indicare che il tuo modello non è il più adatto per l'utilizzo per l'accelerazione GPU e potrebbe richiedere il refactoring del modello.
Modelli di esempio
I seguenti modelli di esempio sono creati per sfruttare l'accelerazione GPU con LiteRT e vengono forniti a scopo di riferimento e test:
- Classificazione delle immagini MobileNet v1 (224x224)
- Un modello di classificazione delle immagini progettato per applicazioni di visione
basate su dispositivi mobili e incorporati.
(model)
* Segmentazione DeepLab (257x257)
- modello di segmentazione delle immagini che assegna etichette semantiche, come
cane, gatto, auto, a ogni pixel dell'immagine di input.
(modello)
* Rilevamento di oggetti MobileNet SSD
- Un modello di classificazione delle immagini che rileva più oggetti con
riquadri di delimitazione.
(modello)
* PoseNet per la stima della postura
- Un modello di visione che stima le pose delle persone in un'immagine o in un video. (modello)
- Un modello di classificazione delle immagini che rileva più oggetti con
riquadri di delimitazione.
(modello)
* PoseNet per la stima della postura
- modello di segmentazione delle immagini che assegna etichette semantiche, come
cane, gatto, auto, a ogni pixel dell'immagine di input.
(modello)
* Rilevamento di oggetti MobileNet SSD
- Un modello di classificazione delle immagini progettato per applicazioni di visione
basate su dispositivi mobili e incorporati.
(model)
* Segmentazione DeepLab (257x257)
Ottimizzazione per le GPU
Le seguenti tecniche possono aiutarti a ottenere prestazioni migliori durante l'esecuzione di modelli su hardware GPU utilizzando il delegato GPU LiteRT:
Operazioni di rimodellamento: alcune operazioni rapide su una CPU potrebbero avere un costo elevato per la GPU sui dispositivi mobili. Le operazioni di rimodellamento sono particolarmente costose da eseguire, tra cui
BATCH_TO_SPACE,SPACE_TO_BATCH,SPACE_TO_DEPTHe così via. Esamina attentamente l'utilizzo delle operazioni di rimodellamento e tieni presente che potrebbero essere state applicate solo per l'esplorazione dei dati o per le prime iterazioni del modello. La loro rimozione può migliorare significativamente il rendimento.Canali di dati immagine: sulla GPU, i dati tensoriali vengono suddivisi in 4 canali, quindi un calcolo su un tensore con forma
[B,H,W,5]viene eseguito in modo simile a un tensore di forma[B,H,W,8], ma in modo significativamente peggiore rispetto a[B,H,W,4]. Se l'hardware della videocamera che utilizzi supporta i frame delle immagini in RGBA, l'inserimento di questo input a 4 canali è molto più veloce, in quanto evita una copia della memoria da RGB a 3 canali a RGBX a 4 canali.Modelli ottimizzati per il mobile: per ottenere il massimo rendimento, ti consigliamo di eseguire di nuovo l'addestramento del classificatore con un'architettura di rete ottimizzata per il mobile. L'ottimizzazione per l'inferenza sul dispositivo può ridurre drasticamente la latenza e il consumo energetico sfruttando le funzionalità hardware del dispositivo mobile.
Supporto GPU avanzato
Puoi utilizzare tecniche avanzate aggiuntive con l'elaborazione della GPU per ottenere 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 in che modo il delegato GPU accelera i modelli quantizzati a 8 bit, tra cui:
- Modelli addestrati con l'addestramento consapevole della quantizzazione
- Quantizzazione dell'intervallo dinamico post-addestramento
- Quantizzazione full-integer post-addestramento
Per ottimizzare le prestazioni, utilizza modelli con tensori di input e output in virgola mobile.
Come funziona?
Poiché il backend GPU supporta solo l'esecuzione in virgola mobile, eseguiamo modelli quantizzati fornendo una "visualizzazione in virgola mobile" del modello originale. A livello generale, ciò comporta i seguenti passaggi:
I tensori costanti (come pesi/bias) vengono dequantizzati una volta nella memoria della GPU. Questa operazione viene eseguita quando il delegato è abilitato per LiteRT.
Gli input e gli output del programma GPU, se quantizzati a 8 bit, vengono dequantizzati e quantizzati (rispettivamente) per ogni inferenza. Questa operazione viene eseguita sulla CPU utilizzando i kernel ottimizzati di LiteRT.
I simulatori di quantizzazione vengono inseriti tra le operazioni per simulare il comportamento quantizzato. Questo approccio è necessario per i modelli in cui le operazioni prevedono che le attivazioni seguano i limiti appresi durante la quantizzazione.
Per informazioni sull'attivazione di questa funzionalità con il delegato GPU, consulta quanto segue:
- Utilizzo di modelli quantizzati con GPU su Android
- Utilizzo di modelli quantizzati con GPU su iOS
Riduzione del tempo di inizializzazione con la serializzazione
La funzionalità di delega GPU consente di caricare il codice del kernel precompilato e i 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 con un risparmio di tempo. Puoi attivare questa funzionalità con alcune opzioni di configurazione, come mostrato negli esempi di codice seguenti:
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);
Quando utilizzi la funzionalità di serializzazione, assicurati che il codice sia conforme a queste regole di implementazione:
- Archivia i dati di serializzazione in una directory non accessibile ad altre
app. Sui dispositivi Android, utilizza
getCodeCacheDir()che punta a una posizione privata per l'applicazione corrente. - Il token modello deve essere univoco per il dispositivo per il modello specifico. Puoi
calcolare un token del modello generando un'impronta dai dati del modello utilizzando
librerie come
farmhash::Fingerprint64.