از سرویس TensorFlow با Kubernetes استفاده کنید

این آموزش نحوه استفاده از مؤلفه‌های سرویس TensorFlow را که در کانتینرهای Docker اجرا می‌شوند برای ارائه مدل TensorFlow ResNet و نحوه استقرار خوشه سرویس با Kubernetes را نشان می‌دهد.

برای کسب اطلاعات بیشتر در مورد سرویس TensorFlow، آموزش اولیه TensorFlow Serving و آموزش پیشرفته TensorFlow Serving را توصیه می کنیم.

برای کسب اطلاعات بیشتر در مورد مدل TensorFlow ResNet، توصیه می کنیم ResNet را در TensorFlow بخوانید.

  • قسمت 1 تنظیمات محیط شما را دریافت می کند
  • بخش 2 نحوه اجرای تصویر سرویس دهی محلی 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 را شبیه سازی کنیم:

git clone https://github.com/tensorflow/serving
cd serving

سرور را با resnet_client_grpc.py پرس و جو کنید. مشتری یک تصویر را دانلود می کند و آن را برای طبقه بندی به دسته های ImageNet از طریق gRPC ارسال می کند.

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 منتقل کنیم تا بتوانیم آن را در Google Cloud Platform اجرا کنیم.

ابتدا تصویر $USER/resnet_serving را با استفاده از فرمت Container Registry و نام پروژه خود تگ می کنیم.

docker tag $USER/resnet_serving gcr.io/tensorflow-serving/resnet

در مرحله بعد، داکر را برای استفاده از gcloud به عنوان کمک کننده اعتبار پیکربندی می کنیم:

gcloud auth configure-docker

سپس تصویر را به رجیستری فشار می دهیم،

docker push gcr.io/tensorflow-serving/resnet

استقرار و سرویس Kubernetes را ایجاد کنید

این استقرار شامل 3 نسخه از سرور resnet_inference است که توسط یک Kubernetes Deployment کنترل می شود. کپی‌ها توسط یک سرویس 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 به کار گرفتید!