পোস্ট-ট্রেনিং কোয়ান্টাইজেশন

পোস্ট-ট্রেনিং কোয়ান্টাইজেশন হল একটি রূপান্তর কৌশল যা মডেলের আকার কমাতে পারে পাশাপাশি CPU এবং হার্ডওয়্যার অ্যাক্সিলারেটর লেটেন্সি উন্নত করতে পারে, মডেলের যথার্থতায় সামান্য অবনতি সহ। আপনি টেনসরফ্লো লাইট কনভার্টার ব্যবহার করে টেনসরফ্লো লাইট ফর্ম্যাটে রূপান্তর করার সময় আপনি ইতিমধ্যেই প্রশিক্ষিত ফ্লোট টেনসরফ্লো মডেলের পরিমাণ নির্ধারণ করতে পারেন।

অপ্টিমাইজেশান পদ্ধতি

বেছে নেওয়ার জন্য বেশ কয়েকটি পোস্ট-ট্রেনিং কোয়ান্টাইজেশন বিকল্প রয়েছে। এখানে পছন্দের একটি সংক্ষিপ্ত সারণী এবং তারা যে সুবিধাগুলি প্রদান করে:

প্রযুক্তি সুবিধা হার্ডওয়্যার
গতিশীল পরিসীমা পরিমাপ 4x ছোট, 2x-3x গতি সিপিইউ
সম্পূর্ণ পূর্ণসংখ্যা পরিমাপ 4x ছোট, 3x+ স্পিডআপ সিপিইউ, এজ টিপিইউ, মাইক্রোকন্ট্রোলার
Float16 কোয়ান্টাইজেশন 2x ছোট, GPU ত্বরণ সিপিইউ, জিপিইউ

নিম্নলিখিত সিদ্ধান্ত গাছটি আপনার ব্যবহারের ক্ষেত্রে প্রশিক্ষণ-পরবর্তী পরিমাপকরণ পদ্ধতিটি সর্বোত্তম তা নির্ধারণ করতে সহায়তা করতে পারে:

প্রশিক্ষণ-পরবর্তী অপ্টিমাইজেশান বিকল্প

গতিশীল পরিসীমা পরিমাপ

ট্রেনিং-পরবর্তী কোয়ান্টাইজেশনের সহজতম ফর্মটি স্ট্যাটিক্যালি শুধুমাত্র ফ্লোটিং পয়েন্ট থেকে পূর্ণসংখ্যা পর্যন্ত ওজনের পরিমাণ নির্ধারণ করে, যার 8-বিট নির্ভুলতা রয়েছে:

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-বিটের উপর ভিত্তি করে অ্যাক্টিভেশনগুলিকে গতিশীলভাবে পরিমাপ করে এবং 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)]

যেহেতু টেনসরফ্লো 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()

শুধুমাত্র পূর্ণসংখ্যা

মাইক্রোকন্ট্রোলার এবং কোরাল এজ TPU-এর জন্য 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()

Float16 কোয়ান্টাইজেশন

16-বিট ফ্লোটিং পয়েন্ট সংখ্যার জন্য IEEE স্ট্যান্ডার্ড, float16-এ ওজনের পরিমাণ নির্ধারণ করে আপনি একটি ফ্লোটিং পয়েন্ট মডেলের আকার কমাতে পারেন। ওজনের 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()

float16 কোয়ান্টাইজেশনের সুবিধাগুলি নিম্নরূপ:

  • এটি মডেলের আকার অর্ধেক পর্যন্ত হ্রাস করে (যেহেতু সমস্ত ওজন তাদের আসল আকারের অর্ধেক হয়ে যায়)।
  • এটি নির্ভুলতার সর্বনিম্ন ক্ষতি ঘটায়।
  • এটি কিছু প্রতিনিধিকে সমর্থন করে (যেমন GPU প্রতিনিধি) যা সরাসরি float16 ডেটাতে কাজ করতে পারে, যার ফলে float32 কম্পিউটেশনের চেয়ে দ্রুত কার্যকর হয়।

