ट्रेनिंग के बाद संख्या बढ़ाने की सुविधा

पोस्ट-ट्रेनिंग क्वांटाइज़ेशन, एक कन्वर्ज़न तकनीक है. यह मॉडल के साइज़ को कम कर सकती है. साथ ही, इससे सीपीयू और हार्डवेयर ऐक्सेलरेटर इंतज़ार का समय भी बेहतर हो सकती है. इससे मॉडल को सटीक बनाने में थोड़ी भी कमी आ सकती है. TensorFlow Lite Converter का इस्तेमाल करके, उस मॉडल को TensorFlow Lite फ़ॉर्मैट में बदला जा सकता है जिसे पहले से ट्रेन किया गया है. TensorFlow मॉडल को मापा जा सकता है.

ऑप्टिमाइज़ेशन के तरीके

ट्रेनिंग के बाद संख्या बढ़ाने के कई विकल्प हैं. यहां विकल्पों और उनसे मिलने वाले फ़ायदों की खास जानकारी वाली टेबल दी गई है:

तकनीक फ़ायदे हार्डवेयर
डाइनैमिक रेंज क्वांटाइज़ेशन चार गुना छोटा, दो गुना से तीन गुना स्पीडअप CPU
फ़ुल इंटीजर क्वांटाइज़ेशन चार गुना छोटा, 3 गुना से ज़्यादा स्पीडअप सीपीयू, एज टीपीयू, माइक्रोकंट्रोलर
फ़्लोट16 क्वांटाइज़ेशन दोगुना छोटा, जीपीयू एक्सेलरेशन सीपीयू, जीपीयू

नीचे दिए गए डिसिज़न ट्री से यह तय करने में मदद मिल सकती है कि ट्रेनिंग के बाद संख्या बढ़ाने का कौनसा तरीका आपके इस्तेमाल के उदाहरण के लिए सबसे अच्छा है:

ट्रेनिंग के बाद के ऑप्टिमाइज़ेशन के विकल्प

कोई क्वांटाइज़ेशन नहीं

हमारा सुझाव है कि शुरुआत के लिए, क्वांटाइज़ेशन के बिना TFLite मॉडल में बदलाव किया जाना चाहिए. इससे एक फ़्लोट TFLite मॉडल जनरेट होगा.

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

हमारा सुझाव है कि आप शुरुआती चरण के तौर पर इसे जांच लें, ताकि यह पुष्टि की जा सके कि ओरिजनल टीएफ़ मॉडल के ऑपरेटर, TFLite के साथ काम करते हैं या नहीं. साथ ही, इसे ट्रेनिंग के बाद वाले क्वांटाइज़ेशन के तरीकों से क्वांटाइज़ेशन की गड़बड़ियों को डीबग करने के लिए बेसलाइन के तौर पर भी इस्तेमाल किया जा सकता है. उदाहरण के लिए, अगर संख्या वाले TFLite मॉडल उम्मीद के मुताबिक नतीजे नहीं देता है, जबकि फ़्लोट TFLite मॉडल सटीक है, तो हम इस समस्या को TFLite ऑपरेटर के क्वांटाइज़ किए गए वर्शन से शुरू होने वाली गड़बड़ियों तक सीमित कर सकते हैं.

डाइनैमिक रेंज क्वांटाइज़ेशन

डाइनैमिक रेंज क्वांटाइज़ेशन की सुविधा से, मेमोरी का कम इस्तेमाल होता है और कैलकुलेशन तेज़ी से होती है. इसके लिए, आपको कैलिब्रेशन के लिए कोई प्रतिनिधि डेटासेट देने की ज़रूरत नहीं होती. इस तरह क्वांटाइज़ेशन का यह तरीका, कन्वर्ज़न के समय फ़्लोटिंग पॉइंट से पूर्णांक तक की वैल्यू को स्टैटिक रूप से गिनता है. इससे आठ-बिट की सटीक वैल्यू मिलती है:

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

