يوضح هذا البرنامج التعليمي كيفية استخدام مكونات TensorFlow Serving التي تعمل في حاويات Docker لخدمة نموذج TensorFlow ResNet وكيفية نشر مجموعة الخدمة مع Kubernetes.
لمعرفة المزيد حول TensorFlow Serving، نوصي بالبرنامج التعليمي الأساسي لـ TensorFlow Serving والبرنامج التعليمي المتقدم لـ TensorFlow Serving .
لمعرفة المزيد حول نموذج TensorFlow ResNet، نوصي بقراءة ResNet في TensorFlow .
- الجزء الأول يحصل على إعداد البيئة الخاصة بك
- يوضح الجزء الثاني كيفية تشغيل صورة عرض Docker المحلية
- يوضح الجزء 3 كيفية النشر في Kubernetes.
الجزء 1: الإعداد
قبل البدء، قم أولاً بتثبيت Docker .
قم بتنزيل ResNet SavedModel
دعونا نمسح دليل النماذج المحلية الخاص بنا في حالة وجود واحد بالفعل:
rm -rf /tmp/resnet
قدمت الشبكات المتبقية العميقة، أو ResNets باختصار، فكرة رائعة لرسم خرائط الهوية من أجل تمكين تدريب الشبكات العصبية التلافيفية العميقة جدًا. على سبيل المثال، سنقوم بتنزيل TensorFlow SavedModel من ResNet لمجموعة بيانات ImageNet.
# Download Resnet model from TF Hub
wget https://tfhub.dev/tensorflow/resnet_50/classification/1?tf-hub-format=compressed -o resnet.tar.gz
# Extract SavedModel into a versioned subfolder ‘123’
mkdir -p /tmp/resnet/123
tar xvfz resnet.tar.gz -C /tmp/resnet/123/
يمكننا التحقق من أن لدينا SavedModel:
$ ls /tmp/resnet/*
saved_model.pb variables
الجزء 2: التشغيل في دوكر
الالتزام بالصورة للنشر
نريد الآن التقاط صورة عرض وتنفيذ جميع التغييرات على صورة جديدة $USER/resnet_serving
لنشر Kubernetes.
أولاً نقوم بتشغيل صورة التقديم كبرنامج خفي:
docker run -d --name serving_base tensorflow/serving
بعد ذلك، نقوم بنسخ بيانات نموذج ResNet إلى مجلد نموذج الحاوية:
docker cp /tmp/resnet serving_base:/models/resnet
أخيرًا نلزم الحاوية بخدمة نموذج ResNet:
docker commit --change "ENV MODEL_NAME resnet" serving_base \
$USER/resnet_serving
الآن دعونا نوقف حاوية قاعدة التقديم
docker kill serving_base
docker rm serving_base
ابدأ الخادم
لنبدأ الآن الحاوية بنموذج ResNet حتى تصبح جاهزة للعرض، ونكشف عن منفذ gRPC 8500:
docker run -p 8500:8500 -t $USER/resnet_serving &
الاستعلام عن الخادم
بالنسبة للعميل، سنحتاج إلى استنساخ TensorFlow Serving GitHub repo:
git clone https://github.com/tensorflow/serving
cd serving
استعلم عن الخادم باستخدام resnet_client_grpc.py . يقوم العميل بتنزيل الصورة وإرسالها عبر gRPC لتصنيفها إلى فئات ImageNet .
tools/run_in_docker.sh python tensorflow_serving/example/resnet_client_grpc.py
يجب أن يؤدي هذا إلى إخراج مثل:
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 123
}
signature_name: "serving_default"
}
إنها تعمل! نجح الخادم في تصنيف صورة قطة!
الجزء 3: النشر في Kubernetes
نستخدم في هذا القسم صورة الحاوية المضمنة في الجزء 0 لنشر مجموعة الخدمة مع Kubernetes في Google Cloud Platform .
تسجيل الدخول لمشروع GCloud
نفترض هنا أنك قمت بإنشاء وتسجيل الدخول إلى مشروع gcloud باسم tensorflow-serving
.
gcloud auth login --project tensorflow-serving
إنشاء مجموعة حاوية
نقوم أولاً بإنشاء مجموعة Google Kubernetes Engine لنشر الخدمة.
$ gcloud container clusters create resnet-serving-cluster --num-nodes 5
والتي يجب أن تنتج شيئًا مثل:
Creating cluster resnet-serving-cluster...done.
Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/resnet-serving-cluster].
kubeconfig entry generated for resnet-serving-cluster.
NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
resnet-serving-cluster us-central1-f 1.1.8 104.197.163.119 n1-standard-1 1.1.8 5 RUNNING
قم بتعيين المجموعة الافتراضية لأمر حاوية gcloud وقم بتمرير بيانات اعتماد المجموعة إلى kubectl .
gcloud config set container/cluster resnet-serving-cluster
gcloud container clusters get-credentials resnet-serving-cluster
والتي ينبغي أن تؤدي إلى:
Fetching cluster endpoint and auth data.
kubeconfig entry generated for resnet-serving-cluster.
قم بتحميل صورة عامل الميناء
لننقل الآن صورتنا إلى Google Container Registry حتى نتمكن من تشغيلها على Google Cloud Platform.
أولاً نقوم بوضع علامة على الصورة $USER/resnet_serving
باستخدام تنسيق Container Registry واسم مشروعنا،
docker tag $USER/resnet_serving gcr.io/tensorflow-serving/resnet
بعد ذلك، نقوم بتكوين Docker لاستخدام gcloud كمساعد بيانات الاعتماد:
gcloud auth configure-docker
بعد ذلك نقوم بدفع الصورة إلى التسجيل،
docker push gcr.io/tensorflow-serving/resnet
إنشاء نشر وخدمة Kubernetes
يتكون النشر من 3 نسخ متماثلة لخادم resnet_inference
يتم التحكم فيها بواسطة نشر Kubernetes . يتم عرض النسخ المتماثلة خارجيًا بواسطة خدمة Kubernetes بالإضافة إلى موازن التحميل الخارجي .
نقوم بإنشائها باستخدام المثال Kubernetes config resnet_k8s.yaml .
kubectl create -f tensorflow_serving/example/resnet_k8s.yaml
مع الإخراج:
deployment "resnet-deployment" created
service "resnet-service" created
لعرض حالة النشر والبودات:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
resnet-deployment 3 3 3 3 5s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
resnet-deployment-bbcbc 1/1 Running 0 10s
resnet-deployment-cj6l2 1/1 Running 0 10s
resnet-deployment-t1uep 1/1 Running 0 10s
لعرض حالة الخدمة:
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
resnet-service 10.239.240.227 104.155.184.157 8500/TCP 1m
قد يستغرق الأمر بعض الوقت حتى يصبح كل شيء جاهزًا للعمل.
$ kubectl describe service resnet-service
Name: resnet-service
Namespace: default
Labels: run=resnet-service
Selector: run=resnet-service
Type: LoadBalancer
IP: 10.239.240.227
LoadBalancer Ingress: 104.155.184.157
Port: <unset> 8500/TCP
NodePort: <unset> 30334/TCP
Endpoints: <none>
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer
1m 1m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer
يتم إدراج عنوان IP الخارجي للخدمة بجوار LoadBalancer Ingress.
الاستعلام عن النموذج
يمكننا الآن الاستعلام عن الخدمة على عنوانها الخارجي من مضيفنا المحلي.
$ tools/run_in_docker.sh python \
tensorflow_serving/example/resnet_client_grpc.py \
--server=104.155.184.157:8500
outputs {
key: "classes"
value {
dtype: DT_INT64
tensor_shape {
dim {
size: 1
}
}
int64_val: 286
}
}
outputs {
key: "probabilities"
value {
dtype: DT_FLOAT
tensor_shape {
dim {
size: 1
}
dim {
size: 1001
}
}
float_val: 2.41628322328e-06
float_val: 1.90121829746e-06
float_val: 2.72477100225e-05
float_val: 4.42638565801e-07
float_val: 8.98362372936e-07
float_val: 6.84421956976e-06
float_val: 1.66555237229e-05
...
float_val: 1.59407863976e-06
float_val: 1.2315689446e-06
float_val: 1.17812135159e-06
float_val: 1.46365800902e-05
float_val: 5.81210713335e-07
float_val: 6.59980651108e-05
float_val: 0.00129527016543
}
}
model_spec {
name: "resnet"
version {
value: 1538687457
}
signature_name: "serving_default"
}
لقد نجحت في نشر نموذج ResNet الذي يعمل كخدمة في Kubernetes!