التعلم الآلي كخدمة مع TensorFlow

تخيل هذا: لقد صعدت على متن AI Hype Train وقررت تطوير تطبيق يقوم بتحليل فعالية أنواع عيدان الطعام المختلفة. لتحقيق الدخل من تطبيق AI المذهل هذا وإثارة إعجاب رؤوس الأموال ، سنحتاج إلى فتحه للعالم. ومن الأفضل أن تكون قابلة للتطوير حيث سيرغب الجميع في استخدامها.

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

هندسة معمارية

نظرًا لأننا لسنا فقط علماء بيانات ولكن أيضًا مهندسي برمجيات مسؤولين ، سنقوم أولاً بصياغة هيكلنا. أولاً ، سنحتاج إلى اتخاذ قرار بشأن كيفية الوصول إلى نموذجنا المنشور لعمل تنبؤات. بالنسبة إلى TensorFlow ، قد يكون الخيار الساذج هو استخدام خدمة TensorFlow. يتيح لك إطار العمل هذا نشر نماذج TensorFlow المدربة ، ويدعم إصدار النماذج ، ويستخدم gRPC تحت الغطاء.

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

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

سنحتاج أيضًا إلى تلبية المتطلبات غير الوظيفية لنظامنا. إذا كان الكثير من المستخدمين يرغبون في معرفة مستوى فعالية عيدان الطعام ، فسنحتاج إلى أن يكون النظام متسامحًا مع الأخطاء وقابل للتطوير. أيضًا ، سيحتاج فريق UI إلى نشر تطبيق الويب chopstick'o'meter الخاص بهم في مكان ما أيضًا. وسنحتاج إلى موارد لنمذجة نماذج جديدة للتعلم الآلي ، ربما في مختبر Jupyter مع الكثير من القوة الحاسوبية وراءها. أحد أفضل الإجابات على هذه الأسئلة هو استخدام Kubernetes.

Kubernetes هو نظام مفتوح المصدر لأتمتة نشر التطبيقات المعبأة في حاويات وتوسيع نطاقها وإدارتها.

مع وجود Kubernetes في مكانه ، وفي ظل المعرفة وبعض الوقت ، يمكننا إنشاء حل PaaS السحابي الداخلي القابل للتطوير والذي يوفر البنية التحتية والبرامج لتطوير مشروع علوم البيانات بدورة كاملة. إذا لم تكن معتادًا على Kubernetes ، أقترح عليك مشاهدة هذا:

تعمل Kubernetes على رأس تقنية Docker ، لذلك إذا لم تكن على دراية بها ، فقد يكون من الجيد قراءة البرنامج التعليمي الرسمي أولاً.

بشكل عام ، هذا موضوع غني جدًا يستحق عدة كتب لتغطيته بالكامل ، لذلك سنركز هنا على جزء واحد: نقل نماذج التعلم الآلي إلى الإنتاج.

الاعتبارات

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

أيضًا ، نحن بحاجة إلى إثارة إعجاب أصحاب رؤوس الأموال ، لذا فإن التعلم العميق أمر لا بد منه! :)

الشفرة

تتوفر جميع ملفات التعليمات البرمجية والتهيئة المستخدمة في هذا المنشور في مستودع GitHub المصاحب.

تدريب المصنف العميق عود

أولاً ، يجب أن نختار إطار عمل للتعلم الآلي لاستخدامه. نظرًا لأن هذه المقالة تهدف إلى توضيح إمكانات خدمة TensorFlow ، فسنختار TensorFlow.

كما تعلم ، هناك طريقتان يمكننا من خلالهما تدريب المصنف لدينا: استخدام TensorFlow واستخدام TensorFlow Estimator API. تعد واجهة API المقدر محاولة لتقديم واجهة موحدة لنماذج التعلم العميق بطريقة يقوم بها scikit-Learn لمجموعة من نماذج ML الكلاسيكية. لهذه المهمة ، يمكننا استخدامها tf.estimator.LinearClassifierلتنفيذ الانحدار اللوجستي بسرعة وتصدير النموذج بعد اكتمال التدريب.

الطريقة الأخرى التي يمكننا بها القيام بذلك هي استخدام TensorFlow العادي لتدريب مصنف وتصديره:

إعداد خدمة TensorFlow

إذن ، لديك نموذج رائع للتعلم العميق مع TensorFlow وتريد وضعه في الإنتاج؟ حان الوقت الآن للحصول على خدمة TensorFlow.