अनुमान के दौरान इंतज़ार के समय को और कम करने के लिए, "डाइनैमिक-रेंज" ऑपरेटर अपनी रेंज के हिसाब से डाइनैमिक तौर पर 8-बिट की रेंज में ऐक्टिवेशन का आकलन करते हैं. साथ ही, 8-बिट वेट और ऐक्टिवेशन के साथ कंप्यूट करते हैं. यह ऑप्टिमाइज़ेशन, पूरी तरह से तय पॉइंट के अनुमानों के आस-पास इंतज़ार का समय उपलब्ध कराता है. हालांकि, आउटपुट अब भी फ़्लोटिंग पॉइंट का इस्तेमाल करके सेव किए जाते हैं, इसलिए डाइनैमिक-रेंज ऑपरेशन की बढ़ी हुई स्पीड, पूरे फ़िक्स्ड-पॉइंट कंप्यूटेशन से कम होती है.

पूर्ण पूर्णांक क्वांटाइज़ेशन

इससे इंतज़ार का समय और बेहतर बनाया जा सकता है, कम स्टोरेज का इस्तेमाल किया जा सकता है, और इंटीजर के हिसाब से, सिर्फ़ हार्डवेयर डिवाइसों या ऐक्सेलरेटर के साथ काम किया जा सकता है. इसके लिए, यह पक्का करना होगा कि मॉडल की पूरी गिनती इंटीजर की हो.

पूर्णांक की संख्या का इस्तेमाल करने के लिए, आपको रेंज को कैलिब्रेट करना होगा या उसका अनुमान लगाना होगा. जैसे, मॉडल में सभी फ़्लोटिंग-पॉइंट टेंसर का (कम से कम, ज़्यादा से ज़्यादा) मान का इस्तेमाल करें. वेट और बायस, जैसे कॉन्स्टेंट टेंसर के उलट, मॉडल इनपुट, ऐक्टिवेशन (इंटरमीडिएट लेयर के आउटपुट), और मॉडल आउटपुट जैसे वैरिएबल टेंसर को तब तक कैलिब्रेट नहीं किया जा सकता, जब तक कि हम कुछ अनुमान साइकल न चलाएं. इस वजह से, कन्वर्टर को कैलिब्रेट करने के लिए प्रतिनिधि डेटासेट की ज़रूरत होती है. यह डेटासेट, ट्रेनिंग या पुष्टि करने वाले डेटा का एक छोटा सबसेट हो सकता है. यह करीब 100 से 500 सैंपल हो सकता है. नीचे दिया गया representative_dataset() फ़ंक्शन देखें.

TensorFlow 2.7 वर्शन से, सिग्नेचर की मदद से प्रतिनिधि डेटासेट की जानकारी दी जा सकती है. इसका उदाहरण नीचे दिया गया है:

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

अगर दिए गए TensorFlow मॉडल में एक से ज़्यादा हस्ताक्षर हैं, तो हस्ताक्षर कुंजियां बताकर एक से ज़्यादा डेटासेट के बारे में बताया जा सकता है:

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

इनपुट टेंसर की सूची देकर, प्रतिनिधि डेटासेट जनरेट किया जा सकता है:

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

TensorFlow 2.7 वर्शन के बाद से, हम इनपुट टेंसर सूची-आधारित तरीके के बजाय सिग्नेचर पर आधारित तरीके का इस्तेमाल करने का सुझाव देते हैं, क्योंकि इनपुट टेंसर के क्रम को आसानी से फ़्लिप किया जा सकता है.

टेस्टिंग के लिए, डमी डेटासेट का इस्तेमाल इस तरह किया जा सकता है:

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

फ़्लोट फ़ॉलबैक के साथ पूर्णांक (डिफ़ॉल्ट फ़्लोट इनपुट/आउटपुट का इस्तेमाल करके)

अगर आपको किसी मॉडल को पूरी तरह से पूर्णांक में सेट करना है, लेकिन पूर्णांक लागू न होने पर फ़्लोट ऑपरेटर का इस्तेमाल करें (यह पक्का करने के लिए कि कन्वर्ज़न आसानी से हो), तो यह तरीका अपनाएं:

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

