使用EAS Python SDK部署模型

本文为您介绍如何使用阿里云模型在线服务(EAS)的Python SDK代码将训练获得的模型部署为EAS在线服务,再使用EAS的预测SDK代码调用EAS服务,实现模型在线推理。

背景信息

本文旨在介绍如何在Python环境中,通过SDK调用EAS接口来部署和调用基于MNIST数据集训练的手写数字识别模型服务。MNIST数据集是手写的数字0~9的数据集,本文会随机选取一个手写数字测试样本并输出其灰度图像,以此作为输入数据对模型进行模拟预测。具体操作流程如下:

前提条件

  • 已创建OSS存储空间(Bucket),用于存储已获得的模型文件和配置文件。关于如何创建存储空间,详情请参见创建存储空间

  • 已准备运行Python SDK的环境,请选择一种准备即可。

    • (推荐)使用DSW实例的Notebook环境。建议创建DSW实例时,镜像选择tensorflow:2.3-cpu-py36-ubuntu18.04,实例规格选择ecs.c6.large,详情请参见创建及管理DSW实例

    • 使用本地Python环境。建议Python 3.6或以上版本,编译环境推荐使用JupyterLab。同时您需要在本地下载EASCMD客户端并进行身份认证,详情请参见下载并认证客户端

步骤一:准备模型

  1. 安装Python SDK。后续将使用SDK调用EAS接口来部署和预测模型服务。

    1. 进入Notebook页面。

      • 如果您使用的是DSW实例,首先需要单击目标实例操作列下的打开,打开DSW实例界面。在Notebook页签,单击快速开始区域Notebook下的Python3,进入Notebook编辑页面,详情请参见创建及管理DSW实例

      • 如果您使用的是本地Python环境,安装PythonJupyterLab后,进入JupyterLab编辑页面。

    2. Notebook中,执行以下代码安装Python SDK,安装过程大约需要持续15分钟。

      ! pip install tensorflow tensorflow_datasets
      ! pip install opencv-python 
      ! pip install eas-prediction alibabacloud_eas20210701==1.1.2 --upgrade
      说明

      回显信息中出现的ERRORWARNING信息可以忽略。

    3. 执行以下命令验证是否安装成功。

      pip list

      返回结果中,如果能看到tensorflowtensorflow_datasetsopencv-pythoneas-prediction,则表示Python包安装成功。

  2. 训练并产出一个模型。

    Notebook中,参考TensorFlow的基础示例,执行以下代码来训练一个TensorFlow模型,并将训练获得的模型文件输出到当前目录下的eas_demo_output3目录。训练过程大约需要持续20分钟。

    import tensorflow as tf
    import tensorflow_datasets as tfds
    
    (ds_train, ds_test), ds_info = tfds.load(
        'mnist',
        split=['train', 'test'],
        data_dir='./cached_datasets',
        shuffle_files=True,
        as_supervised=True,
        with_info=True,
    )
    
    def normalize_img(image, label):
      """Normalizes images: `uint8` -> `float32`."""
      return tf.cast(image, tf.float32) / 255., label
    
    ds_train = ds_train.map(
        normalize_img)
    ds_train = ds_train.cache()
    ds_train = ds_train.shuffle(ds_info.splits['train'].num_examples)
    ds_train = ds_train.batch(128)
    ds_train = ds_train.prefetch(10)
    
    ds_test = ds_test.map(normalize_img)
    ds_test = ds_test.batch(128)
    ds_test = ds_test.cache()
    ds_test = ds_test.prefetch(10)
    model = tf.keras.models.Sequential([
      tf.keras.layers.Flatten(input_shape=(28, 28)),
      tf.keras.layers.Dense(128, activation='relu'),
      tf.keras.layers.Dense(10)
    ])
    model.compile(
        optimizer=tf.keras.optimizers.Adam(0.001),
        loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=[tf.keras.metrics.SparseCategoricalAccuracy()],
    )
    
    model.fit(
        ds_train,
        epochs=6,
        validation_data=ds_test,
    )
    model.save('./eas_demo_output3')

    eas_demo_output3目录下生成的模型文件如下图所示。image.png

