Delegati TensorFlow Lite

introduzione

I delegati consentono l'accelerazione hardware dei modelli TensorFlow Lite sfruttando gli acceleratori sul dispositivo come la GPU e il processore di segnale digitale (DSP) .

Per impostazione predefinita, TensorFlow Lite utilizza kernel CPU ottimizzati per il set di istruzioni ARM Neon . Tuttavia, la CPU è un processore multiuso che non è necessariamente ottimizzato per l'aritmetica pesante tipica dei modelli di Machine Learning (ad esempio, la matematica delle matrici coinvolta nella convoluzione e nei livelli densi).

D'altra parte, la maggior parte dei telefoni cellulari moderni contiene chip che gestiscono meglio queste operazioni pesanti. Il loro utilizzo per le operazioni di rete neurale offre enormi vantaggi in termini di latenza ed efficienza energetica. Ad esempio, le GPU possono fornire una velocità di latenza fino a 5 volte superiore, mentre il Qualcomm® Hexagon DSP ha dimostrato di ridurre il consumo energetico fino al 75% nei nostri esperimenti.

Ciascuno di questi acceleratori ha API associate che consentono calcoli personalizzati, come OpenCL o OpenGL ES per GPU mobili e Qualcomm® Hexagon SDK per DSP. In genere, dovresti scrivere molto codice personalizzato per eseguire una rete neurale attraverso queste interfacce. Le cose si complicano ancora di più se si considera che ogni acceleratore ha i suoi pro e contro e non può eseguire tutte le operazioni in una rete neurale. L'API Delegate di TensorFlow Lite risolve questo problema fungendo da ponte tra il runtime TFLite e queste API di livello inferiore.

runtime con i delegati

La scelta di un delegato

TensorFlow Lite supporta più delegati, ognuno dei quali è ottimizzato per determinate piattaforme e particolari tipi di modelli. Di solito, ci saranno più delegati applicabili al tuo caso d'uso, a seconda di due criteri principali: la piattaforma (Android o iOS?) di destinazione e il tipo di modello (virgola mobile o quantizzato?) che stai cercando di accelerare .

Delegati per piattaforma

Multipiattaforma (Android e iOS)

  • Delegato GPU : il delegato GPU può essere utilizzato sia su Android che su iOS. È ottimizzato per eseguire modelli basati su float a 32 bit e 16 bit in cui è disponibile una GPU. Supporta anche modelli quantizzati a 8 bit e fornisce prestazioni della GPU alla pari con le loro versioni float. Per i dettagli sul delegato GPU, vedere TensorFlow Lite su GPU . Per esercitazioni dettagliate sull'utilizzo del delegato GPU con Android e iOS, vedere Tutorial del delegato GPU TensorFlow Lite .

Androide

  • Delegato NNAPI per dispositivi Android più recenti : il delegato NNAPI può essere utilizzato per accelerare i modelli su dispositivi Android con GPU, DSP e/o NPU disponibili. È disponibile in Android 8.1 (API 27+) o versioni successive. Per una panoramica del delegato NNAPI, istruzioni dettagliate e best practice, consulta TensorFlow Lite Delegato NNAPI .
  • Delegato Hexagon per dispositivi Android meno recenti: il delegato Hexagon può essere utilizzato per accelerare i modelli su dispositivi Android con Qualcomm Hexagon DSP. Può essere utilizzato su dispositivi che eseguono versioni precedenti di Android che non supportano NNAPI. Per maggiori dettagli, vedere delegato TensorFlow Lite Hexagon .

iOS

  • Delegato Core ML per iPhone e iPad più recenti: per iPhone e iPad più recenti in cui è disponibile Neural Engine, puoi utilizzare il delegato Core ML per accelerare l'inferenza per modelli a virgola mobile a 32 o 16 bit. Neural Engine è disponibile per dispositivi mobili Apple con SoC A12 o superiore. Per una panoramica del delegato Core ML e istruzioni dettagliate, vedere TensorFlow Lite Core ML delegato .

Delegati per tipo di modello

Ogni acceleratore è progettato tenendo conto di una certa larghezza di bit di dati. Se fornisci un modello a virgola mobile a un delegato che supporta solo operazioni quantizzate a 8 bit (come Hexagon delegate ), rifiuterà tutte le sue operazioni e il modello verrà eseguito interamente sulla CPU. Per evitare tali sorprese, la tabella seguente fornisce una panoramica del supporto dei delegati in base al tipo di modello:

Tipo di modello GPU NNAPI Esagono CoreML
In virgola mobile (32 bit) No
Quantizzazione float16 post-allenamento No No
Quantizzazione della gamma dinamica post-allenamento No No
Quantizzazione di interi post-allenamento No
Formazione consapevole della quantizzazione No

Convalida delle prestazioni

Le informazioni in questa sezione fungono da linea guida approssimativa per selezionare i delegati che potrebbero migliorare la tua candidatura. Tuttavia, è importante notare che ogni delegato ha un insieme predefinito di operazioni che supporta e può eseguire in modo diverso a seconda del modello e del dispositivo; ad esempio, il delegato NNAPI può scegliere di utilizzare l'Edge-TPU di Google su un telefono Pixel mentre utilizza un DSP su un altro dispositivo. Pertanto, in genere si consiglia di eseguire alcuni benchmarking per valutare l'utilità di un delegato per le proprie esigenze. Questo aiuta anche a giustificare l'aumento della dimensione binaria associato all'associazione di un delegato al runtime TensorFlow Lite.

TensorFlow Lite dispone di estesi strumenti di valutazione delle prestazioni e dell'accuratezza che possono consentire agli sviluppatori di essere sicuri nell'utilizzo dei delegati nella loro applicazione. Questi strumenti sono discussi nella sezione successiva.