सिर्फ़ पूर्णांक

सिर्फ़ पूर्णांक वाले मॉडल बनाना, आम तौर पर माइक्रोकंट्रोलर के लिए TensorFlow Lite और कोरल एज टीपीयू के लिए इस्तेमाल होता है.

इसके अलावा, सिर्फ़ पूर्णांक वाले डिवाइसों (जैसे कि 8-बिट माइक्रोकंट्रोलर) और ऐक्सेलरेटर (जैसे, कोरल एज TPU) के साथ काम करना पक्का करने के लिए, इनपुट और आउटपुट जैसे सभी ऑपरेशन के लिए, फ़ुल इंटीजर क्वांटाइज़ेशन की सुविधा लागू की जा सकती है. इसके लिए, यह तरीका अपनाएं:

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

फ़्लोट16 क्वांटाइज़ेशन

किसी फ़्लोटिंग पॉइंट मॉडल के साइज़ को कम करने के लिए, वज़न का हिसाब float16 पर लगाया जा सकता है, जो 16-बिट फ़्लोटिंग पॉइंट नंबर के लिए आईईईई का स्टैंडर्ड है. वेट के float16 क्वांटाइज़ेशन को चालू करने के लिए, यह तरीका अपनाएं:

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

फ़्लोट16 क्वांटाइज़ेशन के फ़ायदे यहां दिए गए हैं:

  • यह मॉडल के साइज़ को कम करके आधा कर देता है, क्योंकि सभी वज़न अपने ओरिजनल साइज़ का आधा हो जाते हैं.
  • इससे सटीक नतीजे बहुत कम मिलते हैं.
  • यह कुछ डेलिगेट के साथ काम करता है, जैसे कि जीपीयू डेलिगेट. ये लोग, सीधे float16 डेटा पर काम कर सकते हैं, जो float32 के मुकाबले तेज़ी से काम कर सकते हैं.

float16 क्वांटाइज़ेशन के नुकसान के बारे में यहां बताया गया है:

  • यह लेटेंसी को इतना कम नहीं करता, जितना कि फ़िक्स्ड पॉइंट के गणित के क्वांटाइज़ेशन के समय को कम किया जाता है.
  • डिफ़ॉल्ट रूप से, float16 क्वांटाइज़्ड मॉडल, सीपीयू पर इस्तेमाल किए जाने पर, float32 के वेट की वैल्यू को "तय" करेगा. (ध्यान दें कि जीपीयू डेलिगेट इस डीक्वांटाइज़ेशन का इस्तेमाल नहीं करेगा, क्योंकि यह float16 डेटा पर काम कर सकता है.)

सिर्फ़ पूर्णांक: 8-बिट वेट के साथ 16-बिट ऐक्टिवेशन (एक्सपेरिमेंट के तौर पर उपलब्ध)

यह एक एक्सपेरिमेंटल क्वांटाइज़ेशन स्कीम है. यह "सिर्फ़ पूर्णांक" योजना की तरह है, लेकिन ऐक्टिवेशन की संख्या उनकी रेंज 16-बिट के हिसाब से तय की जाती है. साथ ही, वेट को 8-बिट वाले पूर्णांक में और बायस की संख्या 64-बिट वाले पूर्णांक में तय की जाती है. इसे आगे 16x8 क्वांटाइज़ेशन कहा जाता है.

माप की इस जानकारी का मुख्य फ़ायदा यह है कि इससे बहुत ज़्यादा सटीक नतीजे मिलते हैं. हालांकि, मॉडल के साइज़ को थोड़ा-बहुत ही बढ़ाया जा सकता है.

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

अगर मॉडल में कुछ ऑपरेटर के लिए 16x8 क्वांटाइज़ेशन की सुविधा काम नहीं करती है, तो भी मॉडल को क्वांट किया जा सकता है. हालांकि, काम न करने वाले ऑपरेटर को फ़्लोट में रखा जाता है. इसकी अनुमति देने के लिए, target_spec में यह विकल्प जोड़ा जाना चाहिए.

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

