Kuantizimi pas stërvitjes, Kuantizimi pas stërvitjes

Kuantizimi pas trajnimit është një teknikë konvertimi që mund të zvogëlojë madhësinë e modelit duke përmirësuar gjithashtu vonesën e CPU-së dhe të përshpejtuesit të harduerit, me pak degradim në saktësinë e modelit. Ju mund të kuantizoni një model float TensorFlow tashmë të trajnuar kur e konvertoni në formatin LiteRT duke përdorur Konvertuesin LiteRT .

Metodat e Optimizimit

Ka disa opsione kuantizimi pas stërvitjes për të zgjedhur. Këtu është një tabelë përmbledhëse e zgjedhjeve dhe përfitimeve që ato ofrojnë:

Teknika Përfitimet Hardware
Kuantizimi i diapazonit dinamik 4x më i vogël, 2x-3x shpejtësi CPU
Kuantizimi i plotë i numrit të plotë 4x më i vogël, 3x+ përshpejtim CPU, Edge TPU, Mikrokontrollues
Kuantizimi Float16 2x më i vogël, përshpejtim GPU CPU, GPU

Pema e mëposhtme e vendimeve mund të ndihmojë në përcaktimin se cila metodë e kuantizimit pas trajnimit është më e mira për rastin tuaj të përdorimit:

opsionet e optimizimit pas trajnimit

Nuk ka kuantizim

Konvertimi në një model TFLite pa kuantizim është një pikënisje e rekomanduar. Kjo do të gjenerojë një model TFLite float.

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

Ne ju rekomandojmë ta bëni këtë si një hap fillestar për të verifikuar nëse operatorët e modelit origjinal TF janë të pajtueshëm me TFLite dhe mund të përdoren gjithashtu si bazë për të korrigjuar gabimet e kuantizimit të paraqitura nga metodat e mëpasshme të kuantizimit pas trajnimit. Për shembull, nëse një model i kuantizuar TFLite prodhon rezultate të papritura, ndërsa modeli float TFLite është i saktë, ne mund ta kufizojmë problemin në gabimet e paraqitura nga versioni i kuantizuar i operatorëve TFLite.

Kuantizimi i diapazonit dinamik

Kuantizimi i diapazonit dinamik siguron përdorim të reduktuar të memories dhe llogaritje më të shpejtë pa pasur nevojë të siguroni një grup të dhënash përfaqësuese për kalibrim. Ky lloj kuantizimi, në mënyrë statike kuantizon vetëm peshat nga pika lundruese në numër të plotë në kohën e konvertimit, gjë që siguron 8-bit saktësi:

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

Për të reduktuar më tej vonesën gjatë konkluzionit, operatorët e "rangut dinamik" kuantizojnë dinamikisht aktivizimet bazuar në diapazonin e tyre në 8-bit dhe kryejnë llogaritje me pesha dhe aktivizime 8-bitësh. Ky optimizim siguron vonesa afër konkluzioneve me pikë plotësisht fikse. Megjithatë, rezultatet ruhen ende duke përdorur pikën lundruese, kështu që shpejtësia e rritur e operacioneve me rreze dinamike është më e vogël se një llogaritje e plotë me pikë fikse.

Kuantizimi i plotë i numrit të plotë

Ju mund të merrni përmirësime të mëtejshme të vonesës, reduktime në përdorimin maksimal të memories dhe përputhshmëri me pajisjet harduerike ose përshpejtuesit vetëm me numra të plotë, duke u siguruar që e gjithë matematika e modelit të jetë e kuantizuar me numra të plotë.

Për kuantizimin e plotë të numrave të plotë, ju duhet të kalibroni ose vlerësoni diapazonin, dmth, (min, max) të të gjithë tensorëve me pikë lundruese në model. Ndryshe nga tensorët konstant si peshat dhe paragjykimet, tensorët e ndryshueshëm si hyrja e modelit, aktivizimet (daljet e shtresave të ndërmjetme) dhe dalja e modelit nuk mund të kalibrohen nëse nuk ekzekutojmë disa cikle konkluzionesh. Si rezultat, konverteri kërkon një grup të dhënash përfaqësuese për t'i kalibruar ato. Ky grup të dhënash mund të jetë një nëngrup i vogël (rreth ~ 100-500 mostra) të të dhënave të trajnimit ose të vërtetimit. Referojuni funksionit representative_dataset() më poshtë.

Nga versioni TensorFlow 2.7, mund të specifikoni grupin e të dhënave përfaqësuese përmes një nënshkrimi si shembulli i mëposhtëm:

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

Nëse ka më shumë se një nënshkrim në modelin e dhënë TensorFlow, mund të specifikoni të dhënat e shumëfishta duke specifikuar çelësat e nënshkrimit:

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,
      },
    )

Ju mund të gjeneroni grupin e të dhënave përfaqësuese duke ofruar një listë tensore hyrëse:

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

Që nga versioni TensorFlow 2.7, ne rekomandojmë përdorimin e qasjes së bazuar në nënshkrim mbi qasjen e bazuar në listën e tensorëve të hyrjes, sepse renditja e tensoreve të hyrjes mund të kthehet lehtësisht.

Për qëllime testimi, mund të përdorni një grup të dhënash të rreme si më poshtë:

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

Numër i plotë me rikthim float (duke përdorur hyrjen/daljen e parazgjedhur të notimit)

Për të kuantizuar plotësisht një model, por përdorni operatorët float kur ata nuk kanë një zbatim të numrit të plotë (për të siguruar që konvertimi të ndodhë pa probleme), përdorni hapat e mëposhtëm:

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