تعتمد خدمة TensorFlow على gRPC - وهي مكتبة استدعاء إجراءات عن بُعد سريعة تستخدم مشروع Google آخر تحت الغطاء - مخازن البروتوكول المؤقتة.

بروتوكول Buffers هو إطار عمل تسلسلي يسمح لك بتحويل الكائنات من الذاكرة إلى تنسيق ثنائي فعال مناسب للإرسال عبر الشبكة.

للتلخيص ، يعد gRPC إطارًا يتيح استدعاءات الوظائف البعيدة عبر الشبكة. يستخدم بروتوكول المخازن المؤقتة لتسلسل البيانات وإلغاء تسلسلها.

المكونات الرئيسية لخدمة TensorFlow هي:

  • قابل للخدمة - هذا هو في الأساس نسخة من نموذجك المدرّب الذي تم تصديره بتنسيق مناسب لتحميل TF Serving
  • اللودر - مكون خدمة TF يقوم ، عن طريق الصدفة ، بتحميل المواد القابلة للخدمة في الذاكرة
  • مدير - ينفذ عمليات دورة حياة الخدمة. يتحكم في الولادة الصالحة (التحميل) ، والعمر الطويل (الخدمة) ، والموت (التفريغ)
  • Core - يجعل جميع المكونات تعمل معًا (الوثائق الرسمية غامضة بعض الشيء حول ماهية الجوهر بالفعل ، ولكن يمكنك دائمًا إلقاء نظرة على الكود المصدري للتعرف على ما يفعله)

يمكنك قراءة نظرة عامة أكثر تعمقًا على بنية خدمة TF في الوثائق الرسمية.

للحصول على خدمة قائمة على خدمة TF وتشغيلها ، سوف تحتاج إلى:

  1. قم بتصدير النموذج إلى تنسيق متوافق مع خدمة TensorFlow. بمعنى آخر ، قم بإنشاء ملف.
  2. قم بتثبيت أو تجميع خدمة TensorFlow
  3. قم بتشغيل خدمة TensorFlow وتحميل أحدث إصدار من النموذج المُصدَّر (قابل للخدمة)

يمكن إعداد خدمة TernsorFlow بعدة طرق:

  • البناء من المصدر. هذا يتطلب منك تثبيت Bazel وإكمال عملية تجميع مطولة
  • استخدام حزمة ثنائية مسبقة الصنع. خدمة TF متاحة كحزمة ديب.

لأتمتة هذه العملية وتبسيط التثبيت اللاحق لـ Kubernetes ، أنشأنا Dockerfile بسيطًا لك. يرجى استنساخ مستودع المقالة واتباع التعليمات الموجودة في ملف README.md لإنشاء صورة TensorFlow Serving Docker:

➜ make build_image

تحتوي هذه الصورة على خدمة TensorFlow وجميع التبعيات مثبتة مسبقًا. بشكل افتراضي ، يقوم بتحميل النماذج من /modelsالدليل داخل حاوية عامل الإرساء.

تشغيل خدمة التنبؤ

لتشغيل خدمتنا داخل الصورة المبنية حديثًا وجاهزة لاستخدام صورة TF Serving ، تأكد أولاً من تدريب النموذج وتصديره (أو إذا كنت تستخدم مستودعًا مصاحبًا ، فما عليك سوى تشغيل make train_classifierالأمر).

بعد تدريب المصنف وتصديره ، يمكنك تشغيل حاوية التقديم باستخدام الاختصار make run_serverأو باستخدام الأمر التالي:

➜ docker run -p8500:8500 -d --rm -v /path/to/exported/model:/models tfserve_bin
  • -p خرائط المنافذ من الحاوية إلى الجهاز المحلي
  • -d يدير الحاوية في وضع الخفي (الخلفية)
  • --rm يزيل الحاوية بعد توقفها
  • -vتعيين الدليل المحلي إلى دليل داخل الحاوية قيد التشغيل. بهذه الطريقة نمرر نماذجنا المصدرة إلى مثيل TF Serving الذي يعمل داخل الحاوية

استدعاء خدمات النموذج من جانب العميل

للاتصال بخدماتنا ، سوف نستخدم grpctensorflow-serving-apiحزم بايثون. يرجى ملاحظة أن هذه الحزمة متاحة حاليًا لـ Python 2 فقط ، لذلك يجب أن يكون لديك بيئة افتراضية منفصلة لعميل TF Serving.

لاستخدام واجهة برمجة التطبيقات هذه مع Python 3 ، ستحتاج إما إلى استخدام حزمة غير رسمية من هنا ثم تنزيل الحزمة وفك ضغطها يدويًا ، أو إنشاء خدمة TensorFlow من المصدر (راجع الوثائق). فيما يلي أمثلة للعملاء لكل من Estimator API و TensorFlow العادي:

