Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Quantizzazione post-formazione

La quantizzazione post-training è una tecnica di conversione che può ridurre le dimensioni del modello migliorando allo stesso tempo la latenza della CPU e dell'acceleratore hardware, con un minimo degrado nella precisione del modello. È possibile quantizzare un modello TensorFlow float già addestrato convertendolo nel formato TensorFlow Lite utilizzando il convertitore TensorFlow Lite .

Metodi di ottimizzazione

Sono disponibili diverse opzioni di quantizzazione post-training tra cui scegliere. Ecco una tabella riassuntiva delle scelte e dei vantaggi che forniscono:

Tecnica Benefici Hardware
Quantizzazione della gamma dinamica 4x più piccolo, 2x-3x più veloce processore
Quantizzazione intera completa 4x più piccolo, 3x + aumento della velocità CPU, Edge TPU, microcontrollori
Quantizzazione Float16 2x più piccola, accelerazione GPU CPU, GPU

Il seguente albero decisionale può aiutare a determinare quale metodo di quantizzazione post-training è il migliore per il tuo caso d'uso:

opzioni di ottimizzazione post-formazione

Quantizzazione della gamma dinamica

La forma più semplice di quantizzazione post-training quantizza staticamente solo i pesi da virgola mobile a intero, che ha 8 bit di precisione:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quant_model = converter.convert()

Per inferenza, i pesi vengono convertiti da 8 bit di precisione a virgola mobile e calcolati utilizzando kernel a virgola mobile. Questa conversione viene eseguita una volta e memorizzata nella cache per ridurre la latenza.

Per migliorare ulteriormente la latenza, gli operatori di "intervallo dinamico" quantizzano dinamicamente le attivazioni in base al loro intervallo a 8 bit ed eseguono calcoli con pesi e attivazioni a 8 bit. Questa ottimizzazione fornisce latenze vicine all'inferenza a virgola fissa. Tuttavia, gli output vengono comunque memorizzati utilizzando la virgola mobile in modo che l'accelerazione con operazioni a gamma dinamica sia inferiore a un calcolo completo in virgola fissa.

Quantizzazione intera completa

È possibile ottenere ulteriori miglioramenti della latenza, riduzioni del picco di utilizzo della memoria e compatibilità con dispositivi hardware o acceleratori solo interi assicurandosi che tutta la matematica del modello sia quantizzata a numeri interi.

Per la quantizzazione intera completa, è necessario misurare la gamma dinamica di attivazioni e input fornendo dati di input di esempio al convertitore. Fare riferimento alla funzione representative_dataset_gen() utilizzata nel codice seguente.

Numero intero con fallback float (utilizzando input / output float predefinito)

Per quantizzare completamente un modello intero, ma utilizzare operatori float quando non hanno un'implementazione intera (per garantire che la conversione avvenga senza problemi), utilizzare i seguenti passaggi:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
def representative_dataset_gen():
  for _ in range(num_calibration_steps):
    # Get sample input data as a numpy array in a method of your choosing.
    yield [input]
converter.representative_dataset = representative_dataset_gen
tflite_quant_model = converter.convert()

Solo numeri interi

La creazione di modelli solo interi è un caso d'uso comune per TensorFlow Lite per microcontrollori e TPU Coral Edge .

Inoltre, per garantire la compatibilità con dispositivi solo interi (come microcontrollori a 8 bit) e acceleratori (come Coral Edge TPU), puoi applicare la quantizzazione intera completa per tutte le operazioni, inclusi input e output, utilizzando i seguenti passaggi:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
def representative_dataset_gen():
  for _ in range(num_calibration_steps):
    # Get sample input data as a numpy array in a method of your choosing.
    yield [input]
converter.representative_dataset = representative_dataset_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8  # or tf.uint8
converter.inference_output_type = tf.int8  # or tf.uint8
tflite_quant_model = converter.convert()

Quantizzazione Float16

È possibile ridurre le dimensioni di un modello in virgola mobile quantizzando i pesi in float16, lo standard IEEE per i numeri in virgola mobile a 16 bit. Per abilitare la quantizzazione float16 dei pesi, utilizzare i seguenti passaggi:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_quant_model = converter.convert()

I vantaggi della quantizzazione float16 sono i seguenti:

  • Riduce le dimensioni del modello fino alla metà (poiché tutti i pesi diventano la metà della loro dimensione originale).
  • Causa una perdita minima di precisione.
  • Supporta alcuni delegati (ad esempio il delegato GPU) che possono operare direttamente sui dati float16, risultando in un'esecuzione più veloce rispetto ai calcoli float32.

