המרת RNN של TensorFlow ל-LiteRT

סקירה כללית

ב-LiteRT יש תמיכה בהמרת מודלים של TensorFlow RNN למודלים של LiteRT פעולות משולבות של LSTM. קיימות פעולות משולבות שנועדו למקסם את הביצועים של את הטמעת הליבה שלהם, וגם לספק רמה גבוהה יותר להגדרת טרנספורמציות מורכבות כמו קוונטיזציה.

מכיוון שיש ב-TensorFlow וריאנטים רבים של ממשקי RNN API, הגישה שלנו לקפל:

  1. לספק תמיכה מובנית בממשקי API סטנדרטיים של TensorFlow RNN כמו Keras LSTM. זו האפשרות המומלצת.
  2. מספקים ממשק לתשתית ההמרות עבור הטמעות RNN שהוגדרו על ידי המשתמש כדי לחבר אותן ולהמיר אותן LiteRT. נציג כמה דוגמאות מחוץ לאריזה של שמשתמשים ב-lingvo LSTMCellSimple וגם LayerNormalizedLSTMCellSimple ממשקי RNN.

ממשק API של Converter

התכונה היא חלק מגרסת TensorFlow 2.3. זמינה גם דרך PIP או tf-nightly מהראש.

פונקציונליות ההמרה הזו זמינה כשממירים ל-LiteRT דרך SaveModel או ישירות ממודל 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.

תמיכה בממשקי API של TensorFlow RNN

אנחנו תומכים בהמרה מוכנה מראש של Keras LSTM ל-LiteRT. עבור הסבר איך זה עובד, ממשק Keras LSTM וללוגיקת ההמרות כאן.

חשוב גם להדגיש בכבוד את חוזה LSTM של LiteRT להגדרה של פעולת Keras:

  1. המאפיין 0 של מפריד הקלט הוא גודל האצווה.
  2. המאפיין 0 של הטינזור recurrent_weight הוא מספר הפלט.
  3. הטנזטורים weight ו-recurrent_kernel עוברים טרנספורמציה.
  4. המשקל המוחלף, הפרמטרים של recurrent_kernel והטיות שעברו טרנספורמציה הם מחולקים ל-4 מעבדי Tensor בגודל שווה לאורך המאפיין 0. הן מתייחסות אל שער קלט, שכח שער, תא ושער פלט.

וריאציות של Keras LSTM

זמן ראשי

משתמשים יכולים לבחור בהגדרה 'תקופה גדולה יותר' או 'ללא'. Keras LSTM מוסיף עניין בזמן במאפיין ' הגדרת פונקציה'. עבור רצף חד-כיווני LSTM, אנחנו יכולים פשוט למפות unidirecional_sequence_lstm המאפיין 'זמן ראשי'.

מערכת LSTM דו-כיוונית

ניתן להטמיע שרת LSTM דו-כיווני עם שתי שכבות Keras LSTM, אחת קדימה ואחת אחורה, אפשר לראות דוגמאות כאן. כשאנחנו רואים את המאפיין go_backward, אנחנו מזהים אותו בתור LSTM לאחור, אנחנו מקבצים קדימה לאחור ב-LSTM. זו עבודה עתידית. נכון לעכשיו, הדבר יוצר שתי פעולות UnidirectionalSequenceLSTM ב-LiteRT מודל טרנספורמר.

דוגמאות להמרות של LSTM בהגדרת המשתמש

LiteRT מאפשר גם להמיר נתוני LSTM שהוגדרו על ידי המשתמש בפועל. כאן אנחנו משתמשים ב-LSTM של Lingvo כדוגמה לאופן שבו . פרטים נוספים זמינים ממשק lingvo.LSTMCellSimple ולוגיקת ההמרות כאן. הוספנו דוגמה להגדרות נוספות של Lingvo LSTM ב: ממשק lingvo.LayerregularizedLSTMCellSimple ואת לוגיקת ההמרות שלו כאן.

"Bring your TensorFlow RNN" ל-LiteRT

אם ממשק ה-RNN של המשתמש שונה מהממשק הרגיל שנתמך, יש שתי אפשרויות:

אפשרות 1: כתיבת קוד מתאם ב-TensorFlow python כדי להתאים את ממשק ה-RNN לממשק ה-RNN של Keras. כלומר פונקציית tf.function עם tf_Implements הערה ב- הפונקציה של ממשק ה-RNN שנוצרה שזהה את שכבת Keras LSTM. לאחר מכן, אותו API להמרה שבו נעשה שימוש ב-Keras LSTM יפעל.

אפשרות 2: אם הפעולה שלמעלה לא אפשרית (למשל, חסרים ב-Keras LSTM פונקציונליות שנחשפת כרגע על ידי הפעלת LSTM של LiteRT, כמו שכבת הנורמליזציה), ולאחר מכן להרחיב את ממיר LiteRT באמצעות קוד המרות מותאם אישית ותחבר אותו אל הפונקציות המורכבות MLIR-pass כאן. צריך להתייחס לממשק של הפונקציה כמו לחוזה API, מכילים את הארגומנטים הנדרשים כדי להמיר ל-Fused LiteRT LSTM פעולות - כלומר קלט, הטיה, משקלים, היטל, נירמול של שכבות וכו'. הוא עדיף בשביל שהטנסטורים שמועברים בתור ארגומנטים לפונקציה הזו יהיו יודעים דירוג (כלומר RankedTensorType ב-MLIR). כך הרבה יותר קל לכתוב קוד המרה שיכול להניח את הפרמטרים האלה כ-rankedTensorType, וממירים אותם לטינורים מדורגים שתואמים לשכבת ה-LiteRT האופרנדים של המפעיל.

דוגמה מלאה לתהליך המרה כזה היא ה-LSTMCellSimple של Lingvo המרת LiteRT.

הגדרת LSTMCellSimple ב-Lingvo כאן. ניתן להמיר מודלים שאומנו באמצעות תא LSTM הזה ל-LiteRT בתור ככה:

  1. אפשר לאחסן את כל השימושים של LSTMCellSimple ב-tf.function באמצעות tf_applieds הערה שמסווגת ככזו (למשל, lingvo.LSTMCellSimple תהיה יש כאן שם טוב להערה). צריך לוודא שהפונקציה tf.function נוצרת תואם לממשק של הפונקציה הצפויה בקוד ההמרות. הזה הוא חוזה בין המחבר שמוסיף את ההערה של Google.
  2. הרחבת המעבר של פונקציות מורכבות כדי לחבר פעולה מורכבת מותאמת אישית להמרה של פעולות LSTM ב-LiteRT. צפייה LSTMCellSimple של Google.

    חוזה ההמרה:

  3. הפרמטרים משקל והיטל עוברים טרנספורמציה.

  4. הערך {input, recurrent} בשדה {cell, קלט gate, Delete gate, פלט gate} מחולצים על ידי חיתוך של רכיב המשקל המוחלף.

  5. הערכים {bias} ל-{bias} שחולצו באמצעות חיתוך של זווית ההטיה.

  6. ההיטל מחולץ על ידי חיתוך של מקדח ההיטל המוחלף.

  7. המרה דומה נכתבת עבור LayerNormalizedLSTMCellSimple.

  8. שאר תשתית ההמרות של LiteRT, כולל כל אישורי MLIR מוגדר, כמו גם את הייצוא הסופי למאגר הנתונים הזמני של LiteRT. שנעשה בו שימוש חוזר.

בעיות/מגבלות מוכרות

  1. נכון לעכשיו יש תמיכה רק בהמרת Keras LSTM ללא שמירת מצב (ברירת המחדל היא ב-Keras). המרת Stateful Keras LSTM היא עבודה עתידית.
  2. עדיין אפשר ליצור מודל של שכבת Keras LSTM עם שמירת מצב באמצעות בשכבת תשומת הלב של Keras LSTM ללא שמירת מצב וניהול שלה במפורש בתוכנת המשתמש. עדיין אפשר להמיר תוכנת TensorFlow כזו LiteRT באמצעות התכונה שמתוארת כאן.
  3. מודל LSTM דו-כיווני כרגע מעוצב כשני UnidirectionalSequenceLSTM ב-LiteRT. הערך הזה יוחלף בסימון פעולה של BidirectionalSequenceLSTM