Delegati TensorFlow Lite

introduzione

I delegati abilitano 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 complessa tipica dei modelli di machine learning (ad esempio, la matematica delle matrici coinvolta nella convoluzione e negli strati densi).

D'altra parte, la maggior parte dei telefoni cellulari moderni contiene chip che sono in grado di gestire meglio queste operazioni pesanti. Utilizzarli 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 , mentre il DSP Qualcomm® Hexagon ha dimostrato di ridurre il consumo energetico fino al 75% nei nostri esperimenti.

A ciascuno di questi acceleratori sono associate API che consentono calcoli personalizzati, come OpenCL o OpenGL ES per GPU mobile e Qualcomm® Hexagon SDK per DSP. In genere, dovresti scrivere molto codice personalizzato per eseguire una rete neurale attraverso queste interfacce. Le cose diventano ancora più complicate 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

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?) a cui ti rivolgi e il tipo di modello (a 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 e 16 bit in cui è disponibile una GPU. Supporta anche modelli quantizzati a 8 bit e fornisce prestazioni GPU alla pari con le versioni float. Per dettagli sul delegato GPU, consulta TensorFlow Lite su GPU . Per tutorial passo passo sull'utilizzo del delegato GPU con Android e iOS, consulta Tutorial sul 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 Delegato NNAPI TensorFlow Lite .
  • Delegato Hexagon per dispositivi Android meno recenti : il delegato Hexagon può essere utilizzato per accelerare i modelli sui dispositivi Android con Qualcomm Hexagon DSP. Può essere utilizzato su dispositivi che eseguono versioni precedenti di Android che non supportano NNAPI. Per ulteriori dettagli, consulta Delegato TensorFlow Lite Hexagon .

iOS

  • Delegato Core ML per iPhone e iPad più recenti : per gli 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 sui dispositivi mobili Apple con SoC A12 o superiore. Per una panoramica del delegato Core ML e istruzioni dettagliate, consulta Delegato TensorFlow Lite Core ML .

Delegati per tipo di modello

Ogni acceleratore è progettato tenendo presente una determinata larghezza di bit dei dati. Se fornisci un modello a virgola mobile a un delegato che supporta solo operazioni quantizzate a 8 bit (come il delegato Hexagon ), 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
Virgola mobile (32 bit) NO
Quantizzazione float16 post-allenamento NO NO
Quantizzazione della gamma dinamica post-allenamento NO NO
Quantizzazione intera post-addestramento NO
Formazione consapevole della quantizzazione NO

Convalida delle prestazioni

Le informazioni contenute in questa sezione fungono da linee guida approssimative per selezionare i delegati che potrebbero migliorare la tua candidatura. Tuttavia, è importante notare che ciascun delegato dispone di un insieme predefinito di operazioni supportate e può essere eseguito in modo diverso a seconda del modello e del dispositivo; ad esempio, il delegato NNAPI può scegliere di utilizzare Edge-TPU di Google su un telefono Pixel mentre utilizza un DSP su un altro dispositivo. Pertanto, in genere è consigliabile eseguire alcuni benchmark per valutare l'utilità di un delegato per le proprie esigenze. Ciò aiuta anche a giustificare l'aumento delle dimensioni binarie associato al collegamento di un delegato al runtime TensorFlow Lite.

TensorFlow Lite dispone di strumenti estesi di valutazione delle prestazioni e dell'accuratezza che possono consentire agli sviluppatori di avere fiducia nell'utilizzo dei delegati nella loro applicazione. Questi strumenti verranno 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 di inferenza media, sovraccarico di inizializzazione, ingombro di memoria, ecc. Questo strumento supporta più flag per individuare la migliore configurazione del delegato per il tuo 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 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 ).

Accuratezza e correttezza

I delegati di solito eseguono calcoli con una precisione diversa rispetto alle loro controparti della CPU. Di conseguenza, esiste un compromesso di precisione (solitamente minore) associato all'utilizzo di un delegato per l'accelerazione hardware. Tieni presente che questo non è sempre vero; ad esempio, poiché la GPU utilizza la precisione in virgola mobile per eseguire modelli quantizzati, potrebbe verificarsi un leggero miglioramento della precisione (ad esempio, <1% di miglioramento nella Top-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 indipendente dalle 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 esegue le stesse prestazioni della CPU?) piuttosto che sulla valutazione del modello (il modello stesso è adatto al compito?).

Valutazione basata sulle attività

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

I file binari predefiniti di questi strumenti (Android, architettura ARM a 64 bit), insieme alla documentazione, possono essere trovati 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 delle 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 indipendente dal compito

Per le attività in cui non è disponibile uno strumento di valutazione sul dispositivo consolidato o se stai sperimentando modelli personalizzati, TensorFlow Lite dispone dello strumento Inference Diff . (Android, 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 della 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 agli elementi.

Per un modello con un singolo tensore di uscita, l'output potrebbe assomigliare 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 output all'indice 0 , gli elementi dell'output della CPU differiscono dall'output del delegato in 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 si tratta di un errore con il delegato). Tuttavia, risultati 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 con il delegato: considera due classi (false): "TV (ID: 10)", "Monitor (ID:20)" - Se un delegato è leggermente fuori dalla verità e mostra il monitor anziché la TV, la differenza di uscita per questo tensore potrebbe essere pari a 20-10 = 10.