Delegati GPU per LiteRT

Utilizzo delle GPU (Graphics Processing Unit) per eseguire i modelli di machine learning (ML) può migliorare notevolmente le prestazioni del modello e l'esperienza utente delle tue applicazioni abilitate per il machine learning. LiteRT consente l'uso di GPU e altri processori specializzati attraverso un driver hardware chiamato delegati. Abilitazione dell'uso delle GPU con LiteRT ML le applicazioni possono offrire i seguenti vantaggi:

  • Velocità - Le GPU sono progettate per un'elevata velocità effettiva delle GPU carichi di lavoro con scale out impegnativi. Questo design li rende particolarmente adatti alle reti neurali profonde, che sono costituiti da un numero enorme di operatori, ognuno dei quali lavora sui tensori di input possono essere elaborati in parallelo, il che di norma si traduce in una latenza inferiore. Nella lo scenario migliore, l'esecuzione del modello su una GPU può essere eseguita abbastanza velocemente applicazioni in tempo reale che prima non erano possibili.
  • Efficienza energetica: le GPU eseguono i calcoli di ML in modo molto efficiente e ottimizzato, di solito consumando meno energia e generando meno rispetto alla stessa attività in esecuzione sulle CPU.

Questo documento fornisce una panoramica del supporto delle GPU in LiteRT e alcuni per usi avanzati dei processori GPU. Per informazioni più specifiche su per implementare il supporto delle GPU su piattaforme specifiche, consulta le seguenti guide:

Supporto per le operazioni di ML della GPU

Esistono alcune limitazioni a ciò che è possibile eseguire con le operazioni di TensorFlow ML, o operazioni. accelerata dal delegato LiteRT. Il delegato supporta operazioni seguenti con precisione in virgola mobile 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. Attivazione della quantizzazione support attiva le versioni appropriate, ad esempio ADD v2.

Risoluzione dei problemi di supporto delle GPU

Se alcune operazioni non sono supportate dal delegato GPU, il framework solo una parte del grafico sulla GPU e la parte rimanente sulla CPU. Scadenza dall'alto costo della sincronizzazione CPU/GPU, una modalità di esecuzione divisa come questa spesso comportano prestazioni più lente rispetto a quando l'intera rete viene eseguita CPU da sola. In questo caso, l'applicazione genera un avviso, ad esempio:

WARNING: op code #42 cannot be handled by this delegate.

Non è presente alcun callback per gli errori di questo tipo, poiché non si tratta di un un errore di runtime. Quando testi l'esecuzione del modello con il delegato GPU, dovresti essere vigile per questi avvisi. Un numero elevato di questi avvisi può indicare che il modello non è il più adatto 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, sono forniti a scopo di riferimento e di test:

Ottimizzazione per le GPU

Le seguenti tecniche possono aiutarti a ottenere prestazioni migliori durante l'esecuzione dei modelli sull'hardware GPU utilizzando il delegato GPU LiteRT:

  • Operazioni di rimodellamento - Alcune operazioni rapide su una CPU possono avere costi elevati per la GPU dei dispositivi mobili. Le operazioni di rimodellamento sono particolarmente costosi da gestire, tra cui BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH e così via. Dovresti esaminare attentamente l'uso dei modelli operazioni e considera che potrebbe essere stato applicato solo per l'esplorazione dei dati o per le prime iterazioni del modello. La loro rimozione può significativamente a migliorare le prestazioni.

  • Canali di dati immagine: sulla GPU, i dati dei tensori vengono suddivisi in quattro canali e quindi il calcolo su un tensore di forma [B,H,W,5] esegue la stessa cosa su un tensore di forma [B,H,W,8], ma significativamente peggiore di [B,H,W,4]. Se l'hardware della videocamera in uso supporta i frame immagine RGBA, alimentare l'ingresso a 4 canali è molto più veloce, in quanto evita una copia in memoria da RGB a 3 canali a RGBX a 4 canali.

  • Modelli ottimizzati per dispositivi mobili. Per un rendimento ottimale, devi considerare addestrando di nuovo il classificatore con un'architettura di rete ottimizzata per dispositivi mobili. L'ottimizzazione per l'inferenza on-device può ridurre drasticamente la latenza e il consumo energetico grazie alle funzioni dell'hardware mobile.

Supporto GPU avanzato

Puoi utilizzare tecniche aggiuntive e avanzate con l'elaborazione GPU per consentire migliorando le prestazioni dei tuoi modelli, tra cui la quantizzazione e la serializzazione. Nelle sezioni seguenti vengono descritte queste tecniche in modo più dettagliato.

Utilizzo di modelli quantizzati

Questa sezione spiega come il delegato GPU accelera i modelli quantizzati a 8 bit. tra cui:

Per ottimizzare le prestazioni, utilizza modelli che hanno sia input in virgola mobile che tensori di output.

Come funziona?

Poiché il backend della GPU supporta solo l'esecuzione in virgola mobile, eseguiamo di base assegnandogli una "vista in virgola mobile" del modello originale. Presso di alto livello. Sono previsti i seguenti passaggi:

  • I tensori costanti (ad esempio pesi/biasi) vengono dequantizzati una volta nella Memoria GPU. Questa operazione si verifica quando il delegato è abilitato per LiteRT,

  • Gli ingressi e gli output del programma GPU, se quantizzati a 8 bit, vengono de-quantizzata e quantizzata (rispettivamente) per ogni inferenza. Questa operazione viene eseguita sulla CPU usando i kernel ottimizzati di LiteRT.

  • I simulatori di quantizzazione vengono inseriti tra le operazioni per simulare le comportamento degli utenti. Questo approccio è necessario per i modelli in cui le operazioni prevedono attivazioni a seguire i limiti appresi durante la quantizzazione.

Per informazioni sull'abilitazione di questa funzionalità con il delegato GPU, consulta le seguenti:

Riduzione del tempo di inizializzazione con la serializzazione

La funzionalità di delega GPU consente di caricare da codice kernel precompilato e i dati del modello sono serializzati e salvati su disco dalle esecuzioni precedenti. Questo approccio evita ricompilazione e può ridurre i tempi di avvio fino al 90%. Questo miglioramento è si ottiene scambiando spazio su disco per risparmiare tempo. Puoi attivare questa funzionalità 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;
      

Java

    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 codice sia conforme a queste regole di implementazione:

  • Archiviare i dati di serializzazione in una directory non accessibile ad altri app. Sui dispositivi Android, utilizza getCodeCacheDir() che punta a una posizione privata per l'applicazione corrente.
  • Il token del modello deve essere univoco del dispositivo per il modello specifico. Puoi calcolare un token del modello generando un'impronta dai dati del modello utilizzando librerie come farmhash::Fingerprint64
di Gemini Advanced.