Text Classification

BentoML makes moving trained ML models to production easy:

  • Package models trained with any ML framework and reproduce them for model serving in production
  • Deploy anywhere for online API serving or offline batch serving
  • High-Performance API model server with adaptive micro-batching support
  • Central hub for managing models and deployment process via Web UI and APIs
  • Modular and flexible design making it adaptable to your infrastrcuture

BentoML is a framework for serving, managing, and deploying machine learning models. It is aiming to bridge the gap between Data Science and DevOps, and enable teams to deliver prediction services in a fast, repeatable, and scalable way.

Before reading this example project, be sure to check out the Getting started guide to learn about the basic concepts in BentoML.

FastText is a library for efficient learning of word representations and sentence classification.

The goal of text classification is to assign documents (such as emails, posts, text messages, product reviews, etc...) to one or multiple categories. Such categories can be review scores, spam v.s. non-spam, or the language in which the document was typed. Nowadays, the dominant approach to build such classifiers is machine learning, that is learning classification rules from examples. In order to build such classifiers, we need labeled data, which consists of documents and their corresponding categories (or tags, or labels).

As an example, it builds a classifier which automatically classifies stackexchange questions about cooking into one of several possible tags, such as pot, bowl or baking.

This example notebook is base on the guide from fasttext: https://fasttext.cc/docs/en/supervised-tutorial.html

Impression

In [1]:
%reload_ext autoreload
%autoreload 2
%matplotlib inline

import warnings
warnings.filterwarnings("ignore")
In [3]:
!pip install -q bentoml "fasttext==0.9.2"
Requirement already satisfied: fasttext in /usr/local/anaconda3/envs/dev-py3/lib/python3.7/site-packages (0.9.2)
Requirement already satisfied: numpy in /usr/local/anaconda3/envs/dev-py3/lib/python3.7/site-packages (from fasttext) (1.16.4)
Requirement already satisfied: pybind11>=2.2 in /usr/local/anaconda3/envs/dev-py3/lib/python3.7/site-packages (from fasttext) (2.5.0)
Requirement already satisfied: setuptools>=0.7.0 in /usr/local/anaconda3/envs/dev-py3/lib/python3.7/site-packages (from fasttext) (45.1.0.post20200119)

Prepare data

In [2]:
!curl https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz --output cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  446k  100  446k    0     0   466k      0 --:--:-- --:--:-- --:--:--  465k
x cooking.stackexchange.id
x cooking.stackexchange.txt
x readme.txt
In [3]:
!head cooking.stackexchange.txt
__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe?
__label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments
__label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove?
__label__restaurant Michelin Three Star Restaurant; but if the chef is not there
__label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables?
__label__storage-method __label__equipment __label__bread What's the purpose of a bread box?
__label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home?
__label__chocolate American equivalent for British chocolate terms
__label__baking __label__oven __label__convection Fan bake vs bake
__label__sauce __label__storage-lifetime __label__acidity __label__mayonnaise Regulation and balancing of readymade packed mayonnaise and other sauces
In [4]:
!head -n 12404 cooking.stackexchange.txt > cooking.train
!tail -n 3000 cooking.stackexchange.txt > cooking.valid

Train model

In [5]:
import fasttext
In [6]:
model = fasttext.train_supervised(input="cooking.train")

Define and save BentoService

In [7]:
%%writefile text_classification.py

from bentoml import env, artifacts, BentoService, api
from bentoml.frameworks.fasttext import FasttextModelArtifact
from bentoml.adapters import JsonInput

@env(infer_pip_packages=True)
@artifacts([FasttextModelArtifact('model')])
class FasttextClassification(BentoService):
    
    @api(input=JsonInput(), batch=True)
    def predict(self, json_list):
        input = [i['text'] for i in json_list]
        result = self.artifacts.model.predict(input)
        # return top result
        prediction_result = [i[0].replace('__label__', '') for i in result[0]]
        return prediction_result
Writing text_classification.py
In [8]:
from text_classification import FasttextClassification

svc = FasttextClassification()
svc.pack('model', model)

saved_path = svc.save()
[2020-09-22 12:09:52,940] WARNING - Using BentoML installed in `editable` model, the local BentoML repository including all code changes will be packaged together with saved bundle created, under the './bundled_pip_dependencies' directory of the saved bundle.
[2020-09-22 12:09:53,839] INFO - Using default docker base image: `None` specified inBentoML config file or env var. User must make sure that the docker base image either has Python 3.7 or conda installed.
[2020-09-22 12:09:55,087] INFO - Detected non-PyPI-released BentoML installed, copying local BentoML modulefiles to target saved bundle path..
warning: no previously-included files matching '*~' found anywhere in distribution
warning: no previously-included files matching '*.pyo' found anywhere in distribution
warning: no previously-included files matching '.git' found anywhere in distribution
warning: no previously-included files matching '.ipynb_checkpoints' found anywhere in distribution
warning: no previously-included files matching '__pycache__' found anywhere in distribution
no previously-included directories found matching 'e2e_tests'
no previously-included directories found matching 'tests'
no previously-included directories found matching 'benchmark'
UPDATING BentoML-0.9.0rc0+3.gcebf2015/bentoml/_version.py
set BentoML-0.9.0rc0+3.gcebf2015/bentoml/_version.py to '0.9.0.pre+3.gcebf2015'
[2020-09-22 12:10:00,091] INFO - BentoService bundle 'FasttextClassification:20200922120954_28C4D0' saved to: /Users/bozhaoyu/bentoml/repository/FasttextClassification/20200922120954_28C4D0

REST API Model Serving

To start a REST API model server with the BentoService saved above, use the bentoml serve command:

In [12]:
!bentoml serve {saved_path}
[2020-09-22 12:11:58,505] INFO - Starting BentoML API server in development mode..
[2020-09-22 12:11:58,967] WARNING - Using BentoML installed in `editable` model, the local BentoML repository including all code changes will be packaged together with saved bundle created, under the './bundled_pip_dependencies' directory of the saved bundle.
[2020-09-22 12:11:58,981] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 12:11:59,380] INFO - Using default docker base image: `None` specified inBentoML config file or env var. User must make sure that the docker base image either has Python 3.7 or conda installed.
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
 * Serving Flask app "FasttextClassification" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2020-09-22 12:12:17,344] INFO - {'service_name': 'FasttextClassification', 'service_version': '20200922120954_28C4D0', 'api': 'predict', 'task': {'data': '{"text": "Which baking dish is best to bake a banana bread ?"}', 'task_id': '81e679d6-5cab-48c5-9ce2-b486cbf7c6c7', 'http_headers': (('Host', 'localhost:5000'), ('User-Agent', 'curl/7.65.3'), ('Accept', '*/*'), ('Content-Type', 'application/json'), ('Content-Length', '62'))}, 'result': {'data': '"baking"', 'http_status': 200, 'http_headers': (('Content-Type', 'application/json'),)}, 'request_id': '81e679d6-5cab-48c5-9ce2-b486cbf7c6c7'}
127.0.0.1 - - [22/Sep/2020 12:12:17] "POST /predict HTTP/1.1" 200 -
WARNING: Logging before flag parsing goes to stderr.
I0922 12:12:17.346314 4676050368 _internal.py:122] 127.0.0.1 - - [22/Sep/2020 12:12:17] "POST /predict HTTP/1.1" 200 -
^C

If you are running this notebook from Google Colab, you can start the dev server with --run-with-ngrok option, to gain acccess to the API endpoint via a public endpoint managed by ngrok:

In [11]:
!bentoml serve FasttextClassification:latest --run-with-ngrok
[2020-09-22 12:11:20,296] INFO - Getting latest version FasttextClassification:20200922120954_28C4D0
[2020-09-22 12:11:20,297] INFO - Starting BentoML API server in development mode..
[2020-09-22 12:11:20,550] WARNING - Using BentoML installed in `editable` model, the local BentoML repository including all code changes will be packaged together with saved bundle created, under the './bundled_pip_dependencies' directory of the saved bundle.
[2020-09-22 12:11:20,564] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 12:11:20,902] INFO - Using default docker base image: `None` specified inBentoML config file or env var. User must make sure that the docker base image either has Python 3.7 or conda installed.
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
 * Serving Flask app "FasttextClassification" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/anaconda3/envs/dev-py3/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/local/anaconda3/envs/dev-py3/lib/python3.7/threading.py", line 1166, in run
    self.function(*self.args, **self.kwargs)
  File "/Users/bozhaoyu/src/bento/bentoml/utils/flask_ngrok.py", line 90, in start_ngrok
    ngrok_address = _run_ngrok(port)
  File "/Users/bozhaoyu/src/bento/bentoml/utils/flask_ngrok.py", line 39, in _run_ngrok
    os.chmod(executable, 0o777)
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/kn/xnc9k74x03567n1mx2tfqnpr0000gn/T/ngrok/ngrok'

127.0.0.1 - - [22/Sep/2020 12:11:29] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /swagger_static/swagger-ui.css HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /swagger_static/swagger-ui-bundle.js HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /docs.json HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET //favicon.ico HTTP/1.1" 308 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /swagger_static/swagger-ui.css HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /swagger_static/swagger-ui-bundle.js HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:30] "GET /docs.json HTTP/1.1" 200 -
127.0.0.1 - - [22/Sep/2020 12:11:31] "GET /favicon.ico HTTP/1.1" 404 -
^C

Open http://127.0.0.1:5000 to see more information about the REST APIs server in your browser.

Send prediction requeset to the REST API server

Navigate to parent directory of the notebook(so you have reference to the test.jpg image), and run the following curl command to send the image to REST API server and get a prediction result:

curl -X POST \
  http://localhost:5000/predict \
  -H 'Content-Type: application/json' \
  -d '{"text": "Which baking dish is best to bake a banana bread ?"}'

Containerize model server with Docker

