#!/usr/bin/env python # coding: utf-8 # # BentoML Example: Fast AI with Tabular data # # **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](https://github.com/bentoml/BentoML/blob/master/guides/quick-start/bentoml-quick-start-guide.ipynb) to learn about the basic concepts in BentoML. # # # This notebook is based on fastai v1's cours v3 lesson 4. It will train a model that predict salary range base on the data we provided. # # # ![Impression](https://www.google-analytics.com/collect?v=1&tid=UA-112879361-3&cid=555&t=event&ec=fast-ai&ea=fast-ai-salary-range-prediction&dt=fast-ai-salary-range-prediction) # In[1]: get_ipython().run_line_magic('reload_ext', 'autoreload') get_ipython().run_line_magic('autoreload', '2') get_ipython().run_line_magic('matplotlib', 'inline') # In[2]: get_ipython().system("pip install -q -U 'fastai<=1.0.61'") # In[3]: from fastai.tabular import * # ## Prepare Training Data # In[4]: path = untar_data(URLs.ADULT_SAMPLE) df = pd.read_csv(path/'adult.csv') # In[5]: dep_var = 'salary' cat_names = ['workclass', 'education', 'marital-status', 'occupation', 'relationship', 'race'] cont_names = ['age', 'fnlwgt', 'education-num'] procs = [FillMissing, Categorify, Normalize] # In[6]: test = TabularList.from_df(df.iloc[800:1000].copy(), path=path, cat_names=cat_names, cont_names=cont_names) # In[7]: data = (TabularList.from_df(df, path=path, cat_names=cat_names, cont_names=cont_names, procs=procs) .split_by_idx(list(range(800,1000))) .label_from_df(cols=dep_var) .add_test(test) .databunch()) # In[8]: data.show_batch(rows=10) # ## Model Training # In[9]: learn = tabular_learner(data, layers=[200,100], metrics=accuracy) # In[10]: learn.fit(1, 1e-2) # In[11]: row = df.iloc[0] # sample input date for testing learn.predict(row) # ## Create BentoService for model serving # In[12]: get_ipython().run_cell_magic('writefile', 'tabular_csv.py', "\nfrom bentoml import env, api, artifacts, BentoService\nfrom bentoml.frameworks.fastai import Fastai1ModelArtifact\nfrom bentoml.adapters import DataframeInput\n\n\n@env(pip_packages=['fastai'])\n@artifacts([Fastai1ModelArtifact('model')])\nclass FastaiTabularModel(BentoService):\n \n @api(input=DataframeInput(), batch=True)\n def predict(self, df):\n results = []\n for _, row in df.iterrows(): \n prediction = self.artifacts.model.predict(row)\n results.append(prediction[0].obj)\n return results\n") # ## Save BentoService to file archive # In[13]: # 1) import the custom BentoService defined above from tabular_csv import FastaiTabularModel # 2) `pack` it with required artifacts svc = FastaiTabularModel() svc.pack('model', learn) # 3) save your BentoSerivce saved_path = svc.save() # ## REST API Model Serving # # # To start a REST API model server with the BentoService saved above, use the bentoml serve command: # In[15]: get_ipython().system('bentoml serve FastaiTabularModel:latest') # 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](https://ngrok.com/): # In[ ]: get_ipython().system('bentoml serve FastaiTabularModel:latest --run-with-ngrok') # ### Send prediction requeset to the REST API server # # #### JSON Request # # ```bash # curl -X POST \ # http://localhost:5000/predict \ # -H 'Content-Type: application/json' \ # -d '[{ # "age": 49, # "workclass": "Private", # "fnlwgt": 101320, # "education": "Assoc-acdm", # "education-num": 12.0, # "marital-status": "Married-civ-spouse", # "occupation": "", # "relationship": "Wift", # "race": "White", # "sex": "Female", # "capital-gain": 0, # "capital-loss": 1902, # "hours-per-week": 40, # "native-country": "United-States", # "salary": ">=50k" # }]' # ``` # # #### CSV Request # # ```bash # curl -X POST "http://127.0.0.1:5000/predict" \ # -H "Content-Type: text/csv" \ # --data-binary @test.csv # ``` # ## 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[16]: get_ipython().system('bentoml containerize FastaiTabularModel:latest') # In[17]: get_ipython().system('docker run -p 5000:5000 fastaitabularmodel:20200922163833_30289D') # ## Load saved BentoService # # bentoml.load is the API for loading a BentoML packaged model in python: # In[14]: from bentoml import load svc = load(saved_path) print(svc.predict(df.iloc[0:1])) # ## 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[ ]: get_ipython().system('wget https://raw.githubusercontent.com/bentoml/gallery/master/fast-ai/salary-range-prediction/test.csv') get_ipython().system('bentoml run FastaiTabularModel:latest predict --input-file test.csv') # # 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: # - [AWS Lambda Deployment Guide](https://docs.bentoml.org/en/latest/deployment/aws_lambda.html) # - [AWS SageMaker Deployment Guide](https://docs.bentoml.org/en/latest/deployment/aws_sagemaker.html) # - [Azure Functions Deployment Guide](https://docs.bentoml.org/en/latest/deployment/azure_functions.html) # # 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: # - [AWS ECS Deployment](https://docs.bentoml.org/en/latest/deployment/aws_ecs.html) # - [Google Cloud Run Deployment](https://docs.bentoml.org/en/latest/deployment/google_cloud_run.html) # - [Azure container instance Deployment](https://docs.bentoml.org/en/latest/deployment/azure_container_instance.html) # - [Heroku Deployment](https://docs.bentoml.org/en/latest/deployment/heroku.html) # # 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: # - [Kubernetes Deployment](https://docs.bentoml.org/en/latest/deployment/kubernetes.html) # - [Knative Deployment](https://docs.bentoml.org/en/latest/deployment/knative.html) # - [Kubeflow Deployment](https://docs.bentoml.org/en/latest/deployment/kubeflow.html) # - [KFServing Deployment](https://docs.bentoml.org/en/latest/deployment/kfserving.html) # - [Clipper.ai Deployment Guide](https://docs.bentoml.org/en/latest/deployment/clipper.html) # # # In[ ]: