تحويل TensorFlow RNN إلى LiteRT

نظرة عامة

يتيح LiteRT تحويل نماذج الشبكات العصبية المتكررة (RNN) في TensorFlow إلى عمليات LSTM المدمجة في LiteRT. تتوفّر العمليات المدمجة لزيادة أداء عمليات التنفيذ الأساسية للنواة إلى أقصى حدّ، بالإضافة إلى توفير واجهة ذات مستوى أعلى لتحديد عمليات التحويل المعقّدة، مثل التكميم.

بما أنّ هناك العديد من صيغ واجهات برمجة التطبيقات الخاصة بالشبكات العصبية المتكررة في TensorFlow، فقد اتّبعنا نهجًا ذا شقّين:

  1. توفير دعم مدمج لواجهات برمجة التطبيقات العادية لشبكات RNN في TensorFlow، مثل Keras LSTM هذا هو الخيار الذي يُنصح به.
  2. توفير واجهة في بنية الإحالات الناجحة لعمليات تنفيذ الشبكات العصبية المتكرّرة (RNN) التي يحدّدها المستخدم لتوصيلها وتحويلها إلى LiteRT نقدّم مثالَين جاهزَين للاستخدام على هذا النوع من التحويل باستخدام واجهتَي شبكة RNN LSTMCellSimple وLayerNormalizedLSTMCellSimple في Lingvo.

Converter API

هذه الميزة متوفّرة في الإصدار 2.3 من TensorFlow. ويمكن أيضًا الحصول عليه من خلال حزمة tf-nightly pip أو من أحدث إصدار.

تتوفّر وظيفة التحويل هذه عند التحويل إلى LiteRT من خلال SavedModel أو من نموذج Keras مباشرةً. الاطّلاع على أمثلة على الاستخدام

من النموذج المحفوظ

# build a saved model. Here concrete_function is the exported function
# corresponding to the TensorFlow model containing one or more
# Keras LSTM layers.
saved_model, saved_model_dir = build_saved_model_lstm(...)
saved_model.save(saved_model_dir, save_format="tf", signatures=concrete_func)

# Convert the model.
converter = TFLiteConverter.from_saved_model(saved_model_dir)
tflite_model = converter.convert()

من نموذج Keras

# build a Keras model
keras_model = build_keras_lstm(...)

# Convert the model.
converter = TFLiteConverter.from_keras_model(keras_model)
tflite_model = converter.convert()

مثال

يوضّح نموذج Keras LSTM إلى LiteRT Colab طريقة الاستخدام الكاملة مع مفسّر LiteRT.

واجهات برمجة تطبيقات الشبكات العصبية المتكرّرة (RNN) المتوافقة مع TensorFlow

نوفّر إمكانية تحويل Keras LSTM إلى LiteRT بدون الحاجة إلى إجراء أي تعديلات. للحصول على تفاصيل حول طريقة عمل ذلك، يُرجى الرجوع إلى واجهة Keras LSTM وإلى منطق التحويل هنا.

من المهم أيضًا إبراز عقد LiteRT الخاص بـ LSTM فيما يتعلق بتعريف عملية Keras:

  1. البُعد 0 لموتر الإدخال هو حجم الدفعة.
  2. تمثّل السمة 0 لموتر recurrent_weight عدد المخرجات.
  3. يتم تبديل موضع الموترَين weight وrecurrent_kernel.
  4. يتم تقسيم موترات الوزن المنقول وموترات recurrent_kernel المنقولة وbias إلى 4 موترات متساوية الحجم على طول البُعد 0. وتتطابق هذه القيم مع بوابة الإدخال وبوابة النسيان والخلية وبوابة الإخراج.

صيغ LSTM في Keras

الوقت الرئيسي

يمكن للمستخدمين اختيار عرض البيانات حسب الوقت أو عدم عرضها حسب الوقت. تضيف Keras LSTM سمة time-major في سمات تعريف الدالة. بالنسبة إلى LSTM المتسلسل أحادي الاتجاه، يمكننا ببساطة الربط بالسمة time major الخاصة بـ unidirecional_sequence_lstm.

BiDirectional LSTM

يمكن تنفيذ شبكة LSTM ثنائية الاتجاه باستخدام طبقتَي LSTM في Keras، إحداهما للتسلسل الأمامي والأخرى للتسلسل الخلفي، ويمكنك الاطّلاع على الأمثلة هنا. عندما نرصد السمة go_backward، نتعرّف عليها على أنّها LSTM عكسي، ثم نجمع بين LSTM العادي والعكسي. هذه ميزة سيتم إطلاقها في المستقبل. في الوقت الحالي، يؤدي ذلك إلى إنشاء عمليتَي UnidirectionalSequenceLSTM في نموذج LiteRT.

أمثلة على الإحالات الناجحة المستندة إلى نموذج LSTM من تحديد المستخدم

توفّر LiteRT أيضًا طريقة لتحويل عمليات تنفيذ LSTM التي يحدّدها المستخدم. نستخدم هنا شبكة LSTM من Lingvo كمثال على كيفية تنفيذ ذلك. للحصول على التفاصيل، يُرجى الرجوع إلى واجهة lingvo.LSTMCellSimple ومنطق التحويل هنا. نقدّم أيضًا مثالاً على تعريف آخر من تعريفات LSTM في Lingvo في واجهة lingvo.LayerNormalizedLSTMCellSimple ومنطق التحويل الخاص بها هنا.