One common way of distributing this model API server for production deployment, is via Docker containers. And BentoML provides a convenient way to do that.

Note that docker is not available in Google Colab. You will need to download and run this notebook locally to try out this containerization with docker feature.

If you already have docker configured, simply run the follow command to product a docker container serving the IrisClassifier prediction service created above:

In [13]:
!bentoml containerize FasttextClassification:latest
[2020-09-22 12:13:07,456] INFO - Getting latest version FasttextClassification:20200922120954_28C4D0
Found Bento: /Users/bozhaoyu/bentoml/repository/FasttextClassification/20200922120954_28C4D0
[2020-09-22 12:13:07,495] WARNING - Using BentoML installed in `editable` model, the local BentoML repository including all code changes will be packaged together with saved bundle created, under the './bundled_pip_dependencies' directory of the saved bundle.
[2020-09-22 12:13:07,511] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
Tag not specified, using tag parsed from BentoService: 'fasttextclassification:20200922120954_28C4D0'
Building Docker image fasttextclassification:20200922120954_28C4D0 from FasttextClassification:latest 
-we in here
processed docker file
(None, None)
root in create archive /Users/bozhaoyu/bentoml/repository/FasttextClassification/20200922120954_28C4D0 ['Dockerfile', 'FasttextClassification', 'FasttextClassification/__init__.py', 'FasttextClassification/__pycache__', 'FasttextClassification/__pycache__/text_classification.cpython-37.pyc', 'FasttextClassification/artifacts', 'FasttextClassification/artifacts/__init__.py', 'FasttextClassification/artifacts/model', 'FasttextClassification/bentoml.yml', 'FasttextClassification/text_classification.py', 'MANIFEST.in', 'README.md', 'bentoml-init.sh', 'bentoml.yml', 'bundled_pip_dependencies', 'bundled_pip_dependencies/BentoML-0.9.0rc0+3.gcebf2015.tar.gz', 'docker-entrypoint.sh', 'environment.yml', 'python_version', 'requirements.txt', 'setup.py']
about to build
about to upgrade params
check each param and update
if use config proxy
if buildargs
if shmsize
if labels
if cache from
if target
if network_mode
if squash
if extra hosts is not None
if platform is not None
if isolcation is not None
if context is not None
setting auth {'Content-Type': 'application/tar'}
\docker build <tempfile._TemporaryFileWrapper object at 0x7ffe4d5b5d68> {'t': 'fasttextclassification:20200922120954_28C4D0', 'remote': None, 'q': False, 'nocache': False, 'rm': False, 'forcerm': False, 'pull': False, 'dockerfile': (None, None)}
|docker response <Response [200]>
context closes
print responses
Step 1/15 : FROM bentoml/model-server:0.9.0.pre
 ---> a25066aa8b0e
Step 2/15 : ARG EXTRA_PIP_INSTALL_ARGS=
\ ---> Running in e09cbc5bfce1
- ---> fc6e47d06522
Step 3/15 : ENV EXTRA_PIP_INSTALL_ARGS $EXTRA_PIP_INSTALL_ARGS
/ ---> Running in 232b8623b0b9
| ---> db8172e98571
Step 4/15 : COPY environment.yml requirements.txt setup.sh* bentoml-init.sh python_version* /bento/
/ ---> c41f172d737b
Step 5/15 : WORKDIR /bento
| ---> Running in 1e1c28b0fd29
\ ---> 61863d5599df
Step 6/15 : RUN chmod +x /bento/bentoml-init.sh
 ---> Running in 0bf14a8a8cdf
/ ---> 3bba73c15b1a
Step 7/15 : RUN if [ -f /bento/bentoml-init.sh ]; then bash -c /bento/bentoml-init.sh; fi
 ---> Running in cfa5c292d12e
-+++ dirname /bento/bentoml-init.sh

/++ cd /bento
++ pwd -P

+ SAVED_BUNDLE_PATH=/bento
+ cd /bento

+ '[' -f ./setup.sh ']'

+ '[' -f ./python_version ']'

++ cat ./python_version

+ PY_VERSION_SAVED=3.7.3
+ DESIRED_PY_VERSION=3.7

++ python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")'

+ CURRENT_PY_VERSION=3.7
+ [[ 3.7 == \3\.\7 ]]
+ echo 'Python Version in docker base image 3.7 matches requirement python=3.7. Skipping.'

Python Version in docker base image 3.7 matches requirement python=3.7. Skipping.
+ command -v conda
+ echo 'Updating conda base environment with environment.yml'
+ conda env update -n base -f ./environment.yml

Updating conda base environment with environment.yml
\Collecting package metadata (repodata.json): ...working... 
-done
Solving environment: ...working... 
-done
/
Downloading and Extracting Packages
pip-20.2.3           | 1.1 MB    |            |   0% 
pip-20.2.3           | 1.1 MB    | 1          |   1% 
pip-20.2.3           | 1.1 MB    | #####1     |  51% 
pip-20.2.3           | 1.1 MB    | ########## | 100% 
pip-20.2.3           | 1.1 MB    | ########## | 100% 

