Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gsunner committed Jun 4, 2018
2 parents ded0b22 + 666ee35 commit 8bc2d03
Show file tree
Hide file tree
Showing 21 changed files with 9,651 additions and 33 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,9 @@ wrappers/s2i/python/Dockerfile
wrappers/s2i/python/_wrappers

.Rhistory
examples/models/pyspark_pmml/metastore_db
examples/models/pyspark_pmml/data
examples/models/pyspark_pmml/derby.log
examples/models/pyspark_pmml/mnist_train.csv
examples/models/pyspark_pmml/src/main/resources/model.pmml
examples/models/pyspark_pmml/.gitignore
72 changes: 72 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Install Seldon-Core

To install seldon-core on a Kubernetes cluster you have several choices:

* Decide on which package manager to use, we support:
* Helm
* Ksonnet
* Decide on how you wish APIs to be exposed, we support:
* Ambassador reverse proxy
* Seldon's builtin OAuth API Gateway
* Decide on whether you wish to contribute anonymous usage metrics. We encourage you to allow anonymous usage metrics to help us improve the project by understanding the deployment environments. More details can be found [here](/docs/developer/readme.md#usage-reporting)
* Does your kubernetes cluster have RBAC enabled?
* If not then disable seldon RBAC setup

Follow one of the methods below:

## With Helm

* [Install Helm](https://docs.helm.sh)
* [Optionally, Install Ambassador](https://www.getambassador.io)
* Install Seldon CRD. Set:
* ```usage_metrics.enabled``` as appropriate.

```
helm install seldon-core-crd --name seldon-core-crd --repo https://storage.googleapis.com/seldon-charts \
--set usage_metrics.enabled=true
```
* Install seldon-core components. Set
* ```apife.enabled``` : (default true) set to ```false``` if you have installed Ambassador.
* ```rbac.enabled``` : (default true) set to ```false``` if running an old Kubernetes cluster without RBAC.
```
helm install seldon-core --name seldon-core --repo https://storage.googleapis.com/seldon-charts \
--set apife.enabled=<true|false> \
--set rbac.enabled=<true|false>
```

Notes

* You can use ```--namespace``` to install seldon-core to a particular namespace

## With Ksonnet

* [install Ksonnet](https://ksonnet.io/)
* [Optionally, Install Ambassador](https://www.getambassador.io)
* Create a seldon ksonnet app
```
ks init my-ml-deployment --api-spec=version:v1.8.0
```
* Install seldon-core. Set:
* ```withApife``` set to ```false``` if you are using Ambassador
* ```withRbac``` set to ```true``` if your cluster has RBAC enabled
```
cd my-ml-deployment && \
ks registry add seldon-core github.com/SeldonIO/seldon-core/tree/master/seldon-core && \
ks pkg install seldon-core/seldon-core@master && \
ks generate seldon-core seldon-core \
--withApife=<true|false> \
--withRbac=<true|false>
```
* Launch components onto cluster
```
ks apply default
```
Notes

* You can use ```--namespace``` to install seldon-core to a particular namespace

## Other Options

### Install with kubeflow

* [Install Seldon as part of kubeflow.](https://github.com/kubeflow/kubeflow/blob/master/user_guide.md)
2 changes: 2 additions & 0 deletions examples/models/pyspark_pmml/.s2i/environment
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
API_TYPE=REST
SERVICE_TYPE=MODEL
22 changes: 22 additions & 0 deletions examples/models/pyspark_pmml/contract.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"features":[
{
"name":"_c",
"dtype":"INT",
"ftype":"continuous",
"range":[0,255],
"repeat":784
}
],
"targets":[
{
"name":"class",
"dtype":"FLOAT",
"ftype":"continuous",
"range":[0,1],
"repeat":10
}
]
}


282 changes: 282 additions & 0 deletions examples/models/pyspark_pmml/mnist.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# PySpark and PMML Example\n",
"In this example we train an MNIST model using pySpark, export the model to PMML and then wrap it using Seldon's S2I interface so we can run predictions against it using seldon-core.\n",
"\n",
"## Dependencies\n",
"\n",
"To run this notebook you will need to set up pySpark and JPMML's spark export.\n",
"\n",
" * [Install pySpark along with Spark](http://spark.apache.org/downloads.html)\n",
" * [Install JPMML Spark Package](https://github.com/jpmml/jpmml-sparkml-package)\n",
" \n",
" Following the above instruction you should add a set of environment variables of the form shown below to your shell:\n",
"\n",
"```\n",
"export SPARK_HOME=<MY SPARK INSTALL FOLDER>/spark-2.3.0-bin-hadoop2.7\n",
"export PATH=$SPARK_HOME/bin:$PATH\n",
"export PYSPARK_DRIVER_PYTHON=jupyter\n",
"export PYSPARK_DRIVER_PYTHON_OPTS='notebook'\n",
"export PYTHONPATH=<MY JPPML FOLDER>/jpmml-sparkml-package/target/jpmml_sparkml-1.4rc0-py3.6.egg\n",
"```\n",
"\n",
"Then when you run pyspark from the folder of this notebook it should start Jupyter running with a Spark context and the JPMML libraries availble, e.g.\n",
"\n",
"```\n",
"pyspark --jars <MY JPPML FOLDER>/jpmml-sparkml-package/target/jpmml-sparkml-package-1.4-SNAPSHOT.jar\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Train MNIST Model using pySpark"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.examples.tutorials.mnist import input_data\n",
"import numpy as np\n",
"\n",
"mnist = input_data.read_data_sets('data/MNIST_data', one_hot=False)\n",
"X = (mnist.train.images * 225).astype(int)\n",
"X_y = np.concatenate((X,np.expand_dims(mnist.train.labels,1)),axis=1)\n",
"np.savetxt(\"mnist_train.csv\", X_y, fmt='%i', delimiter=\",\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pyspark.ml import Pipeline\n",
"from pyspark.ml.classification import LogisticRegression, LogisticRegressionModel\n",
"from pyspark.ml.feature import VectorAssembler\n",
"\n",
"df = sqlContext.read.csv(\"./mnist_train.csv\",inferSchema=True)\n",
"\n",
"df = df.withColumnRenamed(\"_c784\",\"label\")\n",
"\n",
"assembler = (VectorAssembler()\n",
" .setInputCols(df.columns[0:784])\n",
" .setOutputCol(\"features\"))\n",
"\n",
"lr = LogisticRegression(maxIter=10, regParam=0.01)\n",
"\n",
"pipeline = Pipeline(stages=[assembler, lr])\n",
"model = pipeline.fit(df)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from jpmml_sparkml import toPMMLBytes\n",
"\n",
"pmmlBytes = toPMMLBytes(sc, df, model)\n",
"f = open('model.pmml', 'wb')\n",
"f.write(pmmlBytes)\n",
"f.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!mv model.pmml src/main/resources"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Build Image with S2I"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!s2i build . seldonio/seldon-core-s2i-java-build pyspark-test:0.1 --runtime-image seldonio/seldon-core-s2i-java-runtime"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test with Docker"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!docker run --name \"pyspark_predictor\" -d --rm -p 5000:5000 pyspark-test:0.1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!cd ../../../wrappers/testing && make build_protos"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!python ../../../wrappers/testing/tester.py contract.json 0.0.0.0 5000 -p -t"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!docker rm pyspark_predictor --force"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Test in Minikube"
]
},
{
"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 pyspark-test:0.1 --runtime-image seldonio/seldon-core-s2i-java-runtime"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!kubectl create -f 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": [
"!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"
]
}
],
"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
}
Loading

0 comments on commit 8bc2d03

Please sign in to comment.