float16 কোয়ান্টাইজেশনের অসুবিধাগুলি নিম্নরূপ:

  • এটি স্থির বিন্দু গণিতের পরিমাণ নির্ধারণের মতো বিলম্ব কমায় না।
  • ডিফল্টরূপে, একটি float16 কোয়ান্টাইজড মডেল সিপিইউতে চালানোর সময় ফ্লোট 32-এর ওজনের মানগুলিকে "অপমানিত" করবে। (উল্লেখ্য যে GPU প্রতিনিধি এই ডিকোয়ান্টাইজেশন সঞ্চালন করবে না, যেহেতু এটি 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()

এই কোয়ান্টাইজেশন স্কিম দ্বারা প্রদত্ত নির্ভুলতার উন্নতিগুলির উদাহরণগুলির মধ্যে রয়েছে: * সুপার-রেজোলিউশন, * অডিও সিগন্যাল প্রসেসিং যেমন নয়েজ ক্যান্সেলিং এবং বিমফর্মিং, * ইমেজ ডি-নোইজিং, * একটি একক ইমেজ থেকে HDR পুনর্গঠন।

এই পরিমাণ নির্ধারণের অসুবিধা হল:

  • অপ্টিমাইজ করা কার্নেল বাস্তবায়নের অভাবের কারণে বর্তমানে অনুমান 8-বিট পূর্ণ পূর্ণসংখ্যার তুলনায় উল্লেখযোগ্যভাবে ধীর।
  • বর্তমানে এটি বিদ্যমান হার্ডওয়্যার এক্সিলারেটেড TFLite প্রতিনিধিদের সাথে বেমানান।

এই কোয়ান্টাইজেশন মোডের জন্য একটি টিউটোরিয়াল এখানে পাওয়া যাবে।

মডেল নির্ভুলতা

যেহেতু ওজনগুলি প্রশিক্ষণের পরে পরিমাপ করা হয়, বিশেষত ছোট নেটওয়ার্কগুলির জন্য সঠিকতা হ্রাস হতে পারে। TensorFlow Hub- এ নির্দিষ্ট নেটওয়ার্কের জন্য প্রাক-প্রশিক্ষিত সম্পূর্ণ কোয়ান্টাইজড মডেলগুলি প্রদান করা হয়। সঠিকতার কোন অবনতি গ্রহণযোগ্য সীমার মধ্যে রয়েছে তা যাচাই করার জন্য কোয়ান্টাইজড মডেলের যথার্থতা পরীক্ষা করা গুরুত্বপূর্ণ। TensorFlow Lite মডেলের নির্ভুলতা মূল্যায়ন করার জন্য টুল আছে।

বিকল্পভাবে, সঠিকতা ড্রপ খুব বেশি হলে, কোয়ান্টাইজেশন সচেতন প্রশিক্ষণ ব্যবহার করার কথা বিবেচনা করুন। যাইহোক, এটি করার জন্য জাল কোয়ান্টাইজেশন নোড যোগ করার জন্য মডেল প্রশিক্ষণের সময় পরিবর্তনের প্রয়োজন, যেখানে এই পৃষ্ঠায় প্রশিক্ষণ-পরবর্তী কোয়ান্টাইজেশন কৌশলগুলি একটি বিদ্যমান প্রাক-প্রশিক্ষিত মডেল ব্যবহার করে।

কোয়ান্টাইজড টেনসরের জন্য প্রতিনিধিত্ব

8-বিট কোয়ান্টাইজেশন নিম্নলিখিত সূত্র ব্যবহার করে ভাসমান বিন্দু মান আনুমানিক।

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

উপস্থাপনার দুটি প্রধান অংশ রয়েছে:

  • প্রতি-অক্ষ (ওরফে প্রতি-চ্যানেল) বা প্রতি-টেনসর ওজন 0-এর সমান শূন্য-বিন্দু সহ পরিসরে [-127, 127] int8 দুই এর পরিপূরক মান দ্বারা উপস্থাপিত।

  • প্রতি-টেনসর অ্যাক্টিভেশন/ইনপুট int8 দুই এর পরিপূরক মান দ্বারা উপস্থাপিত পরিসর [-128, 127], পরিসরে একটি শূন্য-বিন্দু সহ [-128, 127]।

আমাদের কোয়ান্টাইজেশন স্কিমের বিশদ দর্শনের জন্য, দয়া করে আমাদের কোয়ান্টাইজেশন স্পেক দেখুন। যে হার্ডওয়্যার বিক্রেতারা TensorFlow Lite-এর প্রতিনিধি ইন্টারফেসে প্লাগ-ইন করতে চান তাদের সেখানে বর্ণিত কোয়ান্টাইজেশন স্কিম বাস্তবায়ন করতে উৎসাহিত করা হয়।