Conversione TensorFlow RNN in LiteRT

Panoramica

LiteRT supporta la conversione dei modelli TensorFlow RNN in fusibili di operazioni LSTM. Le operazioni combinate esistono per massimizzare le prestazioni le implementazioni del kernel sottostanti, oltre a fornire un livello per definire trasformazioni complesse come la quantizzazione.

Poiché esistono molte varianti delle API RNN in TensorFlow, il nostro approccio è stato due volte:

  1. Fornisci supporto nativo per le API TensorFlow RNN standard come Keras LSTM. Questa è l'opzione consigliata.
  2. Fornisci un'interfaccia nell'infrastruttura di conversione per Implementate dall'utente Implementazioni RNN da collegare e convertire LiteRT, Forniamo un paio di esempi pronti all'uso utilizzando la traduzione in lingvo LSTMCellSimple e LayerNormalizedLSTMCellSimple RNN.

API Converter

La funzionalità fa parte della versione TensorFlow 2.3. È disponibile anche tramite tf-nightly o dalla testa.

Questa funzionalità di conversione è disponibile durante la conversione in LiteRT tramite un SavedModel o direttamente dal modello Keras. Guarda esempi di utilizzo.

Dal modello salvato

# build a saved model. Here concrete_function is the exported function
# corresponding to the TensorFlow model containing one or more
# Keras LSTM layers.
saved_model, saved_model_dir = build_saved_model_lstm(...)
saved_model.save(saved_model_dir, save_format="tf", signatures=concrete_func)

# Convert the model.
converter = TFLiteConverter.from_saved_model(saved_model_dir)
tflite_model = converter.convert()

Dal modello Keras

# build a Keras model
keras_model = build_keras_lstm(...)

# Convert the model.
converter = TFLiteConverter.from_keras_model(keras_model)
tflite_model = converter.convert()

Esempio

Keras da LSTM a LiteRT Colab illustra l'utilizzo end-to-end con l'interprete LiteRT.

API TensorFlow RNNs supportate

Supportiamo la conversione immediata di Keras LSTM in LiteRT. Per per informazioni dettagliate su come funziona, consulta Interfaccia Keras LSTM e alla logica di conversione qui.

È importante anche evidenziare il contratto LSTM di LiteRT per rispetto alla definizione delle operazioni Keras:

  1. La dimensione 0 del tensore input è la dimensione del batch.
  2. La dimensione 0 del tensore recurrent_weight è il numero di come output.
  3. I tensori weight e recurrent_kernel vengono trasposti.
  4. Il peso trasposta, il kernel_recurrent_trasposto e i tensori di bias sono suddivisi in 4 tensori di uguali dimensioni lungo la dimensione 0. Questi corrispondono gate di input, delete gate, cell, e output gate.

Varianti Keras LSTM

Ora principale

Gli utenti possono scegliere tra data principale e nessuna data principale. Keras LSTM aggiunge un fattore temporale negli attributi def della funzione. Per l'LSTM della sequenza unidirezionale, può semplicemente mappare attributo ora principale.

LSTM bidirezionale

L'LSTM bidirezionale può essere implementato con due strati Keras LSTM, uno per avanti e uno per tornare indietro, vedi esempi qui Una volta visto l'attributo go_backward, lo riconosciamo come LSTM indietro, quindi raggruppiamo in avanti LSTM indietro insieme. Si tratta di un lavoro futuro. Al momento, Questo crea due operazioni UnidirectionalSequenceLSTM in LiteRT un modello di machine learning.

Esempi di conversione LSTM definiti dall'utente

LiteRT offre anche un modo per convertire l'LSTM definito dall'utente implementazioni. Qui usiamo l'LSTM di Lingvo come esempio di come implementate. Per maggiori dettagli, consulta Interfaccia lingvo.LSTMCellSimple e la logica di conversione qui. Forniamo anche un esempio per un'altra delle definizioni LSTM di Lingvo in Interfaccia lingvo.layerNormalizedLSTMCellSimple e la sua logica di conversione qui.

