diff --git a/examples/models/deep_mnist/README.md b/examples/models/deep_mnist/README.md deleted file mode 100644 index 635bc5438b..0000000000 --- a/examples/models/deep_mnist/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# Tensorflow MNIST -A TensorFlow model for MNIST classification. - -## Dependencies - -```bash -pip install tensorflow -``` - -## Train locally - -```bash -make train -``` - -## Wrap using [s2i](https://github.com/openshift/source-to-image#installation). - -```bash -s2i build . seldonio/seldon-core-s2i-python2 deep-mnist -``` - -## Local Docker Smoke Test - -Run under docker. - -```bash -docker run --rm -p 5000:5000 deep-mnist -``` - -Ensure test grpc modules compiled. - -```bash -pushd ../../../wrappers/testing ; make build_protos ; popd -``` - -Send a data request using the wrapper tester. - -```bash -python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -``` - -## Minikube test - -```bash -minikube start --memory 4096 -``` - -Install seldon core - -``` -helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts --set usage_metrics.enabled=true --set rbac.enabled=false -helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts --set rbac.enabled=false -``` - -Connect to Minikube Docker daemon - -```bash -eval $(minikube docker-env) -``` - -Build image using minikube docker daemon. - -```bash -s2i build . seldonio/seldon-core-s2i-python2 deep-mnist -``` - -Launch deployment - -```bash -kubectl create -f deep_mnist.json -``` - -Port forward API server - -```bash -kubectl port-forward $(kubectl get pods -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].metadata.name}') 8080:8080 -``` - -Ensure tester gRPC modules compiled. You will need to install grpc-tools module. - -```bash -pushd ../../../util/api_tester ; make build_protos ; popd -``` - -Send test request -```bash -python ../../../util/api_tester/api-tester.py contract.json 0.0.0.0 8080 --oauth-key oauth-key --oauth-secret oauth-secret -p -``` - - diff --git a/examples/models/deep_mnist/deep_mnist.ipynb b/examples/models/deep_mnist/deep_mnist.ipynb new file mode 100644 index 0000000000..9801bbaa55 --- /dev/null +++ b/examples/models/deep_mnist/deep_mnist.ipynb @@ -0,0 +1,261 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tensorflow MNIST Model Deployment\n", + "\n", + " * Wrap a Tensorflow MNIST python model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + "\n", + "```bash\n", + "pip install tensorflow\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.examples.tutorials.mnist import input_data\n", + "mnist = input_data.read_data_sets(\"MNIST_data/\", one_hot = True)\n", + "import tensorflow as tf\n", + "\n", + "if __name__ == '__main__':\n", + " \n", + " x = tf.placeholder(tf.float32, [None,784], name=\"x\")\n", + "\n", + " W = tf.Variable(tf.zeros([784,10]))\n", + " b = tf.Variable(tf.zeros([10]))\n", + "\n", + " y = tf.nn.softmax(tf.matmul(x,W) + b, name=\"y\")\n", + "\n", + " y_ = tf.placeholder(tf.float32, [None, 10])\n", + "\n", + "\n", + " cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))\n", + "\n", + " train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)\n", + "\n", + " init = tf.initialize_all_variables()\n", + "\n", + " sess = tf.Session()\n", + " sess.run(init)\n", + "\n", + " for i in range(1000):\n", + " batch_xs, batch_ys = mnist.train.next_batch(100)\n", + " sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})\n", + "\n", + " correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))\n", + " accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n", + " print(sess.run(accuracy, feed_dict = {x: mnist.test.images, y_:mnist.test.labels}))\n", + "\n", + " saver = tf.train.Saver()\n", + "\n", + " saver.save(sess, \"model/deep_mnist_model\")\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-python2 deep-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"mnist_predictor\" -d --rm -p 5000:5000 deep-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm mnist_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-python2 deep-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f deep_mnist.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments deep-mnist -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/models/deep_mnist/deep_mnist.json b/examples/models/deep_mnist/deep_mnist.json index 3b95f90816..44710cc199 100644 --- a/examples/models/deep_mnist/deep_mnist.json +++ b/examples/models/deep_mnist/deep_mnist.json @@ -21,7 +21,7 @@ "spec": { "containers": [ { - "image": "deep-mnist:latest", + "image": "deep-mnist:0.1", "imagePullPolicy": "IfNotPresent", "name": "classifier", "resources": { diff --git a/examples/models/h2o_mojo/h2o_model.ipynb b/examples/models/h2o_mojo/h2o_model.ipynb new file mode 100644 index 0000000000..5a010c02d1 --- /dev/null +++ b/examples/models/h2o_mojo/h2o_model.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# H2O Model\n", + "\n", + " * Wrap a H2O model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + " * [H2O](https://www.h2o.ai/download/)\n", + "\n", + "```bash\n", + "pip install sklearn\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!mkdir -p experiment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import h2o\n", + "h2o.init()\n", + "from h2o.estimators.glm import H2OGeneralizedLinearEstimator\n", + "path = \"http://s3.amazonaws.com/h2o-public-test-data/smalldata/prostate/prostate.csv.zip\"\n", + "h2o_df = h2o.import_file(path)\n", + "h2o_df['CAPSULE'] = h2o_df['CAPSULE'].asfactor()\n", + "model = H2OGeneralizedLinearEstimator(family = \"binomial\")\n", + "model.train(y = \"CAPSULE\",\n", + " x = [\"AGE\", \"RACE\", \"PSA\", \"GLEASON\"],\n", + " training_frame = h2o_df)\n", + "modelfile = model.download_mojo(path=\"./experiment/\", get_genmodel_jar=False)\n", + "print(\"Model saved to \" + modelfile)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!mv experiment/*.zip src/main/resources/model.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-java-build h2o-test:0.1 --runtime-image seldonio/seldon-core-s2i-java-runtime" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"h2o_predictor\" -d --rm -p 5000:5000 h2o-test:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm h2o_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-java-build h2o-test:0.1 --runtime-image seldonio/seldon-core-s2i-java-runtime" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f h2o_deployment.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments seldon-deployment-example -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/models/keras_mnist/README.md b/examples/models/keras_mnist/README.md deleted file mode 100644 index b632fdf243..0000000000 --- a/examples/models/keras_mnist/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Deep MNIST -A Keras model for MNIST classification. - -## Depenencies - -```bash -pip install keras -pip install grpcio-tools -``` - -## Train locally - -```bash -python train_mnist.py -``` - -## Wrap using [s2i](https://github.com/openshift/source-to-image#installation). - -```bash -s2i build . seldonio/seldon-core-s2i-python3 keras-mnist:0.1 -``` - -## Local Docker Smoke Test - -Run under docker. - -```bash -docker run --rm -p 5000:5000 keras-mnist:0.1 -``` - -Ensure test grpc modules compiled. - -```bash -pushd ../../../wrappers/testing ; make build_protos ; popd -``` - -Send a data request using the wrapper tester. - -```bash -python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -``` - -## Minikube test - -```bash -minikube start --memory 4096 -``` - -Install seldon core - -``` -helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts --set usage_metrics.enabled=true --set rbac.enabled=false -helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts --set rbac.enabled=false -``` - -Connect to Minikube Docker daemon - -```bash -eval $(minikube docker-env) -``` - -Build image using minikube docker daemon. - -```bash -s2i build . seldonio/seldon-core-s2i-python3 keras-mnist:0.1 -``` - -Launch deployment - -```bash -kubectl create -f keras_mnist_deployment.json -``` - -Port forward API server - -```bash -kubectl port-forward $(kubectl get pods -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].metadata.name}') 8080:8080 -``` - -Ensure tester gRPC modules compiled. - -```bash -pushd ../../../util/api_tester ; make build_protos ; popd -``` - -Send test request -```bash -python ../../../util/api_tester/api-tester.py contract.json 0.0.0.0 8080 --oauth-key oauth-key --oauth-secret oauth-secret -p -``` - - diff --git a/examples/models/keras_mnist/keras_mnist.ipynb b/examples/models/keras_mnist/keras_mnist.ipynb new file mode 100644 index 0000000000..13d6e978af --- /dev/null +++ b/examples/models/keras_mnist/keras_mnist.ipynb @@ -0,0 +1,429 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Keras MNIST Model Deployment\n", + "\n", + " * Wrap a Tensorflow MNIST python model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + "\n", + "```bash\n", + "pip install keras\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import math\n", + "import datetime\n", + "#from seldon.pipeline import PipelineSaver\n", + "import os\n", + "import tensorflow as tf\n", + "from keras import backend\n", + "from keras.models import Model,load_model\n", + "from keras.layers import Dense,Input\n", + "from keras.layers import Dropout\n", + "from keras.layers import Flatten, Reshape\n", + "from keras.constraints import maxnorm\n", + "from keras.layers.convolutional import Convolution2D\n", + "from keras.layers.convolutional import MaxPooling2D\n", + "\n", + "from keras.callbacks import TensorBoard\n", + "\n", + "class MnistFfnn(object):\n", + "\n", + " def __init__(self,\n", + " input_shape=(784,),\n", + " nb_labels=10,\n", + " optimizer='Adam',\n", + " run_dir='tensorboardlogs_test'):\n", + " \n", + " self.model_name='MnistFfnn'\n", + " self.run_dir=run_dir\n", + " self.input_shape=input_shape\n", + " self.nb_labels=nb_labels\n", + " self.optimizer=optimizer\n", + " self.build_graph()\n", + "\n", + " def build_graph(self):\n", + " \n", + " inp = Input(shape=self.input_shape,name='input_part')\n", + "\n", + " #keras layers\n", + " with tf.name_scope('dense_1') as scope:\n", + " h1 = Dense(256,\n", + " activation='relu',\n", + " W_constraint=maxnorm(3))(inp)\n", + " drop1 = Dropout(0.2)(h1)\n", + "\n", + " with tf.name_scope('dense_2') as scope:\n", + " h2 = Dense(128,\n", + " activation='relu',\n", + " W_constraint=maxnorm(3))(drop1)\n", + " drop2 = Dropout(0.5)(h2)\n", + " \n", + " out = Dense(self.nb_labels,\n", + " activation='softmax')(drop2)\n", + "\n", + " self.model = Model(inp,out)\n", + " \n", + " if self.optimizer == 'rmsprop':\n", + " self.model.compile(loss='categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])\n", + " elif self.optimizer == 'Adam':\n", + " self.model.compile(loss='categorical_crossentropy',\n", + " optimizer='Adam',\n", + " metrics=['accuracy'])\n", + " \n", + " print('graph builded')\n", + "\n", + " def fit(self,X,y=None,\n", + " X_test=None,y_test=None,\n", + " batch_size=128,\n", + " nb_epochs=2,\n", + " shuffle=True):\n", + " \n", + " now = datetime.datetime.now()\n", + " tensorboard_logname = self.run_dir+'/{}_{}'.format(self.model_name,\n", + " now.strftime('%Y.%m.%d_%H.%M')) \n", + " tensorboard = TensorBoard(log_dir=tensorboard_logname)\n", + " \n", + " self.model.fit(X,y,\n", + " validation_data=(X_test,y_test),\n", + " callbacks=[tensorboard],\n", + " batch_size=batch_size, \n", + " nb_epoch=nb_epochs,\n", + " shuffle = shuffle)\n", + " return self\n", + " \n", + " def predict_proba(self,X):\n", + "\n", + " return self.model.predict_proba(X)\n", + " \n", + " def predict(self, X):\n", + " probas = self.model.predict_proba(X)\n", + " return([[p>0.5 for p in p1] for p1 in probas])\n", + " \n", + " def score(self, X, y=None):\n", + " pass\n", + "\n", + " def get_class_id_map(self):\n", + " return [\"proba\"]\n", + "\n", + "class MnistConv(object):\n", + "\n", + " def __init__(self,\n", + " input_shape=(784,),\n", + " nb_labels=10,\n", + " optimizer='Adam',\n", + " run_dir='tensorboardlogs_test',\n", + " saved_model_file='MnistClassifier.h5'):\n", + " \n", + " self.model_name='MnistConv'\n", + " self.run_dir=run_dir\n", + " self.input_shape=input_shape\n", + " self.nb_labels=nb_labels\n", + " self.optimizer=optimizer\n", + " self.saved_model_file=saved_model_file\n", + " self.build_graph()\n", + "\n", + " def build_graph(self):\n", + " \n", + " inp = Input(shape=self.input_shape,name='input_part')\n", + " inp2 = Reshape((28,28,1))(inp) \n", + " #keras layers\n", + " with tf.name_scope('conv') as scope:\n", + " conv = Convolution2D(32, 3, 3,\n", + " input_shape=(32, 32, 3),\n", + " border_mode='same',\n", + " activation='relu',\n", + " W_constraint=maxnorm(3))(inp2)\n", + " drop_conv = Dropout(0.2)(conv)\n", + " max_pool = MaxPooling2D(pool_size=(2, 2))(drop_conv)\n", + "\n", + " with tf.name_scope('dense') as scope:\n", + " flat = Flatten()(max_pool) \n", + " dense = Dense(128,\n", + " activation='relu',\n", + " W_constraint=maxnorm(3))(flat)\n", + " drop_dense = Dropout(0.5)(dense)\n", + " \n", + " out = Dense(self.nb_labels,\n", + " activation='softmax')(drop_dense)\n", + "\n", + " self.model = Model(inp,out)\n", + " \n", + " if self.optimizer == 'rmsprop':\n", + " self.model.compile(loss='categorical_crossentropy',\n", + " optimizer='rmsprop',\n", + " metrics=['accuracy'])\n", + " elif self.optimizer == 'Adam':\n", + " self.model.compile(loss='categorical_crossentropy',\n", + " optimizer='Adam',\n", + " metrics=['accuracy'])\n", + " \n", + " print('graph builded')\n", + "\n", + " def fit(self,X,y=None,\n", + " X_test=None,y_test=None,\n", + " batch_size=128,\n", + " nb_epochs=2,\n", + " shuffle=True):\n", + " \n", + " now = datetime.datetime.now()\n", + " tensorboard_logname = self.run_dir+'/{}_{}'.format(self.model_name,\n", + " now.strftime('%Y.%m.%d_%H.%M')) \n", + " tensorboard = TensorBoard(log_dir=tensorboard_logname)\n", + " \n", + " self.model.fit(X,y,\n", + " validation_data=(X_test,y_test),\n", + " callbacks=[tensorboard],\n", + " batch_size=batch_size, \n", + " nb_epoch=nb_epochs,\n", + " shuffle = shuffle)\n", + " #if not os.path.exists('saved_model'):\n", + " # os.makedirs('saved_model')\n", + " self.model.save(self.saved_model_file)\n", + " return self\n", + " \n", + " def predict_proba(self,X):\n", + " return self.model.predict_proba(X)\n", + " \n", + " def predict(self, X):\n", + " probas = self.model.predict_proba(X)\n", + " return([[p>0.5 for p in p1] for p1 in probas])\n", + " \n", + " def score(self, X, y=None):\n", + " pass\n", + "\n", + " def get_class_id_map(self):\n", + " return [\"proba\"]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from tensorflow.examples.tutorials.mnist import input_data\n", + "mnist = input_data.read_data_sets('data/MNIST_data', one_hot=True)\n", + "X_train = mnist.train.images\n", + "y_train = mnist.train.labels\n", + "X_test = mnist.test.images\n", + "y_test = mnist.test.labels\n", + "mc = MnistConv()\n", + "mc.fit(X_train,y=y_train,\n", + " X_test=X_test,y_test=y_test)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-python3 keras-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"mnist_predictor\" -d --rm -p 5000:5000 keras-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm mnist_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-python3 keras-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f keras_mnist_deployment.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments seldon-deployment-example -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/models/r_iris/README.md b/examples/models/r_iris/README.md deleted file mode 100644 index 6567591e37..0000000000 --- a/examples/models/r_iris/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# R model for IRIS dataset -An R Iris model. - -## Depenencies - -R - -## Train locally - -```bash -Rscript train.R -``` - -## Wrap using [s2i](https://github.com/openshift/source-to-image#installation). - -```bash -s2i build . seldonio/seldon-core-s2i-r r-iris:0.1 -``` - -## Local Docker Smoke Test - -Run under docker. - -```bash -docker run --rm -p 5000:5000 r-iris:0.1 -``` - -Ensure test grpc modules compiled. - -```bash -pushd ../../../wrappers/testing ; make build_protos ; popd -``` - -Send a data request using the wrapper tester. - -```bash -python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -``` - -## Minikube test - -```bash -minikube start --memory 4096 -``` - -Install seldon core - -``` -helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts --set usage_metrics.enabled=true --set rbac.enabled=false -helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts --set rbac.enabled=false -``` - -Connect to Minikube Docker daemon - -```bash -eval $(minikube docker-env) -``` - -Build image using minikube docker daemon. - -```bash -s2i build . seldonio/seldon-core-s2i-r r-iris:0.1 -``` - -Launch deployment - -```bash -kubectl create -f r_iris_deployment.json -``` - -Port forward API server - -```bash -kubectl port-forward $(kubectl get pods -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].metadata.name}') 8080:8080 -``` - -Ensure tester gRPC modules compiled. - -```bash -pushd ../../../util/api_tester ; make build_protos ; popd -``` - -Send test request -```bash -python ../../../util/api_tester/api-tester.py contract.json 0.0.0.0 8080 --oauth-key oauth-key --oauth-secret oauth-secret -p -``` - - diff --git a/examples/models/r_iris/r_iris.ipynb b/examples/models/r_iris/r_iris.ipynb new file mode 100644 index 0000000000..1b21d084d6 --- /dev/null +++ b/examples/models/r_iris/r_iris.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# R IRIS Model\n", + "\n", + " * Wrap a scikit-learn python model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + " * R\n", + "\n", + "```bash\n", + "pip install sklearn\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!Rscript train.R" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-r r-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"iris_predictor\" -d --rm -p 5000:5000 r-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm iris_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-r r-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f r_iris_deployment.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments seldon-deployment-example -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/models/r_mnist/README.md b/examples/models/r_mnist/README.md deleted file mode 100644 index bedd582973..0000000000 --- a/examples/models/r_mnist/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Deep MNIST -An R MNIST model. - -## Depenencies - -R - -## Train locally - -```bash -make train -``` - -## Wrap using [s2i](https://github.com/openshift/source-to-image#installation). - -```bash -s2i build . seldonio/seldon-core-s2i-r r-mnist:0.1 -``` - -## Local Docker Smoke Test - -Run under docker. - -```bash -docker run --rm -p 5000:5000 r-mnist:0.1 -``` - -Ensure test grpc modules compiled. - -```bash -pushd ../../../wrappers/testing ; make build_protos ; popd -``` - -Send a data request using the wrapper tester. - -```bash -python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -``` - -## Minikube test - -```bash -minikube start --memory 4096 -``` - -Install seldon core - -``` -helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts --set usage_metrics.enabled=true --set rbac.enabled=false -helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts --set rbac.enabled=false -``` - -Connect to Minikube Docker daemon - -```bash -eval $(minikube docker-env) -``` - -Build image using minikube docker daemon. - -```bash -s2i build . seldonio/seldon-core-s2i-r r-mnist:0.1 -``` - -Launch deployment - -```bash -kubectl create -f r_mnist_deployment.json -n seldon -``` - -Port forward API server - -```bash -kubectl port-forward $(kubectl get pods -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].metadata.name}') 8080:8080 -``` - -Ensure tester gRPC modules compiled. - -```bash -pushd ../../../util/api_tester ; make build_protos ; popd -``` - -Send test request -```bash -python ../../../util/api_tester/api-tester.py contract.json 0.0.0.0 8080 --oauth-key oauth-key --oauth-secret oauth-secret -p -``` - - diff --git a/examples/models/r_mnist/r_mnist.ipynb b/examples/models/r_mnist/r_mnist.ipynb new file mode 100644 index 0000000000..4d9229425b --- /dev/null +++ b/examples/models/r_mnist/r_mnist.ipynb @@ -0,0 +1,226 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# R MNIST Model\n", + "\n", + " * Wrap a scikit-learn python model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + " * R\n", + "\n", + "```bash\n", + "pip install sklearn\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!rm -f *ubyte && ./get_data.sh && Rscript train.R" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-r r-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"mnist_predictor\" -d --rm -p 5000:5000 r-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm mnist_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-r r-mnist:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f r_mnist_deployment.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments seldon-deployment-example -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/models/sklearn_iris/README.md b/examples/models/sklearn_iris/README.md deleted file mode 100644 index 4ca4dabc96..0000000000 --- a/examples/models/sklearn_iris/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# SKLearn Iris -A scikit-learn Iris model. - -## Depenencies - -```bash -pip install sklearn -pip install grpcio-tools -``` - -## Train locally - -```bash -python train_iris.py -``` - -## Wrap using [s2i](https://github.com/openshift/source-to-image#installation). - -```bash -s2i build . seldonio/seldon-core-s2i-python3 sklearn-iris:0.1 -``` - -## Local Docker Smoke Test - -Run under docker. - -```bash -docker run --rm -p 5000:5000 sklearn-iris:0.1 -``` - -Ensure test grpc modules compiled. - -```bash -pushd ../../../wrappers/testing ; make build_protos ; popd -``` - -Send a data request using the wrapper tester. - -```bash -python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -``` - -## Minikube test - -```bash -minikube start --memory 4096 -``` - -Install seldon core - -``` -helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts --set usage_metrics.enabled=true --set rbac.enabled=false -helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts --set rbac.enabled=false -``` - -Connect to Minikube Docker daemon - -```bash -eval $(minikube docker-env) -``` - -Build image using minikube docker daemon. - -```bash -s2i build . seldonio/seldon-core-s2i-python3 sklearn-iris:0.1 -``` - -Launch deployment - -```bash -kubectl create -f sklearn_iris_deployment.json -``` - -Port forward API server - -```bash -kubectl port-forward $(kubectl get pods -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].metadata.name}') 8080:8080 -``` - -Ensure tester gRPC modules compiled. - -```bash -pushd ../../../util/api_tester ; make build_protos ; popd -``` - -Send test request -```bash -python ../../../util/api_tester/api-tester.py contract.json 0.0.0.0 8080 --oauth-key oauth-key --oauth-secret oauth-secret -p -``` - - diff --git a/examples/models/sklearn_iris/sklearn_iris.ipynb b/examples/models/sklearn_iris/sklearn_iris.ipynb new file mode 100644 index 0000000000..15fdc51c43 --- /dev/null +++ b/examples/models/sklearn_iris/sklearn_iris.ipynb @@ -0,0 +1,241 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Scikit-Learn IRIS Model\n", + "\n", + " * Wrap a scikit-learn python model for use as a prediction microservice in seldon-core\n", + " * Run locally on Docker to test\n", + " * Deploy on seldon-core running on minikube\n", + " \n", + "## Depenencies\n", + "\n", + " * [Helm](https://github.com/kubernetes/helm)\n", + " * [Minikube](https://github.com/kubernetes/minikube)\n", + " * [S2I](https://github.com/openshift/source-to-image)\n", + "\n", + "```bash\n", + "pip install sklearn\n", + "pip install grpcio-tools\n", + "```\n", + "\n", + "## Train locally\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import os\n", + "from sklearn.linear_model import LogisticRegression\n", + "from sklearn.pipeline import Pipeline\n", + "from sklearn.externals import joblib\n", + "from sklearn import datasets\n", + "\n", + "def main():\n", + " clf = LogisticRegression()\n", + " p = Pipeline([('clf', clf)])\n", + " print('Training model...')\n", + " p.fit(X, y)\n", + " print('Model trained!')\n", + "\n", + " filename_p = 'IrisClassifier.sav'\n", + " print('Saving model in %s' % filename_p)\n", + " joblib.dump(p, filename_p)\n", + " print('Model saved!')\n", + " \n", + "if __name__ == \"__main__\":\n", + " print('Loading iris data set...')\n", + " iris = datasets.load_iris()\n", + " X, y = iris.data, iris.target\n", + " print('Dataset loaded!')\n", + " main()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wrap model using s2i" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!s2i build . seldonio/seldon-core-s2i-python3 sklearn-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker run --name \"iris_predictor\" -d --rm -p 5000:5000 sklearn-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../wrappers/testing && make build_protos" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Send some random features that conform to the contract" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!docker rm iris_predictor --force" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC\n", + "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm init" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!helm install ../../../helm-charts/seldon-core-crd --name seldon-core-crd --set usage_metrics.enabled=true\n", + "!helm install ../../../helm-charts/seldon-core --name seldon-core " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!eval $(minikube docker-env) && s2i build . seldonio/seldon-core-s2i-python3 sklearn-iris:0.1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl create -f sklearn_iris_deployment.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wait until ready (replicas == replicasAvailable)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!kubectl get seldondeployments seldon-deployment-example -o jsonpath='{.status}' " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!cd ../../../util/api_tester && make build_protos " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!python ../../../util/api_tester/api-tester.py contract.json \\\n", + " `minikube ip` `kubectl get svc -l app=seldon-apiserver-container-app -o jsonpath='{.items[0].spec.ports[0].nodePort}'` \\\n", + " --oauth-key oauth-key --oauth-secret oauth-secret -p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!minikube delete" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/ksonnet_ambassador_minikube.ipynb b/notebooks/ksonnet_ambassador_minikube.ipynb index 677c067985..36ea4a232c 100644 --- a/notebooks/ksonnet_ambassador_minikube.ipynb +++ b/notebooks/ksonnet_ambassador_minikube.ipynb @@ -29,13 +29,28 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "!minikube start --memory=5000 --feature-gates=CustomResourceValidation=true" + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting local Kubernetes v1.9.4 cluster...\n", + "Starting VM...\n", + "Getting VM IP address...\n", + "Moving files into cluster...\n", + "Setting up certs...\n", + "Connecting to cluster...\n", + "Setting up kubeconfig...\n", + "Starting cluster components...\n", + "Kubectl is now configured to use the cluster.\n", + "Loading cached images from config file.\n" + ] + } + ], + "source": [ + "!minikube start --memory 4096 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=AlwaysAllow" ] }, { @@ -47,11 +62,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "namespace \"seldon\" created\r\n" + ] + } + ], "source": [ "!kubectl create namespace seldon" ] @@ -66,22 +87,35 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "service \"ambassador\" created\r\n" + ] + } + ], "source": [ "!kubectl apply -f resources/ambassador-service.yaml -n seldon" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "service \"ambassador-admin\" created\r\n", + "deployment \"ambassador\" created\r\n" + ] + } + ], "source": [ "!kubectl apply -f https://getambassador.io/yaml/ambassador/ambassador-no-rbac.yaml -n seldon" ] @@ -96,22 +130,38 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34mINFO \u001b[0mUsing context 'minikube' from the kubeconfig file specified at the environment variable $KUBECONFIG\n", + "\u001b[34mINFO \u001b[0mCreating environment \"default\" with namespace \"default\", pointing to cluster at address \"https://192.168.99.100:8443\"\n", + "\u001b[34mINFO \u001b[0mGenerating ksonnet-lib data at path '/home/clive/work/seldon-core/fork-seldon-core/notebooks/my-ml-deployment/lib/v1.8.0'\n", + "\u001b[34mINFO \u001b[0mksonnet app successfully created! Next, try creating a component with `ks generate`.\n" + ] + } + ], "source": [ "!ks init my-ml-deployment --api-spec=version:v1.8.0" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34mINFO \u001b[0mRetrieved 12 files\n", + "\u001b[34mINFO \u001b[0mWriting component at '/home/clive/work/seldon-core/fork-seldon-core/notebooks/my-ml-deployment/components/seldon-core.jsonnet'\n" + ] + } + ], "source": [ "!cd my-ml-deployment && \\\n", " ks registry add seldon-core github.com/SeldonIO/seldon-core/tree/master/seldon-core && \\\n", @@ -121,11 +171,24 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[34mINFO \u001b[0mUpdating deployments seldon.seldon-cluster-manager\n", + "\u001b[34mINFO \u001b[0mCreating non-existent deployments seldon.seldon-cluster-manager\n", + "\u001b[34mINFO \u001b[0mUpdating deployments seldon.redis\n", + "\u001b[34mINFO \u001b[0mCreating non-existent deployments seldon.redis\n", + "\u001b[34mINFO \u001b[0mUpdating services seldon.redis\n", + "\u001b[34mINFO \u001b[0mCreating non-existent services seldon.redis\n", + "\u001b[34mINFO \u001b[0mUpdating customresourcedefinitions seldondeployments.machinelearning.seldon.io\n", + "\u001b[34mINFO \u001b[0mCreating non-existent customresourcedefinitions seldondeployments.machinelearning.seldon.io\n" + ] + } + ], "source": [ "!cd my-ml-deployment && \\\n", " ks apply default" @@ -147,10 +210,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 8, + "metadata": {}, "outputs": [], "source": [ "!cp ../proto/prediction.proto ./proto\n", @@ -166,10 +227,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 9, + "metadata": {}, "outputs": [], "source": [ "import requests\n", @@ -474,21 +533,21 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.6.4" } }, "nbformat": 4, diff --git a/notebooks/kubectl_demo_minikube.ipynb b/notebooks/kubectl_demo_minikube.ipynb index 0c8a01633d..899c1690bf 100644 --- a/notebooks/kubectl_demo_minikube.ipynb +++ b/notebooks/kubectl_demo_minikube.ipynb @@ -34,7 +34,7 @@ "metadata": {}, "outputs": [], "source": [ - "!minikube start --memory=5000 --feature-gates=CustomResourceValidation=true" + "!minikube start --memory=5000 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=AlwaysAllow" ] }, { diff --git a/notebooks/kubectl_demo_minikube_rbac.ipynb b/notebooks/kubectl_demo_minikube_rbac.ipynb index 744c42dfc5..40bd736fbc 100644 --- a/notebooks/kubectl_demo_minikube_rbac.ipynb +++ b/notebooks/kubectl_demo_minikube_rbac.ipynb @@ -34,7 +34,15 @@ "metadata": {}, "outputs": [], "source": [ - "!minikube start --memory=5000 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC\n", + "!minikube start --memory=5000 --feature-gates=CustomResourceValidation=true --extra-config=apiserver.Authorization.Mode=RBAC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "!kubectl create clusterrolebinding kube-system-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default" ] }, diff --git a/readme.md b/readme.md index aaad9a07ed..37df51b383 100644 --- a/readme.md +++ b/readme.md @@ -48,8 +48,7 @@ Machine learning deployment has many [challenges](./docs/challenges.md). Seldon - [Quick Start tutorial using Minikube](./docs/getting_started/minikube.md) - Jupyter notebooks showing worked examples: * Minikube: - * [Jupyter Notebook showing deployment of prebuilt model using Minikube - with RBAC](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/kubectl_demo_minikube_rbac.ipynb) - * [Jupyter Notebook showing deployment of prebuilt model using Minikube - no RBAC](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/kubectl_demo_minikube.ipynb) + * [Jupyter Notebook showing deployment of prebuilt model using Minikube - with RBAC](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/kubectl_demo_minikube_rbac.ipynb) * [Jupyter notebook to create seldon-core with ksonnet and expose APIs using Ambassador on Minikube.](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/ksonnet_ambassador_minikube.ipynb) * GCP: * [Jupyter Notebook showing deployment of prebuilt model using GCP cluster](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/kubectl_demo_gcp.ipynb) @@ -65,9 +64,15 @@ Machine learning deployment has many [challenges](./docs/challenges.md). Seldon Seldon-core allows various types of components to be built and plugged into the runtime prediction graph. These include [models, routers, transformers and combiners](docs/reference/internal-api.md). Some example components that are available as part of the project are: * **Models** : example that illustrate simple machine learning models to help you build your own integrations - * [Tensorflow MNIST Classifier](./examples/models/deep_mnist/README.md) - * [Keras MNIST Classifier](./examples/models/keras_mnist/README.md) - * [scikit-learn Iris Classifier](./examples/models/sklearn_iris/README.md) + * Python + * [Tensorflow MNIST Classifier](./examples/models/deep_mnist/deep_mnist.ipynb) + * [Keras MNIST Classifier](./examples/models/keras_mnist/keras_mnist.ipynb) + * [Scikit-learn Iris Classifier](./examples/models/sklearn_iris/sklearn_iris.ipynb) + * R + * [R MNIST Classifier](./examples/models/r_mnist/r_mnist.ipynb) + * [R Iris Classifier](./examples/models/r_iris/r_iris.ipynb) + * Java + * [H2O Classifier](./examples/models/h2o_mojo/h2o_model.ipynb) * **routers** * [Epsilon-greedy multi-armed bandits for real time optimization of models](https://github.com/SeldonIO/seldon-core/blob/master/notebooks/epsilon_greedy_gcp.ipynb) * **transformers**