Skip to content

Commit

Permalink
Merge pull request kubeflow#75 from animeshsingh/sklearn-server
Browse files Browse the repository at this point in the history
Sklearn server
  • Loading branch information
abhi-g authored May 10, 2019
2 parents 2030c8b + 9690520 commit 32a7a8b
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 0 deletions.
35 changes: 35 additions & 0 deletions docs/samples/sklearn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Creating your own model and testing the SKLearn server.

To test the Scikit-learn Server, first we need to generate a simple scikit-learn model using Python. Sample model is also added in this directory to reuse if needed.

```python
from sklearn import svm
from sklearn import datasets
from joblib import dump
clf = svm.SVC(gamma='scale')
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf.fit(X, y)
dump(clf, 'model.joblib')
```

Then, we can run the Scikit-learn Server using the generated model and test for prediction. Models can be on local filesystem, S3 compatible object storage or Google Cloud Storage.

```shell
python -m sklearnserver --model_dir model.joblib --model_name svm
```

We can also use the inbuilt sklearn support for sample datasets and do some simple predictions

```python
from sklearn import datasets
import requests
iris = datasets.load_iris()
X, y = iris.data, iris.target
formData = {
'instances': X[0:1].tolist()
}
res = requests.post('http://localhost:8080/models/svm:predict', json=formData)
print(res)
print(res.text)
```
Binary file added docs/samples/sklearn/model.joblib
Binary file not shown.
Empty file added python/sklearnserver/DOCKERFILE
Empty file.
38 changes: 38 additions & 0 deletions python/sklearnserver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Scikit-Learn Server

[Scikit-Learn](https://scikit-learn.org/stable/) server is an implementation of KFServing for serving Scikit-learn models, and provides a Scikit-learn model implementation for prediction, pre and post processing.

To start the server locally for development needs, run the following command under this folder in your github repository.

```
pip install -e .
```

The following output indicates a successful install.

```
Obtaining file://kfserving/python/sklearn
Requirement already satisfied: kfserver==0.1.0 in /Users/username/Desktop/kfserving/python/kfserving (from sklearnserver==0.1.0) (0.1.0)
Requirement already satisfied: scikit-learn==0.20.3 in /anaconda3/lib/python3.6/site-packages (from sklearnserver==0.1.0) (0.20.3)
Requirement already satisfied: argparse>=1.4.0 in /anaconda3/lib/python3.6/site-packages (from sklearnserver==0.1.0) (1.4.0)
Requirement already satisfied: numpy>=1.8.2 in /anaconda3/lib/python3.6/site-packages (from sklearnserver==0.1.0) (1.16.2)
Requirement already satisfied: tornado>=1.4.1 in /anaconda3/lib/python3.6/site-packages (from kfserver==0.1.0->sklearnserver==0.1.0) (5.0.2)
Requirement already satisfied: scipy>=0.13.3 in /anaconda3/lib/python3.6/site-packages (from scikit-learn==0.20.3->sklearnserver==0.1.0) (1.1.0)
Installing collected packages: sklearnserver
Found existing installation: sklearnserver 0.1.0
Uninstalling sklearnserver-0.1.0:
Successfully uninstalled sklearnserver-0.1.0
Running setup.py develop for sklearnserver
Successfully installed sklearnserver
```

Once Scikit-learn server is up and running, you can check for successful installation by running the following command

```
python3 -m sklearnserver
usage: __main__.py [-h] [--http_port HTTP_PORT] [--grpc_port GRPC_PORT]
--model_dir MODEL_DIR [--model_name MODEL_NAME]
__main__.py: error: the following arguments are required: --model_dir
```

You can now point to your `joblib` model file and use the server to load the model and test for prediction. Models can be on local filesystem, S3 compatible object storage or Google Cloud Storage. Please follow [this sample](https://github.com/kubeflow/kfserving/tree/master/docs/samples/sklearn) to test your server by generating your own model.
20 changes: 20 additions & 0 deletions python/sklearnserver/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from setuptools import setup, find_packages

setup(
name='sklearnserver',
version='0.1.0',
author_email='singhan@us.ibm.com',
license='https://github.com/kubeflow/kfserving/LICENSE',
url='https://github.com/kubeflow/kfserving/python/sklearnserver',
description='Model Server implementation for scikit-learn. Not intended for use outside KFServing Frameworks Images',
long_description=open('README.md').read(),
python_requires='>3.4',
packages=find_packages("sklearnserver"),
install_requires=[
"kfserver==0.1.0",
"scikit-learn == 0.20.3",
"argparse >= 1.4.0",
"numpy >= 1.8.2",
"joblib >= 0.13.0"
],
)
1 change: 1 addition & 0 deletions python/sklearnserver/sklearnserver/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .model import SKLearnModel
20 changes: 20 additions & 0 deletions python/sklearnserver/sklearnserver/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import kfserving
import argparse


from sklearnserver import SKLearnModel

DEFAULT_MODEL_NAME = "model"
DEFAULT_LOCAL_MODEL_DIR = "/tmp/model"

parser = argparse.ArgumentParser(parents=[kfserving.server.parser])
parser.add_argument('--model_dir', required=True,
help='A URI pointer to the model binary')
parser.add_argument('--model_name', default=DEFAULT_MODEL_NAME,
help='The name that the model is served under.')
args, _ = parser.parse_known_args()

if __name__ == "__main__":
model = SKLearnModel(args.model_name, args.model_dir)
model.load()
kfserving.KFServer().start([model])
27 changes: 27 additions & 0 deletions python/sklearnserver/sklearnserver/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import kfserving
import joblib
import numpy as np
import os

class SKLearnModel(kfserving.KFModel):
def __init__(self, name, model_dir):
self.name = name
self.model_dir = model_dir
self.ready = False

def load(self):
model_file = kfserving.Storage.download(self.model_dir)
self._joblib = joblib.load(model_file)
self.ready = True

def predict(self, inputs):
try:
inputs = np.array(inputs)
except Exception as e:
raise Exception(
"Failed to initialize NumPy array from inputs: %s, %s" % (e, inputs))
try:
result = self._joblib.predict(inputs).tolist()
return result
except Exception as e:
raise Exception("Failed to predict %s" % e)

0 comments on commit 32a7a8b

Please sign in to comment.