Bantuan melindungi Great Barrier Reef dengan TensorFlow pada Kaggle Bergabung Tantangan

Kuantisasi pasca pelatihan

Kuantisasi pasca pelatihan adalah teknik konversi yang dapat mengurangi ukuran model sekaligus meningkatkan latensi akselerator CPU dan perangkat keras, dengan sedikit penurunan akurasi model. Anda dapat quantize model TensorFlow mengambang sudah terlatih ketika Anda mengubahnya ke format TensorFlow Lite menggunakan TensorFlow Lite Converter .

Metode Optimasi

Ada beberapa opsi kuantisasi pasca-pelatihan untuk dipilih. Berikut adalah tabel ringkasan dari pilihan dan manfaat yang mereka berikan:

Teknik Manfaat Perangkat keras
Kuantisasi rentang dinamis 4x lebih kecil, kecepatan 2x-3x CPU
Kuantisasi bilangan bulat penuh 4x lebih kecil, 3x+ percepatan CPU, Edge TPU, Mikrokontroler
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

Kuantisasi rentang dinamis

Bentuk paling sederhana dari kuantisasi pasca-pelatihan secara statis hanya mengkuantisasi bobot dari floating point ke integer, yang memiliki 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()

Pada inferensi, bobot dikonversi dari presisi 8-bit ke floating point dan dihitung menggunakan kernel floating-point. Konversi ini dilakukan sekali dan di-cache untuk mengurangi latensi.

Untuk lebih meningkatkan latensi, operator "rentang dinamis" secara dinamis mengkuantisasi aktivasi berdasarkan jangkauannya hingga 8-bit dan melakukan komputasi dengan bobot dan aktivasi 8-bit. Pengoptimalan ini memberikan latensi yang mendekati inferensi titik tetap sepenuhnya. Namun, output masih disimpan menggunakan floating point sehingga percepatan dengan operasi rentang dinamis kurang dari perhitungan titik tetap penuh.

Kuantisasi bilangan bulat penuh

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

Untuk kuantisasi bilangan bulat penuh, Anda perlu mengkalibrasi atau memperkirakan rentang, yaitu, (min, maks) dari semua tensor titik-mengambang dalam model. Tidak seperti tensor konstan seperti bobot dan bias, tensor variabel seperti input model, aktivasi (output lapisan menengah) dan output model tidak dapat dikalibrasi kecuali kita menjalankan beberapa siklus inferensi. Akibatnya, konverter memerlukan kumpulan data yang representatif untuk mengkalibrasinya. Dataset ini dapat berupa subset kecil (sekitar ~100-500 sampel) dari data pelatihan atau validasi. Mengacu pada representative_dataset() fungsi di bawah ini.

Dari TensorFlow 2,7 versi, Anda dapat menentukan dataset perwakilan melalui tanda tangan seperti 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 yang diberikan, Anda dapat menentukan beberapa kumpulan 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 dapat membuat kumpulan data representatif dengan memberikan 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)]

Sejak versi TensorFlow 2.7, sebaiknya gunakan pendekatan berbasis tanda tangan daripada pendekatan berbasis daftar tensor input karena urutan tensor input dapat dengan mudah dibalik.

Untuk tujuan pengujian, Anda dapat menggunakan dataset dummy sebagai berikut:

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

Integer dengan float fallback (menggunakan input/output float default)

Untuk mengkuantisasi model integer sepenuhnya, tetapi gunakan operator float ketika mereka tidak memiliki implementasi integer (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 bilangan bulat hanya model adalah kasus penggunaan umum untuk TensorFlow Lite untuk Microcontrollers dan Coral Ujung TPUs .

Selain itu, untuk memastikan kompatibilitas dengan perangkat bilangan bulat saja (seperti mikrokontroler 8-bit) dan akselerator (seperti TPU Coral Edge), 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 mengkuantisasi bobot ke float16, standar IEEE untuk angka 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:

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

Kerugian dari kuantisasi float16 adalah sebagai berikut:

  • Itu tidak mengurangi latensi sebanyak kuantisasi ke matematika titik tetap.
  • Secara default, model terkuantisasi float16 akan "mendekuantisasi" nilai bobot ke 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 (percobaan)

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

Keuntungan utama dari kuantisasi ini adalah 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, maka model masih dapat dikuantisasi, tetapi operator yang tidak didukung tetap mengambang. Opsi berikut harus ditambahkan ke target_spec untuk mengizinkan ini.

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 di mana peningkatan akurasi yang disediakan oleh skema kuantisasi ini meliputi: * resolusi super, * pemrosesan sinyal audio seperti pembatalan derau dan beamforming, * penghilangan derau gambar, * rekonstruksi HDR dari satu gambar.

Kerugian dari kuantisasi ini adalah:

  • Saat ini inferensi terasa lebih lambat daripada integer penuh 8-bit karena kurangnya implementasi kernel yang dioptimalkan.
  • Saat ini tidak kompatibel dengan delegasi TFLite yang dipercepat perangkat keras yang ada.

Sebuah tutorial untuk mode kuantisasi ini dapat ditemukan di sini .

Akurasi model

Karena bobot dikuantisasi setelah pelatihan, mungkin ada kehilangan akurasi, terutama untuk jaringan yang lebih kecil. Pre-dilatih model sepenuhnya dikuantisasi disediakan untuk jaringan tertentu dalam TensorFlow Lite Model repositori . Penting untuk memeriksa keakuratan model terkuantisasi untuk memverifikasi bahwa setiap penurunan akurasi berada dalam batas yang dapat diterima. Ada alat untuk mengevaluasi TensorFlow Lite akurasi Model .

Atau, jika penurunan akurasi terlalu tinggi, pertimbangkan untuk menggunakan kuantisasi pelatihan sadar . Namun, hal itu memerlukan modifikasi selama pelatihan model untuk menambahkan node kuantisasi palsu, sedangkan teknik kuantisasi pasca-pelatihan di halaman ini menggunakan model pra-pelatihan yang ada.

Representasi untuk tensor terkuantisasi

Kuantisasi 8-bit mendekati nilai floating point menggunakan rumus berikut.

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

Representasi memiliki dua bagian utama:

  • Bobot per sumbu (alias per saluran) atau per tensor diwakili oleh nilai komplemen dua int8 dalam kisaran [-127, 127] dengan titik nol sama dengan 0.

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

Untuk tampilan rinci skema kuantisasi kami, silakan lihat kami kuantisasi spek . Vendor perangkat keras yang ingin terhubung ke antarmuka delegasi TensorFlow Lite didorong untuk menerapkan skema kuantisasi yang dijelaskan di sana.