"استخدام شبكة عصبية متكررة (RNN) خاصة بك في LiteRT"

إذا كانت واجهة شبكة RNN الخاصة بالمستخدم مختلفة عن الواجهات المتوافقة العادية، يتوفّر خياران:

الخيار 1: كتابة رمز محوّل في TensorFlow python لتكييف واجهة الشبكة العصبية المتكررة مع واجهة الشبكة العصبية المتكررة في Keras وهذا يعني دالة tf.function مع التعليق التوضيحي tf_implements على الدالة التي تم إنشاؤها لواجهة RNN والتي تتطابق مع الدالة التي أنشأتها طبقة LSTM في Keras. بعد ذلك، ستعمل واجهة برمجة التطبيقات نفسها للإحالات الناجحة المستخدَمة في Keras LSTM.

الخيار 2: إذا لم يكن ما سبق ممكنًا (على سبيل المثال، إذا كان Keras LSTM يفتقد بعض الوظائف التي يوفّرها حاليًا عامل التشغيل المدمج LSTM في LiteRT، مثل تسوية الطبقة)، يمكنك توسيع محوّل LiteRT من خلال كتابة رمز تحويل مخصّص وتوصيله بتمرير MLIR الخاص بوظائف prepare-composite-functions هنا. يجب التعامل مع واجهة الدالة على أنّها عقد واجهة برمجة تطبيقات، ويجب أن تحتوي على الوسيطات اللازمة للتحويل إلى عمليات LiteRT LSTM المدمجة، أي الإدخال والانحياز والأوزان والإسقاط والتسوية على مستوى الطبقة وما إلى ذلك. من الأفضل أن يكون للموترات التي يتم تمريرها كوسيطات إلى هذه الدالة ترتيب معروف (أي RankedTensorType في MLIR). ويسهّل ذلك كثيرًا كتابة رمز الإحالة الناجحة الذي يمكنه افتراض هذه الموترات على أنّها RankedTensorType، ويساعد في تحويلها إلى موترات مرتبة تتوافق مع معاملات عامل LiteRT المدمج.

من الأمثلة الكاملة على مسار الإحالة الناجحة هذا عملية تحويل LSTMCellSimple إلى LiteRT في Lingvo.

يمكنك الاطّلاع على تعريف LSTMCellSimple في Lingvo هنا. يمكن تحويل النماذج التي تم تدريبها باستخدام خلية LSTM هذه إلى LiteRT على النحو التالي:

  1. يجب تضمين جميع استخدامات LSTMCellSimple في tf.function مع إضافة التعليق التوضيحي tf_implements الذي يحمل التصنيف المناسب (على سبيل المثال، سيكون lingvo.LSTMCellSimple اسمًا مناسبًا للتعليق التوضيحي هنا). تأكَّد من أنّ tf.function الذي تم إنشاؤه يتطابق مع واجهة الدالة المتوقّعة في رمز التحويل. هذا هو عقد بين مؤلف النموذج الذي يضيف التعليق التوضيحي ورمز التحويل.
  2. توسيع عملية prepare-composite-functions لتضمين عملية مركّبة مخصّصة في عملية تحويل LSTM المدمجة في LiteRT اطّلِع على رمز التحويل الخاص بـ LSTMCellSimple.

    عقد التحويل:

  3. يتم تبديل موضع موترات الوزن والإسقاط.

  4. يتم استخراج {الإدخال، المتكرر} إلى {الخلية، بوابة الإدخال، بوابة النسيان، بوابة الإخراج} من خلال تقسيم موتر الأوزان المحوَّل.

  5. يتم استخراج {bias} إلى {cell, input gate, forget gate, output gate} من خلال تقسيم موتر الانحياز.

  6. يتم استخراج الإسقاط من خلال تقسيم موتر الإسقاط المحوَّل.

  7. تمت كتابة رمز إحالة ناجحة مشابهة لـ LayerNormalizedLSTMCellSimple.

  8. يمكن إعادة استخدام بقية بنية LiteRT الأساسية للإحالات الناجحة، بما في ذلك جميع عمليات MLIR المحدّدة، بالإضافة إلى عملية التصدير النهائية إلى LiteRT flatbuffer.

المشاكل/القيود المعروفة

  1. في الوقت الحالي، لا تتوفّر سوى إمكانية تحويل Keras LSTM بدون حالة (السلوك التلقائي في Keras). تحويل Keras LSTM ذي الحالة هو عمل مستقبلي.
  2. لا يزال من الممكن تصميم طبقة Keras LSTM ذات حالة باستخدام طبقة Keras LSTM الأساسية عديمة الحالة وإدارة الحالة بشكل صريح في برنامج المستخدم. سيظل بإمكانك تحويل برنامج TensorFlow هذا إلى LiteRT باستخدام الميزة الموضّحة هنا.
  3. يتم حاليًا تصميم شبكة LSTM الثنائية الاتجاه على شكل عمليتَي UnidirectionalSequenceLSTM في LiteRT. سيتم استبدال ذلك بعملية BidirectionalSequenceLSTM واحدة.