Kubernetes के साथ TensorFlow सर्विंग का उपयोग करें

यह ट्यूटोरियल दिखाता है कि TensorFlow ResNet मॉडल की सेवा के लिए डॉकर कंटेनर में चल रहे TensorFlow सर्विंग घटकों का उपयोग कैसे करें और Kubernetes के साथ सर्विंग क्लस्टर को कैसे तैनात करें।

TensorFlow सर्विंग के बारे में अधिक जानने के लिए, हम TensorFlow सर्विंग बेसिक ट्यूटोरियल और TensorFlow सर्विंग उन्नत ट्यूटोरियल की अनुशंसा करते हैं।

TensorFlow ResNet मॉडल के बारे में अधिक जानने के लिए, हम TensorFlow में ResNet पढ़ने की सलाह देते हैं।

  • भाग 1 आपके पर्यावरण सेटअप को प्राप्त करता है
  • भाग 2 दिखाता है कि स्थानीय डॉकर सेवारत छवि को कैसे चलाया जाए
  • भाग 3 दिखाता है कि कुबेरनेट्स में कैसे तैनात किया जाए।

भाग 1: सेटअप

आरंभ करने से पहले, पहले डॉकर इंस्टॉल करें

रेसनेट सेव्डमॉडल डाउनलोड करें

यदि हमारे पास पहले से ही कोई स्थानीय मॉडल निर्देशिका है तो आइए उसे साफ़ करें:

rm -rf /tmp/resnet

गहरे अवशिष्ट नेटवर्क, या संक्षेप में ResNets, ने बहुत गहरे दृढ़ तंत्रिका नेटवर्क के प्रशिक्षण को सक्षम करने के लिए पहचान मैपिंग का महत्वपूर्ण विचार प्रदान किया। हमारे उदाहरण के लिए, हम ImageNet डेटासेट के लिए ResNet का TensorFlow SavedModel डाउनलोड करेंगे।

# 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/

हम सत्यापित कर सकते हैं कि हमारे पास SaveModel है:

$ ls /tmp/resnet/*
saved_model.pb  variables

भाग 2: डॉकर में चल रहा है

परिनियोजन के लिए छवि प्रतिबद्ध करें

अब हम एक सर्विंग छवि लेना चाहते हैं और कुबेरनेट्स परिनियोजन के लिए एक नई छवि $USER/resnet_serving में सभी परिवर्तन करना चाहते हैं

सबसे पहले हम एक सर्विंग इमेज को डेमॉन के रूप में चलाते हैं:

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

सर्वर प्रारंभ करें

अब कंटेनर को रेसनेट मॉडल से शुरू करते हैं ताकि यह जीआरपीसी पोर्ट 8500 को उजागर करते हुए परोसने के लिए तैयार हो:

docker run -p 8500:8500 -t $USER/resnet_serving &

सर्वर से पूछताछ करें

क्लाइंट के लिए, हमें TensorFlow सर्विंग GitHub रेपो को क्लोन करना होगा:

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

सर्वर को resnet_client_grpc.py से क्वेरी करें। क्लाइंट एक छवि डाउनलोड करता है और उसे इमेजनेट श्रेणियों में वर्गीकरण के लिए जीआरपीसी पर भेजता है।

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: कुबेरनेट्स में तैनाती

इस अनुभाग में हम Google क्लाउड प्लेटफ़ॉर्म में कुबेरनेट्स के साथ एक सर्विंग क्लस्टर को तैनात करने के लिए भाग 0 में निर्मित कंटेनर छवि का उपयोग करते हैं।

जीक्लाउड प्रोजेक्ट लॉगिन

यहां हम मानते हैं कि आपने tensorflow-serving नामक एक जीक्लाउड प्रोजेक्ट बनाया और लॉग इन किया है।

gcloud auth login --project tensorflow-serving

एक कंटेनर क्लस्टर बनाएं

सबसे पहले हम सेवा परिनियोजन के लिए एक Google Kubernetes इंजन क्लस्टर बनाते हैं।

$ 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 क्लाउड प्लेटफ़ॉर्म पर चला सकें।

सबसे पहले हम कंटेनर रजिस्ट्री प्रारूप और हमारे प्रोजेक्ट नाम का उपयोग करके $USER/resnet_serving छवि को टैग करते हैं,

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

इसके बाद, हम डॉकर को एक क्रेडेंशियल सहायक के रूप में gcloud का उपयोग करने के लिए कॉन्फ़िगर करते हैं:

gcloud auth configure-docker

इसके बाद हम छवि को रजिस्ट्री में भेजते हैं,

docker push gcr.io/tensorflow-serving/resnet

कुबेरनेट्स परिनियोजन और सेवा बनाएँ

परिनियोजन में Kubernetes परिनियोजन द्वारा नियंत्रित resnet_inference सर्वर की 3 प्रतिकृतियां शामिल हैं। प्रतिकृतियां बाहरी लोड बैलेंसर के साथ कुबेरनेट्स सेवा द्वारा बाहरी रूप से प्रदर्शित की जाती हैं।

हम उन्हें उदाहरण 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

सेवा बाहरी आईपी पता लोडबैलेंसर इनग्रेस के बगल में सूचीबद्ध है।

मॉडल से पूछताछ करें

अब हम अपने स्थानीय होस्ट से सेवा के बाहरी पते पर क्वेरी कर सकते हैं।

$ 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"
}

आपने Kubernetes में एक सेवा के रूप में ResNet मॉडल को सफलतापूर्वक तैनात किया है!