Kuantisasi pasca pelatihan

Kuantisasi pasca-pelatihan adalah teknik konversi yang dapat mengurangi ukuran model sekaligus meningkatkan latensi akselerator hardware dan CPU, dengan sedikit penurunan akurasi model. Anda dapat mengkuantiasi model TensorFlow float yang sudah terlatih saat mengonversinya menjadi format TensorFlow Lite menggunakan Konverter TensorFlow Lite.

Metode Pengoptimalan

Ada beberapa opsi kuantisasi pasca-pelatihan yang dapat dipilih. Berikut tabel ringkasan pilihan dan manfaat yang diberikan:

Teknik Manfaat Hardware
Kuantisasi rentang dinamis 4x lebih kecil, 2x-3x lebih cepat CPU
Kuantisasi bilangan bulat penuh 4x lebih kecil, 3x lebih cepat CPU, Edge TPU, Microcontroller
Kuantisasi Float16 2x lebih kecil, akselerasi GPU CPU, GPU

Pohon keputusan berikut dapat membantu menentukan metode kuantisasi pasca-pelatihan mana yang terbaik untuk kasus penggunaan Anda:

opsi pengoptimalan pasca-pelatihan

Tidak Ada Kuantisasi

Konversi ke model TFLite tanpa kuantisasi merupakan titik awal yang direkomendasikan. Ini akan menghasilkan model TFLite float.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
tflite_quant_model = converter.convert()

Sebaiknya lakukan hal ini sebagai langkah awal untuk memverifikasi bahwa operator model TF asli kompatibel dengan TFLite dan juga dapat digunakan sebagai dasar pengukuran untuk men-debug error kuantisasi yang diperkenalkan oleh metode kuantisasi pasca-pelatihan berikutnya. Misalnya, jika model TFLite terkuantisasi memberikan hasil yang tidak diharapkan, sementara model TFLite float akurat, kita dapat mempersempit masalah pada error yang diperkenalkan oleh operator TFLite versi terkuantisasi.

Kuantisasi rentang dinamis

Kuantisasi rentang dinamis memberikan pengurangan penggunaan memori dan komputasi yang lebih cepat tanpa harus menyediakan set data representatif untuk kalibrasi. Jenis kuantisasi ini, secara statis hanya menghitung bobot dari floating point ke bilangan bulat pada waktu konversi, yang memberikan presisi 8 bit:

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

Untuk mengurangi latensi selama inferensi, operator "rentang dinamis" mengkuantifikasi aktivasi secara dinamis berdasarkan rentangnya hingga 8-bit, serta melakukan komputasi dengan bobot dan aktivasi 8-bit. Pengoptimalan ini memberikan latensi yang mendekati inferensi titik tetap yang sepenuhnya. Namun, output masih disimpan menggunakan floating point sehingga peningkatan kecepatan operasi rentang dinamis kurang daripada komputasi titik tetap penuh.

Kuantisasi bilangan bulat penuh

Anda bisa mendapatkan peningkatan latensi lebih lanjut, pengurangan penggunaan memori puncak, dan kompatibilitas dengan akselerator atau perangkat hardware khusus bilangan bulat dengan memastikan semua matematika model dikuantifikasi bilangan bulat.

Untuk kuantisasi bilangan bulat penuh, Anda perlu mengkalibrasi atau memperkirakan rentangnya, yaitu, (min, max) dari semua tensor floating point dalam model. Tidak seperti tensor konstan seperti bobot dan bias, tensor variabel seperti input model, aktivasi (output lapisan perantara), dan output model tidak dapat dikalibrasi kecuali jika kami menjalankan beberapa siklus inferensi. Akibatnya, konverter memerlukan set data representatif untuk mengkalibrasinya. Set data ini dapat berupa subset kecil (sekitar ~100-500 sampel) dari data pelatihan atau validasi. Lihat fungsi representative_dataset() di bawah.

Dari versi TensorFlow 2.7, Anda dapat menentukan set data representatif melalui tanda tangan sebagai contoh berikut:

def representative_dataset():
  for data in dataset:
    yield {
      "image": data.image,
      "bias": data.bias,
    }

Jika ada lebih dari satu tanda tangan dalam model TensorFlow tertentu, Anda dapat menentukan beberapa set data dengan menentukan kunci tanda tangan:

def representative_dataset():
  # Feed data set for the "encode" signature.
  for data in encode_signature_dataset:
    yield (
      "encode", {
        "image": data.image,
        "bias": data.bias,
      }
    )

  # Feed data set for the "decode" signature.
  for data in decode_signature_dataset:
    yield (
      "decode", {
        "image": data.image,
        "hint": data.hint,
      },
    )

Anda bisa menghasilkan set data representatif dengan menyediakan daftar tensor input:

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

Mulai versi TensorFlow 2.7, sebaiknya gunakan pendekatan berbasis tanda tangan dibandingkan pendekatan berbasis daftar tensor input karena pengurutan tensor input dapat dibalik dengan mudah.

Untuk tujuan pengujian, Anda dapat menggunakan {i>dataset<i} contoh sebagai berikut:

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

Bilangan bulat dengan penggantian float (menggunakan input/output float default)

Untuk mengukur jumlah model dengan bilangan bulat sepenuhnya, tetapi menggunakan operator float saat tidak memiliki implementasi bilangan bulat (untuk memastikan konversi terjadi dengan lancar), gunakan langkah-langkah berikut:

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

