Odpowiedz już dziś na lokalne wydarzenie TensorFlow Everywhere!
Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Kwantyzacja potreningowa

Kwantyzacja potreningowa to technika konwersji, która może zmniejszyć rozmiar modelu, jednocześnie poprawiając opóźnienie procesora i akceleratora sprzętowego, z niewielkim pogorszeniem dokładności modelu. Możesz kwantyzować już wyuczony model TensorFlow typu float, konwertując go do formatu TensorFlow Lite za pomocą konwertera TensorFlow Lite .

Metody optymalizacji

Do wyboru jest kilka opcji kwantyzacji po treningu. Oto tabela podsumowująca dostępne opcje i korzyści:

Technika Korzyści Sprzęt komputerowy
Kwantyzacja zakresu dynamicznego 4x mniejsze, przyspieszenie 2x-3x procesor
Pełna kwantyzacja liczb całkowitych 4x mniejsze, 3x + przyspieszenie CPU, Edge TPU, mikrokontrolery
Kwantyzacja Float16 2x mniejsze, przyspieszenie GPU CPU, GPU

Poniższe drzewo decyzyjne może pomóc określić, która metoda kwantyzacji po treningu jest najlepsza dla twojego przypadku użycia:

opcje optymalizacji po treningu

Kwantyzacja zakresu dynamicznego

Najprostsza forma kwantyzacji potreningowej kwantyzuje statycznie tylko wagi od zmiennoprzecinkowej do całkowitej, która ma 8-bitową precyzję:

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()

Wnioskując, wagi są konwertowane z 8-bitowej precyzji na zmiennoprzecinkowe i obliczane przy użyciu jądra zmiennoprzecinkowego. Ta konwersja jest wykonywana raz i zapisywana w pamięci podręcznej, aby zmniejszyć opóźnienia.

Aby jeszcze bardziej poprawić opóźnienie, operatorzy „zakresu dynamicznego” dynamicznie kwantyzują aktywacje w oparciu o ich zakres do 8-bitów i wykonują obliczenia z 8-bitowymi wagami i aktywacjami. Ta optymalizacja zapewnia opóźnienia zbliżone do wnioskowania w pełni ustalonego punktu. Jednak dane wyjściowe są nadal przechowywane przy użyciu zmiennoprzecinkowych, więc przyspieszenie z operacjami dynamicznego zakresu jest mniejsze niż pełne obliczenia stałoprzecinkowe.

Pełna kwantyzacja liczb całkowitych

Możesz uzyskać dalsze ulepszenia opóźnień, zmniejszenie szczytowego wykorzystania pamięci i kompatybilność z urządzeniami lub akceleratorami obsługującymi tylko liczby całkowite, upewniając się, że cała matematyka modelu jest kwantyzowana na liczbach całkowitych.

Aby uzyskać pełną kwantyzację liczb całkowitych, musisz skalibrować lub oszacować zakres, tj. (Min, max) wszystkich tensorów zmiennoprzecinkowych w modelu. W przeciwieństwie do stałych tensorów, takich jak wagi i odchylenia, zmienne tensory, takie jak dane wejściowe modelu, aktywacje (dane wyjściowe warstw pośrednich) i dane wyjściowe modelu, nie mogą być kalibrowane, chyba że wykonamy kilka cykli wnioskowania. W rezultacie konwerter wymaga reprezentatywnego zestawu danych do ich kalibracji. Ten zestaw danych może stanowić niewielki podzbiór (około 100–500 próbek) danych uczących lub walidacyjnych. Zapoznaj się z funkcją Representative_dataset representative_dataset() poniżej.

def representative_dataset():
  for data in tf.data.Dataset.from_tensor_slices((images)).batch(1).take(100):
    yield [data.astype(tf.float32)]

Do celów testowych możesz użyć fikcyjnego zbioru danych w następujący sposób:

def representative_dataset():
    for _ in range(100):
      data = np.random.rand(1, 244, 244, 3)
      yield [data.astype(np.float32)]
 

Liczba całkowita z rezerwą zmiennoprzecinkową (przy użyciu domyślnego wejścia / wyjścia typu float)

Aby w pełni kwantyzować model w liczbach całkowitych, ale użyj operatorów zmiennoprzecinkowych, gdy nie mają implementacji liczb całkowitych (aby zapewnić płynną konwersję), wykonaj następujące czynności:

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

Tylko liczby całkowite

Tworzenie modeli zawierających wyłącznie liczby całkowite to typowy przypadek użycia TensorFlow Lite dla mikrokontrolerów i TPU Coral Edge .

Ponadto, aby zapewnić zgodność z urządzeniami zawierającymi wyłącznie liczby całkowite (takimi jak 8-bitowe mikrokontrolery) i akceleratorami (takimi jak Coral Edge TPU), można wymusić pełną kwantyzację liczb całkowitych dla wszystkich operacji, w tym wejścia i wyjścia, wykonując następujące czynności:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
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()

