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 mengukur float yang sudah dilatih model TensorFlow saat Anda mengonversinya ke format LiteRT menggunakan Konverter LiteRT.

Metode Pengoptimalan

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

Teknik Manfaat Hardware
Rentang dinamis kuantisasi 4x lebih kecil, 2x-3x lebih cepat CPU
Bilangan bulat penuh kuantisasi 4x lebih kecil, 3x lebih cepat CPU, Edge TPU, Microcontroller
Kuantisasi Float16 2x lebih kecil, GPU percepatan CPU, GPU

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

opsi pengoptimalan pasca-pelatihan

Tidak Ada Kuantisasi

Konversi ke model TFLite tanpa kuantisasi adalah langkah awal yang direkomendasikan poin. 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 data asli Operator model TF kompatibel dengan TFLite dan juga dapat digunakan sebagai dasar untuk men-debug kesalahan kuantisasi yang diperkenalkan oleh pasca-pelatihan berikutnya metode kuantisasi. Misalnya, jika model TFLite terkuantisasi menghasilkan hasil yang tidak diharapkan, sementara model TFLite {i>float<i} akurat, kita dapat mempersempit masalah pada {i>error<i} yang diperkenalkan oleh operator TFLite versi terkuantisasi.

Kuantisasi rentang dinamis

Kuantisasi rentang dinamis memberikan pengurangan penggunaan memori dan komputasi yang lebih cepat tanpa perlu menyediakan set data representatif untuk kalibrasi. Ini jenis kuantisasi, yang secara statis hanya menghitung bobot dari floating point menjadi integer 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, "rentang dinamis" operator secara dinamis mengkuantifikasi aktivasi berdasarkan rentangnya hingga 8-bit dan melakukan komputasi dengan bobot dan aktivasi 8-bit. Pengoptimalan ini memberikan dan latensi yang mendekati inferensi tetap. Namun, output-nya masih disimpan menggunakan floating point sehingga peningkatan kecepatan operasi jarak dinamis daripada komputasi titik tetap penuh.

Kuantisasi bilangan bulat penuh

Anda bisa mendapatkan peningkatan latensi, pengurangan penggunaan memori puncak, dan kompatibilitas dengan perangkat keras atau akselerator atau perangkat keras saja dengan memastikan semua matematika model dikuantisasikan dalam 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 konstanta seperti bobot dan bias, tensor variabel seperti input model, aktivasi (output dari lapisan perantara) dan output model tidak boleh dikalibrasi kecuali jika kita menjalankan beberapa siklus inferensi. Hasilnya, konverter membutuhkan {i>dataset<i} yang representatif untuk mengkalibrasinya. {i>Dataset<i} ini dapat berupa (sekitar ~100-500 sampel) dari data pelatihan atau validasi. Rujuk ke fungsi representative_dataset() di bawah ini.

Dari versi TensorFlow 2.7, Anda bisa menentukan set data yang 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 di model TensorFlow tertentu, Anda bisa menentukan beberapa {i>dataset<i} dengan menetapkan 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)]

Sejak versi TensorFlow 2.7, kami merekomendasikan penggunaan pendekatan berbasis tanda tangan di atas pendekatan berbasis daftar tensor input karena pengurutan tensor input bisa mudah dibalik.

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 sepenuhnya menghitung bilangan bulat dari model, tetapi gunakan operator float ketika mereka tidak memiliki penerapan 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 LiteRT untuk Microcontroller dan Coral Edge TPU.

Selain itu, untuk memastikan kompatibilitas dengan perangkat khusus bilangan bulat (seperti 8-bit mikrokontroler) 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 mengukur bobot ke float16, standar IEEE untuk angka floating point 16-bit. Untuk mengaktifkan float16 kuantisasi bobot, 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:

  • Hal ini mengurangi ukuran model hingga setengahnya (karena semua bobot menjadi setengahnya ukuran asli).
  • Ini menyebabkan kerugian yang minimal dalam akurasi.
  • Mendukung beberapa delegasi (misalnya delegasi GPU) yang dapat beroperasi langsung pada data float16, menghasilkan eksekusi yang lebih cepat daripada float32 komputasi berperforma tinggi.

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 ke float32 saat dijalankan pada CPU. (Perhatikan, 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. Hal ini serupa dengan "hanya bilangan bulat" Namun, aktivasi dikuantisasi berdasarkan rentangnya hingga 16-bit, bobotnya dikuantisasi dalam integer 8-bit dan bias dikuantisasi menjadi integer 64-bit. Ini lebih lanjut disebut sebagai kuantisasi 16x8.

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 dalam keadaan float. Tujuan 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 diberikan oleh skema kuantisasi meliputi:

  • resolusi super,
  • 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 dari bilangan bulat penuh 8-bit karena kurangnya implementasi {i>kernel<i} yang dioptimalkan.
  • Saat ini tidak kompatibel dengan TFLite dengan akselerasi hardware yang ada delegasi.

Tutorial untuk mode kuantisasi ini dapat ditemukan di sini.

Akurasi model

Karena bobot terkuantisasi setelah pelatihan, mungkin ada kerugian akurasi, terutama untuk jaringan yang lebih kecil. Model terkuantisasi sepenuhnya yang sudah dilatih sebelumnya disediakan untuk jaringan tertentu di Kaggle Model kami. Penting untuk memeriksa keakuratan model terkuantisasi untuk memverifikasi bahwa setiap penurunan akurasi berada dalam batas yang dapat diterima. Ada alat untuk mengevaluasi model LiteRT akurasi.

Atau, jika penurunan akurasi terlalu tinggi, pertimbangkan untuk menggunakan kuantisasi sadar pelatihan kami. Namun, diperlukan modifikasi selama pelatihan model untuk menambahkan kuantisasi, sedangkan teknik kuantisasi pasca-pelatihan pada menggunakan model terlatih yang sudah ada.

Representasi untuk tensor terkuantisasi

Kuantisasi 8-bit mendekati nilai floating point menggunakan formula.

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

Representasinya memiliki dua bagian utama:

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

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

Untuk gambaran terperinci tentang skema kuantisasi kami, silakan lihat kuantisasi spesifikasi. Vendor hardware yang ingin terhubung ke TensorFlow Antarmuka delegasi Lite dianjurkan untuk menerapkan skema kuantisasi jelaskan di sana.