इस्तेमाल के ऐसे मामलों के उदाहरण जहां इस क्वांटाइज़ेशन स्कीम के ज़रिए दिए गए सटीक सुधारों में ये शामिल हैं:

  • super-resolution,
  • ऑडियो सिग्नल प्रोसेसिंग, जैसे कि ग़ैर-ज़रूरी आवाज़ें कम करना और बीमफ़ॉर्मिंग,
  • इमेज से ग़ैर-ज़रूरी आवाज़ें कम करने की सुविधा,
  • किसी एक इमेज से एचडीआर क्वालिटी में वीडियो बनाने की सुविधा.

नतीजों को आंकड़ों में बदलने की इस सुविधा का नुकसान है:

  • ऑप्टिमाइज़ किए गए कर्नेल को लागू न करने की वजह से, फ़िलहाल अनुमान 8-बिट वाले पूर्णांक से काफ़ी धीमा है.
  • फ़िलहाल, यह हार्डवेयर ऐक्सेलरेटेड TFLite के मौजूदा डेलिगेट के साथ काम नहीं करता.

इस क्वांटाइज़ेशन मोड का ट्यूटोरियल यहां मिल सकता है.

मॉडल की सटीक जानकारी

ट्रेनिंग के बाद वज़न की रिपोर्ट को आंकड़ों के हिसाब से दिखाया जाता है. इसलिए, खास तौर पर छोटे नेटवर्क के मामले में, सटीक तरीके से नुकसान हो सकता है. TensorFlow हब पर खास नेटवर्क के लिए, पहले से ट्रेन किए गए पूरी तरह से क्वांटिफ़ाइड मॉडल दिए जाते हैं. यह देखने के लिए कि क्वांटाइज़्ड मॉडल कितना सटीक है, इसकी जांच करना ज़रूरी है. इससे यह पुष्टि हो पाएगी कि सटीक होने वाली कोई भी कमी, स्वीकार की जाने वाली सीमाओं के अंदर है. TensorFlow Lite मॉडल सटीक है या नहीं, इसका आकलन करने के लिए कई टूल उपलब्ध हैं.

इसके अलावा, अगर सटीक जानकारी बहुत कम मिलती है, तो संख्या का अनुमान लगाने की ट्रेनिंग का इस्तेमाल करें. हालांकि, ऐसा करने के लिए मॉडल ट्रेनिंग के दौरान बदलावों की ज़रूरत होती है, ताकि नकली क्वांटाइज़ेशन नोड जोड़े जा सकें. हालांकि, इस पेज पर पोस्ट-ट्रेनिंग क्वांटाइज़ेशन की तकनीकों में, पहले से ट्रेन किए गए मॉडल का इस्तेमाल किया जाता है.

क्वांटाइज़्ड टेंसर का प्रतिनिधित्व

8-बिट क्वांटाइज़ेशन, फ़्लोटिंग पॉइंट वैल्यू का अनुमान लगाने के लिए नीचे दिए गए फ़ॉर्मूला का इस्तेमाल करता है.

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

प्रतिनिधित्व के दो मुख्य हिस्से होते हैं:

  • हर ऐक्सिस (यानी हर चैनल) या हर टेंसर के भार को, [-127, 127] की रेंज में int8 दो की कॉम्प्लिमेंट वैल्यू से दिखाया जाता है. इस रेंज में शून्य-पॉइंट 0 होता है.

  • हर टेंसर के ऐक्टिवेशन/इनपुट को [-128, 127] की रेंज में int8 दो की पूरक वैल्यू से दिखाया जाता है. इस रेंज में शून्य पॉइंट का मतलब है [-128, 127].

संख्या बढ़ाने की हमारी स्कीम के बारे में ज़्यादा जानने के लिए, कृपया संख्या में बदलाव करने की खास जानकारी देखें. ऐसे हार्डवेयर वेंडर जिन्हें TensorFlow Lite के डेलिगेट इंटरफ़ेस में प्लग-इन करना है उन्हें वहां बताई गई संख्या में बदलाव करने की स्कीम को लागू करने के लिए कहा जाता है.