Gunakan Penayangan TensorFlow dengan Kubernetes

Tutorial ini menunjukkan cara menggunakan komponen TensorFlow Serving yang berjalan di container Docker untuk melayani model TensorFlow ResNet dan cara men-deploy cluster servis dengan Kubernetes.

Untuk mempelajari lebih lanjut tentang TensorFlow Serving, kami merekomendasikan tutorial dasar TensorFlow Serving dan tutorial lanjutan TensorFlow Serving .

Untuk mempelajari lebih lanjut model TensorFlow ResNet, sebaiknya baca ResNet di TensorFlow .

  • Bagian 1 menyiapkan lingkungan Anda
  • Bagian 2 menunjukkan cara menjalankan image penyajian Docker lokal
  • Bagian 3 menunjukkan cara penerapan di Kubernetes.

Bagian 1: Pengaturan

Sebelum memulai, instal dulu Docker .

Unduh ResNet SavedModel

Mari kita bersihkan direktori model lokal kita jika kita sudah memilikinya:

rm -rf /tmp/resnet

Jaringan sisa dalam, atau disingkat ResNets, memberikan ide terobosan pemetaan identitas untuk memungkinkan pelatihan jaringan saraf konvolusional yang sangat dalam. Sebagai contoh, kita akan mendownload TensorFlow SavedModel dari ResNet untuk kumpulan data 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/

Kami dapat memverifikasi bahwa kami memiliki SavedModel:

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

Bagian 2: Berjalan di Docker

Komit gambar untuk penerapan

Sekarang kami ingin mengambil gambar penyajian dan melakukan semua perubahan pada gambar baru $USER/resnet_serving untuk penerapan Kubernetes.

Pertama kita menjalankan gambar penyajian sebagai daemon:

docker run -d --name serving_base tensorflow/serving

Selanjutnya, kita menyalin data model ResNet ke folder model kontainer:

docker cp /tmp/resnet serving_base:/models/resnet

Terakhir, kami mengkomit container untuk melayani model ResNet:

docker commit --change "ENV MODEL_NAME resnet" serving_base \
  $USER/resnet_serving

Sekarang mari kita hentikan wadah dasar penyajian

docker kill serving_base
docker rm serving_base

Mulai servernya

Sekarang mari kita mulai container dengan model ResNet agar siap ditayangkan, dengan menampilkan port gRPC 8500:

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

Kueri server

Untuk klien, kita perlu mengkloning repo GitHub TensorFlow Serving:

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

Kueri server dengan resnet_client_grpc.py . Klien mendownload gambar dan mengirimkannya melalui gRPC untuk klasifikasi ke dalam kategori ImageNet .

tools/run_in_docker.sh python tensorflow_serving/example/resnet_client_grpc.py

Ini akan menghasilkan keluaran seperti:

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

Itu berhasil! Server berhasil mengklasifikasikan gambar kucing!

Bagian 3: Penerapan di Kubernetes

Di bagian ini kami menggunakan image container yang dibuat di Bagian 0 untuk men-deploy cluster yang melayani dengan Kubernetes di Google Cloud Platform .

Login proyek GCloud

Di sini kami berasumsi Anda telah membuat dan masuk ke proyek gcloud bernama tensorflow-serving .

gcloud auth login --project tensorflow-serving

Buat kluster kontainer

Pertama kita membuat cluster Google Kubernetes Engine untuk penerapan layanan.

$ gcloud container clusters create resnet-serving-cluster --num-nodes 5

Yang seharusnya menghasilkan sesuatu seperti:

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

Tetapkan perintah cluster default untuk gcloud container dan teruskan kredensial cluster ke kubectl .

gcloud config set container/cluster resnet-serving-cluster
gcloud container clusters get-credentials resnet-serving-cluster

yang seharusnya menghasilkan:

Fetching cluster endpoint and auth data.
kubeconfig entry generated for resnet-serving-cluster.

Unggah gambar Docker

Sekarang mari kita dorong gambar kita ke Google Container Registry sehingga kita dapat menjalankannya di Google Cloud Platform.

Pertama kita menandai gambar $USER/resnet_serving menggunakan format Container Registry dan nama proyek kita,

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

Selanjutnya, kami mengonfigurasi Docker untuk menggunakan gcloud sebagai pembantu kredensial:

gcloud auth configure-docker

Selanjutnya kita push image tersebut ke Registry,

docker push gcr.io/tensorflow-serving/resnet

Buat Penerapan dan Layanan Kubernetes

Deployment terdiri dari 3 replika server resnet_inference yang dikendalikan oleh Deployment Kubernetes . Replika tersebut diekspos secara eksternal oleh Layanan Kubernetes bersama dengan Load Balancer Eksternal .

Kami membuatnya menggunakan contoh konfigurasi Kubernetes resnet_k8s.yaml .

kubectl create -f tensorflow_serving/example/resnet_k8s.yaml

Dengan keluaran:

deployment "resnet-deployment" created
service "resnet-service" created

Untuk melihat status penerapan dan pod:

$ 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

Untuk melihat status layanan:

$ kubectl get services
NAME                    CLUSTER-IP       EXTERNAL-IP       PORT(S)     AGE
resnet-service       10.239.240.227   104.155.184.157   8500/TCP    1m

Diperlukan waktu beberapa saat agar semuanya aktif dan berjalan.

$ 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

Alamat IP eksternal layanan tercantum di sebelah LoadBalancer Ingress.

Kueri modelnya

Kami sekarang dapat menanyakan layanan di alamat eksternalnya dari host lokal kami.

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

Anda telah berhasil menerapkan model ResNet yang berfungsi sebagai layanan di Kubernetes!