步骤二:部署模型到EAS

  1. Notebook中,执行以下代码创建EAS的客户端对象。后续将使用该对象调用EAS客户端命令来创建模型服务。

    from alibabacloud_eas20210701.client import Client as eas20210701Client
    from alibabacloud_tea_openapi import models as open_api_models
    from alibabacloud_eas20210701 import models as eas_20210701_models
    from alibabacloud_tea_util import models as util_models
    from alibabacloud_tea_util.client import Client as UtilClient
    from alibabacloud_eas20210701.models import (ListServicesRequest, CreateServiceRequest)
    
    access_key_id = "<AccessKey>"
    access_key_secret = "<AccessKeySecret>"
    
    import os.path
    config_path="/mnt/data/pai.config"
    if os.path.isfile(config_path):
        with open(config_path) as f:
            access_key_id = f.readline().strip('\n')
            access_key_secret = f.readline().strip('\n')
    
    config = open_api_models.Config(
                access_key_id=access_key_id,
                access_key_secret=access_key_secret
            )
    
    # 访问的域名
    region = "cn-shanghai"
    config.endpoint = f'pai-eas.{region}.aliyuncs.com'
    eas_client = eas20210701Client(config)

    其中关键参数配置如下。

    参数

    描述

    region

    服务即将部署的地域ID,详情请参见地域和可用区

    本文示例值为:cn-shanghai

    说明

    region需要与OSS Bucket所在地域一致。否则后续创建EAS服务时读取模型文件失败。

    access_key_id

    需要配置您自己的AccessKeyAccessKeySecret。您可以使用阿里云账号或RAM用户来创建EAS客户端对象,如何获取AccessKey,详情请参见如何获取AccessKey

    本文以阿里云账号为例,如果您使用RAM用户,需要为RAM用户授予EAS的操作权限,具体操作,请参见云产品依赖与授权:EAS

    access_key_secret

  2. 准备模型文件。

    将已获取的eas_demo_output3目录下的所有文件按照下图所示目录结构上传到OSS Bucket中。如何上传文件,详情请参见控制台上传文件

    image.png
  3. Notebook中,执行以下代码创建EAS服务。

    import json
    resource_config = { "instance": 1,
                       	 "memory": 7000,
                         "cpu": 4}
    model_path = "oss://examplebucket/dsw/eas_demo_output3/"                     
    service_config = {"name": "service_from_dsw",
                     "model_path": model_path,
                     "processor": "tensorflow_cpu_2.4",
                     "metadata": resource_config}
    print(json.dumps(service_config))
    
    service1 = eas_client.create_service(CreateServiceRequest(body=json.dumps(service_config))).body
    print(service1)

    其中关键参数配置如下。服务创建过程大约需要持续5分钟,服务创建成功后,会在控制台的PAI EAS模型在线服务页面展示。

    参数

    描述

    model_path

    替换为您的模型文件所在的OSS Bucket路径。

    service_config.name

    您可以自定义模型服务名称,命名格式为:

    • 只能包含数字、小写字母以及下划线,且必须以字母开头。

    • 模型服务名称需唯一,不能与同地域内其他服务名称重复。

    本文示例值为:service_from_dsw

  4. Notebook中,执行以下代码查看EAS服务状态。

    说明

    cluster_id需要与上述步骤中配置的region保持一致。

    service2 = eas_client.describe_service(cluster_id='cn-shanghai', service_name=service1.service_name).body
    print(service2.status)

    当返回结果为Running时,表示服务创建成功。

步骤三:模拟预测

  1. 创建测试样本。

    Notebook中,执行以下代码从MNIST数据集中随机选取一个手写数字测试样本,并输出其灰度图像。每次执行代码会生成一个不同的数字图像,后续您可以根据图像中的数字来评估预测结果是否准确。您也可以创建自己的测试数据,进行模拟预测。

    # import tensorflow.compat.v2 as tf
    import tensorflow_datasets as tfds
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Construct a tf.data.Dataset
    ds = tfds.load('mnist', split='train', data_dir='./cached_datasets',  shuffle_files=False)
    
    # Build your input pipeline
    ds = ds.shuffle(1024).take(3)
    
    target = []
    for example in ds.take(1):
        image, label = example['image'], example['label']
        print(label)
        target = np.reshape(image, 784)
        plt.imshow(tf.squeeze(image))
        plt.show()

    系统返回结果如下图所示。您的测试样本输出结果以实际为准。image

  2. 使用eas_prediction调用已部署的服务,进行在线预测,具体操作步骤如下。

    1. Notebook中,执行以下代码查询模型服务的详细信息,包括:AccessToken、Endpoint等,后续通过该调用信息来调用服务进行模拟测试。

      service3 = eas_client.describe_service(cluster_id='cn-shanghai', service_name='service_from_dsw').body
      print(service3)

      其中关键参数配置如下。

      参数

      描述

      cluster_id

      服务所在的地域名称。

      本文示例值为:cn-shanghai

      service_name

      替换为上述步骤中部署的模型服务名称。

      本文示例值为:service_from_dsw

      系统输出结果如下图所示。您的输出结果以实际为准。

      image
    2. Notebook中,执行以下代码构造PredictClient对象来调用服务。

      将步骤1中输出的灰度图像作为输入数据,使用步骤2中查询的access_token、Endpoint等信息来调用服务,并输出预测结果。

      from eas_prediction import PredictClient, TFRequest
      import urllib
      client = PredictClient(urllib.parse.urlsplit(service3.internet_endpoint).hostname,
                             service3.service_name)
      client.set_token(service3.access_token)
      client.init()
      
      req = TFRequest('serving_default') # signature_name 参数:serving_default
      req.add_feed('flatten_input', [1, 28, 28], TFRequest.DT_FLOAT, target)
      
      resp = client.predict(req)
      print((resp.response.outputs).keys)

      预测结果如下图所示。您的模型服务预测结果以实际为准。image

      预测结果说明:

      float_val从上到下表示数字0~9,float_val最大值所在的行位置表示预测结果。例如:上图示例中,第一行float_val的值最大,预测结果为数字0,与测试样本图像中的数字一致。