-
Notifications
You must be signed in to change notification settings - Fork 280
R model deployment #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
R model deployment #195
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
80ca026
Initial commit
dcrankshaw 578d559
heap size for clipper/spark-scala-container.
dubeyabhi07 99f5d33
Merge branch 'develop' into develop
dcrankshaw cb7756e
created dockerfile
dubeyabhi07 199ca85
update clipper manager
dubeyabhi07 1b01809
Update clipper_manager.py
dubeyabhi07 4240a5b
Add files via upload
dubeyabhi07 ff3580c
Create R_model_support.py
dubeyabhi07 d3d6ca9
tutorial added
dubeyabhi07 b9d651b
Merge remote-tracking branch 'upstream/master' into develop
b413b58
Merge remote-tracking branch 'upstream/develop' into develop
daecade
removed license
d8f1d13
Delete R_model_deployment_tutorial-checkpoint.ipynb
dubeyabhi07 1d0abcf
added fresh tutorial
dubeyabhi07 e81f0ba
Delete R_model_deployment_tutorial.ipynb
dubeyabhi07 d9eef9e
Merge branch 'develop' into develop
dubeyabhi07 f72141d
Update clipper_manager.py
dubeyabhi07 9cba595
Merge branch 'develop' into develop
dubeyabhi07 c32d6a3
made R directory
6461601
added test and updated admin file
fe8d998
Merge remote-tracking branch 'upstream/develop' into develop
b1ad25d
xyz
31b2132
deleted tutorials
30ed4c8
idk
1a15f11
added readme
bc9f0f1
prefinal
28b4d97
final
797e695
solved space issues due to text editor
dubeyabhi07 4992214
deleted undesired .Rhistory and other files
5be53b1
Create clipper_manager.py
dubeyabhi07 92f5542
deleted undesired .Rhistory and other files
9ec89d9
Merge branch 'develop' of https://github.com/dubeyabhi07/clipper into…
6ea4f55
Update README
Corey-Zumar 44b9735
Fix container prediction behavior, simplify csv encoding
Corey-Zumar ff8a80a
Format code
Corey-Zumar f49acc5
Update r_python_container.py
dubeyabhi07 188cdf7
modified test
1289396
Revert to row-by-row prediction style using dataframe splitting
Corey-Zumar 6a69b3a
Remove unused line. format code
Corey-Zumar db520e5
Format code
Corey-Zumar 35fd78e
Merge branch 'develop' into develop
Corey-Zumar fa82010
typo and method-args fix
f044be7
fix
343e98b
removed whitespaces
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| FROM clipper/py-rpc:latest | ||
|
|
||
| ## Use Debian unstable via pinning -- new style via APT::Default-Release | ||
| RUN echo "deb http://http.debian.net/debian sid main" > /etc/apt/sources.list.d/debian-unstable.list \ | ||
| && echo 'APT::Default-Release "testing";' > /etc/apt/apt.conf.d/default | ||
|
|
||
| ENV R_BASE_VERSION 3.4.0 | ||
|
|
||
| ## Now install R and littler, and create a link for littler in /usr/local/bin | ||
| ## Also set a default CRAN repo, and make sure littler knows about it too | ||
| RUN apt-get update \ | ||
| && apt-get install -t unstable -y --no-install-recommends \ | ||
| littler \ | ||
| r-cran-littler \ | ||
| r-base=${R_BASE_VERSION}* \ | ||
| r-base-dev=${R_BASE_VERSION}* \ | ||
| r-recommended=${R_BASE_VERSION}* \ | ||
| && echo 'options(repos = c(CRAN = "https://cran.rstudio.com/"), download.file.method = "libcurl")' >> /etc/R/Rprofile.site \ | ||
| && echo 'source("/etc/R/Rprofile.site")' >> /etc/littler.r \ | ||
| && ln -s /usr/share/doc/littler/examples/install.r /usr/local/bin/install.r \ | ||
| && ln -s /usr/share/doc/littler/examples/install2.r /usr/local/bin/install2.r \ | ||
| && ln -s /usr/share/doc/littler/examples/installGithub.r /usr/local/bin/installGithub.r \ | ||
| && ln -s /usr/share/doc/littler/examples/testInstalled.r /usr/local/bin/testInstalled.r \ | ||
| && install.r docopt \ | ||
| && rm -rf /tmp/downloaded_packages/ /tmp/*.rds \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
|
|
||
|
|
||
|
|
||
| RUN conda install rpy2 | ||
|
|
||
| COPY containers/R/r_python_container.py /container/ | ||
|
|
||
| CMD ["python", "/container/r_python_container.py"] | ||
|
|
||
|
|
||
|
|
||
| # vim: set filetype=dockerfile: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # RPython model container | ||
| This container enables the deployment of R models. It supports both the R and Python runtimes. R functions are called from Python using the RPy2 interface, while the container is built upon the [Python RPC client](https://github.com/ucbrise/clipper/blob/develop/containers/python/rpc.py). | ||
|
|
||
| ## Prerequisites : | ||
| In addition to the requirements of running clipper, | ||
|
|
||
| 1. R must be installed (version:latest , >=3.4) | ||
| 2. Python version must be =2.7. | ||
| 3. RPy2 must be installed. For more info, go to <https://rpy2.bitbucket.io/> | ||
|
|
||
| ## Instructions for Model Deployment and Prediction : | ||
| - Make sure 'r_python_container' image is created from <clipper-root>/RPythonDockerfile and Clipper is running. | ||
| - R models can be formulated and trained in python notebooks using the RPy2 interface, for example : | ||
|
|
||
| ```py | ||
| import rpy2.robjects as ro | ||
| ro.r('formula=mpg~wt+cyl') #model's formula | ||
| ro.r('dataset=mtcars') #model's training dataset | ||
| # Create an R model with an RPy2 reference | ||
| model_RPy2 = ro.r('model_R <- lm(formula,data=dataset)') | ||
| ``` | ||
| - A previously trained and saved model (in .rds format) can also be loaded as RPy2 object : | ||
|
|
||
| ```py | ||
| from rpy2.robjects.packages import importr | ||
| base = importr('base') | ||
| self.model = base.readRDS(PATH) #PATH is the path of saved model. | ||
| ``` | ||
|
|
||
| - Deploy the model : | ||
|
|
||
| ```py | ||
| Clipper.deploy_R_model( | ||
| "example_model", 1, model_RPy2 | ||
| ) | ||
| ``` | ||
|
|
||
| - Register Application : | ||
|
|
||
| ``` | ||
| Clipper.register_application( | ||
| "example_app", "example_model", "strings", default_output, slo_micros=2000 | ||
| ) | ||
| ``` | ||
|
|
||
| - Requesting predictions | ||
|
|
||
| The container inputs are of type **string**. Each string input is a csv-encoded pandas dataframe. | ||
| The following is an example encoding: | ||
| ```py | ||
| pandas_dataframe = DataFrame({'wt':[5.43,6.00,7.89],'cyl' :[4.32,5.76,7.90]}) | ||
| encoded_dataframe = pandas_dataframe.to_csv(sep=";") | ||
| assert type(encoded_dataframe) == str | ||
| ``` | ||
|
|
||
| Once a data frame has been string encoded, we can pass it to the container via the `requests.post()` method and obtain batched predictions for each data frame row. | ||
|
|
||
| This process is illustrated in the `predict_R_model()` method of | ||
| [R Model Integration Test](../../integration-tests/deploy_R_models.py) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| from __future__ import print_function | ||
| import rpc | ||
| import os | ||
| import numpy as np | ||
| import pandas as pd | ||
| from rpy2.robjects import r, pandas2ri | ||
| from rpy2.robjects.packages import importr | ||
| import rpy2.robjects as ro | ||
| import sys | ||
| if sys.version_info[0] < 3: | ||
| from StringIO import StringIO | ||
| else: | ||
| from io import StringIO | ||
| stats = importr('stats') | ||
| base = importr('base') | ||
|
|
||
|
|
||
| class RContainer(rpc.ModelContainerBase): | ||
| def __init__(self, path): | ||
| self.model = base.readRDS(path) | ||
| print("Loaded %s model" % type(self.model), file=sys.stderr) | ||
| self.path = path | ||
|
|
||
| def predict_strings(self, inputs): | ||
| outputs = [] | ||
| for input_csv in inputs: | ||
| csv_handle = StringIO(input_csv) | ||
| pdf = pd.read_csv(csv_handle, sep=";", index_col=0) | ||
| pandas2ri.activate() | ||
| rdf = pandas2ri.py2ri(pdf) | ||
| preds = stats.predict(self.model, rdf) | ||
| make_list = ro.r('as.list') | ||
| make_df = ro.r('data.frame') | ||
| rdf_preds = make_df(make_list(preds)) | ||
| pdf_preds = pandas2ri.ri2py(rdf_preds) | ||
| response_csv = pdf_preds.to_csv(sep=";") | ||
| outputs.append(response_csv) | ||
| return outputs | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| print("Starting R container") | ||
| try: | ||
| model_name = os.environ["CLIPPER_MODEL_NAME"] | ||
| except KeyError: | ||
| print( | ||
| "ERROR: CLIPPER_MODEL_NAME environment variable must be set", | ||
| file=sys.stdout) | ||
| sys.exit(1) | ||
| try: | ||
| model_version = os.environ["CLIPPER_MODEL_VERSION"] | ||
| except KeyError: | ||
| print( | ||
| "ERROR: CLIPPER_MODEL_VERSION environment variable must be set", | ||
| file=sys.stdout) | ||
| sys.exit(1) | ||
|
|
||
| ip = "127.0.0.1" | ||
| if "CLIPPER_IP" in os.environ: | ||
| ip = os.environ["CLIPPER_IP"] | ||
| else: | ||
| print("Connecting to Clipper on localhost") | ||
|
|
||
| port = 7000 | ||
| if "CLIPPER_PORT" in os.environ: | ||
| port = int(os.environ["CLIPPER_PORT"]) | ||
| else: | ||
| print("Connecting to Clipper with default port: 7000") | ||
|
|
||
| input_type = "strings" | ||
| model_path = os.environ["CLIPPER_MODEL_PATH"] | ||
|
|
||
| rds_names = [ | ||
| l for l in os.listdir(model_path) if os.path.splitext(l)[-1] == ".rds" | ||
| ] | ||
|
|
||
| if len(rds_names) != 1: | ||
| print("Found %d *.rds files. Expected 1" % len(rds_names)) | ||
| sys.exit(1) | ||
| rds_path = os.path.join(model_path, rds_names[0]) | ||
| print(rds_path, file=sys.stdout) | ||
|
|
||
| model = RContainer(rds_path) | ||
| rpc_service = rpc.RPCService() | ||
| rpc_service.start(model, ip, port, model_name, model_version, input_type) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you removed the container_name and input_type arguments from the method, set the variables here:
Also make sure to update the examples and tests in the rest of the PR.