python_abi-3.7       | 4 KB      |            |   0% 
python_abi-3.7       | 4 KB      | ########## | 100% 

python-3.7.9         | 45.3 MB   |            |   0% 
python-3.7.9         | 45.3 MB   |            |   0% 
python-3.7.9         | 45.3 MB   | 1          |   2% 
python-3.7.9         | 45.3 MB   | 4          |   4% 
python-3.7.9         | 45.3 MB   | 6          |   7% 
python-3.7.9         | 45.3 MB   | 9          |   9% 
python-3.7.9         | 45.3 MB   | #2         |  12% 
python-3.7.9         | 45.3 MB   | #5         |  15% 
python-3.7.9         | 45.3 MB   | #8         |  19% 
python-3.7.9         | 45.3 MB   | ##2        |  22% 
python-3.7.9         | 45.3 MB   | ##5        |  26% 
python-3.7.9         | 45.3 MB   | ##9        |  29% 
python-3.7.9         | 45.3 MB   | ###2       |  33% 
python-3.7.9         | 45.3 MB   | ###5       |  36% 
python-3.7.9         | 45.3 MB   | ###9       |  39% 
python-3.7.9         | 45.3 MB   | ####2      |  43% 
python-3.7.9         | 45.3 MB   | ####6      |  47% 
python-3.7.9         | 45.3 MB   | #####      |  50% 
python-3.7.9         | 45.3 MB   | #####4     |  54% 
python-3.7.9         | 45.3 MB   | #####8     |  59% 
python-3.7.9         | 45.3 MB   | ######2    |  63% 
python-3.7.9         | 45.3 MB   | ######6    |  66% 
python-3.7.9         | 45.3 MB   | #######    |  70% 
python-3.7.9         | 45.3 MB   | #######3   |  74% 
python-3.7.9         | 45.3 MB   | #######7   |  78% 
python-3.7.9         | 45.3 MB   | ########1  |  81% 
python-3.7.9         | 45.3 MB   | ########4  |  84% 
python-3.7.9         | 45.3 MB   | ########8  |  88% 
python-3.7.9         | 45.3 MB   | #########2 |  92% 
python-3.7.9         | 45.3 MB   | #########6 |  96% 
python-3.7.9         | 45.3 MB   | ########## | 100% 
python-3.7.9         | 45.3 MB   | ########## | 100% 

readline-8.0         | 281 KB    |            |   0% 
readline-8.0         | 281 KB    | ########## | 100% 
readline-8.0         | 281 KB    | ########## | 100% 

ca-certificates-2020 | 145 KB    |            |   0% 
ca-certificates-2020 | 145 KB    | ########## | 100% 

openssl-1.1.1h       | 2.1 MB    |            |   0% 
openssl-1.1.1h       | 2.1 MB    | ###2       |  32% 
openssl-1.1.1h       | 2.1 MB    | ########## | 100% 
openssl-1.1.1h       | 2.1 MB    | ########## | 100% 

certifi-2020.6.20    | 151 KB    |            |   0% 
certifi-2020.6.20    | 151 KB    | ########## | 100% 

Preparing transaction: 
...working... 
\done
Verifying transaction: ...working... 
|done
Executing transaction: ...working... 
\done
/#
# To activate this environment, use
#
#     $ conda activate base
#
# To deactivate an active environment, use
#
#     $ conda deactivate
-+ pip install -r ./requirements.txt --no-cache-dir