Kwantyzacja Float16

Możesz zmniejszyć rozmiar modelu zmiennoprzecinkowego, kwantyzując wagi do float16, standardu IEEE dla 16-bitowych liczb zmiennoprzecinkowych. Aby włączyć kwantyzację wag typu float16, wykonaj następujące czynności:

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()

Zalety kwantyzacji float16 są następujące:

  • Zmniejsza rozmiar modelu nawet o połowę (ponieważ wszystkie wagi stają się o połowę mniejsze niż ich pierwotne rozmiary).
  • Powoduje minimalną utratę dokładności.
  • Obsługuje niektórych delegatów (np. Delegatów GPU), którzy mogą działać bezpośrednio na danych typu float16, co skutkuje szybszym wykonaniem niż obliczenia typu float32.

Wady kwantyzacji float16 są następujące:

  • Nie zmniejsza opóźnienia tak bardzo, jak kwantyzacja do matematyki stałoprzecinkowej.
  • Domyślnie skwantowany model typu float16 „dekwantyzuje” wartości wag do float32 po uruchomieniu na procesorze. (Zauważ, że delegat GPU nie wykona tej dekwantyzacji, ponieważ może działać na danych float16).

Tylko liczby całkowite: 16-bitowe aktywacje z 8-bitowymi wagami (eksperymentalne)

To jest eksperymentalny schemat kwantyzacji. Jest podobny do schematu „tylko liczby całkowite”, ale aktywacje są kwantowane na podstawie ich zakresu do 16-bitów, wagi są kwantyzowane jako 8-bitowe liczby całkowite, a odchylenie jest kwantowane do 64-bitowej liczby całkowitej. Jest to dalej określane jako kwantyzacja 16x8.

Główną zaletą tej kwantyzacji jest to, że może znacznie poprawić dokładność, ale tylko nieznacznie zwiększyć rozmiar modelu.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.representative_dataset = representative_dataset
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()

Jeśli kwantyzacja 16x8 nie jest obsługiwana dla niektórych operatorów w modelu, to model nadal może być kwantyzowany, ale operatory nieobsługiwane pozostają w zmiennej typu float. Aby to umożliwić, do parametru target_spec należy dodać następującą opcję.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.representative_dataset = representative_dataset
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()

Przykłady przypadków użycia, w których poprawa dokładności zapewniana przez ten schemat kwantyzacji obejmuje: * super rozdzielczość, * przetwarzanie sygnału audio, takie jak redukcja szumów i formowanie wiązki, * redukcja szumów obrazu, * rekonstrukcja HDR z pojedynczego obrazu.

Wadą tej kwantyzacji jest:

  • Obecnie wnioskowanie jest zauważalnie wolniejsze niż 8-bitowa pełna liczba całkowita z powodu braku zoptymalizowanej implementacji jądra.
  • Obecnie jest niekompatybilny z istniejącymi delegatami TFLite z akceleracją sprzętową.

Samouczek dotyczący tego trybu kwantyzacji można znaleźć tutaj .

Dokładność modelu

Ponieważ wagi są kwantyzowane po treningu, może wystąpić utrata dokładności, szczególnie w przypadku mniejszych sieci. W repozytorium modeli TensorFlow Lite udostępniono wstępnie wytrenowane, w pełni skwantyzowane modele dla określonych sieci. Ważne jest, aby sprawdzić dokładność skwantowanego modelu, aby zweryfikować, czy jakiekolwiek pogorszenie dokładności mieści się w dopuszczalnych granicach. Istnieją narzędzia do oceny dokładności modelu TensorFlow Lite .

Alternatywnie, jeśli spadek dokładności jest zbyt duży, rozważ użycie treningu świadomego kwantyzacji . Jednak wykonanie tego wymaga modyfikacji podczas uczenia modelu w celu dodania fałszywych węzłów kwantyzacji, podczas gdy techniki kwantyzacji po treningu na tej stronie wykorzystują istniejący wstępnie wytrenowany model.

Reprezentacja skwantyzowanych tensorów

8-bitowa kwantyzacja aproksymuje wartości zmiennoprzecinkowe przy użyciu następującego wzoru.

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

Przedstawienie składa się z dwóch głównych części:

  • Wagi na oś (aka na kanał) lub wagi na tensor reprezentowane przez wartości uzupełnienia do dwóch int8 w zakresie [-127, 127] z punktem zerowym równym 0.

  • Aktywacje / wejścia per-tensor reprezentowane przez wartości uzupełnienia int8 do dwóch z zakresu [-128, 127], z punktem zerowym w zakresie [-128, 127].

Aby uzyskać szczegółowy widok naszego schematu kwantyzacji, zobacz naszą specyfikację kwantyzacji . Producentów sprzętu, którzy chcą podłączyć się do interfejsu delegata TensorFlow Lite, zachęca się do wdrożenia opisanego tam schematu kwantyzacji.