快速入门统一模型部署(Model Serving)框架 BentoML

简介: BentoML 是一个用于机器学习模型服务的开源框架,旨在弥合数据科学和 DevOps 之间的差距(gap)。数据科学家可以使用 BentoMl 轻松打包使用任何 ML 框架训练的模型,并重现该模型以用于生产。BentoML 协助管理 BentoML 格式打包的模型,并允许 DevOps 将它们部署为任何云平台上的在线 API 服务端点或离线批量推理作业。

简述

BentoML 是一个用于机器学习模型服务的开源框架,旨在弥合数据科学和 DevOps 之间的差距(gap)。

数据科学家可以使用 BentoMl 轻松打包使用任何 ML 框架训练的模型,并重现该模型以用于生产。

BentoML 协助管理 BentoML 格式打包的模型,并允许 DevOps 将它们部署为任何云平台上的在线 API 服务端点或离线批量推理作业。


为什么选择 BentoML

  • 将您的 ML 模型转换为生产就绪 API 非常简单。
  • 高性能模型服务,并且全部使用 Python。
  • 标准化模型打包和 ML 服务定义以简化部署。
  • 支持所有主流的机器学习训练框架。
  • 通过Yatai在 Kubernetes 上大规模部署和运行 ML 服务。

下面将演示了如何使用 BentoML 通过 REST API 服务为 sklearn 模型提供服务,然后将模型服务容器化以进行生产部署。


依赖库安装

BentoML 需要 Python 3.6 或更高版本,然后,通过 pip 安装依赖项:

# 安装本教程需要的依赖包,包括BentoML
pip install -q bentoml==v1.0.0-a6
pip install -q 'scikit-learn>=0.23.2' 'pandas>=1.1.1'
复制代码


训练模型及保存模型

我们预先准备一个训练的模型来使用 BentoML 提供服务。 模型训练完成后,使用我们的工具将特定框架训练的模型保存为 BentoML 标准格式。

首先,在鸢尾花(Iris)数据集上训练一个分类模型:

# train.py
from sklearn import svm
from sklearn import datasets
import bentoml
# Load training data
iris = datasets.load_iris()
X, y = iris.data, iris.target
# Model Training
clf = svm.SVC(gamma='scale')
clf.fit(X, y)
# 调用`bentoml.<FRAMEWORK>.save(<MODEL_NAME>, model)` 为了在本地模型存储中保存为 BentoML 的标准格式
bentoml.sklearn.save("iris_clf", clf)
复制代码


运行结果:

$ python train.py
03/31/22 16:15:13 INFO     [cli] Successfully saved Model(tag="iris_clf:wdqpqfvqzk32yhqa", path="/Users/liguodong/bentoml/models/iris_clf/wdqpqfvqzk32yhqa/") 
复制代码


bentoml.sklearn.save()会将 Iris 分类模型保存到由 BentoML 管理的本地模型存储中。 目前所有受支持的建模库,请参阅ML framework specific API


查看 BentoML 本地模型仓库的模型

模型也可以通过 bentoml models CLI 命令进行管理。 更多信息请使用 bentoml models --help

$ bentoml models list
 Tag                        Module           Path                                                       Size      Creation Time       
 iris_clf:wdqpqfvqzk32yhqa  bentoml.sklearn  /Users/liguodong/bentoml/models/iris_clf/wdqpqfvqzk32yhqa  5.64 KiB  2022-03-31 08:15:13 
复制代码


然后,您可以使用bentoml.<FRAMEWORK>.load(<TAG>) 加载要在线运行的模型。同时,您也可以使用 bentoml.<FRAMEWORK>.load_runner(<TAG>) API 使用性能优化的运行器。


验证模型是否可以作为运行器加载

# verify.py
import bentoml
runner = bentoml.sklearn.load_runner("iris_clf:latest")
print(runner.run([5.9, 3., 5.1, 1.8]))  # => array(2)
复制代码


使用 BentoML 定义和调试 ML 预测服务

服务是 BentoML 的核心组件,其中定义了服务逻辑。

通过保存在模型仓库中的模型,我们可以创建 Python 文件 service.py 来定义服务,其内容如下:

