إنّ قياس الكمّية بعد التدريب هو أسلوب إحالة ناجحة يمكن أن يقلّل من حجم النموذج. مع تحسين وقت استجابة وحدة المعالجة المركزية (CPU) ومسرِّع الأجهزة، مع تراجع دقة النموذج. يمكنك تحديد كمّي لعدد عشري تم تدريبه مسبقًا جدول TensorFlow عند تحويله إلى تنسيق LiteRT باستخدام محول LiteRT:
طرق التحسين
هناك العديد من خيارات التحديد الكمي بعد التدريب للاختيار من بينها. إليك موجز للخيارات والمزايا التي تقدمها:
الأسلوب | المزايا | أجهزة |
---|---|---|
النطاق الديناميكي تحديد الكَمي | أصغر بـ 4 مرات، وبسرعة أكبر 2x-3x | وحدة معالجة مركزية (CPU) |
عدد صحيح كامل تحديد الكَمي | أصغر بـ 4 مرات، وأسرع بمقدار 3 مرات | وحدة معالجة مركزية (CPU) ووحدة معالجة الموتّرات مع Edge TPU متحكّمات دقيقة |
كمية التعويم 16 | وحدة معالجة رسومات أصغر حجمًا بمرتين التسريع | وحدة المعالجة المركزية (CPU)، وحدة معالجة الرسومات (GPU) |
يمكن أن تساعد شجرة القرار التالية في تحديد عملية القياس الكمّي بعد التدريب الأفضل لحالة استخدامك وهي:
ما مِن عملية كمّي
يوصى ببدء التحويل إلى نموذج TFLite بدون التحديد الكمي نقطة واحدة. سيؤدي هذا إلى إنشاء نموذج TFLite عائم.
import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir) tflite_quant_model = converter.convert()
وننصحك بإجراء ذلك كخطوة أولى للتحقق من أنّ الملف الأصلي تتوافق مشغلات نموذج TF مع TFLite ويمكن استخدامها أيضًا الأساسي لتصحيح أخطاء الكمية الناتجة عن التدريب اللاحق طرق التحليل الكمي. فعلى سبيل المثال، إذا نتج نموذج TFLite محدد نتائج غير متوقعة، في حين أن نموذج TFLite العائم دقيق، يمكننا تضييق مشكلة الأخطاء التي أحدثتها النسخة الكَمية من عوامل تشغيل TFLite.
تقدير النطاق الديناميكي
يوفر تحديد النطاق الديناميكي استهلاكًا أقل للذاكرة وعملية حسابية أسرع. دون الحاجة إلى تقديم مجموعة بيانات تمثيلية للمعايرة. هذا النمط نوع قياس الكمي، تحدد بشكل ثابت الأوزان فقط من النقطة العائمة إلى عدد صحيح في وقت الإحالة الناجحة، وهو ما يوفر دقة 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 بت وعمليات التفعيل. يوفّر هذا التحسين وقت الاستجابة قريب من استنتاجات النقاط الثابتة بالكامل. ومع ذلك، لا تزال النتائج باستخدام النقطة العائمة، بحيث تكون السرعة المتزايدة لعمليات النطاق الديناميكي أقل من العملية الحسابية ذات النقاط الثابتة الكاملة.
التحديد الكامل للأعداد الصحيحة
كما يمكنك الحصول على المزيد من التحسينات المتعلقة بوقت الاستجابة، وتقليل الاستخدام في ذروة استخدام الذاكرة، التوافق مع الأجهزة أو مسرِّعات الأعمال بعدد صحيح فقط من خلال التأكد جميع نماذج الرياضيات يتم قياسها بأعداد صحيحة.
لكمية الأعداد الصحيحة الكاملة، تحتاج إلى معايرة أو تقدير النطاق،
بعبارة أخرى، (الحد الأدنى، الحد الأقصى) لجميع نقاط التوتر العائمة في النموذج. على عكس الثابت
عوامل القوة مثل الأوزان والانحرافات والعشرات المتغيرة مثل إدخال النموذج
عمليات التفعيل (مخرجات الطبقات الوسيطة) ومخرجات النموذج
ما لم نجري بضع دورات استنتاجية. وبالتالي، قام المحول
مجموعة بيانات تمثيلية لمعايرتها. يمكن أن تكون مجموعة البيانات هذه عبارة عن
مجموعة فرعية (حوالي 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 من TensorFlow، ننصح باستخدام الأسلوب المستند إلى التوقيع على النهج القائم على قائمة مترابط الإدخال لأن ترتيب متّجه المدخلات يمكن يمكن قلبها بسهولة.
لأغراض الاختبار، يمكنك استخدام مجموعة بيانات وهمية على النحو التالي:
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()
العدد الصحيح فقط
إن إنشاء نماذج أعداد صحيحة فقط هو من حالات الاستخدام الشائعة لـ LiteRT وحدات تحكُّم دقيقة ومرجاني وحدات معالجة الموتّرات Edge
بالإضافة إلى ذلك، لضمان التوافق مع الأجهزة التي تتضمّن أعدادًا صحيحة فقط (مثل الأجهزة التي تعمل بنظام 8 بت وحدات التحكم الدقيقة) والمسرِّعات (مثل وحدة معالجة الموصّلات المركزية Coral Edge 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، وهو معيار معهد معهد الهندسة الكهربائية والإلكترونية (IEEE) لأرقام النقاط العائمة 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 عند تشغيله على وحدة المعالجة المركزية (CPU). (ملاحظة: لن يعمل تفويض وحدة معالجة الرسومات تحديد كمية البيانات هذه، حيث إنه يمكن أن يعمل على بيانات العدد العشري 16).
عدد صحيح فقط: عمليات تفعيل 16 بت بأوزان 8 بت (تجريبية)
هذا نظام كمي تجريبي. وهو مشابه "للعدد الصحيح فقط" ولكن تُحدَّد عمليات التفعيل بناءً على مدى وصولها إلى 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()
إذا لم يكن تقدير الكمّية 16×8 متاحًا لبعض عوامل التشغيل في النموذج، فعندئذٍ من النموذج، إلا أننا نحتفظ بالعوامل غير المدعومة في عدد عائم. تشير رسالة الأشكال البيانية يجب إضافة الخيار التالي إلى 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()
أمثلة على حالات الاستخدام التي تم فيها إدخال تحسينات على الدقة نظام الكمية ما يلي:
- بدقة فائقة،
- معالجة الإشارات الصوتية مثل إلغاء الضوضاء والإنشاء الشعاعي،
- إزالة تشويش الصور
- إعادة إنشاء النطاق العالي الديناميكية من صورة واحدة.
عيب هذا الكم هو:
- يكون الاستنتاج حاليًا أبطأ بشكل ملحوظ من العدد الصحيح الكامل الذي يبلغ 8 بت بسبب نقص في التنفيذ الأمثل للنواة.
- وهو غير متوافق حاليًا مع تنسيق TFLite الحالي الذي تم تسريعه باستخدام الأجهزة. المفوَّضين.
يمكنك العثور على دليل توجيهي لوضع قياس الكمية هذا. هنا.
دقة النموذج
ونظرًا لأن الأوزان يتم قياسها كميًا بعد التدريب، فقد يكون هناك انخفاض في الدقة، خاصةً للشبكات الأصغر. النماذج الكميّة المدرّبة مسبقًا بشكل كامل المقدمة لشبكات محددة على Kaggle الطُرز . من المهم التحقق من دقة النموذج الكمي للتحقق من أن أي انخفاض في الدقة ضمن الحدود المقبولة. هناك أدوات تقييم نموذج LiteRT ودقتها.
بدلاً من ذلك، إذا كان الانخفاض في الدقة كبيرًا جدًا، يمكنك استخدام تحديد الكمّي مدرك التدريب . ومع ذلك، فإن إجراء ذلك يتطلب إجراء تعديلات أثناء تدريب النماذج لإضافة نماذج عقد الكمي، في حين أن تقنيات الكمي الكمّي بعد التدريب على هذا نموذجًا مدرّبًا مسبقًا بالفعل.
تمثيل عوامل العشرات الكَمية
يعمل أسلوب التحديد الكمي بتنسيق 8 بت على تقريب قيم النقطة العائمة باستخدام ما يلي: المعادلة.
\[real\_value = (int8\_value - zero\_point) \times scale\]
يتكون التمثيل من جزأين رئيسيين:
معاملات الترجيح لكل محور (المعروفة أيضًا باسم كل قناة) أو قيم الترجيح لكل متسابق التي تمثلها int8 two تكملة القيم في النطاق [ -127, 127] بنقطة صفرية تساوي 0.
عمليات التفعيل/الإدخالات لكل موتّر ممثلة بقيم التكملة لـ int8 two في النطاق [-128، 127]، بنقطة صفرية في النطاق [-128، 127].
للحصول على عرض تفصيلي لنظام الكمية، يُرجى مراجعة مقالة تحديد الكمّي. المواصفات. مورّدو الأجهزة الذين يريدون استخدام TensorFlow يتم تشجيع واجهة التفويض في Lite على تنفيذ مخطط الكمية الموضحة هناك.