Bootstrap

Seldon 使用 (二):打包模型

当部署模型服务(即创建SeldonDeployment)时,模型文件已包含在docker image中。那模型文件是如何打包成docker image呢?

1 Seldon支持的模型服务类型

一个模型服务可由三部分组成:

  • 运行环境:包括系统环境,python环境,依赖库等

  • 服务代码:包括http服务(或grpc服务),metrics服务等

  • 模型代码:包括预测代码,模型文件等

以上三个部分,通常更新较频繁的是模型代码,通常可以复用运行环境和服务代码,简化和加快部署效率。但是有些特殊的模型服务,会需要定制的依赖环境。为了满足这两种不同的部署需求,seldon支持两种类型的模型服务:

  • 可复用的(reusable):复用docker image,每次部署仅需从存储服务(repo)获取模型代码

  • 不可复用的(non-reusable):每次部署需要重新构建docker image,将模型代码打包在docker image内

2 如何构建docker image

无论是哪种方式,我们都需要将模型打包成docker image形式再进行部署。这里主要先讨论non-reusable的方式。而构建docker image,seldon推荐两种方式s2i(source-to-image)和Dockerfile方式。最终结果是一样的,都是产生用于部署的docker image。两种方式的差别只是Dockerfile更原始和直接(需要用户了解dockerfile和build的一些相关知识),而s2则更贴近使用,相对更容易理解。但我觉得构建效率上并没有太大区别,看用户各自的使用习惯吧。我个人更推荐Dockerfile的方式。

2.1 Dockerfile方式

需要文件如下:

  • 模型文件:MyModel.py

  • 依赖文件:requirements.txt

  • 构建文件:Dockerfile文件

其中,MyModel.py文件内容如下:

class MyModel(object):
    """
    Model template. You can load your model parameters in __init__ from a location accessible at runtime
    """

    def __init__(self):
        """
        Add any initialization parameters. These will be passed at runtime from the graph definition parameters defined in your seldondeployment kubernetes resource manifest.
        """
        print("Initializing")

    def predict(self,X,features_names):
        """
        Return a prediction.

        Parameters
        ----------
        X : array-like
        feature_names : array of feature names (optional)
        """
        print("Predict called - will run identity function")
        return X

说明:

  • class类名称保持与文件同名

  • __init__()初始化模型,predict()模型推理时被调用

requirements.txt内容如下:

seldon-core

说明:

  • 镜像将使用seldon-core包实现的microservice加载和启动模型服务

  • 如果MyModel.py还有其他依赖包,应该也加上

最后Dockerfile内容如下:

FROM python:3.7-slim
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000

# Define environment variable
ENV MODEL_NAME MyModel
ENV SERVICE_TYPE MODEL
ENV PERSISTENCE 0

CMD exec seldon-core-microservice $MODEL_NAME --service-type $SERVICE_TYPE --persistence $PERSISTENCE

说明:

  • 镜像将使用seldon-core-microservice加载模型,并启动http服务

  • --service-type,当前支持MODEL,ROUTER,TRANSFORMER,COMBINER,OUTLIER_DETECTOR这五种。将在后续文章展开说明。

所需文件准备好之后,执行如下命令,构建镜像。

docker build . -t $ORG/$MODEL_NAME:$TAG
# 镜像构建完成后,需push到镜像仓库
# docker push $ORG/$MODEL_NAME:$TAG

其中,-t指定镜像的名称及标签,例如hub.abc.com:business-A/alpha-model:v1。

2.2 s2i方式(非必须了解,可跳过)

s2i(source-to-image)是openshift提供的用于程序代码(source)构建成docker image的简化方式。

而seldon在s2i的基础上,预先构建了包含seldon-core-microservices的镜像,用户只需要提供自己的模型代码,就可以使用s2i构建镜像。

首先,需要安装s2i(可参考官方

需要准备如下文件:

  • 模型文件:MyModel.py(同2.1)

  • 依赖文件:requirements.txt(同2.1)

  • 构建文件:.s2i/environment

注:依赖文件默认使用的是requirements.txt方式,但还支持setup.py和enviroment.yml的方式。

.s2i/environment内容如下:

MODEL_NAME=MyModel
SERVICE_TYPE=MODEL
PERSISTENCE=0

这里指定了seldon-core-microservices服务启动时所需要的三个参数(同2.1 Dockerfile文件中服务的启动参数一致)。

执行如下命令完成镜像构建

s2i build  seldonio/seldon-core-s2i-python3:1.8.0-dev 
# 例如:
# s2i build my-model-files/ seldonio/seldon-core-s2i-python3:1.8.0-dev hub.abc.com:business-A/alpha-model:v1

其中,seldonio/seldon-core-s2i-python3是由seldon提供的基础镜像,这是使用s2i的方式时必须选择的基础镜像。主要原因是,它们包含了两个脚本assemble和run。其中assemble用于支持更丰富的依赖文件,run脚本包含了启动seldon-core-microservices的实现方式,包括读取s2i/environment文件内的环境变量。

相比较于Dockerfile方式,s2方式更简洁一点,用户不需要懂Dockerfile如何写,只需要配置好环境变量。

但却也封装和屏蔽了底层细节,有利有弊。

后面的文章,我们将介绍seldon-core-microservices是如何实现模型加载及推理服务的。