# service.py
import numpy as np
import bentoml
from bentoml.io import NumpyNdarray
# 加载我们刚刚保存的最新 ScikitLearn 模型的运行器
iris_clf_runner = bentoml.sklearn.load_runner("iris_clf:latest")
# 使用 ScikitLearn 运行器创建 iris_classifier 服务
# 如果需要,可以在runners数组中指定多个运行器
# 当包装为bento时,运行器(runners)也会被包括在里面
svc = bentoml.Service("iris_classifier", runners=[iris_clf_runner])
# 使用“svc”注解创建具有预处理和后处理逻辑的 API 函数
@svc.api(input=NumpyNdarray(), output=NumpyNdarray())
def classify(input_series: np.ndarray) -> np.ndarray:
    # 定义预处理逻辑
    result = iris_clf_runner.run(input_series)
    # 定义后处理逻辑
    return result
复制代码


在此示例中,我们将输入和输出类型定义为 numpy.ndarray。 还支持更多选项,例如 pandas.DataFramePIL.image。 要查看所有支持的选项,请参阅API 和 IO 描述。

到此为止,我们现在拥有了满足第一个请求所需要的一切。


在本地启动一个 API server 进行测试

我们通过在当前工作目录中运行 bentoml serve 命令以调试模式启动服务。使用 --reload 选项允许服务显示对 service.py 模块所做的任何更改,而无需重新启动(热更新):

$ bentoml serve ./service.py:svc --reload
03/31/22 17:00:54 INFO     [cli] Starting development BentoServer from "./service.py:svc" running on http://127.0.0.1:3000 (Press CTRL+C to quit)                           
03/31/22 17:00:55 INFO     [dev_api_server] Service imported from source: bentoml.Service(name="iris_classifier", import_str="service:svc",                                 
                           working_dir="/Users/liguodong/work/gitee/sample-all-py3/mlops/bentoml/bento_deploy")                                                             
03/31/22 17:00:55 INFO     [dev_api_server] Will watch for changes in these directories: ['/Users/liguodong/work/gitee/sample-all-py3/mlops/bentoml/bento_deploy']          
03/31/22 17:00:55 INFO     [dev_api_server] Started reloader process [54356] using statreload                                                                               
03/31/22 17:00:56 INFO     [cli] Started server process [54359]                                                                                                             
03/31/22 17:00:56 INFO     [cli] Waiting for application startup.                                                                                                           
03/31/22 17:00:56 INFO     [cli] Application startup complete.                                                                                                              
03/31/22 17:05:36 WARNING  [dev_api_server] StatReload detected file change in 'service.py'. Reloading...                                                                   
03/31/22 17:05:36 INFO     [cli] Shutting down                                                                                                                              
03/31/22 17:05:36 INFO     [cli] Waiting for application shutdown.                                                                                                          
03/31/22 17:05:36 INFO     [cli] Application shutdown complete.                                                                                                             
03/31/22 17:05:36 INFO     [cli] Finished server process [54359]                                                                                                            
03/31/22 17:05:37 INFO     [cli] Started server process [54372]                                                                                                             
03/31/22 17:05:37 INFO     [cli] Waiting for application startup.                                                                                                           
03/31/22 17:05:37 INFO     [cli] Application startup complete.                                                                                                              
03/31/22 17:08:13 INFO     [cli] 127.0.0.1:56051 (scheme=http,method=POST,path=/classify,type=application/json,length=9) (status=200,type=application/json,length=1) 3.123ms
                           (trace=108811182904080858968430329246303376687,span=3358824710013532286,sampled=0)                                                               
复制代码


然后,我们可以使用任何 HTTP 客户端向新启动的服务发送请求。比如,通过python http request 请求:

# http_request.py
import requests
print(requests.post(
    "http://127.0.0.1:3000/classify",
    headers={"content-type": "application/json"},
    data="[5,4,3,2]").text)
复制代码


或者通过curl请求:

> curl \
  -X POST \
  -H "content-type: application/json" \
  --data "[5,4,3,2]" \
  http://127.0.0.1:3000/classify
复制代码


BentoML 可以以多种方式优化您的服务,例如,BentoML 使用了两个最快的 Python Web 框架 StarletteUvicorn,以便大规模高效地为您的模型提供服务。

有关性能优化的更多信息,请参阅 BentoServer


构建和部署 Bentos

一旦我们对服务定义感到满意,我们就可以将模型和服务构建成bento。 Bentos 是服务的分发格式,包含运行或部署这些服务所需的所有信息,例如模型和依赖项。 有关构建bento的更多信息,请参阅Building Bentos

要构建 Bento,首先在项目目录中创建一个名为 bentofile.yaml 的文件:

# bentofile.yaml
service: "service.py:svc"  # 定位服务的约定:<YOUR_SERVICE_PY>:<YOUR_SERVICE_ANNOTATION>
description: "file: ./README.md"
labels:
    owner: bentoml-team
    stage: demo
include:
 - "*.py"  # 用于匹配要包含在bento中的文件的格式
python:
  packages:
   - scikit-learn==0.23.2  # bento中将包含的其他的依赖库
   - pandas>=1.1.1
复制代码


接下来,在同样的目录中的bentoml build CLI 命令来构建一个bento。

$ bentoml build
03/31/22 17:41:06 INFO     [cli] Building BentoML service "iris_classifier:v7eedwvq22c5ahqa" from build context                                                             
                           "/Users/liguodong/work/gitee/sample-all-py3/mlops/bentoml/bento_deploy"                                                                          
03/31/22 17:41:06 INFO     [cli] Packing model "iris_clf:wdqpqfvqzk32yhqa" from "/Users/liguodong/bentoml/models/iris_clf/wdqpqfvqzk32yhqa"                                 
03/31/22 17:41:06 INFO     [cli] Successfully saved Model(tag="iris_clf:wdqpqfvqzk32yhqa",                                                                                  
                           path="/var/folders/_7/b59dvhj56lq3lr4jpsx2h7t80000gn/T/tmpfekkt4b3bentoml_bento_iris_classifier/models/iris_clf/wdqpqfvqzk32yhqa/")              
03/31/22 17:41:06 INFO     [cli] Locking PyPI package versions..                                                                                                            
03/31/22 17:47:00 INFO     [cli]                                                                                                                                            
                           ██████╗░███████╗███╗░░██╗████████╗░█████╗░███╗░░░███╗██╗░░░░░                                                                                    
                           ██╔══██╗██╔════╝████╗░██║╚══██╔══╝██╔══██╗████╗░████║██║░░░░░                                                                                    
                           ██████╦╝█████╗░░██╔██╗██║░░░██║░░░██║░░██║██╔████╔██║██║░░░░░                                                                                    
                           ██╔══██╗██╔══╝░░██║╚████║░░░██║░░░██║░░██║██║╚██╔╝██║██║░░░░░                                                                                    
                           ██████╦╝███████╗██║░╚███║░░░██║░░░╚█████╔╝██║░╚═╝░██║███████╗                                                                                    
                           ╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═╝╚══════╝                                                                                    
03/31/22 17:47:00 INFO     [cli] Successfully built Bento(tag="iris_classifier:v7eedwvq22c5ahqa") at "/Users/liguodong/bentoml/bentos/iris_classifier/v7eedwvq22c5ahqa/" 
复制代码


构建的Bentos将保存在本地bento商店中,您可以使用bentoml list CLI 命令查看。

$ bentoml list
 Tag                               Service      Path                                                              Size       Creation Time       
 iris_classifier:v7eedwvq22c5ahqa  service:svc  /Users/liguodong/bentoml/bentos/iris_classifier/v7eedwvq22c5ahqa  15.21 KiB  2022-03-31 09:47:00 
复制代码


我们可以使用bentoml serve --production CLI 命令从bento商店提供bentos服务。其中,--production 选项将在生产模式下提供bento服务。

$ bentoml serve iris_classifier:veshoxfq3wzyqhqa --production
03/31/22 18:02:41 INFO     [cli] Service loaded from Bento store: bentoml.Service(tag="iris_classifier:v7eedwvq22c5ahqa",                                                   
                           path="/Users/liguodong/bentoml/bentos/iris_classifier/v7eedwvq22c5ahqa")                                                                         
03/31/22 18:02:41 INFO     [cli] Starting production BentoServer from "bento_identifier" running on http://0.0.0.0:3000 (Press CTRL+C to quit)                              
03/31/22 18:02:42 INFO     [api_server] Service loaded from Bento store: bentoml.Service(tag="iris_classifier:v7eedwvq22c5ahqa",                                            
                           path="/Users/liguodong/bentoml/bentos/iris_classifier/v7eedwvq22c5ahqa")                                                                         
03/31/22 18:02:42 INFO     [iris_clf] Service loaded from Bento store: bentoml.Service(tag="iris_classifier:v7eedwvq22c5ahqa",                                              
                           path="/Users/liguodong/bentoml/bentos/iris_classifier/v7eedwvq22c5ahqa")                                                                         