Vetëm numër i plotë

Krijimi i modeleve vetëm me numra të plotë është një rast i zakonshëm përdorimi për LiteRT për mikrokontrolluesit dhe TPU-të Coral Edge .

Për më tepër, për të siguruar përputhshmëri me pajisjet vetëm me numra të plotë (si mikrokontrolluesit 8-bit) dhe përshpejtuesit (siç është TPU Coral Edge), mund të zbatoni kuantizimin e plotë të numrit të plotë për të gjitha funksionet, duke përfshirë hyrjen dhe daljen, duke përdorur hapat e mëposhtëm:

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

Kuantizimi Float16

Ju mund të zvogëloni madhësinë e një modeli me pikë lundruese duke i kuantizuar peshat në float16, standardi IEEE për numrat me pikë lundruese 16-bitësh. Për të mundësuar kuantizimin float16 të peshave, përdorni hapat e mëposhtëm:

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

Përparësitë e kuantizimit float16 janë si më poshtë:

  • Zvogëlon madhësinë e modelit deri në gjysmë (pasi të gjitha peshat bëhen gjysma e madhësisë së tyre origjinale).
  • Ajo shkakton humbje minimale në saktësi.
  • Ai mbështet disa delegatë (p.sh. delegatin e GPU) të cilët mund të operojnë drejtpërdrejt në të dhënat float16, duke rezultuar në ekzekutim më të shpejtë se llogaritjet float32.

Disavantazhet e kuantizimit float16 janë si më poshtë:

  • Nuk e redukton vonesën aq shumë sa një kuantizimi në matematikë me pikë fikse.
  • Si parazgjedhje, një model i kuantizuar float16 do të "dekuantizojë" vlerat e peshave në float32 kur të ekzekutohet në CPU. (Vini re se delegati i GPU-së nuk do ta kryejë këtë dekuantizim, pasi mund të funksionojë në të dhëna float16.)

Vetëm numër i plotë: aktivizime 16-bit me pesha 8-bitësh (eksperimentale)

Kjo është një skemë eksperimentale kuantizimi. Është e ngjashme me skemën "vetëm numër i plotë", por aktivizimet kuantizohen në bazë të gamës së tyre në 16-bit, peshat kuantizohen në numër të plotë 8-bit dhe paragjykimi kuantizohet në numër të plotë 64-bit. Më tej kjo quhet kuantizimi 16x8.

Avantazhi kryesor i këtij kuantizimi është se ai mund të përmirësojë ndjeshëm saktësinë, por vetëm pak të rrisë madhësinë e modelit.

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

Nëse kuantizimi 16x8 nuk mbështetet për disa operatorë në model, atëherë modeli ende mund të kuantizohet, por operatorët e pambështetur mbahen në float. Opsioni i mëposhtëm duhet të shtohet në target_spec për ta lejuar këtë.

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

Shembuj të rasteve të përdorimit ku përmirësimet e saktësisë të ofruara nga kjo skemë kuantizimi përfshijnë:

  • super-rezolucion,
  • përpunimi i sinjalit audio si anulimi i zhurmës dhe formimi i rrezeve,
  • heqja e zhurmës së imazhit,
  • Rindërtimi HDR nga një imazh i vetëm.

Disavantazhi i këtij kuantizimi është:

  • Aktualisht përfundimi është dukshëm më i ngadalshëm se numri i plotë 8-bit për shkak të mungesës së zbatimit të optimizuar të kernelit.
  • Aktualisht është i papajtueshëm me delegatët ekzistues të përshpejtuar të harduerit TFLite.

Një tutorial për këtë mënyrë kuantizimi mund të gjendet këtu .

Saktësia e modelit

Meqenëse peshat janë të kuantizuara pas stërvitjes, mund të ketë një humbje të saktësisë, veçanërisht për rrjetet më të vogla. Modele plotësisht të kuantizuara të para-trajnuara ofrohen për rrjete specifike në Kaggle Models . Është e rëndësishme të kontrollohet saktësia e modelit të kuantizuar për të verifikuar që çdo degradim i saktësisë është brenda kufijve të pranueshëm. Ka mjete për të vlerësuar saktësinë e modelit LiteRT .

Përndryshe, nëse rënia e saktësisë është shumë e lartë, merrni parasysh përdorimin e trajnimit të vetëdijshëm për kuantizimin . Megjithatë, kjo kërkon modifikime gjatë trajnimit të modelit për të shtuar nyje të rreme kuantizimi, ndërsa teknikat e kuantizimit pas trajnimit në këtë faqe përdorin një model ekzistues të para-stërvitur.

Përfaqësim për tensorët e kuantizuar

Kuantizimi 8-bit përafron vlerat e pikës lundruese duke përdorur formulën e mëposhtme.

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

Përfaqësimi ka dy pjesë kryesore:

  • Peshat për bosht (aka për kanal) ose për tensor të përfaqësuara nga vlerat e plotësimit të int8 two në rangun [-127, 127] me pikë zero të barabartë me 0.

  • Aktivizimet/hyrjet për tensor të përfaqësuara nga vlerat e plotësimit të int8 two në intervalin [-128, 127], me një pikë zero në intervalin [-128, 127].

Për një pamje të detajuar të skemës sonë të kuantizimit, ju lutemi shihni specifikimet tona të kuantizimit . Shitësit e pajisjeve që duan të futen në ndërfaqen e delegatëve të TensorFlow Lite inkurajohen të zbatojnë skemën e kuantizimit të përshkruar atje.