"Bring Your Own TensorFlow RNN" in LiteRT

Se l'interfaccia RNN di un utente è diversa da quelle supportate standard, sono disponibili due opzioni:

Opzione 1: scrivi il codice dell'adattatore in TensorFlow Python per adattare l'interfaccia RNN all'interfaccia RNN di Keras. Ciò significa che una funzione tf.function con tf_implements annotazioni su funzione dell'interfaccia RNN generata identica a quella generata lo strato Keras LSTM. Dopodiché, la stessa API di conversione utilizzata per Keras LSTM può funzionare.

Opzione 2: se non è possibile eseguire quanto sopra (ad es. nell'LSTM di Keras mancano alcuni funzionalità attualmente esposta dall'operazione LSTM integrata di LiteRT, come LayerNormalization), ed estendi il convertitore LiteRT scrivendo personalizzato e collegarlo alle funzioni preparate MLIR-pass qui. L'interfaccia della funzione deve essere trattata come un contratto API e Contenere gli argomenti necessari per la conversione nel modulo LiteRT LSTM operazioni, ossia input, bias, ponderazioni, proiezione, normalizzazione degli strati e così via. è preferibile che i tensori passati come argomenti a questa funzione abbiano (ovvero RankedTensorType in MLIR). In questo modo è molto più facile scrivere codice di conversione che può assumere questi tensori come RankedTensorType e li trasformiamo in tensori classificati corrispondenti al modello LiteRT operandi dell'operatore.

Un esempio completo di questo flusso di conversione è LSTMCellSimple di Lingvo per Conversione LiteRT.

Il parametro LSTMCellSimple in Lingvo è definito qui I modelli addestrati con questa cella LSTM possono essere convertiti in LiteRT come che segue:

  1. Aggrega tutti gli utilizzi di LSTMCellSimple in una funzione tf.function con un comando tf_implements etichettata come tale (ad es. lingvo.LSTMCellSimple sarebbe un'etichetta un buon nome dell'annotazione). Assicurati che la funzione tf.function che viene generata corrisponde all'interfaccia della funzione prevista nel codice di conversione. Questo esiste un contratto tra l'autore del modello che aggiunge l'annotazione e codice di conversione.
  2. Estendi il passaggio per le funzioni preparate per il composto per collegare un'operazione composita personalizzata alla conversione operativa LSTM integrata con LiteRT. Consulta: LSTMCellSimple codice di conversione.

    Il contratto di conversione:

  3. Il peso e i tensori di proiezione sono trasposti.

  4. Da {input, recurrent} a {cell, input gate, wipe gate, output gate} vengono estratti dividendo il tensore dei pesi trasposti.

  5. I valori da {bias} a {bias} sono estratti mediante la suddivisione del tensore di bias.

  6. La proiezione viene estratta dividendo il tensore di proiezione trasposta.

  7. Una conversione simile è scritta per LayerNormalizedLSTMCellSimple.

  8. Il resto dell'infrastruttura di conversione LiteRT, incluse tutte le Passaggi MLIR nonché l'esportazione finale nel flatbuffer LiteRT, possono essere riutilizzate.

Problemi noti/limitazioni

  1. Attualmente è disponibile solo il supporto per la conversione stateless di Keras LSTM (valore predefinito: il comportamento degli utenti in Keras). La conversione stateful Keras LSTM è un lavoro futuro.
  2. È ancora possibile modellare uno strato stateful Keras LSTM utilizzando lo strato stateless Keras LSTM sottostante e la gestione dello stato in modo esplicito il programma utente. Un programma TensorFlow di questo tipo può essere convertito LiteRT utilizzando la funzionalità descritta qui.
  3. Bidirectional LSTM è attualmente modellato come due UnidirectionalSequenceLSTM operazioni in LiteRT. Verrà sostituito con un singolo Op. BidirectionalSequenceLSTM