03/31/22 18:02:42 INFO     [iris_clf] Started server process [54672]                                                                                                        
03/31/22 18:02:42 INFO     [iris_clf] Waiting for application startup.                                                                                                      
03/31/22 18:02:42 INFO     [api_server] Started server process [54673]                                                                                                      
03/31/22 18:02:42 INFO     [api_server] Waiting for application startup.                                                                                                    
03/31/22 18:02:42 INFO     [api_server] Application startup complete.                                                                                                       
03/31/22 18:02:45 INFO     [iris_clf] Application startup complete.       
复制代码


Bento 目录说明

Bento 目录包含运行此服务所需的所有代码、文件、模型和配置。 BentoML 标准化了这个文件结构,使服务运行时和部署工具能够建立在它之上。

默认情况下,Bentos 在~/bentoml/bentos 目录下进行管理:

$ cd ~/bentoml/bentos/iris_classifier && cd $(cat latest)
$ tree
.
├── README.md
├── apis
│   └── openapi.yaml
├── bento.yaml
├── env
│   ├── docker
│   │   ├── Dockerfile
│   │   ├── entrypoint.sh
│   │   └── init.sh
│   └── python
│       ├── requirements.lock.txt
│       ├── requirements.txt
│       └── version.txt
├── models
│   └── iris_clf
│       ├── latest
│       └── y3f4ijcxj3i6zo6x2ie5eubhd
│           ├── model.yaml
│           └── saved_model.pkl
└── src
    ├── iris_classifier.py
    └── train.py
8 directories, 14 files
复制代码


将 Bento 容器化以进行部署

最后,我们可以使用bentoml containerize CLI 命令将 bentos 容器化为Docker 镜像,并使用模型和 bento 管理服务 来大规模管理bentos。

首先,需确保您已安装 docker 并运行了 docker deamon,以下命令将使用您的本地 docker 环境构建一个新的 docker 镜像,并包含来自此 Bento 的模型服务配置。

$ bentoml containerize iris_classifier:veshoxfq3wzyqhqa
# 运行容器测试镜像的构建
$ docker run -p 5000:5000 iris_classifier:invwzzsw7li6zckb2ie5eubhd 
复制代码


总结

BentoML 是一个开放平台,可简化 ML 模型部署并使您能够在几分钟内以生产规模为模型提供服务。


相关文章
|
Kubernetes 网络协议 前端开发
k8s更新策略-系列文章第一篇:蓝绿发布
k8s更新策略-系列文章第一篇:蓝绿发布
|
运维 监控 数据可视化
软件质量保障体系建设
所谓的愿景,就是长期规划,我们要到哪里去的问题。一个组织或者团队,是一定要有愿景的。在软件质量保障领域,所谓的愿景概括来说就四个字:保质提效。
软件质量保障体系建设
|
机器学习/深度学习 缓存 并行计算
NVIDIA Tesla GPU系列P4、T4、P40以及V100参数性能对比
NVIDIA Tesla系列GPU适用于高性能计算(HPC)、深度学习等超大规模数据计算,Tesla系列GPU能够处理解析PB级的数据,速度比使用传统CPU快几个数量级,NVIDIA Tesla GPU系列P4、T4、P40以及V100是Tesla GPU系列的明星产品,云服务器吧分享NVIDIA.
85453 1
|
机器学习/深度学习 人工智能 异构计算
SkyReels-A1:解放动画师!昆仑开源「数字人制造机」:一张照片生成逼真虚拟主播,表情连眉毛颤动都可控
SkyReels-A1 是昆仑万维开源的首个 SOTA 级别表情动作可控的数字人生成模型,支持高保真肖像动画生成和精确的表情动作控制。
1284 23
|
存储 机器学习/深度学习 算法
【mlflow系列1】mlflow 的搭建使用
【mlflow系列1】mlflow 的搭建使用
1672 0
【mlflow系列1】mlflow 的搭建使用
|
机器学习/深度学习 存储 人工智能
如何玩转Kubeflow Pipelines
 1. 背景近些年来,人工智能技术在自然语言处理、视觉图像和自动驾驶方面都取得不小的成就,无论是工业界还是学术界大家都在惊叹一个又一个的模型设计。但是对于真正做过算法工程落地的同学,在惊叹这些模型的同时,更多的是在忧虑如果快速且有效的将这些模型落地到业务中,并产生商业价值。正如Google 《Hidden Technical Debt in Machine Learning Systems》中说的
如何玩转Kubeflow Pipelines
|
消息中间件 运维 数据库
架构设计之解析CQRS架构模式!
架构设计之解析CQRS架构模式!
614 1
架构设计之解析CQRS架构模式!
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计