Hanya bilangan bulat

Membuat model khusus bilangan bulat adalah kasus penggunaan umum untuk TensorFlow Lite untuk Microcontrollers dan Coral Edge TPU.

Selain itu, untuk memastikan kompatibilitas dengan perangkat khusus bilangan bulat (seperti mikrokontroler 8-bit) dan akselerator (seperti Coral Edge TPU), Anda dapat menerapkan kuantisasi bilangan bulat penuh untuk semua operasi termasuk input dan output, dengan menggunakan langkah-langkah berikut:

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

Kuantisasi Float16

Anda dapat mengurangi ukuran model floating point dengan mengkuantifikasi bobot menjadi float16, standar IEEE untuk bilangan floating point 16 bit. Untuk mengaktifkan kuantisasi bobot float16, gunakan langkah-langkah berikut:

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

Keuntungan dari kuantisasi float16 adalah sebagai berikut:

  • Mode ini mengurangi ukuran model hingga setengahnya (karena semua bobot menjadi setengah dari ukuran aslinya).
  • Ini menyebabkan kerugian yang minimal dalam akurasi.
  • Float ini mendukung beberapa delegasi (misalnya delegasi GPU) yang dapat beroperasi langsung pada data float16, sehingga menghasilkan eksekusi yang lebih cepat daripada komputasi float32.

Kekurangan kuantisasi float16 adalah sebagai berikut:

  • Hal ini tidak mengurangi latensi sebanyak kuantisasi ke perhitungan titik tetap.
  • Secara default, model terkuantisasi float16 akan "mendekuantisasi" nilai bobot menjadi float32 saat dijalankan pada CPU. (Perhatikan bahwa delegasi GPU tidak akan melakukan dekuantisasi ini, karena dapat beroperasi pada data float16.)

Hanya bilangan bulat: Aktivasi 16-bit dengan bobot 8-bit (eksperimental)

Ini adalah skema kuantisasi eksperimental. Skema ini mirip dengan skema "khusus bilangan bulat", tetapi aktivasi dikuantisasi berdasarkan rentangnya hingga 16-bit, bobot dikuantisasi dalam bilangan bulat 8-bit, dan bias dikuantisasi menjadi bilangan bulat 64-bit. Hal ini disebut sebagai kuantisasi 16x8 lebih lanjut.

Keuntungan utama dari kuantisasi ini adalah akurasinya dapat meningkatkan akurasi secara signifikan, tetapi hanya sedikit meningkatkan ukuran model.

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

Jika kuantisasi 16x8 tidak didukung untuk beberapa operator dalam model, model masih dapat dikuantisasi, tetapi operator yang tidak didukung akan tetap dalam status float. Opsi berikut harus ditambahkan ke target_spec untuk mengizinkannya.

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

Contoh kasus penggunaan saat peningkatan akurasi yang diberikan oleh skema kuantisasi ini mencakup:

  • super-resolution,
  • pemrosesan sinyal audio seperti peredam bising dan beamforming,
  • penghilang noise gambar,
  • Rekonstruksi HDR dari satu gambar.

Kekurangan dari kuantisasi ini adalah:

  • Saat ini, inferensi terasa lebih lambat daripada bilangan bulat penuh 8-bit karena kurangnya implementasi kernel yang dioptimalkan.
  • Saat ini, metode ini tidak kompatibel dengan delegasi TFLite dengan akselerasi hardware yang ada.

Tutorial untuk mode kuantisasi ini dapat ditemukan di sini.

Akurasi model

Karena bobot dikuantifikasi setelah pelatihan, kemungkinan akan ada penurunan akurasi, terutama untuk jaringan yang lebih kecil. Model terkuantisasi sepenuhnya terlatih disediakan untuk jaringan tertentu di TensorFlow Hub. Penting untuk memeriksa akurasi model terkuantisasi untuk memverifikasi bahwa degradasi akurasi berada dalam batas yang dapat diterima. Terdapat alat untuk mengevaluasi akurasi model TensorFlow Lite.

Atau, jika penurunan akurasi terlalu tinggi, pertimbangkan untuk menggunakan pelatihan berbasis kuantisasi . Namun, diperlukan modifikasi selama pelatihan model untuk menambahkan node kuantisasi palsu, sedangkan teknik kuantisasi pasca-pelatihan di halaman ini menggunakan model terlatih yang sudah ada.

Representasi untuk tensor terkuantisasi

Kuantisasi 8-bit memperkirakan nilai floating point menggunakan formula berikut.

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

Representasinya memiliki dua bagian utama:

  • Bobot per sumbu (alias per saluran) atau per-tensor yang diwakili oleh nilai pelengkap int8 two dalam rentang [-127, 127] dengan titik nol sama dengan 0.

  • Aktivasi/input per-tensor diwakili oleh nilai pelengkap int8 dua dalam rentang [-128, 127], dengan titik nol dalam rentang [-128, 127].

Untuk mengetahui tampilan mendetail tentang skema kuantisasi kami, lihat spesifikasi kuantisasi kami. Vendor hardware yang ingin terhubung ke antarmuka delegasi TensorFlow Lite dianjurkan untuk menerapkan skema kuantisasi yang dijelaskan di sana.