الدخول في الإنتاج مع Kubernetes

إذا لم يكن لديك مجموعة Kubernetes متاحة ، فيمكنك إنشاء واحدة للتجارب المحلية باستخدام minikube ، أو يمكنك بسهولة نشر مجموعة حقيقية باستخدام kubeadm.

سنستخدم خيار minikube في هذا المنشور. بمجرد تثبيته ( brew cask install minikubeعلى نظام Mac) ، قد نبدأ مجموعة محلية ونشارك بيئة Docker الخاصة بها مع أجهزتنا:

➜ minikube start...➜ eval $(minikube docker-env)

بعد ذلك ، سنتمكن من بناء صورتنا ووضعها داخل الكتلة باستخدام

➜ make build_image

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

After having our image built and available to the Minikube instance, we need to deploy our model server. To leverage Kubernetes’ load balancing and high-availability features, we will create a Deployment that will auto-scale our model server to three instances and will also keep them monitored and running. You can read more about Kubernetes deployments here.

All Kubernetes objects can be configured in various text formats and then passed to kubectl apply -f file_name command to (meh) apply our configuration to the cluster. Here is our chopstick server deployment config:

Let’s apply this deployment using the kubectl apply -f chopstick_deployment.yml command. After a while, you’ll see all components running:

➜ kubectl get allNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEdeploy/chopstick-classifier 3 3 3 3 1d
NAME DESIRED CURRENT READY AGErs/chopstick-classifier-745cbdf8cd 3 3 3 1d
NAME AGEdeploy/chopstick-classifier 1d
NAME AGErs/chopstick-classifier-745cbdf8cd 1d
NAME READY STATUS RESTARTS AGEpo/chopstick-classifier-745cbdf8cd-5gx2g 1/1 Running 0 1dpo/chopstick-classifier-745cbdf8cd-dxq7g 1/1 Running 0 1dpo/chopstick-classifier-745cbdf8cd-pktzr 1/1 Running 0 1d

Notice that based on the Deployment config, Kubernetes created for us:

  • Deployment
  • Replica Set
  • Three pods running our chopstick-classifier image

Now we want to call our new shiny service. To make this happen, first we need to expose it to the outside world. In Kubernetes, this can be done by defining Services. Here is the Service definition for our model:

As always, we can install it using kubectl apply -f chopstick_service.yml. Kubernetes will assign an external port to our LoadBalancer, and we can see it by running

➜ kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEchopstick-classifier LoadBalancer 10.104.213.253  8500:32372/TCP 1dkubernetes ClusterIP 10.96.0.1  443/TCP 1d

As you can see, our chopstick-classifier is available via port 32372 in my case. It may be different in your machine, so don’t forget to check it out. A convenient way to get the IP and port for any Service when using Minikube is running the following command:

➜ minikube service chopstick-classifier --url//192.168.99.100:32372

Inference

Finally, we are able to call our service!

python tf_api/client.py 192.168.99.100:32372 1010.0Sending requestoutputs { key: "classes_prob" value { dtype: DT_FLOAT tensor_shape { dim { size: 1 } dim { size: 3 } } float_val: 3.98174306027e-11 float_val: 1.0 float_val: 1.83699980923e-18 }}

Before going to real production

As this post is meant mainly for educational purposes and has some simplifications for the sake of clarity, there are several important points to consider before going to production:

  • Use a service mesh like linkerd.io. Accessing services from randomly generated node ports is not recommended in production. As a plus, linkerd will add much more value to your production infrastructure: monitoring, service discovery, high speed load balancing, and more
  • Use Python 3 everywhere, as there is really no reason to use Python 2 now
  • تطبيق التعلم العميق بحكمة. على الرغم من أنه إطار عام للغاية ومذهل وقابل للتطبيق على نطاق واسع ، إلا أن التعلم العميق ليس الأداة الوحيدة المتاحة لعالم البيانات. إنها أيضًا ليست رصاصة فضية تحل أي مشكلة. التعلم الآلي لديه الكثير ليقدمه. إذا كانت لديك بيانات علائقية / جدولية ، أو مجموعات بيانات صغيرة ، أو قيودًا صارمة على موارد الحساب ، أو وقت التدريب أو إمكانية تفسير النموذج ، ففكر في استخدام خوارزميات ومناهج أخرى.
  • تواصل معنا إذا كنت بحاجة إلى أي مساعدة في حل تحديات التعلم الآلي: [email protected]