TensorFlow Serving是一个适用于深度学习模型的推理服务引擎,支持将TensorFlow标准的SavedModel格式的模型部署为在线服务,并支持模型热更新与模型版本管理等功能。本文为您介绍如何使用镜像部署的方式部署TensorFlow Serving模型服务。
部署服务
部署单模型服务
在OSS存储空间中创建模型存储目录,详情请参见管理目录。
TensorFlow Serving模型的存储目录要求以如下目录结构存储模型:
模型版本目录:每个模型至少包含一个模型版本目录,且必须以数字命名,作为模型版本号,数字越大版本号越新。
模型文件:模型版本目录下存放导出的SavedModel格式的模型文件,服务会自动加载最大模型版本号目录下的模型文件。
假设模型存储目录在
oss://examplebucket/models/tf_serving/
路径下,模型存储目录的格式如下:tf_serving └── mnist └──1 ├── saved_model.pb └── variables ├── variables.data-00000-of-00001 └── variables.index
部署TensorFlow Serving服务。
TensorFlow Serving服务支持配置以下两种端口,在场景化模型部署中,服务默认使用8501端口,若您需要使用8500端口,则需要执行步骤e,否则忽略步骤e即可。
8501:支持HTTP请求,在8501端口启动HTTP或REST服务。
8500:支持gRPC请求,在8500端口启动gRPC服务,
具体操作步骤如下:
进入模型在线服务(EAS)页面。
登录PAI控制台。
在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。
在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。
在模型在线服务(EAS)页面,单击部署服务。
在场景化模型部署区域,单击TFServing部署。
在TFServing部署页面,配置以下关键参数,其他参数配置说明,请参见服务部署:控制台。
参数
描述
服务名称
自定义配置服务名称。
部署方式
选择标准模型部署。
模型配置
将OSS配置为步骤1中已准备的模型所在的OSS存储路径,例如
oss://examplebucket/models/tf_serving/
。(可选)单击页面右侧的切换为自定义部署,修改模型服务信息区域的运行命令,将端口号修改为8500,同时您需要在对应配置编辑中添加以下配置。
说明服务默认在8501端口启动HTTP或REST服务,支持HTTP请求。若您需要该服务支持gRPC请求,您需要将端口号修改为8500,系统会在8500端口启动gRPC服务。
"metadata": { "enable_http2": true }, "networking": { "path": "/" }
参数配置完成后,单击部署。
部署多模型服务
TensorFlow Serving支持同时部署多个模型,具体操作步骤如下。
在OSS Bucket中创建模型存储目录,详情请参见管理目录。
假设模型存储目录在
oss://examplebucket/models/tf_serving/
路径下,多个模型存储目录的格式如下:tf_serving ├── model_config.pbtxt │ ├── model1 │ ├── 1 │ │ ├── saved_model.pb │ │ └── variables │ │ ├── variables.data-00000-of-00001 │ │ └── variables.index │ ├── 2 │ │ └── ... │ └── 3 │ └── ... │ ├── model2 │ ├── 1 │ │ └── ... │ └── 2 │ └── ... │ └── model3 ├── 1 │ └── ... ├── 2 │ └── ... └── 3 └── ...
其中模型配置文件model_config.pbtxt内容示例如下。
model_config_list { config { name: 'model1' base_path: '/models/model1/' model_platform: 'tensorflow' model_version_policy{ specific { versions: 1 versions: 2 } } version_labels { key: 'stable' value: 1 } version_labels { key: 'canary' value: 2 } } config { name: 'model2' base_path: '/models/model2/' model_platform: 'tensorflow' model_version_policy{ all: {} } } config { name: 'model3' base_path: '/models/model3/' model_platform: 'tensorflow' model_version_policy{ latest { num_versions: 2 } } } }
其中关键配置说明如下:
参数
是否必选
描述
name
否
自定义配置模型名称。建议配置该参数,如果不配置模型名称,则model_name为空,后续无法调用该模型服务。
base_path
是
配置模型存储目录在实例中的路径,后续部署服务时用于读取模型文件。例如:挂载目录为
/models
,要加载的模型目录为/models/model1
,则该参数配置为/models/model1
。model_version_policy
否
表示模型版本加载策略。
不配置该参数:表示默认加载模型最新版本。
all{}:表示加载该模型所有版本。示例中model2模型加载所有版本。
latest{num_versions}:示例中model3配置为
num_versions: 2
,表示加载最新的2个版本,即版本2和3。specific{}:表示加载指定版本。示例中model1模型加载版本1和2。
version_labels
否
为模型版本配置自定义标签。
说明标签默认只能分配给已成功加载并启动为服务的模型版本,若想要预先为尚未加载的模型版本分配标签,需要在运行命令中设置启动参数
--allow_version_labels_for_unavailable_models=true
。部署服务。
进入模型在线服务(EAS)页面。
登录PAI控制台。
在左侧导航栏单击工作空间列表,在工作空间列表页面中单击待操作的工作空间名称,进入对应工作空间内。
在工作空间页面的左侧导航栏选择模型部署>模型在线服务(EAS),进入模型在线服务(EAS)页面。
在模型在线服务(EAS)页面,单击部署服务。
在场景化模型部署区域,单击TFServing部署。
在TFServing部署页面,配置以下关键参数,其他参数配置说明,请参见服务部署:控制台。
参数
描述
服务名称
自定义配置服务名称。
部署方式
选择配置文件部署。
模型配置
将OSS配置为步骤1已准备的多模型文件所在的OSS存储路径,例如
oss://examplebucket/models/tf_serving/
。将配置文件配置为步骤1已准备的模型配置文件model_config.pbtxt所在的OSS存储路径。
(可选)单击页面右侧的切换为自定义部署,在模型服务信息区域的运行命令中配置以下参数,以实现特定功能。
增加以下参数,以实现特定功能:
参数
是否必选
描述
--model_config_file_poll_wait_seconds
否
如果您希望在服务启动后修改模型配置文件的内容,需要配置轮询模型文件的周期,单位为秒。服务会按照配置的时间定期读取模型配置文件的内容。例如
--model_config_file_poll_wait_seconds=30
表示服务每隔30秒读取一次模型配置文件内容。说明当模型服务读取新的模型配置文件时,只会执行新配置文件中的内容。例如:旧配置文件中包含模型A,而新配置文件将模型A删除并增加了模型B的配置,那么服务会卸载模型A并加载模型B。
--allow_version_labels_for_unavailable_models
否
默认为false,如果您想预先为尚未加载的模型版本分配标签,需要将该参数配置为true。例如
--allow_version_labels_for_unavailable_models=true
。更新端口号为8500,同时您需要在对应配置编辑中添加以下配置,服务将支持gRPC请求。
服务默认在8501端口启动HTTP或REST服务,支持HTTP请求。若您需要该服务支持gRPC请求,您需要将端口号修改为8500,系统会在8500端口启动gRPC服务。
"metadata": { "enable_http2": true }, "networking": { "path": "/" }
参数配置完成后,单击部署。
发送服务请求
根据服务部署时运行命令中配置的端口号,分别支持HTTP和gRPC两种请求协议。
HTTP请求
端口号配置为8501,服务支持HTTP请求,发送服务请求支持以下两种方式:
通过控制台发送服务请求
服务部署完成后,单击服务操作列下的在线调试,在该页面发送服务请求。其中关键参数配置如下:
参数
描述
在线调试请求参数
在服务访问地址后增加
/v1/models/<model_name>:predict
,其中:<model_name>:单模型发送HTTP请求时,配置为运行命令中配置的模型名称;多模型发送HTTP请求时,配置为模型配置文件中配置的模型名称。
<version_num>:可选配置,未指定版本号则默认加载版本号最大的模型。您也可以指定模型版本号,格式为:
/v1/models/<model_name>/versions/<version_num>:predict
。
Body
配置服务请求数据,例如:
{"signature_name": "predict_images", "inputs": [[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]]}
参数配置完成后,单击发送请求,输出如下类似结果。
通过Python代码发送服务请求
Python代码示例如下:
from urllib import request import json # 服务访问地址,未指定版本号则默认加载版本号最大的模型;您也可以参照下方url参数说明指定模型版本号。 url = '<service_url>/v1/models/<model_name>:predict' # 创建HTTP请求。 req = request.Request(url, method="POST") # test-token替换为服务Token。 req.add_header('authorization', '<test-token>') data = { 'signature_name': 'predict_images', 'inputs': [[1.0] * 784] } # 请求服务。 response = request.urlopen(req, data=json.dumps(data).encode('utf-8')).read() # 查看返回结果。 response = json.loads(response) print(response)
其中关键参数配置如下:
参数
描述
url
格式为:
<service_url>/v1/models/<model_name>:predict
其中:
<service_url>:需要替换为您部署的服务访问地址。您可以在模型在线服务(EAS)页面,单击待调用服务服务方式列下的调用信息,在公网地址调用页签查看服务访问地址。
<model_name>:配置方式如下。
单模型发送HTTP请求
配置为运行命令中配置的模型名称。
多模型发送HTTP请求
配置为模型配置文件中配置的模型名称。
<version_num>:可选配置,未指定版本号则默认加载版本号最大的模型。您也可以指定模型版本号,格式为:
<service_url>/v1/models/<model_name>/versions/<version_num>:predict
。
header
将<test-token>替换为服务Token。您可以在公网地址调用页签查看Token。
gRPC请求
端口号配置为8500,并添加gRPC相关配置后,服务支持发送gRPC请求。Python代码示例如下:
import grpc from tensorflow_serving.apis import predict_pb2 from tensorflow_serving.apis import prediction_service_pb2_grpc from tensorflow.core.framework import tensor_shape_pb2 # 服务访问地址。 host = "tf-serving-multi-grpc-test.166233998075****.cn-hangzhou.pai-eas.aliyuncs.com:80" name = "<model_name>" signature_name = "predict_images" version = <version_num> # 创建gRPC请求。 shape = tensor_shape_pb2.TensorShapeProto() dim1 = tensor_shape_pb2.TensorShapeProto.Dim(size=1) dim2 = tensor_shape_pb2.TensorShapeProto.Dim(size=784) shape.dim.extend([dim1, dim2]) request = predict_pb2.PredictRequest() request.model_spec.name = name request.model_spec.signature_name = signature_name request.model_spec.version.value = version request.inputs["images"].tensor_shape.CopyFrom(shape) request.inputs["images"].float_val.extend([1.0] * 784) request.inputs["images"].dtype = 1 # 请求服务。 channel = grpc.insecure_channel(host) stub = prediction_service_pb2_grpc.PredictionServiceStub(channel) metadata = (("authorization", "<test-token>"),) response, _ = stub.Predict.with_call(request, metadata=metadata) print(response)
其中关键参数配置如下:
参数
描述
host
需要配置为服务访问地址,服务访问地址需要省略
http://
并在末尾添加:80
。您可以在模型在线服务(EAS)页面,单击待调用服务服务方式列下的调用信息,在公网地址调用页签查看服务访问地址。name
单模型发送gRPC请求
配置为运行命令中配置的模型名称。
多模型发送gRPC请求
配置为模型配置文件中配置的模型名称。
version
配置为模型版本号。每次只能对单个模型版本发送请求。
metadata
配置为服务Token。您可以在公网地址调用页签查看Token。
相关文档
如何基于Triton Server推理服务引擎部署EAS服务,请参见Triton Inference Server镜像部署。
如何使用Modelscope、Huggingface镜像将相应的开源模型部署为EAS服务,请参见Modelscope镜像部署和HuggingFace镜像部署。
您也可以开发自定义镜像,使用自定义镜像部署EAS服务。具体操作,请参见服务部署:自定义镜像。