تحديد كمية StableHLO

أنواع التكميم في StableHLO

التقييم الكمي هو أسلوب لتحسين نماذج تعلُّم الآلة من خلال تحويل الأرقام ذات الفاصلة العائمة (مثل تلك المستخدَمة في النماذج الأصلية) إلى أعداد صحيحة ذات دقة أقل. يؤدي ذلك إلى تقليل استخدام الذاكرة وتسريع العمليات الحسابية، ما يجعل النماذج أكثر كفاءة عند نشرها على الأجهزة ذات الموارد المحدودة.

تتّبع عملية التكميم في StableHLO مواصفات التكميم في LiteRT، باستخدام نظام تكميم موحّد يتيح التكميم على مستوى كل موتر وعلى مستوى كل محور. يستمدّ هذا النوع تعبيره من لغة Quant في MLIR، ما يوفّر طريقة موحّدة لتمثيل أنواع البيانات الكمّية.

تؤدي عملية التكميم المنتظم إلى ربط قيم الفاصلة العائمة بالأعداد الصحيحة باستخدام حجم خطوة منتظم، ما يؤدي إلى قيم مكَمَّمة متباعدة بشكل متساوٍ. ويتم تحقيق ذلك من خلال علاقة تشابه باستخدام مَعلمتَين رئيسيتَين للتكميم.

يبسّط التكميم المنتظم تمثيل الأرقام النقطية العائمة من خلال ربطها بأعداد صحيحة متباعدة بشكل متساوٍ. يتم تحقيق هذا الربط من خلال تحويل تشابهي يستخدم مَعلمتَين رئيسيتَين هما: المقياس ونقطة الصفر. يحدّد المقياس حجم الخطوة بين القيم الكمية المتتالية. ويعني المقياس الأصغر أنّ القيم المحدّدة تكون أقرب إلى بعضها. تحدّد نقطة الصفر القيمة العددية التي تمثّل الصفر في مساحة الأرقام العشرية الأصلية.

العلاقة بين قيمة النقطة العائمة الأصلية (real_value) وقيمة العدد الصحيح المكمَّمة (quantized_value) في التكميم المنتظم هي:

real_value = scale * (quantized_value - zero_point)

تحديد الكمية لكل موتر

في التكميم لكل موتر، يتم استخدام مقياس واحد ونقطة صفرية واحدة لجميع القيم ضمن الموتر. يتم التعبير عن نوع كمّي لكل موتر في StableHLO على النحو التالي:

quant.uniform scale:zero_point>

مثال: !quant.uniform<i8:f32, 0.01:50>

يمثّل ذلك عددًا صحيحًا مكونًا من 8 بتات (i8) يُستخدم لتخزين رقم نقطة عائمة مكون من 32 بتًا (f32) باستخدام مقياس 0.01 ونقطة صفرية 50.

التكميم لكل محور

يوفّر التكميم لكل محور أسلوبًا أكثر دقة مقارنةً بالتكميم لكل موتر. بدلاً من استخدام مقياس واحد ونقطة صفرية للموتّر بأكمله، يحدّد التكميم لكل محور مقاييس ونقاط صفرية منفصلة للشرائح على طول بُعد معيّن quantized_dimension للموتّر. ويكون ذلك مفيدًا بشكل خاص عندما تختلف القيم بشكل كبير بين السمات المختلفة، ما يتيح الحفاظ على المعلومات ودقتها بشكل أفضل.

لنفترض أنّ لدينا موترًا t بأحجام أبعاد [4, 3, 2]. نختار تحديد عدد البتات لهذا الموتر على طول البُعد الثاني (quantized_dimension = 1)، ما يعني أنّنا سنحصل على ثلاث شرائح (بما أنّ البُعد الثاني يبلغ حجمه 3)، ولكل شريحة مقياس ونقطة صفر خاصَّين بها:

t[:, 0, :]: This slice gets scale[0] and zero_point[0].
t[:, 1, :]: This slice gets scale[1] and zero_point[1].
t[:, 2, :]: This slice gets scale[2] and zero_point[2].

في StableHLO، يتم التعبير عن النوع الكمي لكل محور على النحو التالي:

quant.uniform {scale0:zero_point0, scale1:zero_point1, ...}>

حيث يتطابق طول scale:zero_point مع عدد الشرائح على طول quantized_dimension في الموتر الحاوي.

مثال: tensor<4x3x2x!quant.uniform<i8:f32:1, {0.2:20, 0.1:10, 0.3:30}>>

مراحل التكميم في StableHLO

توفّر StableHLO العديد من عمليات تمرير المترجم التي تتيح إجراء عمليات تحويل وتحسين مختلفة ذات صلة بالتكميم، ما يمنحك المرونة في طريقة التعامل مع النماذج الكمية. وهذه البطاقات هي:

stablehlo-legalize-qdq-to-quantized-op

تدمج هذه الخطوة نمطًا شائعًا في النماذج الكمّية، وهو عملية إلغاء التكميم تليها عملية نقطة عائمة، وأخيرًا عملية تكميم، في عملية كمّية واحدة. التفاصيل

stablehlo-legalize-quantized-op-to-qdq

يؤدي هذا التمرير عكس ما يفعله التمرير السابق. تعمل هذه العملية على تقسيم عملية كمّية إلى تسلسل مكافئ من عمليات إلغاء الكمّية وعمليات الفاصلة العائمة وعمليات الكمّية. التفاصيل

stablehlo-legalize-quant-to-math

