本文为您介绍如何使用阿里云模型在线服务(EAS)的Python SDK代码将训练获得的模型部署为EAS在线服务,再使用EAS的预测SDK代码调用EAS服务,实现模型在线推理。
背景信息
本文旨在介绍如何在Python环境中,通过SDK调用EAS接口来部署和调用基于MNIST数据集训练的手写数字识别模型服务。MNIST数据集是手写的数字0~9的数据集,本文会随机选取一个手写数字测试样本并输出其灰度图像,以此作为输入数据对模型进行模拟预测。具体操作流程如下:
参考Tensorflow基础示例,使用Python SDK代码训练并产出一个模型。
使用Python SDK调用EAS客户端命令,将训练获得的模型部署为EAS在线服务。
创建测试样本,对模型服务进行预测,验证模型效果。
前提条件
已创建OSS存储空间(Bucket),用于存储已获得的模型文件和配置文件。关于如何创建存储空间,详情请参见创建存储空间。
已准备运行Python SDK的环境,请选择一种准备即可。
(推荐)使用DSW实例的Notebook环境。建议创建DSW实例时,镜像选择tensorflow:2.3-cpu-py36-ubuntu18.04,实例规格选择ecs.c6.large,详情请参见创建及管理DSW实例。
使用本地Python环境。建议Python 3.6或以上版本,编译环境推荐使用JupyterLab。同时您需要在本地下载EASCMD客户端并进行身份认证,详情请参见下载并认证客户端。
步骤一:准备模型
安装Python SDK。后续将使用SDK调用EAS接口来部署和预测模型服务。
进入Notebook页面。
如果您使用的是DSW实例,首先需要单击目标实例操作列下的打开,打开DSW实例界面。在Notebook页签,单击快速开始区域Notebook下的Python3,进入Notebook编辑页面,详情请参见创建及管理DSW实例。
如果您使用的是本地Python环境,安装Python及JupyterLab后,进入JupyterLab编辑页面。
在Notebook中,执行以下代码安装Python SDK,安装过程大约需要持续15分钟。
! pip install tensorflow tensorflow_datasets ! pip install opencv-python ! pip install eas-prediction alibabacloud_eas20210701==1.1.2 --upgrade
说明回显信息中出现的ERROR和WARNING信息可以忽略。
执行以下命令验证是否安装成功。
pip list
返回结果中,如果能看到
tensorflow
、tensorflow_datasets
、opencv-python
、eas-prediction
,则表示Python包安装成功。
训练并产出一个模型。
在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目录下生成的模型文件如下图所示。
步骤二:部署模型到EAS
在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
需要配置您自己的AccessKey和AccessKeySecret。您可以使用阿里云账号或RAM用户来创建EAS客户端对象,如何获取AccessKey,详情请参见如何获取AccessKey。
本文以阿里云账号为例,如果您使用RAM用户,需要为RAM用户授予EAS的操作权限,具体操作,请参见云产品依赖与授权:EAS。
access_key_secret
准备模型文件。
将已获取的
eas_demo_output3
目录下的所有文件按照下图所示目录结构上传到OSS Bucket中。如何上传文件,详情请参见控制台上传文件。在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。
在Notebook中,执行以下代码查看EAS服务状态。
说明cluster_id需要与上述步骤中配置的region保持一致。
service2 = eas_client.describe_service(cluster_id='cn-shanghai', service_name=service1.service_name).body print(service2.status)
当返回结果为Running时,表示服务创建成功。
步骤三:模拟预测
创建测试样本。
在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()
系统返回结果如下图所示。您的测试样本输出结果以实际为准。
使用eas_prediction调用已部署的服务,进行在线预测,具体操作步骤如下。
在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。
系统输出结果如下图所示。您的输出结果以实际为准。
在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)
预测结果如下图所示。您的模型服务预测结果以实际为准。
预测结果说明:
float_val从上到下表示数字0~9,float_val最大值所在的行位置表示预测结果。例如:上图示例中,第一行float_val的值最大,预测结果为数字0,与测试样本图像中的数字一致。