Skip to content

Commit

Permalink
Merge pull request #684 from cliveseldon/gunicorn
Browse files Browse the repository at this point in the history
WIP: Update python wrapper to use gunicorn
  • Loading branch information
ukclivecox authored Aug 14, 2019
2 parents 1dff0ec + a2f73c7 commit fa9b745
Show file tree
Hide file tree
Showing 10 changed files with 540 additions and 393 deletions.
67 changes: 67 additions & 0 deletions doc/source/python/python_component.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,73 @@ class UserCustomException(Exception):
return rv

```
### Gunicorn (Alpha Feature)

To run your class under gunicorn set the environment variable `GUNICORN_WORKERS` to an integer value > 1.

```
apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
name: gunicorn
spec:
name: worker
predictors:
- componentSpecs:
- spec:
containers:
- image: seldonio/mock_classifier:1.0
name: classifier
env:
- name: GUNICORN_WORKERS
value: '4'
terminationGracePeriodSeconds: 1
graph:
children: []
endpoint:
type: REST
name: classifier
type: MODEL
labels:
version: v1
name: example
replicas: 1
```



## Gunicorn and load

If the wrapped python class is run under [gunicorn](https://gunicorn.org/) then as part of initialization of each gunicorn worker a `load` method will be called on your class if it has it. You should use this method to load and initialise your model. This is important for Tensorflow models which need their session created in each worker process. The [Tensorflow MNIST example](../examples/deep_mnist.html) does this.

```
import tensorflow as tf
import numpy as np
import os
class DeepMnist(object):
def __init__(self):
self.loaded = False
self.class_names = ["class:{}".format(str(i)) for i in range(10)]
def load(self):
print("Loading model",os.getpid())
self.sess = tf.Session()
saver = tf.train.import_meta_graph("model/deep_mnist_model.meta")
saver.restore(self.sess,tf.train.latest_checkpoint("./model/"))
graph = tf.get_default_graph()
self.x = graph.get_tensor_by_name("x:0")
self.y = graph.get_tensor_by_name("y:0")
self.loaded = True
print("Loaded model")
def predict(self,X,feature_names):
if not self.loaded:
self.load()
predictions = self.sess.run(self.y,feed_dict={self.x:X})
return predictions.astype(np.float64)
```


## Next Steps
Expand Down
12 changes: 10 additions & 2 deletions examples/models/deep_mnist/DeepMnist.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import tensorflow as tf
import numpy as np
import os

class DeepMnist(object):
def __init__(self):
self.loaded = False
self.class_names = ["class:{}".format(str(i)) for i in range(10)]

def load(self):
print("Loading model",os.getpid())
self.sess = tf.Session()
saver = tf.train.import_meta_graph("model/deep_mnist_model.meta")
saver.restore(self.sess,tf.train.latest_checkpoint("./model/"))

graph = tf.get_default_graph()
self.x = graph.get_tensor_by_name("x:0")
self.y = graph.get_tensor_by_name("y:0")

self.loaded = True
print("Loaded model")

def predict(self,X,feature_names):
if not self.loaded:
self.load()
predictions = self.sess.run(self.y,feed_dict={self.x:X})
return predictions.astype(np.float64)

Expand Down
544 changes: 287 additions & 257 deletions examples/models/deep_mnist/deep_mnist.ipynb

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions examples/models/mean_classifier/Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
VERSION=1.2
VERSION=1.3
IMAGE_BASE=seldonio/mock_classifier

build_rest:
s2i build -E environment_rest . seldonio/seldon-core-s2i-python36:0.5-SNAPSHOT ${IMAGE_BASE}_rest:${VERSION}
s2i build -E environment_rest . seldonio/seldon-core-s2i-python36:0.11-SNAPSHOT ${IMAGE_BASE}_rest:${VERSION}

push_rest:
docker push ${IMAGE_BASE}_rest:${VERSION}

build_grpc:
s2i build -E environment_grpc . seldonio/seldon-core-s2i-python36:0.5-SNAPSHOT ${IMAGE_BASE}_grpc:${VERSION}
s2i build -E environment_grpc . seldonio/seldon-core-s2i-python36:0.11-SNAPSHOT ${IMAGE_BASE}_grpc:${VERSION}

push_grpc:
docker push ${IMAGE_BASE}_grpc:${VERSION}
4 changes: 2 additions & 2 deletions examples/models/sklearn_iris/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scikit-learn==0.19.0
scipy==0.18.1
scikit-learn
scipy
Loading

0 comments on commit fa9b745

Please sign in to comment.