يوضح لك هذا البرنامج التعليمي كيفية استخدام مكونات TensorFlow Serving لإنشاء TensorFlow ModelServer القياسي الذي يكتشف الإصدارات الجديدة من نموذج TensorFlow المدرب ويخدمها ديناميكيًا. إذا كنت تريد فقط استخدام الخادم القياسي لخدمة نماذجك، فراجع البرنامج التعليمي الأساسي لخدمة TensorFlow .
يستخدم هذا البرنامج التعليمي نموذج انحدار Softmax البسيط الذي تم تقديمه في البرنامج التعليمي TensorFlow لتصنيف الصور المكتوبة بخط اليد (بيانات MNIST). إذا كنت لا تعرف ما هو TensorFlow أو MNIST، فراجع البرنامج التعليمي MNIST For ML Beginners .
يتكون رمز هذا البرنامج التعليمي من جزأين:
ملف Python mnist_saved_model.py الذي يقوم بتدريب وتصدير إصدارات متعددة من النموذج.
ملف C++ main.cc وهو TensorFlow ModelServer القياسي الذي يكتشف النماذج المصدرة الجديدة ويدير خدمة gRPC لخدمتها.
يمر هذا البرنامج التعليمي بالمهام التالية:
- تدريب وتصدير نموذج TensorFlow.
- إدارة إصدارات النموذج باستخدام TensorFlow Serving
ServerCore
. - قم بتكوين الدفعات باستخدام
SavedModelBundleSourceAdapterConfig
. - خدمة الطلب مع TensorFlow Serving
ServerCore
. - تشغيل واختبار الخدمة.
قبل البدء، قم أولاً بتثبيت Docker
تدريب وتصدير نموذج TensorFlow
أولاً، إذا لم تكن قد قمت بذلك بعد، فقم باستنساخ هذا المستودع على جهازك المحلي:
git clone https://github.com/tensorflow/serving.git
cd serving
امسح دليل التصدير إذا كان موجودًا بالفعل:
rm -rf /tmp/models
تدريب (مع 100 تكرار) وتصدير الإصدار الأول من النموذج:
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
--training_iteration=100 --model_version=1 /tmp/mnist
تدريب (مع تكرارات 2000) وتصدير الإصدار الثاني من النموذج:
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
--training_iteration=2000 --model_version=2 /tmp/mnist
كما ترون في mnist_saved_model.py
، يتم التدريب والتصدير بنفس الطريقة التي يتم بها البرنامج التعليمي الأساسي لـ TensorFlow Serving . لأغراض العرض التوضيحي، أنت تقوم عن قصد بطلب تكرارات التدريب للتشغيل الأول وتصديرها كـ v1، أثناء تدريبها بشكل طبيعي للتشغيل الثاني وتصديرها كـ v2 إلى نفس الدليل الأصلي - كما نتوقع أن يحقق الأخير دقة تصنيف أفضل بسبب التدريب المكثف. يجب أن تشاهد بيانات التدريب لكل تدريب يتم تشغيله في الدليل /tmp/mnist
الخاص بك:
$ ls /tmp/mnist
1 2
ServerCore
الآن تخيل أن الإصدارين 1 و2 من النموذج يتم إنشاؤهما ديناميكيًا في وقت التشغيل، أثناء تجربة خوارزميات جديدة، أو أثناء تدريب النموذج باستخدام مجموعة بيانات جديدة. في بيئة الإنتاج، قد ترغب في إنشاء خادم يمكنه دعم الطرح التدريجي، حيث يمكن اكتشاف الإصدار 2 أو تحميله أو تجربته أو مراقبته أو إرجاعه أثناء تقديم الإصدار 1. وبدلاً من ذلك، قد ترغب في إزالة الإصدار 1 قبل ذكر الإصدار 2. يدعم TensorFlow Serving كلا الخيارين - فبينما يكون أحدهما مفيدًا للحفاظ على التوفر أثناء عملية النقل، فإن الآخر مفيد لتقليل استخدام الموارد (مثل ذاكرة الوصول العشوائي).
Manager
خدمة TensorFlow يفعل ذلك بالضبط. إنه يتعامل مع دورة الحياة الكاملة لنماذج TensorFlow بما في ذلك تحميلها وتقديمها وتفريغها بالإضافة إلى انتقالات الإصدار. في هذا البرنامج التعليمي، ستبني خادمك فوق TensorFlow Serving ServerCore
، والذي يغلف AspiredVersionsManager
داخليًا.
int main(int argc, char** argv) {
...
ServerCore::Options options;
options.model_server_config = model_server_config;
options.servable_state_monitor_creator = &CreateServableStateMonitor;
options.custom_model_config_loader = &LoadCustomModelConfig;
::google::protobuf::Any source_adapter_config;
SavedModelBundleSourceAdapterConfig
saved_model_bundle_source_adapter_config;
source_adapter_config.PackFrom(saved_model_bundle_source_adapter_config);
(*(*options.platform_config_map.mutable_platform_configs())
[kTensorFlowModelPlatform].mutable_source_adapter_config()) =
source_adapter_config;
std::unique_ptr<ServerCore> core;
TF_CHECK_OK(ServerCore::Create(options, &core));
RunServer(port, std::move(core));
return 0;
}
يأخذ ServerCore::Create()
معلمة ServerCore::Options. فيما يلي بعض الخيارات الشائعة الاستخدام:
-
ModelServerConfig
الذي يحدد النماذج التي سيتم تحميلها. يتم الإعلان عن النماذج إما من خلالmodel_config_list
، الذي يعلن عن قائمة ثابتة من النماذج، أو من خلالcustom_model_config
، الذي يحدد طريقة مخصصة للإعلان عن قائمة النماذج التي قد يتم تحديثها في وقت التشغيل. -
PlatformConfigMap
الذي يعين اسم النظام الأساسي (مثلtensorflow
) إلىPlatformConfig
، والذي يُستخدم لإنشاءSourceAdapter
. يقومSourceAdapter
بتكييفStoragePath
(المسار الذي يتم فيه اكتشاف إصدار النموذج) مع ModelLoader
(يقوم بتحميل إصدار النموذج من مسار التخزين ويوفر واجهات انتقال الحالة إلىManager
). إذا كانPlatformConfig
يحتوي علىSavedModelBundleSourceAdapterConfig
، فسيتم إنشاءSavedModelBundleSourceAdapter
، وهو ما سنشرحه لاحقًا.
يعد SavedModelBundle
أحد المكونات الرئيسية لخدمة TensorFlow. إنه يمثل نموذج TensorFlow الذي تم تحميله من مسار معين ويوفر نفس Session::Run
مثل TensorFlow لتشغيل الاستدلال. يقوم SavedModelBundleSourceAdapter
بتكييف مسار التخزين مع Loader<SavedModelBundle>
بحيث يمكن إدارة عمر النموذج بواسطة Manager
. يرجى ملاحظة أن SavedModelBundle
هو خليفة SessionBundle
المهمل. يتم تشجيع المستخدمين على استخدام SavedModelBundle
حيث سيتم قريبًا إزالة دعم SessionBundle
.
مع كل هذه الأمور، يقوم ServerCore
داخليًا بما يلي:
- إنشاء مثيل
FileSystemStoragePathSource
الذي يراقب مسارات تصدير النموذج المعلنة فيmodel_config_list
. - إنشاء مثيل
SourceAdapter
باستخدامPlatformConfigMap
مع النظام الأساسي النموذجي المعلن فيmodel_config_list
وتوصيلFileSystemStoragePathSource
به. بهذه الطريقة، كلما تم اكتشاف إصدار نموذج جديد ضمن مسار التصدير، يقومSavedModelBundleSourceAdapter
بتكييفه معLoader<SavedModelBundle>
. - إنشاء مثيل لتطبيق محدد
Manager
يسمىAspiredVersionsManager
الذي يدير جميع مثيلاتLoader
التي تم إنشاؤها بواسطةSavedModelBundleSourceAdapter
. يقومServerCore
بتصدير واجهةManager
عن طريق تفويض الاستدعاءات إلىAspiredVersionsManager
.
عندما يتوفر إصدار جديد، يقوم AspiredVersionsManager
بتحميل الإصدار الجديد، ويقوم بإلغاء تحميل الإصدار القديم ضمن سلوكه الافتراضي. إذا كنت تريد البدء في التخصيص، فنحن نشجعك على فهم المكونات التي يتم إنشاؤها داخليًا وكيفية تكوينها.
ومن الجدير بالذكر أن TensorFlow Serving تم تصميمه من الصفر ليكون مرنًا للغاية وقابل للتوسيع. يمكنك إنشاء العديد من المكونات الإضافية لتخصيص سلوك النظام، مع الاستفادة من المكونات الأساسية العامة مثل ServerCore
و AspiredVersionsManager
. على سبيل المثال، يمكنك إنشاء مكون إضافي لمصدر البيانات يراقب التخزين السحابي بدلاً من التخزين المحلي، أو يمكنك إنشاء مكون إضافي لسياسة الإصدار يقوم بنقل الإصدار بطريقة مختلفة - في الواقع، يمكنك أيضًا إنشاء مكون إضافي لنموذج مخصص يخدم نماذج غير TensorFlow. هذه المواضيع خارج نطاق هذا البرنامج التعليمي. ومع ذلك، يمكنك الرجوع إلى المصدر المخصص والبرامج التعليمية المخصصة القابلة للعرض لمزيد من المعلومات.
الخلط
ميزة الخادم النموذجية الأخرى التي نريدها في بيئة الإنتاج هي التجميع. عادةً ما تحقق مسرعات الأجهزة الحديثة (وحدات معالجة الرسومات، وما إلى ذلك) المستخدمة في استدلال التعلم الآلي أفضل كفاءة حسابية عند تشغيل طلبات الاستدلال على دفعات كبيرة.
يمكن تشغيل عملية الدفع عن طريق توفير SessionBundleConfig
المناسب عند إنشاء SavedModelBundleSourceAdapter
. في هذه الحالة قمنا بتعيين BatchingParameters
بقيم افتراضية إلى حد كبير. يمكن ضبط عملية الدفع عن طريق تعيين قيم المهلة المخصصة وحجم الدفعة وما إلى ذلك. لمزيد من التفاصيل، يرجى الرجوع إلى BatchingParameters
.
SessionBundleConfig session_bundle_config;
// Batching config
if (enable_batching) {
BatchingParameters* batching_parameters =
session_bundle_config.mutable_batching_parameters();
batching_parameters->mutable_thread_pool_name()->set_value(
"model_server_batch_threads");
}
*saved_model_bundle_source_adapter_config.mutable_legacy_config() =
session_bundle_config;
عند الوصول إلى الدفعة الكاملة، يتم دمج طلبات الاستدلال داخليًا في طلب واحد كبير (الموتر)، ويتم استدعاء tensorflow::Session::Run()
(وهو المكان الذي تأتي منه زيادة الكفاءة الفعلية على وحدات معالجة الرسومات).
يخدم مع المدير
كما هو مذكور أعلاه، تم تصميم TensorFlow Serving Manager
ليكون مكونًا عامًا يمكنه التعامل مع تحميل النماذج التي تم إنشاؤها بواسطة أنظمة التعلم الآلي التعسفية، وتقديمها، وتفريغها، ونقل إصدارها. تم بناء واجهات برمجة التطبيقات الخاصة به حول المفاهيم الأساسية التالية:
Servable : Servable هو أي كائن غير شفاف يمكن استخدامه لخدمة طلبات العميل. يتسم حجم ومستوى التفاصيل القابلة للعرض بالمرونة، بحيث يمكن أن تتضمن الخدمة الفردية القابلة للعرض أي شيء بدءًا من جزء واحد من جدول البحث إلى نموذج واحد يتم تعلمه آليًا إلى مجموعة من النماذج. يمكن أن يكون العرض من أي نوع وواجهة.
الإصدار القابل للعرض : يتم إصدار الإصدارات القابلة للعرض ويمكن
Manager
خدمة TensorFlow إدارة إصدار واحد أو أكثر من الإصدارات القابلة للعرض. يسمح تعيين الإصدار بتحميل أكثر من إصدار واحد للخدمة بشكل متزامن، مما يدعم التشغيل التدريجي والتجريب.الدفق القابل للعرض : الدفق القابل للعرض هو تسلسل إصدارات قابل للعرض، مع أرقام الإصدارات المتزايدة.
النموذج : يتم تمثيل نموذج التعلم الآلي بواسطة واحد أو أكثر من العناصر القابلة للعرض. أمثلة على العناصر القابلة للعرض هي:
- جلسة TensorFlow أو الأغلفة المحيطة بها، مثل
SavedModelBundle
. - أنواع أخرى من نماذج التعلم الآلي.
- جداول البحث عن المفردات
- تضمين جداول البحث.
يمكن تمثيل النموذج المركب على هيئة العديد من العناصر القابلة للعرض المستقلة، أو كنموذج مركب واحد قابل للعرض. قد يتوافق أيضًا العرض القابل للعرض مع جزء من النموذج، على سبيل المثال مع جدول بحث كبير مقسم عبر العديد من مثيلات
Manager
.- جلسة TensorFlow أو الأغلفة المحيطة بها، مثل
لوضع كل هذا في سياق هذا البرنامج التعليمي:
يتم تمثيل نماذج TensorFlow بنوع واحد قابل للعرض -
SavedModelBundle
. يتكونSavedModelBundle
داخليًا منtensorflow:Session
مقترنًا ببعض البيانات التعريفية حول الرسم البياني الذي تم تحميله في الجلسة وكيفية تشغيله للاستدلال.يوجد دليل نظام ملفات يحتوي على دفق من صادرات TensorFlow، كل منها في دليل فرعي خاص بها واسمها هو رقم الإصدار. يمكن اعتبار الدليل الخارجي بمثابة تمثيل متسلسل للتدفق القابل للعرض لنموذج TensorFlow الذي يتم تقديمه. تتوافق كل عملية تصدير مع العناصر القابلة للخدمة التي يمكن تحميلها.
يراقب
AspiredVersionsManager
تدفق التصدير، ويدير دورة حياة جميع العناصر القابلة للخدمةSavedModelBundle
بشكل ديناميكي.
TensorflowPredictImpl::Predict
ثم فقط:
- يطلب
SavedModelBundle
من المدير (من خلال ServerCore). - يستخدم
generic signatures
لتعيين أسماء الموتر المنطقية فيPredictRequest
لأسماء الموتر الحقيقية وربط القيم بالموترات. - يدير الاستدلال.
اختبار وتشغيل الخادم
انسخ الإصدار الأول من التصدير إلى المجلد المراقب:
mkdir /tmp/monitored
cp -r /tmp/mnist/1 /tmp/monitored
ثم قم بتشغيل الخادم:
docker run -p 8500:8500 \
--mount type=bind,source=/tmp/monitored,target=/models/mnist \
-t --entrypoint=tensorflow_model_server tensorflow/serving --enable_batching \
--port=8500 --model_name=mnist --model_base_path=/models/mnist &
سيرسل الخادم رسائل سجل كل ثانية تقول "إصدار طموح للعرض ..."، مما يعني أنه عثر على التصدير، ويقوم بتتبع وجوده المستمر.
لنقم بتشغيل العميل باستخدام --concurrency=10
. سيؤدي هذا إلى إرسال طلبات متزامنة إلى الخادم وبالتالي تشغيل منطق الدفع الخاص بك.
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500 --concurrency=10
مما يؤدي إلى إخراج يبدو كالتالي:
...
Inference error rate: 13.1%
ثم ننسخ الإصدار الثاني من التصدير إلى المجلد المراقب ونعيد تشغيل الاختبار:
cp -r /tmp/mnist/2 /tmp/monitored
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500 --concurrency=10
مما يؤدي إلى إخراج يبدو كالتالي:
...
Inference error rate: 9.5%
وهذا يؤكد أن خادمك يكتشف تلقائيًا الإصدار الجديد ويستخدمه للعرض!