Strumenti per la valutazione

Latenza e impronta di memoria

Lo strumento di benchmark di TensorFlow Lite può essere utilizzato con parametri adeguati per stimare le prestazioni del modello, tra cui latenza media dell'inferenza, sovraccarico di inizializzazione, footprint di memoria, ecc. Questo strumento supporta più flag per determinare la migliore configurazione del delegato per il modello. Ad esempio, --gpu_backend=gl può essere specificato con --use_gpu per misurare l'esecuzione della GPU con OpenGL. L'elenco completo dei parametri dei delegati supportati è definito nella documentazione dettagliata .

Ecco un esempio eseguito per un modello quantizzato con GPU tramite adb :

adb shell /data/local/tmp/benchmark_model \
  --graph=/data/local/tmp/mobilenet_v1_224_quant.tflite \
  --use_gpu=true

Puoi scaricare la versione predefinita di questo strumento per Android, architettura ARM a 64 bit qui ( maggiori dettagli ).

Precisione e correttezza

I delegati di solito eseguono calcoli con una precisione diversa rispetto alle loro controparti CPU. Di conseguenza, esiste un compromesso di precisione (di solito minore) associato all'utilizzo di un delegato per l'accelerazione hardware. Nota che questo non è sempre vero; ad esempio, poiché la GPU utilizza la precisione in virgola mobile per eseguire modelli quantizzati, potrebbe esserci un leggero miglioramento della precisione (ad esempio, miglioramento <1% dei primi 5 nella classificazione delle immagini ILSVRC).

TensorFlow Lite dispone di due tipi di strumenti per misurare la precisione con cui un delegato si comporta per un determinato modello: Basato su attività e Agnostico su attività . Tutti gli strumenti descritti in questa sezione supportano i parametri di delega avanzati utilizzati dallo strumento di benchmarking della sezione precedente. Si noti che le sottosezioni seguenti si concentrano sulla valutazione del delegato (il delegato ha le stesse prestazioni della CPU?) piuttosto che sulla valutazione del modello (il modello stesso è adatto all'attività?).

Valutazione basata sui compiti

TensorFlow Lite dispone di strumenti per valutare la correttezza su due attività basate su immagini:

I binari predefiniti di questi strumenti (Android, architettura ARM a 64 bit), insieme alla documentazione sono disponibili qui:

L'esempio seguente mostra la valutazione della classificazione delle immagini con NNAPI utilizzando Edge-TPU di Google su un Pixel 4:

adb shell /data/local/tmp/run_eval \
  --model_file=/data/local/tmp/mobilenet_quant_v1_224.tflite \
  --ground_truth_images_path=/data/local/tmp/ilsvrc_images \
  --ground_truth_labels=/data/local/tmp/ilsvrc_validation_labels.txt \
  --model_output_labels=/data/local/tmp/model_output_labels.txt \
  --output_file_path=/data/local/tmp/accuracy_output.txt \
  --num_images=0 # Run on all images. \
  --use_nnapi=true \
  --nnapi_accelerator_name=google-edgetpu

L'output previsto è un elenco di metriche Top-K da 1 a 10:

Top-1 Accuracy: 0.733333
Top-2 Accuracy: 0.826667
Top-3 Accuracy: 0.856667
Top-4 Accuracy: 0.87
Top-5 Accuracy: 0.89
Top-6 Accuracy: 0.903333
Top-7 Accuracy: 0.906667
Top-8 Accuracy: 0.913333
Top-9 Accuracy: 0.92
Top-10 Accuracy: 0.923333

Valutazione agnostica

Per le attività in cui non esiste uno strumento di valutazione sul dispositivo stabilito o se si stanno sperimentando modelli personalizzati, TensorFlow Lite dispone dello strumento Inference Diff . (Android, binario dell'architettura binaria ARM a 64 bit qui )

Inference Diff confronta l'esecuzione di TensorFlow Lite (in termini di latenza e deviazione del valore di output) in due impostazioni:

  • Inferenza CPU a thread singolo
  • Inferenza definita dall'utente - definita da questi parametri

Per fare ciò, lo strumento genera dati gaussiani casuali e li passa attraverso due interpreti TFLite: uno che esegue kernel CPU a thread singolo e l'altro parametrizzato dagli argomenti dell'utente.

Misura la latenza di entrambi, nonché la differenza assoluta tra i tensori di output di ciascun interprete, in base all'elemento.

Per un modello con un singolo tensore di output, l'output potrebbe essere simile a questo:

Num evaluation runs: 50
Reference run latency: avg=84364.2(us), std_dev=12525(us)
Test run latency: avg=7281.64(us), std_dev=2089(us)
OutputDiff[0]: avg_error=1.96277e-05, std_dev=6.95767e-06

Ciò significa che per il tensore di uscita all'indice 0 , gli elementi dell'uscita della CPU differiscono dall'uscita del delegato di una media di 1.96e-05 .

Si noti che l'interpretazione di questi numeri richiede una conoscenza più approfondita del modello e del significato di ciascun tensore di output. Se si tratta di una semplice regressione che determina una sorta di punteggio o incorporamento, la differenza dovrebbe essere bassa (altrimenti è un errore con il delegato). Tuttavia, output come quello della "classe di rilevamento" dei modelli SSD sono un po' più difficili da interpretare. Ad esempio, potrebbe mostrare una differenza utilizzando questo strumento, ma ciò potrebbe non significare qualcosa di veramente sbagliato nel delegato: considera due classi (false): "TV (ID: 10)", "Monitor (ID:20)" - If un delegato è leggermente fuori dalla verità d'oro e mostra il monitor invece della TV, la differenza di uscita per questo tensore potrebbe essere qualcosa di alto come 20-10 = 10.