Gli svantaggi della quantizzazione float16 sono i seguenti:

  • Non riduce la latenza tanto quanto una quantizzazione in matematica a virgola fissa.
  • Per impostazione predefinita, un modello quantizzato float16 "dequantizzerà" i valori dei pesi in float32 quando viene eseguito sulla CPU. (Si noti che il delegato GPU non eseguirà questa dequantizzazione, poiché può operare su dati float16.)

Solo numeri interi: attivazioni a 16 bit con pesi a 8 bit (sperimentale)

Questo è uno schema di quantizzazione sperimentale. È simile allo schema "solo intero", ma le attivazioni sono quantizzate in base al loro intervallo a 16 bit, i pesi sono quantizzati in numeri interi a 8 bit e il bias è quantizzato in numeri interi a 64 bit. Questa viene ulteriormente definita quantizzazione 16x8.

Il vantaggio principale di questa quantizzazione è che può migliorare in modo significativo la precisione, ma aumentare solo leggermente le dimensioni del modello.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
def representative_dataset_gen():
  for _ in range(num_calibration_steps):
    # Get sample input data as a numpy array in a method of your choosing.
    yield [input]
converter.representative_dataset = representative_dataset_gen
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8]
tflite_quant_model = converter.convert()

Se la quantizzazione 16x8 non è supportata per alcuni operatori nel modello, il modello può ancora essere quantizzato, ma gli operatori non supportati devono essere mantenuti in virgola mobile. La seguente opzione dovrebbe essere aggiunta a target_spec per consentirlo.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
def representative_dataset_gen():
  for _ in range(num_calibration_steps):
    # Get sample input data as a numpy array in a method of your choosing.
    yield [input]
converter.representative_dataset = representative_dataset_gen
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8,
tf.lite.OpsSet.TFLITE_BUILTINS]
tflite_quant_model = converter.convert()

Esempi di casi d'uso in cui i miglioramenti dell'accuratezza forniti da questo schema di quantizzazione includono: * super risoluzione, * elaborazione del segnale audio come cancellazione del rumore e beamforming, * de-noising dell'immagine, * ricostruzione HDR da una singola immagine.

Lo svantaggio di questa quantizzazione è:

  • Attualmente l'inferenza è notevolmente più lenta dell'intero intero a 8 bit a causa della mancanza di implementazione del kernel ottimizzata.
  • Attualmente non è compatibile con i delegati TFLite con accelerazione hardware esistenti.

Un tutorial per questa modalità di quantizzazione può essere trovato qui .

Precisione del modello

Poiché i pesi sono quantizzati dopo l'allenamento, potrebbe esserci una perdita di precisione, in particolare per le reti più piccole. I modelli completamente quantizzati pre-addestrati sono forniti per reti specifiche nel repository di modelli TensorFlow Lite . È importante controllare l'accuratezza del modello quantizzato per verificare che qualsiasi degrado dell'accuratezza rientri nei limiti accettabili. Sono disponibili strumenti per valutare l' accuratezza del modello TensorFlow Lite .

In alternativa, se il calo di precisione è troppo alto, prendere in considerazione l'utilizzo di un addestramento consapevole della quantizzazione . Tuttavia, ciò richiede modifiche durante l'addestramento del modello per aggiungere nodi di quantizzazione falsi, mentre le tecniche di quantizzazione post-training in questa pagina utilizzano un modello pre-addestrato esistente.

Rappresentazione per tensori quantizzati

La quantizzazione a 8 bit approssima i valori in virgola mobile utilizzando la seguente formula.

$$real\_value = (int8\_value - zero\_point) \times scale$$

La rappresentazione ha due parti principali:

  • Pesi per asse (ovvero per canale) o per tensore rappresentati da int8 valori del complemento a due nell'intervallo [-127, 127] con punto zero uguale a 0.

  • Attivazioni / ingressi per-tensore rappresentati dai valori del complemento a due di int8 nell'intervallo [-128, 127], con punto zero nell'intervallo [-128, 127].

Per una visione dettagliata del nostro schema di quantizzazione, vedere le nostre specifiche di quantizzazione . I fornitori di hardware che desiderano collegarsi all'interfaccia delegato di TensorFlow Lite sono incoraggiati a implementare lo schema di quantizzazione qui descritto.