تحوّل هذه المرحلة عمليات StableHLO على أنواع محدّدة الكم إلى عمليات مكافئة على أنواع الأعداد الصحيحة. وهي تنفّذ بشكل أساسي عمليات حسابية لتحديد الكمية باستخدام عمليات رياضية عادية. تكون عملية التقسيم هذه مفيدة لأنظمة لا تتوافق مع التكميم بشكلٍ أصلي، ولكن يمكنها مع ذلك استخدام عمليات التكميم الحسابية للتعبير عن دلالات النماذج المكمَّمة. التفاصيل

stablehlo-quant-legalize-to-tosa-rescale

توفّر StableHLO إمكانية تحويل العمليات الكمية إلى تمثيلات مقابلة في لهجة TOSA. ويسهّل هذا الإجراء القانوني التوافق وإمكانية التشغيل التفاعلي بين StableHLO وTOSA. يحوّل هذا الإجراء عمليات التكميم في StableHLO بشكل استراتيجي إلى مجموعة من عمليات StableHLO وTOSA، مع استخدام لغة TOSA بشكل أساسي في عملية rescale. تؤدي عملية tosa.rescale دورًا مهمًا في تعديل المقياس ونقطة الصفر للقيم المكمَّمة، ما يتيح تمثيلاً دقيقًا للبيانات المكمَّمة ضمن إطار عمل TOSA. التفاصيل

tosa-rescale-legalize-to-stablehlo

تعيد هذه الخطوة كتابة عمليات إعادة التحجيم في TOSA إلى عمليات رياضية أولية في StableHLO. من حالات الاستخدام الرئيسية لهذه السمة السماح لمفسّر StableHLO بتقييم البرامج التي تحتوي على عمليات إعادة قياس TOSA. التفاصيل

تقييم البرامج الكمية

يمكن لمفسّر StableHLO المرجعي تنفيذ البرامج التي تتضمّن عمليات كمّية بكفاءة. ولتحقيق ذلك، يتم أولاً تحويل البرنامج إلى تمثيل مكافئ باستخدام عمليات الأعداد الصحيحة فقط. تتضمّن عملية التخفيض سلسلة من عمليات التجميع التي تحوّل البرنامج قبل تفسيره.

بشكل أساسي، يستفيد المترجم من عملية stablehlo-legalize-quant-to-math لتحويل العمليات الكمية إلى عمليات حسابية صحيحة مقابلة. يقدّم هذا التمرير عمليات بث CHLO للتعامل مع الضرب/القسمة على نطاق واسع وإضافة نقطة الصفر. لضمان التوافق مع برنامج StableHLO المفسّر، يتم بعد ذلك تحويل عمليات CHLO هذه إلى عمليات StableHLO. يؤدي ذلك إلى تقديم عمليات مرتبطة بالأشكال يتم بعد ذلك تحويلها إلى شكل أساسي وتحسينها باستخدام سلسلة من عمليات التحويل إلى الشكل الأساسي.

في ما يلي التسلسل الكامل لعمليات التمرير المتضمّنة في عملية التخفيض هذه:

stablehlo-legalize-quant-to-math
chlo-legalize-to-stablehlo
canonicalize
shape-legalize-to-stablehlo
stablehlo-canonicalize-dynamism

حالات الاختبار الكمّية

توفر StableHLO مجموعة شاملة من حالات الاختبار الكمّية للتحقّق من صحة العمليات الكمّية وسلوكها. تعمل حالات الاختبار هذه كاختبارات وحدات، وتغطّي عمليات StableHLO المختلفة في سيناريوهات تحديد الكم.

يبدو مثال نموذجي لحالة اختبار كمّية كما يلي

func.func @main() -> tensor<11xf32> {
    %operand_0 = stablehlo.constant dense<...> : tensor<11xf32>
    %operand_1 = stablehlo.constant dense<...> : tensor<11xf32>
    %golden = stablehlo.constant dense<...> : tensor<11xf32>

    %0 = stablehlo.uniform_quantize %operand_0 : (tensor<11xf32>) -> tensor<11x!quant.uniform<i8:f32, 0.3>>
    %1 = stablehlo.uniform_quantize %operand_1 : (tensor<11xf32>) -> tensor<11x!quant.uniform<i8:f32, 0.3>>

    %2 = stablehlo.add %1, %0 : tensor<11x!quant.uniform<i8:f32, 0.3>>

    %result = stablehlo.uniform_dequantize %2 : (tensor<11x!quant.uniform<i8:f32, 0.3>>) -> tensor<11xf32>

    %4 = stablehlo.custom_call @check.eq(%golden, %result) : (tensor<11xf32>, tensor<11xf32>) -> tensor<i1>

    return %3 : tensor<11xf32>
  }

وتشمل:

  • بيانات الإدخال: قيم الإدخال التمثيلية للعملية
  • الناتج الذهبي: هو الناتج المتوقّع للعملية عند تطبيقها على بيانات الإدخال، بما يتوافق مع المفسّر المرجعي StableHLO ومقيّم HLO.

تكون حالات الاختبار هذه مفيدة في ما يلي:

  • التحقّق من صحة التكميم في StableHLO: التأكّد من أنّ سلوك التكميم في عمليات StableHLO يتوافق مع النتائج المتوقّعة.
  • التحقّق من الصحة: مقارنة سلوك التكميم في StableHLO مع عمليات التنفيذ أو الأُطر الأخرى
  • تصحيح الأخطاء والتطوير: المساعدة في تطوير ميزات أو تحسينات جديدة متعلقة بالتكميم وتصحيح الأخطاء فيها