本文为您介绍如何使用Python开发自定义Processor。

PAI-EAS提供的Python SDK支持TensorFlow、PyTorch及Scikit-Learn等基于Python的开源机器学习框架,也支持集成Pandas等数据分析处理框架,使用PAI-EAS Python SDK,您可以快速将本地预测逻辑直接转换为在线服务。Python SDK中预置了PAI-EAS为AI Inference场景订制的高性能PRC框架及与PAI-EAS集群交互所需要的内部接口,您通过实现简单的接口就可以将模型服务部署至PAI-EAS集群,并使用PAI-EAS提供的模型监控、蓝绿发布、弹性伸缩及VPC高速直连等功能。

如下以简单案例介绍使用Python开发自定义Processor的步骤。

步骤一:构建开发环境

可以使用Pyenv或Conda等Python包管理工具构建开发环境,PAI-EAS提供的客户端工具EASCMD对构建过程进行了封装,您仅执行一条命令即可构建Python SDK开发环境。如果需求进行定制化,则可以选择手工方式构建开发环境。

您可以使用以下任何一种方式构建开发环境:
  • EASCMD工具(仅Linux系统)
    EASCMD是PAI-EAS提供的客户端工具,将Python SDK的初始化过程进行了封装。下载该工具后,仅通过一条命令即可完成Python SDK环境初始化,并生成相关的文件模板。
    # 安装并初始化EASCMD,该示例为安装Linux环境的EASCMD工具。
    $ wget https://eas-data.oss-cn-shanghai.aliyuncs.com/tools/eascmd/v2/eascmd64
    # 下载完成后,可以修改访问权限,配置阿里云上AccessKey信息。
    $ chmod +x eascmd64
    $ ./eascmd64 config -i <access_id> -k <access_key>
    
    # 初始化环境。
    $ ./eascmd64 pysdk init ./pysdk_demo
    输入Python版本(默认为3.6版本),系统会自动创建Python环境ENV目录、预测服务代码模板app.py及服务部署模板app.json
  • 手工方式
    如果EASCMD不能满足您的需求或初始化过程中遇到问题,则可以尝试手工初始化开发环境,推荐使用Conda部署环境。
    mkdir demo
    cd demo
    # 使用Conda创建Python环境,目录必须指定为ENV。
    conda create -p ENV python=3.7
    # 安装PAI-EAS Python SDK。
    ENV/bin/pip install http://eas-data.oss-cn-shanghai.aliyuncs.com/sdk/allspark-0.15-py2.py3-none-any.whl
    # 安装其它依赖包,以TensorFlow 1.14为例。
    ENV/bin/pip install tensorflow==1.14
    如果本地未安装Conda,则必须先执行如下命令,安装Conda环境。
    $ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
    $ sh Miniconda3-latest-Linux-x86_64.sh
  • 预构建的开发镜像(推荐)
    PAI-EAS提供预先构建好的开发镜像,该镜像预装了Conda并生成了对应Python版本的ENV环境。PAI-EAS提供的三个预构建镜像如下。
    # 仅安装了Conda的基础镜像。
    registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:latest
    # 安装了Conda及Python2.7和PAI-EAS Allspark 0.8的Python SDK。
    registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:py2.7-allspark-0.8
    # 安装了Conda及Python3.6和PAI-EAS Allspark 0.8的Python SDK。
    registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:py3.6-allspark-0.8
    对该镜像直接使用run命令即可获得Python开发环境,示例如下。
    $sudo docker run -ti registry.cn-shanghai.aliyuncs.com/eas/eas-python-base-image:py3.6-allspark-0.8
    (/data/eas/ENV) [root@487a04df4b21 eas]#
    (/data/eas/ENV) [root@487a04df4b21 eas]# ENV/bin/python app.py
    [INFO] initialize new lua plugin
    [INFO] loading builtin config script
    [INFO] current meritc id:0
    [INFO] loading builtin lua scripts
    [INFO] Success load all lua scripts.
    [INFO] create service
    [INFO] rpc binds to predefined port 8080
    [INFO] updating rpc port to 8080
    [INFO] install builtin handler call to /api/builtin/call
    [INFO] install builtin handler eastool to /api/builtin/eastool
    [INFO] install builtin handler monitor to /api/builtin/monitor
    [INFO] install builtin handler ping to /api/builtin/ping
    [INFO] install builtin handler prop to /api/builtin/prop
    [INFO] install builtin handler realtime_metrics to /api/builtin/realtime_metrics
    [INFO] install builtin handler tell to /api/builtin/tell
    [INFO] install builtin handler term to /api/builtin/term
    [INFO] Service start successfully
    [INFO] shutting down context ... press Ctrl+C again to force quit
    基于该基础镜像的ENV环境,您可以安装自己的依赖库(例如TensorFlow 1.12),再将修改过的Container提交为一个数据镜像。
    ENV/bin/pip install tensorflow==1.12
    您也可以在Docker外构建ENV开发环境,构建完成后,将其拷贝至任意Docker镜像的/data/eas/目录。使用镜像的方式构建开发环境,可以避免每次部署时都将整个ENV环境打包上传,从而提高部署速度。

步骤二:编写预测逻辑

