A gépi tanulás szolgáltatásként a TensorFlow segítségével

Képzelje el ezt: felszállt az AI Hype vonatra, és úgy döntött, hogy kifejleszt egy alkalmazást, amely elemzi a különböző pálcika típusok hatékonyságát. Ahhoz, hogy bevételt szerezhessen ebből az észbontó AI alkalmazásból, és lenyűgözhesse a virtuális gépeket, meg kell nyitnunk a világ előtt. És jobb, ha méretezhető, mivel mindenki használni akarja.

Kiindulásként ezt az adatkészletet fogjuk használni, amely különböző hosszúságú pálcikákkal különféle egyedek ételcsípési hatékonyságának mérését tartalmazza.

Építészet

Mivel nem csak tudósok vagyunk, hanem felelős szoftvermérnökök is, először kidolgozzuk architektúránkat. Először el kell döntenünk arról, hogy miként fogunk hozzáférni a telepített modellünkhöz, hogy jósoljunk. A TensorFlow esetében naiv választás lenne a TensorFlow Serving használata. Ez a keretrendszer lehetővé teszi a betanított TensorFlow modellek telepítését, támogatja a modellek verzióinak kialakítását, és a gRPC-t használja a motorháztető alatt.

A gRPC legfontosabb figyelmeztetése, hogy nem túl közönségbarát, például a REST szolgáltatásokkal összehasonlítva. Bárki, aki rendelkezik minimális szerszámokkal, felhívhatja a REST szolgáltatást, és gyorsan visszakaphatja az eredményt. De amikor a gRPC-t használod, először speciális segédprogramok segítségével elő kell állítanod az ügyfélkódokat a proto fájlokból, majd a programozó nyelvedre írhatod az ügyfelet.

A TensorFlow Serving sok mindent leegyszerűsít ebben a folyamatban, de mégsem ez a legegyszerűbb keretrendszer az API fogyasztásához a kliens oldalon. Fontolja meg a TF Serving szolgáltatást, ha villámgyors, megbízható, szigorúan beírt API-ra van szüksége, amelyet az alkalmazásában fog használni (például egy webes vagy mobilalkalmazás háttérszolgáltatásaként).

Ki kell elégítenünk rendszerünk nem funkcionális követelményeit is. Ha sok felhasználó szeretné tudni a pálcika hatékonyságának szintjét, szükségünk lesz a rendszer hibatűrőre és méretezhetővé. A felhasználói felület csapatának is be kell telepítenie a chopstick'o'meter webalkalmazását. Erőforrásokra lesz szükségünk az új gépi tanulási modellek prototípusának elkészítéséhez, esetleg egy Jupyter Lab-ban, amely mögött nagy számítási teljesítmény áll. Az egyik legjobb válasz ezekre a kérdésekre a Kubernetes használata.

A Kubernetes egy nyílt forráskódú rendszer a konténeres alkalmazások telepítésének, méretezésének és kezelésének automatizálására.

Ha a Kubernetes a helyén van, adott tudással és egy kis idővel, létrehozhatunk egy méretezhető házon belüli felhő PaaS megoldást, amely infrastruktúrát és szoftvert biztosít a teljes ciklusú adattudományi projektek fejlesztéséhez. Ha nem ismeri a Kubernetes-t, javaslom, hogy nézze meg ezt:

A Kubernetes a Docker technológia tetején fut, ezért ha még nem ismeri, jó lehet, ha először elolvassa a hivatalos oktatóanyagot.

Összességében ez egy nagyon gazdag téma, amely több könyvet is megérdemel, hogy teljes terjedelmében lefedjék őket, ezért itt egyetlen részre összpontosítunk: a gépi tanulási modellek gyártásra való áttérésével.

Megfontolások

Igen, ez az adatkészlet kicsi. És igen, a mély tanulás alkalmazása itt nem biztos, hogy a legjobb ötlet. Csak ne feledje, hogy azért vagyunk itt, hogy tanuljunk, és ez az adatkészlet minden bizonnyal szórakoztató. Ennek az oktatóanyagnak a modellezési része nem lesz megfelelő minőségű, mivel a fő hangsúly a modell telepítési folyamatán van.

Lenyűgöznünk kell a VC-t is, ezért a mély tanulás elengedhetetlen! :)

Kód

Az ebben a bejegyzésben használt összes kód- és konfigurációs fájl elérhető egy kísérő GitHub-lerakatban.

Training Deep Chopstick osztályozó

Először ki kell választanunk egy gépi tanulási keretet. Mivel ez a cikk a TensorFlow kiszolgáló képességeinek bemutatására szolgál, a TensorFlow szolgáltatást választjuk.

Mint ismerheti, osztályozónkat kétféleképpen képezhetjük: a TensorFlow és a TensorFlow Estimator API használatával. Az Estimator API egy kísérlet arra, hogy egységes felületet mutasson be a mély tanulási modellek számára oly módon, ahogyan a scikit-learn ezt a klasszikus ML-modellek számára teszi. Ehhez a feladathoz felhasználhatjuk tf.estimator.LinearClassifiera Logistic Regression gyors megvalósítását és a modell exportálását a képzés befejezése után.

A másik mód, ahogyan megtehetjük, hogy a sima TensorFlow-t használjuk egy osztályozó képzésére és exportálására:

A TensorFlow Serving beállítása

Szóval, van egy fantasztikus mély tanulási modellje a TensorFlow-val, és alig várja, hogy gyártásba helyezze? Itt az ideje, hogy kezünkbe vegyük a TensorFlow Serving szolgáltatást.

A TensorFlow kiszolgálás a gRPC-n alapul - egy gyors távoli eljáráshívási könyvtáron, amely egy másik Google-projektet használ a fedél alatt - Protokoll pufferek.

A Protocol Buffers egy sorosítási keretrendszer, amely lehetővé teszi az objektumok memóriából hatékony bináris formátumba történő átalakítását, amely alkalmas a hálózaton történő továbbításra.

Összefoglalva: a gRPC egy olyan keretrendszer, amely lehetővé teszi a távoli funkcióhívásokat a hálózaton keresztül. Protokoll puffereket használ az adatok sorosítására és dezerializálására.

A TensorFlow Serving fő összetevői a következők:

  • Servable - ez alapvetően a betanított modell verziója, amelyet a TF Serving betöltésére alkalmas formátumban exportálnak
  • Loader - TF Szolgáltató komponens, amely véletlenül betölti a szervereket a memóriába
  • Menedzser - végrehajtja a szervable életciklusának műveleteit. Irányítja a kiszolgáló születését (betöltését), hosszú életét (szolgálatát) és halálát (kirakodását)
  • Core - az összes összetevőt együttesen működteti (a hivatalos dokumentáció egy kicsit homályos abban, hogy mi is a mag valójában, de mindig megnézheti a forráskódot, hogy lássa, mit csinál)

A TF Serving architektúra részletesebb áttekintését a hivatalos dokumentációban olvashatja el.

A TF Serving-alapú szolgáltatás működésbe lépéséhez:

  1. Exportálja a modellt a TensorFlow Serving szolgáltatással kompatibilis formátumba. Más szavakkal, hozzon létre egy Servable-t.
  2. Telepítse vagy fordítsa le a TensorFlow Serving szolgáltatást
  3. Futtassa a TensorFlow Serving szolgáltatást, és töltse be az exportált modell legújabb verzióját (szervizelhető)

A TernsorFlow Serving beállítása többféle módon történhet:

  • Építés forrásból. Ehhez telepítenie kell a Bazelt, és be kell fejeznie egy hosszú fordítási folyamatot
  • Előre elkészített bináris csomag használata. A TF Serving deb csomagként érhető el.

To automate this process and simplify subsequent installation to Kubernetes, we created a simple Dockerfile for you. Please clone the article’s repository and follow the instructions in the README.md file to build TensorFlow Serving Docker image:

➜ make build_image

This image has TensorFlow Serving and all dependencies preinstalled. By default, it loads models from the /models directory inside the docker container.

Running a prediction service

To run our service inside the freshly built and ready to use TF Serving image, be sure to first train and export the model (or if you’re using a companion repository, just run the make train_classifier command).

After the classifier is trained and exported, you can run the serving container by using the shortcut make run_server or by using the following command:

➜ docker run -p8500:8500 -d --rm -v /path/to/exported/model:/models tfserve_bin
  • -p maps ports from the container to the local machine
  • -d runs the container in daemon (background) mode
  • --rm removes the container after it has stopped
  • -v maps the local directory to a directory inside the running container. This way we pass our exported models to the TF Serving instance running inside the container

Calling model services from the client side

To call our services, we will use grpctensorflow-serving-api Python packages. Please notice that this package is currently only available for Python 2, so you should have a separate virtual environment for the TF Serving client.

To use this API with Python 3, you’ll either need to use an unofficial package from here then download and unzip the package manually, or build TensorFlow Serving from the source (see the documentation). Example clients for both Estimator API and plain TensorFlow are below:

Going into production with Kubernetes

If you have no Kubernetes cluster available, you may create one for local experiments using minikube, or you can easily deploy a real cluster using kubeadm.

We’ll go with the minikube option in this post. Once you have installed it (brew cask install minikube on Mac) we may start a local cluster and share its Docker environment with our machine:

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

After that, we’ll be able to build our image and put it inside the cluster using

➜ make build_image

A more mature option would be to use the internal docker registry and push the locally built image there, but we’ll leave this out of scope to be more concise.

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
  • Apply Deep Learning wisely. Even though it is a very general, spectacular, and widely applicable framework, deep learning is not the only tool at the disposal of a data scientist. It’s also not a silver bullet that solves any problem. Machine learning has much more to offer. If you have relational/table data, small datasets, strict restrictions on computation resources, or training time or model interpretability, consider using other algorithms and approaches.
  • Reach out to us if you need any help in solving machine learning challenges: [email protected]