Skip to content

Comments

Add clipper deployment support#151

Merged
yubozhao merged 27 commits intobentoml:masterfrom
yubozhao:clipper-support
Jul 16, 2019
Merged

Add clipper deployment support#151
yubozhao merged 27 commits intobentoml:masterfrom
yubozhao:clipper-support

Conversation

@yubozhao
Copy link
Contributor

@yubozhao yubozhao commented Jun 3, 2019

(Thanks for sending a pull request! Please make sure to read the contribution guidelines, then fill out the blanks below.)

What changes were proposed in this pull request?

Does this close any currently open issues?

How was this patch tested?

@pep8speaks
Copy link

pep8speaks commented Jun 3, 2019

Hello @yubozhao, Thanks for updating this PR.

Line 68:89: E501 line too long (91 > 88 characters)

Comment last updated at 2019-07-16 22:50:54 UTC

node_modules/
yarn-error.log
yarn.lock
.DS_Store
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

# MacOS
.DS_Store

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

"""

BENTO_SERVICE_DOCKERFILE_CLIPPER_TEMPLATE = """\
FROM clipper/python36-closure-container:0.3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a note on why we use python36 image, even for BentoArchive built in python27


ENV TINI_VERSION v0.16.1
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN chmod +x /usr/bin/tini
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need tini in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

na, removed it.

done

RUN chmod +x /usr/bin/tini
##### End installation for miniconda3

RUN set -x \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this up to the "apt-get" section above, let's not run apt-get update multiple times in one docker build

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

WORKDIR /container

# update conda base env
RUN conda env update -n base -f /container/environment.yml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be "/container/bento/environment.yml"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for the requirement.txt and setup.sh file below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, those weren't done when i made the draft PR.

done now

shutil.copytree(self.archive_path, model_path)

image = build_docker_image(snapshot_path)
self.clipper_conn.register_application(name=self.application_name,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest leaving register_application and link_model_to_app to the user, similar to the "deploy_xxx" commands provided in clipper, it should only deploy the model, without affecting the application

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return

def check_status(self):
if self.is_deployed:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed offline, remove check_status and delete here, will recommend user follow clipper convention on checking the model status and stopping running model instance

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

with open(os.path.join(path, 'Dockerfile-sagemaker'), 'w') as f:
f.write(BENTO_SERVICE_DOCKERFILE_SAGEMAKER_TEMPLATE)
with open(os.path.join(path, 'Dockerfile-clipper'), 'w') as f:
f.write(BENTO_SERVICE_DOCKERFILE_CLIPPER_TEMPLATE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussed offline, we should handle this similar to DEFAULT_CLIPPER_ENTRY, generate it when calling deploy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for BENTO_SERVICE_DOCKERFILE_SAGEMAKER_TEMPLATE above, but this can be in separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

"""Clipper deployment for BentoML bundle
"""

def __init__(self, clipper_conn, archive_path, api_name, slo_micros=100000):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove slo_micros since we will not handle register application

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

return self.application_name


def deploy_bentoml(clipper_conn, archive_path, api_name):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also expose the clipper "labels" here? http://clipper.ai/api/api.html#definition-Model

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


def build_docker_image(snapshot_path):
docker_api = docker.APIClient()
tag = "something"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use BentoArchive version for tag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

raise BentoMLException(
'Please specify api-name, when more than one API is present in the archive')
application_name = bento_service.name + '-' + api.name
input_type = 'strings'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we still need 'handle_clipper_numbers'? looks like its just strings and bytes we are supporting?

@codecov-io
Copy link

codecov-io commented Jul 11, 2019

Codecov Report

Merging #151 into master will decrease coverage by 2.02%.
The diff coverage is 19.57%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #151      +/-   ##
==========================================
- Coverage   54.57%   52.55%   -2.03%     
==========================================
  Files          51       53       +2     
  Lines        2767     2940     +173     
==========================================
+ Hits         1510     1545      +35     
- Misses       1257     1395     +138
Impacted Files Coverage Δ
...ntoml/deployment/serverless/aws_lambda_template.py 34.09% <ø> (ø) ⬆️
bentoml/deployment/clipper/templates.py 0% <0%> (ø)
bentoml/deployment/clipper/__init__.py 0% <0%> (ø)
bentoml/deployment/sagemaker/__init__.py 21.98% <100%> (+1.47%) ⬆️
bentoml/__init__.py 100% <100%> (ø) ⬆️
bentoml/handlers/fastai_image_handler.py 33.6% <16.66%> (-5.53%) ⬇️
bentoml/handlers/dataframe_handler.py 65.35% <17.14%> (-18.35%) ⬇️
bentoml/deployment/utils.py 42.3% <22.22%> (-45.2%) ⬇️
bentoml/handlers/image_handler.py 61.11% <29.41%> (-7.39%) ⬇️
bentoml/handlers/json_handler.py 69.38% <38.46%> (-11.17%) ⬇️
... and 4 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f4ae4e1...dea4ea7. Read the comment docs.


def handle_clipper_strings(self, inputs, func):
def transform_and_predict(input_string):
# Assuming input string is JSON format
Copy link
Contributor Author

@yubozhao yubozhao Jul 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe give user a choice between json and csv??

@yubozhao yubozhao marked this pull request as ready for review July 15, 2019 22:01
clipper_conn(clipper_admin.ClipperConnection): Clipper conntection instance
archive_path(str): Path to the bentoml service archive.
api_name(str): name of the api that will be running in the clipper cluster
input_type(str): Input type that clipper accept
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add some more notes here - especially about the default value and behavior around ImageHnalder check below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

raise BentoMLException(
"Please specify api-name, when more than one API is present in the archive"
)
application_name = generate_clipper_compatiable_string(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

give the user the option to provide an application name as the function parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if item.startswith('bool'):
return 'boolean'
return 'object'
if item.startswith("int"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this formatted by black? I thought it should be single quote?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, those formatted by black. I will re-run it to make sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed back. format script skip string normalization

return self.handler.handle_clipper_strings(inputs, self.func)

def handle_clipper_bytes(self, inputs):
return self.handler.handle_clipper_strings(inputs, self.func)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo


def handle_clipper_strings(self, inputs, func):
raise RuntimeError(
"Image handler does not support 'strings' input_type \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo? *ImageHandler

sys.stderr.write(error["message"])
raise RuntimeError("Error on build - code %s" % error["code"])
elif "stream" in line_payload:
# TODO: move this to logger.info
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try just use logger.info here? and similarly for the logging.error above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

# update conda and setup environment and pre-install common ML libraries to speed up docker build
RUN conda update conda -y \
&& conda install pip numpy scipy \
&& pip install six bentoml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is ok for now but we need to pin this to the version that user is using for saving the given BentoArchive

@yubozhao yubozhao merged commit 0fc85b5 into bentoml:master Jul 16, 2019
@yubozhao yubozhao deleted the clipper-support branch July 16, 2019 23:00
aarnphm pushed a commit to aarnphm/BentoML that referenced this pull request Jul 29, 2022
Provide `bentoml.deployment.clipper.deploy_bentoml` for users.

```python
from bentoml.deployment.clipper import deploy_bentoml

deployed_model_name, deployed_model_version = deploy_bentoml(
    clipper_connection,
    bentoml_service_archive_path,
    api_name,
    input_type
)
# After model is deployed to clipper cluster, can register application and link up
application and deployed model to be an endpoint in clipper cluster
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants