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:
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.