在 Amazon SageMaker 上快速、灵活构建 Amazon TensorFlow 模型的在线推理服务
背景介绍
当算法工程师在本地使用 Amazon TensorFlow 深度学习框架训练好模型后,会创建模型服务器供应用程序调用实现在线推理。由于部署本身存在一定的复杂性,他们需要考虑如何安装 TensorFlow Serving 相关的依赖,如何实现模型服务的高可用、请求负载均衡、A/B 测试、自动伸缩机制等。Amazon SageMaker 可以帮助用户快速创建多台模型服务器进行负载均衡,利用云上多可用区的方式实现高可用,并且在请求量变化时可以根据用户配置的策略进行自动扩展或收缩。本文会介绍如何将本地训练好的 TensorFlow 模型部署到 Amazon SageMaker 来快速、灵活地创建 Amazon TensorFlow 模型服务器。
TensorFlow Serving 请求数据格式
在将模型部署到 Amazon SageMaker 之前,我们首先要了解 TensorFlow Serving 的 SignatureDefs,它标识了保存模型时所需的接受请求函数的输入与输出,不同 SignatureDefs 下的请求数据格式不同。TensorFlow Serving 支持 gRPC API 与 RESTful API 两种方式进行请求,本文以 RESTful API 的方式为例。
[01] Classify 与 Regress API
Classify 与 Regress 的 SignatureDefs 分别支持分类与回归的 TersorFlow Serving 结构化调用方式。即当 Serving 的输入函数封装了 tf.Example(一种灵活的消息类型,表示{“string”: value}的映射,常用来进行训练过程中的数据流式传输或解析 feature_column 中的特征列),需要调用该 API 进行推理。
参考以下代码,在保存模型时指定 input_receiver_fn 作为接受请求函数,其中定义了将 feature_column 解析为 tf.Example 消息类型的过程,然后输入给模型进行推理。
*左滑查看更多
在创建模型服务器后,若想对服务器进行请求得到推理结果,就需要将数据构造成 Classify 与 Regress API 所能接受的格式,如下所示:
*左滑查看更多
[02] Predict API
Predict SignatureDefs 支持将 tensor 作为输入和输出,可通用于分类与回归的推理问题类型。参考以下代码,在 input_receiver_fn 函数中,读取到数据后构造成 tensor,作为模型的输入。
*左滑查看更多
该情况下对模型服务器发起请求就需要使用 Predict API,其所能接受的数据格式如下所示:
*左滑查看更多
[03] 在 Amazon SageMaker 中向 Serving 发送请求
在 Amazon SageMaker 的 SDK(https://sagemaker.readthedocs.io/en/stable/frameworks/tensorflow/sagemaker.tensorflow.html#tensorflow-serving-predictor)中,将上述三种不同的 API 封装成了三种方法,即创建好 Predictor 之后,根据上述不同 SignatureDefs 所能接受的数据格式构造请求,就可以选择调用方法进行推理,Predict API、Classify 与 Regress API 的调用方法如下所示:
将已训练好的 Amazon TensorFlow 模型部署到 Amazon SageMaker
将模型压缩打包上传到 Amazon S3 之后,有两种方式可以实现模型的部署。
[01] 不提供 inference.py 脚本
若不需要对请求中的数据进行前处理和后处理,就不需要提供 inference.py 脚本,实例化 TensorFlowModel 对象时只需要指定模型在 Amazon S3 中的位置,以及相关的 role,如下所示:
*左滑查看更多
部署完成之后,在推理时需要根据 Serving 所使用的 SignatureDefs,将数据构造成 SignatureDefs 可以接受的格式,再调用相关的 API 进行推理。比如,若使用 Classify API 进行推理,则需要先将数据构造成 1.1 节中提到的请求格式,然后调用 Predictor 的 classify 方法,将推理数据作为参数传入,即可得到推理结果。
[02] 提供 inference.py 脚本
若需要对输入模型的数据进行前处理或对推理产生的结果进行后处理,则需要在实例化 TensorFlowModel 对象时提供 inference.py 脚本,通过 entry_point 参数指定,如下所示:
*左滑查看更多
在 inference.py 的代码中需要定义两个函数,分别是 input_handler 与 output_handler。其中 input_handler 首先需要对传递进来的序列化对象进行解析。比如 TensorFlow Serving Predictor 默认的 serializer 为 JSONSerializer,那么在 input_handler 中就需要对 json 序列化对象解析,之后就可以对数据进行前处理操作。类似地,在推理前需要把处理好的数据转化为 SignatureDefs 所能接受的格式。注意,构造 SignatureDefs 数据格式这个过程是在 input_handler 中定义的,这么做的好处就是用户无需在请求 Serving 前完成请求数据格式的定义,让前端传入的数据更加简洁灵活。
同样,在得到推理结果后,可以把数据后处理过程写在 output_handler 函数中,通过 response_centent_type 指定序列化对象,将结果返回给前端。
实验
本实验使用已经训练好的 iris 模型,展示带有 inference.py 和不带 inference.py 在 Amazon SageMaker 上进行模型部署的过程,并调用 Classify API 进行推理。
实验所需环境
使用 cn-northwest-1 区域;
在 Amazon SageMaker 中创建一台 Jupyter Notebook 实例,创建过程可参考官方文档:https://docs.aws.amazon.com/sagemaker/latest/dg/howitworks-create-ws.html
下载实验所需的材料:git clone https://github.com/micxyj/awsblog-lab-guide.git,进入文件夹,将 tf-byom.zip 文件,上传至 Notebook 环境。
实验步骤如下
打开 Notebook 命令行,执行以下命令解压 zip 包;
cd SageMaker/
unzip tf-byom.zip
双击打开 tf_byom.ipynb 笔记本文件,逐步执行 notebook 中的步骤;
可以看到若不提供 inference.py,在进行推理前需要构造好 Classify SignatureDefs 所能接受的数据格式,如下图 key 为 examples 的字典:
Amazon SageMaker SDK 会把推理数据进行序列化传递给 Serving,推理完成之后会将结果反序化回前端。
在提供了 inference.py 的场景中,由于在 input_handler 函数中定义了加载列表生成 Classify SignatureDefs 数据格式,在调用 classify 进行推理时只需要传入列表数据即可,如下所示:
总结
本文介绍了 TensorFlow Serving 三种不同 SignatureDefs 的区别以及调用方法,展示了如何将本地训练的模型在 Amazon SageMaker 上进行部署与推理。通过使用 Amazon SageMaker,用户可以快速地将模型进行部署上线,无需进行复杂的配置便可实现高可用的、可扩展的模型服务器架构。
参考资料
[1] https://www.tensorflow.org/tfx/serving/api_rest
[2] https://www.tensorflow.org/tfx/serving/signature_defs
[3] https://sagemaker.readthedocs.io//en/stable/frameworks/tensorflow/deploy-ing_tensorflow_serving.html
本篇作者
肖元君
亚马逊云科技解决方案架构师
负责基于亚马逊云科技云计算方案的架构咨询和设计实现,同时致力于数据分析与 AI 的研究与应用。
郭韧
亚马逊云科技人工智能和机器学习方向解决方案架构师
负责基于亚马逊云科技的机器学习方案架构咨询和设计,致力于游戏、电商、互联网媒体等多个行业的机器学习方案实施和推广。在加入亚马逊云科技之前,从事数据智能化相关技术的开源及标准化工作,具有丰富的设计与实践经验。
评论