|Requirement already satisfied: bentoml==0.9.0.pre in /opt/conda/lib/python3.7/site-packages (from -r ./requirements.txt (line 1)) (0.9.0rc0)
/Collecting fasttext==0.9.2
|  Downloading fasttext-0.9.2.tar.gz (68 kB)
-Requirement already satisfied: python-dateutil<3.0.0,>=2.7.3 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2.8.1)
Requirement already satisfied: grpcio<=1.27.2 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.27.2)
Requirement already satisfied: python-json-logger in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.1.11)
Requirement already satisfied: aiohttp in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.6.2)
Requirement already satisfied: requests in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2.24.0)
Requirement already satisfied: multidict in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (4.7.6)
Requirement already satisfied: prometheus-client in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.8.0)
Requirement already satisfied: packaging in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (20.4)
Requirement already satisfied: certifi in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2020.6.20)
Requirement already satisfied: sqlalchemy>=1.3.0 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.3.19)
Requirement already satisfied: flask in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.1.2)
Requirement already satisfied: alembic in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.4.3)
/Requirement already satisfied: docker in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (4.3.1)
Requirement already satisfied: ruamel.yaml>=0.15.0 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.15.87)
Requirement already satisfied: sqlalchemy-utils<0.36.8 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.36.7)
Requirement already satisfied: gunicorn in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (20.0.4)
|Requirement already satisfied: cerberus in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.3.2)
Requirement already satisfied: click>=7.0 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (7.1.2)
Requirement already satisfied: configparser in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (5.0.0)
Requirement already satisfied: numpy in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.19.2)
Requirement already satisfied: humanfriendly in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (8.2)
Requirement already satisfied: tabulate in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.8.7)
Requirement already satisfied: protobuf>=3.6.0 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.13.0)
Requirement already satisfied: boto3 in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.15.2)
Requirement already satisfied: py-zipkin in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.20.0)
Requirement already satisfied: psutil in /opt/conda/lib/python3.7/site-packages (from bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (5.7.2)
Requirement already satisfied: pybind11>=2.2 in /opt/conda/lib/python3.7/site-packages (from fasttext==0.9.2->-r ./requirements.txt (line 2)) (2.5.0)
Requirement already satisfied: setuptools>=0.7.0 in /opt/conda/lib/python3.7/site-packages (from fasttext==0.9.2->-r ./requirements.txt (line 2)) (49.6.0.post20200814)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.7/site-packages (from python-dateutil<3.0.0,>=2.7.3->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.15.0)
Requirement already satisfied: attrs>=17.3.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (20.2.0)
\Requirement already satisfied: chardet<4.0,>=2.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.0.4)
Requirement already satisfied: yarl<2.0,>=1.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.5.1)
Requirement already satisfied: async-timeout<4.0,>=3.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.0.1)
Requirement already satisfied: idna<3,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2.10)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.25.10)
Requirement already satisfied: pyparsing>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2.4.7)
Requirement already satisfied: Jinja2>=2.10.1 in /opt/conda/lib/python3.7/site-packages (from flask->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (2.11.2)
Requirement already satisfied: Werkzeug>=0.15 in /opt/conda/lib/python3.7/site-packages (from flask->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.0.1)
Requirement already satisfied: itsdangerous>=0.24 in /opt/conda/lib/python3.7/site-packages (from flask->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.1.0)
Requirement already satisfied: python-editor>=0.3 in /opt/conda/lib/python3.7/site-packages (from alembic->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.0.4)
Requirement already satisfied: Mako in /opt/conda/lib/python3.7/site-packages (from alembic->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.1.3)
Requirement already satisfied: websocket-client>=0.32.0 in /opt/conda/lib/python3.7/site-packages (from docker->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.57.0)
Requirement already satisfied: s3transfer<0.4.0,>=0.3.0 in /opt/conda/lib/python3.7/site-packages (from boto3->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.3.3)
Requirement already satisfied: botocore<1.19.0,>=1.18.2 in /opt/conda/lib/python3.7/site-packages (from boto3->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.18.2)
Requirement already satisfied: jmespath<1.0.0,>=0.7.1 in /opt/conda/lib/python3.7/site-packages (from boto3->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.10.0)
Requirement already satisfied: thriftpy2>=0.4.0 in /opt/conda/lib/python3.7/site-packages (from py-zipkin->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (0.4.11)
-Requirement already satisfied: typing-extensions>=3.7.4; python_version < "3.8" in /opt/conda/lib/python3.7/site-packages (from yarl<2.0,>=1.0->aiohttp->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.7.4.3)
Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/lib/python3.7/site-packages (from Jinja2>=2.10.1->flask->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (1.1.1)
Requirement already satisfied: ply<4.0,>=3.4 in /opt/conda/lib/python3.7/site-packages (from thriftpy2>=0.4.0->py-zipkin->bentoml==0.9.0.pre->-r ./requirements.txt (line 1)) (3.11)
Building wheels for collected packages: fasttext
  Building wheel for fasttext (setup.py): started
-  Building wheel for fasttext (setup.py): finished with status 'done'
  Created wheel for fasttext: filename=fasttext-0.9.2-cp37-cp37m-linux_x86_64.whl size=4441002 sha256=c9a69b2133d5b1c05b68f9be59d9e74583689c299224445f20de0dcfc227432a
  Stored in directory: /tmp/pip-ephem-wheel-cache-sx8v7vyg/wheels/4e/ca/bf/b020d2be95f7641801a6597a29c8f4f19e38f9c02a345bab9b
Successfully built fasttext
/Installing collected packages: fasttext
\Successfully installed fasttext-0.9.2
\ ---> a90f620bbe4d
Step 8/15 : COPY . /bento
\ ---> 5d2abfb72a02
Step 9/15 : RUN if [ -d /bento/bundled_pip_dependencies ]; then pip install -U bundled_pip_dependencies/* ;fi
 ---> Running in 1f2cf07c7029
|Processing ./bundled_pip_dependencies/BentoML-0.9.0rc0+3.gcebf2015.tar.gz
|  Installing build dependencies: started
\  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
-  Getting requirements to build wheel: finished with status 'done'
    Preparing wheel metadata: started
|    Preparing wheel metadata: finished with status 'done'
\Requirement already satisfied, skipping upgrade: numpy in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.19.2)
-Requirement already satisfied, skipping upgrade: sqlalchemy-utils<0.36.8 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.36.7)
Requirement already satisfied, skipping upgrade: alembic in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.4.3)
Requirement already satisfied, skipping upgrade: gunicorn in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (20.0.4)
Requirement already satisfied, skipping upgrade: aiohttp in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (3.6.2)
Requirement already satisfied, skipping upgrade: psutil in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (5.7.2)
/Requirement already satisfied, skipping upgrade: prometheus-client in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.8.0)
Requirement already satisfied, skipping upgrade: click>=7.0 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (7.1.2)
Requirement already satisfied, skipping upgrade: tabulate in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.8.7)
Requirement already satisfied, skipping upgrade: sqlalchemy>=1.3.0 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.3.19)
Requirement already satisfied, skipping upgrade: packaging in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (20.4)
Requirement already satisfied, skipping upgrade: python-dateutil<3.0.0,>=2.7.3 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (2.8.1)
Requirement already satisfied, skipping upgrade: configparser in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (5.0.0)
Requirement already satisfied, skipping upgrade: python-json-logger in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.1.11)
Requirement already satisfied, skipping upgrade: boto3 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.15.2)
Requirement already satisfied, skipping upgrade: flask in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.1.2)
Requirement already satisfied, skipping upgrade: multidict in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (4.7.6)
Requirement already satisfied, skipping upgrade: ruamel.yaml>=0.15.0 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.15.87)
Requirement already satisfied, skipping upgrade: grpcio<=1.27.2 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.27.2)
Requirement already satisfied, skipping upgrade: certifi in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (2020.6.20)
Requirement already satisfied, skipping upgrade: py-zipkin in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (0.20.0)
Requirement already satisfied, skipping upgrade: docker in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (4.3.1)
|Requirement already satisfied, skipping upgrade: requests in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (2.24.0)
Requirement already satisfied, skipping upgrade: humanfriendly in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (8.2)
Requirement already satisfied, skipping upgrade: cerberus in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (1.3.2)
Requirement already satisfied, skipping upgrade: protobuf>=3.6.0 in /opt/conda/lib/python3.7/site-packages (from BentoML==0.9.0rc0+3.gcebf2015) (3.13.0)
Requirement already satisfied, skipping upgrade: six in /opt/conda/lib/python3.7/site-packages (from sqlalchemy-utils<0.36.8->BentoML==0.9.0rc0+3.gcebf2015) (1.15.0)
Requirement already satisfied, skipping upgrade: Mako in /opt/conda/lib/python3.7/site-packages (from alembic->BentoML==0.9.0rc0+3.gcebf2015) (1.1.3)
Requirement already satisfied, skipping upgrade: python-editor>=0.3 in /opt/conda/lib/python3.7/site-packages (from alembic->BentoML==0.9.0rc0+3.gcebf2015) (1.0.4)
Requirement already satisfied, skipping upgrade: setuptools>=3.0 in /opt/conda/lib/python3.7/site-packages (from gunicorn->BentoML==0.9.0rc0+3.gcebf2015) (49.6.0.post20200814)
Requirement already satisfied, skipping upgrade: async-timeout<4.0,>=3.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->BentoML==0.9.0rc0+3.gcebf2015) (3.0.1)
Requirement already satisfied, skipping upgrade: yarl<2.0,>=1.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->BentoML==0.9.0rc0+3.gcebf2015) (1.5.1)
Requirement already satisfied, skipping upgrade: attrs>=17.3.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->BentoML==0.9.0rc0+3.gcebf2015) (20.2.0)
\Requirement already satisfied, skipping upgrade: chardet<4.0,>=2.0 in /opt/conda/lib/python3.7/site-packages (from aiohttp->BentoML==0.9.0rc0+3.gcebf2015) (3.0.4)
Requirement already satisfied, skipping upgrade: pyparsing>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging->BentoML==0.9.0rc0+3.gcebf2015) (2.4.7)
Requirement already satisfied, skipping upgrade: jmespath<1.0.0,>=0.7.1 in /opt/conda/lib/python3.7/site-packages (from boto3->BentoML==0.9.0rc0+3.gcebf2015) (0.10.0)
Requirement already satisfied, skipping upgrade: s3transfer<0.4.0,>=0.3.0 in /opt/conda/lib/python3.7/site-packages (from boto3->BentoML==0.9.0rc0+3.gcebf2015) (0.3.3)
Requirement already satisfied, skipping upgrade: botocore<1.19.0,>=1.18.2 in /opt/conda/lib/python3.7/site-packages (from boto3->BentoML==0.9.0rc0+3.gcebf2015) (1.18.2)
Requirement already satisfied, skipping upgrade: Jinja2>=2.10.1 in /opt/conda/lib/python3.7/site-packages (from flask->BentoML==0.9.0rc0+3.gcebf2015) (2.11.2)
Requirement already satisfied, skipping upgrade: Werkzeug>=0.15 in /opt/conda/lib/python3.7/site-packages (from flask->BentoML==0.9.0rc0+3.gcebf2015) (1.0.1)
Requirement already satisfied, skipping upgrade: itsdangerous>=0.24 in /opt/conda/lib/python3.7/site-packages (from flask->BentoML==0.9.0rc0+3.gcebf2015) (1.1.0)
Requirement already satisfied, skipping upgrade: thriftpy2>=0.4.0 in /opt/conda/lib/python3.7/site-packages (from py-zipkin->BentoML==0.9.0rc0+3.gcebf2015) (0.4.11)
Requirement already satisfied, skipping upgrade: websocket-client>=0.32.0 in /opt/conda/lib/python3.7/site-packages (from docker->BentoML==0.9.0rc0+3.gcebf2015) (0.57.0)
Requirement already satisfied, skipping upgrade: idna<3,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests->BentoML==0.9.0rc0+3.gcebf2015) (2.10)
Requirement already satisfied, skipping upgrade: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests->BentoML==0.9.0rc0+3.gcebf2015) (1.25.10)
Requirement already satisfied, skipping upgrade: MarkupSafe>=0.9.2 in /opt/conda/lib/python3.7/site-packages (from Mako->alembic->BentoML==0.9.0rc0+3.gcebf2015) (1.1.1)
Requirement already satisfied, skipping upgrade: typing-extensions>=3.7.4; python_version < "3.8" in /opt/conda/lib/python3.7/site-packages (from yarl<2.0,>=1.0->aiohttp->BentoML==0.9.0rc0+3.gcebf2015) (3.7.4.3)
Requirement already satisfied, skipping upgrade: ply<4.0,>=3.4 in /opt/conda/lib/python3.7/site-packages (from thriftpy2>=0.4.0->py-zipkin->BentoML==0.9.0rc0+3.gcebf2015) (3.11)
Building wheels for collected packages: BentoML
  Building wheel for BentoML (PEP 517): started
/  Building wheel for BentoML (PEP 517): finished with status 'done'
  Created wheel for BentoML: filename=BentoML-0.9.0rc0+3.gcebf2015-py3-none-any.whl size=3064091 sha256=0bd361a45c83e2bb80aa10347199c1fd71684e3a1389eec1208f54b4297c1140
  Stored in directory: /root/.cache/pip/wheels/a0/45/41/62152db705af4ff47e7a3d6abf6247986eef4aa1b94a58d3b9
Successfully built BentoML
/Installing collected packages: BentoML
  Attempting uninstall: BentoML
    Found existing installation: BentoML 0.9.0rc0
\    Uninstalling BentoML-0.9.0rc0:
/      Successfully uninstalled BentoML-0.9.0rc0
\Successfully installed BentoML-0.9.0rc0+3.gcebf2015
/ ---> 860b9bec3b35
Step 10/15 : ENV PORT 5000
| ---> Running in c2743985d5de
\ ---> c3f39fdc8450
Step 11/15 : EXPOSE $PORT
 ---> Running in 0733c7dcfea4
- ---> bd7997accbc4
Step 12/15 : COPY docker-entrypoint.sh /usr/local/bin/
| ---> 71c57d9f3c42
Step 13/15 : RUN chmod +x /usr/local/bin/docker-entrypoint.sh
\ ---> Running in 8e7c893f2534
/ ---> e1c5868e8975
Step 14/15 : ENTRYPOINT [ "docker-entrypoint.sh" ]
 ---> Running in 033db21d262e
| ---> 24858e5a145c
Step 15/15 : CMD ["bentoml", "serve-gunicorn", "/bento"]
 ---> Running in b1700521fdb7
\ ---> e35ff263b52f
Successfully built e35ff263b52f
-Successfully tagged fasttextclassification:20200922120954_28C4D0
Finished building fasttextclassification:20200922120954_28C4D0 from FasttextClassification:latest
In [16]:
!docker run --rm -p5000:5000 fasttextclassification:20200922120954_28C4D0
[2020-09-22 19:17:58,674] INFO - Starting BentoML API server in production mode..
[2020-09-22 19:17:59,100] INFO - get_gunicorn_num_of_workers: 3, calculated by cpu count
[2020-09-22 19:17:59 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2020-09-22 19:17:59 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2020-09-22 19:17:59 +0000] [1] [INFO] Using worker: sync
[2020-09-22 19:17:59 +0000] [11] [INFO] Booting worker with pid: 11
[2020-09-22 19:17:59 +0000] [12] [INFO] Booting worker with pid: 12
[2020-09-22 19:17:59 +0000] [13] [INFO] Booting worker with pid: 13
[2020-09-22 19:17:59,365] WARNING - Using BentoML not from official PyPI release. In order to find the same version of BentoML when deploying your BentoService, you must set the 'core/bentoml_deploy_version' config to a http/git location of your BentoML fork, e.g.: 'bentoml_deploy_version = git+https://github.com/{username}/[email protected]{branch}'
[2020-09-22 19:17:59,387] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 19:17:59,387] WARNING - Saved BentoService Python version mismatch: loading BentoService bundle created with Python version 3.7.3, but current environment version is 3.7.9.
[2020-09-22 19:17:59,394] WARNING - Using BentoML not from official PyPI release. In order to find the same version of BentoML when deploying your BentoService, you must set the 'core/bentoml_deploy_version' config to a http/git location of your BentoML fork, e.g.: 'bentoml_deploy_version = git+https://github.com/{username}/[email protected]{branch}'
[2020-09-22 19:17:59,420] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 19:17:59,422] WARNING - Saved BentoService Python version mismatch: loading BentoService bundle created with Python version 3.7.3, but current environment version is 3.7.9.
[2020-09-22 19:17:59,500] WARNING - Using BentoML not from official PyPI release. In order to find the same version of BentoML when deploying your BentoService, you must set the 'core/bentoml_deploy_version' config to a http/git location of your BentoML fork, e.g.: 'bentoml_deploy_version = git+https://github.com/{username}/[email protected]{branch}'
[2020-09-22 19:17:59,528] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 19:17:59,529] WARNING - Saved BentoService Python version mismatch: loading BentoService bundle created with Python version 3.7.3, but current environment version is 3.7.9.
[2020-09-22 19:18:08,246] INFO - {'service_name': 'FasttextClassification', 'service_version': '20200922120954_28C4D0', 'api': 'predict', 'task': {'data': '{"text": "Which baking dish is best to bake a banana bread ?"}', 'task_id': '307d893e-df06-44c9-bba4-1098a6c34cea', 'http_headers': (('Host', 'localhost:5000'), ('User-Agent', 'curl/7.65.3'), ('Accept', '*/*'), ('Content-Type', 'application/json'), ('Content-Length', '62'))}, 'result': {'data': '"baking"', 'http_status': 200, 'http_headers': (('Content-Type', 'application/json'),)}, 'request_id': '307d893e-df06-44c9-bba4-1098a6c34cea'}
^C
[2020-09-22 19:18:15 +0000] [1] [INFO] Handling signal: int
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
[2020-09-22 19:18:15 +0000] [11] [INFO] Worker exiting (pid: 11)
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
[2020-09-22 19:18:15 +0000] [13] [INFO] Worker exiting (pid: 13)
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
[2020-09-22 19:18:15 +0000] [12] [INFO] Worker exiting (pid: 12)

Load saved BentoService

bentoml.load is the API for loading a BentoML packaged model in python:

In [17]:
from bentoml import load

svc = load(saved_path)

print(svc.predict([{"text": "which baking dish is the best?"}]))
[2020-09-22 12:18:22,256] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 12:18:22,257] WARNING - Module `text_classification` already loaded, using existing imported module.
[2020-09-22 12:18:22,278] WARNING - pip package requirement fasttext already exist
['baking']
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.

Launch inference job from CLI

BentoML cli supports loading and running a packaged model from CLI. With the DataframeInput adapter, the CLI command supports reading input Dataframe data from CLI argument or local csv or json files:

In [18]:
!bentoml run FasttextClassification:latest predict --input='{"text": "Which baking dish is best to bake a banana bread ?"}'
[2020-09-22 12:18:42,572] INFO - Getting latest version FasttextClassification:20200922120954_28C4D0
[2020-09-22 12:18:42,609] WARNING - Using BentoML installed in `editable` model, the local BentoML repository including all code changes will be packaged together with saved bundle created, under the './bundled_pip_dependencies' directory of the saved bundle.
[2020-09-22 12:18:42,623] WARNING - Saved BentoService bundle version mismatch: loading BentoService bundle create with BentoML version 0.9.0.pre, but loading from BentoML version 0.9.0.pre+3.gcebf2015
[2020-09-22 12:18:43,064] INFO - Using default docker base image: `None` specified inBentoML config file or env var. User must make sure that the docker base image either has Python 3.7 or conda installed.
Warning : `load_model` does not return WordVectorModel or SupervisedModel any more, but a `FastText` object which is very similar.
[2020-09-22 12:18:47,361] INFO - {'service_name': 'FasttextClassification', 'service_version': '20200922120954_28C4D0', 'api': 'predict', 'task': {'data': '{"text": "Which baking dish is best to bake a banana bread ?"}', 'task_id': '54edf965-1d7d-4eb9-929c-c7d0d0e21732', 'cli_args': ('--input={"text": "Which baking dish is best to bake a banana bread ?"}',)}, 'result': {'data': '"baking"', 'http_status': 200, 'http_headers': (('Content-Type', 'application/json'),)}, 'request_id': '54edf965-1d7d-4eb9-929c-c7d0d0e21732'}
"baking"

Deployment Options

If you are at a small team with limited engineering or DevOps resources, try out automated deployment with BentoML CLI, currently supporting AWS Lambda, AWS SageMaker, and Azure Functions:

If the cloud platform you are working with is not on the list above, try out these step-by-step guide on manually deploying BentoML packaged model to cloud platforms:

Lastly, if you have a DevOps or ML Engineering team who's operating a Kubernetes or OpenShift cluster, use the following guides as references for implementating your deployment strategy:

In [ ]: