تبدیل TensorFlow RNN به LiteRT

نمای کلی

LiteRT از تبدیل مدل های TensorFlow RNN به عملیات LSTM ذوب شده LiteRT پشتیبانی می کند. عملیات ذوب شده برای به حداکثر رساندن عملکرد پیاده‌سازی هسته زیربنایی خود و همچنین ارائه یک رابط سطح بالاتر برای تعریف تبدیل‌های پیچیده مانند کوانتیزه‌سازی وجود دارد.

از آنجایی که انواع مختلفی از API های RNN در TensorFlow وجود دارد، رویکرد ما دو جنبه بوده است:

  1. پشتیبانی بومی برای APIهای استاندارد TensorFlow RNN مانند Keras LSTM ارائه دهید. این گزینه پیشنهادی است.
  2. یک رابط به زیرساخت تبدیل برای پیاده سازی های RNN تعریف شده توسط کاربر برای اتصال و تبدیل به LiteRT ارائه دهید. ما چند نمونه خارج از جعبه از چنین تبدیلی را با استفاده از رابط های LSTMCellSimple و LayerNormalizedLSTMCellSimple RNN lingvo ارائه می کنیم.

مبدل API

این ویژگی بخشی از نسخه TensorFlow 2.3 است. همچنین از طریق پیپ tf-nightly یا از head در دسترس است.

این قابلیت تبدیل هنگام تبدیل به 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()

از مدل کراس

# 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 های RNN TensorFlow پشتیبانی می شوند

ما از تبدیل خارج از جعبه Keras LSTM به LiteRT پشتیبانی می کنیم. برای جزئیات بیشتر در مورد نحوه عملکرد، لطفاً به رابط Keras LSTM مراجعه کنید و به منطق تبدیل اینجا .

همچنین مهم است که قرارداد LSTM LiteRT را با توجه به تعریف عملیات Keras برجسته کنید:

  1. بعد 0 تانسور ورودی اندازه دسته است.
  2. بعد 0 تانسور recurrent_weight تعداد خروجی ها است.
  3. تانسورهای وزن و recurrent_kernel جابه‌جا می‌شوند.
  4. تانسورهای وزن جابجا شده، کرنل_تغییر شده و بایاس به 4 تانسور با اندازه مساوی در امتداد بعد 0 تقسیم می شوند. این تانسورها مربوط به دروازه ورودی، دروازه فراموشی، سلول و دروازه خروجی است .

انواع Keras LSTM

رشته زمان

کاربران ممکن است زمان اصلی یا بدون زمان اصلی را انتخاب کنند. Keras LSTM یک ویژگی زمان عمده را در ویژگی های تابع def اضافه می کند. برای دنباله تک جهتی LSTM، می‌توانیم به سادگی به ویژگی زمان اصلی unidirecional_sequence_lstm نگاشت کنیم.

BiDirectional LSTM

LSTM دو طرفه را می توان با دو لایه Keras LSTM، یکی برای جلو و دیگری برای عقب پیاده سازی کرد، نمونه هایی را در اینجا ببینید. هنگامی که ویژگی go_backward را می بینیم، آن را به عنوان LSTM عقب مانده می شناسیم، سپس LSTM رو به جلو و عقب را با هم گروه بندی می کنیم. این کار آینده است. در حال حاضر، این دو عملیات UnidirectionalSequenceLSTM در مدل LiteRT ایجاد می کند.

مثال های تبدیل LSTM تعریف شده توسط کاربر

LiteRT همچنین راهی برای تبدیل پیاده سازی های LSTM تعریف شده توسط کاربر ارائه می دهد. در اینجا ما از LSTM Lingvo به عنوان نمونه ای از نحوه پیاده سازی آن استفاده می کنیم. برای جزئیات لطفاً به رابط lingvo.LSTMCellSimple و منطق تبدیل اینجا مراجعه کنید. ما همچنین مثالی برای یکی دیگر از تعاریف LSTM Lingvo در رابط lingvo.LayerNormalizedLSTMCellSimple و منطق تبدیل آن در اینجا ارائه می دهیم.

"TensorFlow RNN خود را به LiteRT بیاورید".

اگر رابط RNN کاربر با رابط های استاندارد پشتیبانی شده متفاوت باشد، چند گزینه وجود دارد:

گزینه 1: کد آداپتور را در پایتون TensorFlow بنویسید تا رابط RNN را با رابط Keras RNN تطبیق دهد. این به معنای یک تابع tf. با حاشیه نویسی tf_implements در عملکرد رابط RNN تولید شده است که با آنچه که توسط لایه Keras LSTM ایجاد شده است، یکسان است. پس از این، همان API تبدیل مورد استفاده برای Keras LSTM کار خواهد کرد.

گزینه 2: اگر موارد فوق امکان پذیر نیست (مثلاً Keras LSTM برخی از عملکردها را که در حال حاضر توسط عملیات LSTM ذوب شده LiteRT مانند عادی سازی لایه نشان داده شده است را از دست داده است)، سپس مبدل LiteRT را با نوشتن کد تبدیل سفارشی گسترش دهید و آن را به آماده-کامپوزیت وصل کنید. -عملکرد MLIR-pass در اینجا . رابط تابع باید مانند یک قرارداد API در نظر گرفته شود و باید حاوی آرگومان های مورد نیاز برای تبدیل به عملیات LiteRT LSTM ذوب شده باشد - مانند ورودی، بایاس، وزن، طرح ریزی، عادی سازی لایه، و غیره. ترجیحاً برای تانسورهایی که به عنوان آرگومان به این تابع ارسال می شوند، باشد. داشتن رتبه شناخته شده (یعنی RankedTensorType در MLIR). این کار نوشتن کد تبدیلی که بتواند این تانسورها را به عنوان RankedTensorType در نظر بگیرد بسیار آسان‌تر می‌کند و به تبدیل آن‌ها به تانسورهای رتبه‌بندی شده مربوط به عملوندهای اپراتور LiteRT ذوب شده کمک می‌کند.

یک مثال کامل از چنین جریان تبدیلی، تبدیل LSTMCellSimple به LiteRT Lingvo است.

LSTMCellSimple در Lingvo در اینجا تعریف شده است. مدل های آموزش دیده با این سلول LSTM را می توان به صورت زیر به LiteRT تبدیل کرد:

  1. همه موارد استفاده از LSTMCellSimple را در یک tf.function با حاشیه نویسی tf_implements قرار دهید که به این صورت برچسب گذاری شده است (به عنوان مثال lingvo.LSTMCellSimple یک نام حاشیه نویسی خوب در اینجا خواهد بود). مطمئن شوید که تابع tf. ایجاد شده با رابط تابع مورد انتظار در کد تبدیل مطابقت دارد. این قرارداد بین نویسنده مدل است که حاشیه نویسی و کد تبدیل را اضافه می کند.
  2. پاس توابع آماده-کامپوزیت را گسترش دهید تا تبدیل LSTM ترکیبی سفارشی به LiteRT را متصل کنید. کد تبدیل LSTMCellSimple را ببینید.

    قرارداد تبدیل:

  3. تانسورهای وزن و پروجکشن جابجا می شوند.

  4. {input, recurrent} به {cell, input gate, فراموشی gate, output gate} با برش تانسور وزن جابجا شده استخراج می شود.

  5. با برش دادن تانسور بایاس ، {bias} به {cell, input gate, فراموشی gate, output gate} استخراج می شود.

  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 جایگزین خواهد شد.