在ENV同级目录下,创建预测服务主文件app.py(PAI-EAS预置的开发镜像中已经预先创建了该模板文件),PAI-EAS提供了如下SDK封装,使用EASCMD初始化环境时,系统会自动生成。
# -*- coding: utf-8 -*-
import allspark
class MyProcessor(allspark.BaseProcessor):
    """ MyProcessor is a example
        you can send mesage like this to predict
        curl -v http://127.0.0.1:8080/api/predict/service_name -d '2 105'
    """
    def initialize(self):
        """ load module, executed once at the start of the service
             do service intialization and load models in this function.
        """
        self.module = {'w0': 100, 'w1': 2}
    def pre_process(self, data):
        """ data format pre process
        """
        x, y = data.split(b' ')
        return int(x), int(y)
    def post_process(self, data):
        """ process after process
        """
        return bytes(data, encoding='utf8')
    def process(self, data):
        """ process the request data
        """
        x, y = self.pre_process(data)
        w0 = self.module['w0']
        w1 = self.module['w1']
        y1 = w1 * x + w0
        if y1 >= y:
            return self.post_process("True"), 200
        else:
            return self.post_process("False"), 400
if __name__ == '__main__':
    # parameter worker_threads indicates concurrency of processing
    runner = MyProcessor(worker_threads=10)
    runner.run()
上述代码即为Python SDK的简单示例,您需要继承PAI-EAS提供的基类BaseProcessor,实现initialize()process()函数。其process()函数的输入输出均为BYTES类型,输出参数分别为response_datastatus_code,正常请求status_code可以返回0200
函数 功能描述 参数描述
init(worker_threads=5, worker_processes=1,endpoint=None) Processor构建函数。
  • worker_threads:Worker线程数,默认值为5。
  • worker_processes:进程数,默认值为1。如果worker_processes为1,则表示单进程多线程模式。如果worker_processes大于1,则worker_threads只负责读取数据,请求由多进程并发处理,每个进程均会执行initialize()函数。
  • endpoint:服务监听的Endpoint,通过该参数可以指定服务监听的地址和端口,例如endpoint=’0.0.0.0:8079’
initialize() Processor初始化函数。服务启动时,进行模型加载等初始化工作。 无参数。
process(data) 请求处理函数。每个请求会将Request Body作为参数传递给process()进行处理,并将函数返回值返回至客户端。 data为Request Body,类型为BYTES。返回值也为BYTES类型。
run() 启动服务。 无参数。

步骤三:本地测试服务

./ENV/bin/python app.py
curl http://127.0.0.1:8080/test  -d '10 20'

步骤四:发布线上服务

  1. 打包代码。
    您可以通过以下任何一种方式操作:
    • 打包完整环境及代码
      您可以通过EASCMD或手动打包完整环境:
      • EASCMD封装的打包命令。
        $ ./eascmd64 pysdk pack ./demo
        [PYSDK] Creating package: /home/xingke.lwp/code/test/demo.tar.gz
      • 手动打包(支持.zip.tar.gz压缩包)。
        打包的根目录必须为/ENV目录。已经将该示例的完整.tar.gz包上传至OSS(下载完整包),您可以使用如下服务配置文件部署服务。
        {
          "name": "pysdk_demo",
          "processor_entry": "./app.py",
          "processor_type": "python",
          "processor_path": "oss://eas-model-beijing/1955570263925790/pack.tar.gz",
          "metadata": {
            "instance": 1,
             "memory": 2000,
             "cpu": 1
            }
        }
    • 通过镜像上传环境(推荐)
      通常使用Conda生成的Python ENV环境文件较大,在开发部署过程中,每次都打包并上传环境会浪费大量时间和存储资源。PAI-EAS提供了Data Image部署方式,您可以基于预构建的镜像构建ENV环境,并安装所需的Python依赖包,之后将Container提交为自己的数据镜像并上传至镜像仓库,示例如下。
      sudo docker commit 487a04df4b21 registry.cn-shanghai.aliyuncs.com/eas-service/develop:latest
      sudo docker push registry.cn-shanghai.aliyuncs.com/eas-service/develop:latest
      每次只需要将app.py相关的文件打包上传至OSS即可。您可以使用如下服务描述文件部署服务。
      {
        "name": "pysdk_demo",
        "processor_entry": "./service.py",
        "processor_type": "python",
        "processor_path": "http://eas-data.oss-cn-shanghai.aliyuncs.com/demo/service.py",
        "data_image": "registry.cn-shanghai.aliyuncs.com/eas-service/develop:latest",
        "metadata": {
          "instance": 1,
           "memory": 2000,
           "cpu": 1
          }
      }
  2. 部署服务。
    $ ./eascmd64 create app.json
    [RequestId]: 1202D427-8187-4BCB-8D32-D7096E95B5CA
    +-------------------+-------------------------------------------------------------------+
    | Intranet Endpoint | http://1828488879222746.vpc.cn-beijing.pai-eas.aliyuncs.com/api/predict/pysdk_demo |
    |             Token | ZTBhZTY3ZjgwMmMyMTQ5OTgyMTQ5YmM0NjdiMmNiNmJkY2M5ODI0Zg==          |
    +-------------------+-------------------------------------------------------------------+
    [OK] Waiting task server to be ready
    [OK] Fetching processor from [oss://eas-model-beijing/1955570263925790/pack.tar.gz]
    [OK] Building image [registry-vpc.cn-beijing.aliyuncs.com/eas/pysdk_demo_cn-beijing:v0.0.1-20190806082810]
    [OK] Pushing image [registry-vpc.cn-beijing.aliyuncs.com/eas/pysdk_demo_cn-beijing:v0.0.1-20190806082810]
    [OK] Waiting [Total: 1, Pending: 1, Running: 0]
    [OK] Service is running
    # 测试服务。
    $ curl http://1828488879222746.vpc.cn-beijing.pai-eas.aliyuncs.com/api/predict/pysdk_demo -H 'Authorization: ZTBhZTY3ZjgwMmMyMTQ5OTgyMTQ5YmM0NjdiMmNiNmJkY2M5ODI0Zg==' -d 'hello eas'