推理服务 TFServing
TFServing(TensorFlow Serving)用于部署 TensorFlow 的 saved_model。
平台仅支持已添加服务签名的 saved_model 目录地址(例如 /mnt/xx/.../saved_model/,见 myapp/views/view_inferenceserving.py:227)。
保存 saved_model 模型添加服务化签名
tf.keras.Model 会自动指定服务上线签名。
tf.saved_model.save 要手动指定:
module_with_signature_path = '/xx/'
call = module.__call__.get_concrete_function(tf.TensorSpec(None, tf.float32)) # 第一个参数也可以加上 shape,例如 (1,256,32,1)
tf.saved_model.save(module, module_with_signature_path, signatures=call)
查看网络模型结构
pip3 install tensorflow==x.x.x
saved_model_cli show --all --dir=model_Path
可以看到输入签名:
signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['a_age'] tensor_info:
dtype: DT_INT64
shape: (-1, 1)
name: serving_default_a_age:0
...
Method name is: tensorflow/serving/predict
TFServing 云原生服务部署
镜像
平台提供以下 CubeStudio 镜像(基于上游 tensorflow/serving 重新打包,见 myapp/config.py:1326、images/serving/tfserving/build.sh):
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.14.1
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.14.1-gpu
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.13.1 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.12.2 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.11.1 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.10.1 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.9.3 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.8.4 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.7.4 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.6.5 (及 -gpu)
ccr.ccs.tencentyun.com/cube-studio/tfserving:2.5.4 (及 -gpu)
也可直接使用上游镜像
tensorflow/serving:<version>(含-gpu)。原文档中列出的 1.11.0 ~ 2.6.0 等老版本为上游镜像,平台当前默认提供的镜像版本以上面列表为准。
模型文件目录结构
$model_dir/$model_name/$model_version/saved_model.pb
如下图所示:

编写模型配置文件(必须)
$model_dir/$model_name/models.config
简单样式(标准的 utf-8 编码的 json 文件):
model_config_list {
config {
name: "$model_name"
base_path: "$model_dir/$model_name/"
model_platform: "tensorflow"
model_version_policy {
specific {
versions: $version
}
}
}
}
替换自己的 $model_dir、$model_name 和 $version。
注意:
model_version_policy设置提供服务的版本,不设置则自动选择最新的模型版本。$version只能用 int64 来命名。
建议放在个人目录某个子目录下,配置服务时用启动命令的 --model_config_file=$model_dir/$model_name/models.config 参数指定 models.config 的路径。
编写监控配置文件(必须)
$model_dir/$model_name/monitoring.config
监控配置:
prometheus_config {
enable: true,
path: "/metrics"
}
放在同目录下,配置服务时用启动命令的 --monitoring_config_file=$model_dir/$model_name/monitoring.config 指定。
编写平台配置文件(可忽略)
$model_dir/$model_name/platform.config
platform_configs {
key: "tensorflow"
value {
source_adapter_config {
[type.googleapis.com/tensorflow.serving.SavedModelBundleSourceAdapterConfig] {
legacy_config {
session_config {
gpu_options {
allow_growth: true
}
}
}
}
}
}
}
放在同目录下,配置服务时用启动命令的 --platform_config_file=$model_dir/$model_name/platform.config 指定。
部署服务
启动命令:统一填写 /usr/bin/tf_serving_entrypoint.sh --model_config_file=xxx,必须指定部署配置文件的路径 --model_config_file。
平台部署 TFServing 时,会自动生成 models.config / monitoring.config / platform.config 并挂载到
/config/下,默认启动命令为:/usr/bin/tf_serving_entrypoint.sh --model_config_file=/config/models.config --monitoring_config_file=/config/monitoring.config --platform_config_file=/config/platform.config --rest_api_num_threads=300 --enable_batching=true(见myapp/views/view_inferenceserving.py:87,配置文件生成逻辑见myapp/views/view_inferenceserving.py:495-521)。
后面可选添加其他配置项,常用如监听端口、服务线程数、配置更新间隔、启用缓存、证书鉴权等,详见:
--model_config_file 模型配置文件
--monitoring_config_file 监控配置文件
--enable_batching 是否启动批处理
--batching_parameters_file 批处理配置文件
--platform_config_file 平台配置文件
--port 监听 gRPC API 的端口
--rest_api_port 监听 HTTP/REST API 的端口
--rest_api_num_threads=64 # 并发线程数,会默认配置
--rest_api_timeout_in_ms HTTP/REST API 调用超时
--file_system_poll_wait_seconds 服务器轮询文件系统以获取每个模型各自 model_base_path 处的新模型版本的时间段
--enable_model_warmup 使用 assets.extra/ 目录中用户提供的 PredictionLogs 启用模型预热
--tensorflow_intra_op_parallelism=10 建议设置为申请的 cpu 核数目
--tensorflow_inter_op_parallelism=10 建议设置为申请的 cpu 核数目
日志跟踪:
TF_CPP_MIN_VLOG_LEVEL=1 详细日志
TF_CPP_VMODULE=http_server=1 api 请求日志
支持的启动参数:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/model_servers/main.cc#L59
内存申请、cpu 申请、gpu 申请:按需申请。
域名:按具体业务填写。
镜像:选取合适版本镜像。
端口:8501(REST API;gRPC 默认 8500。平台中 TFServing 服务端口与健康检查端口均为 8501,见 myapp/views/view_inferenceserving.py:108、:125)。
TFServing API 访问
官方文档:https://github.com/tensorflow/serving/blob/master/tensorflow_serving/g3doc/api_rest.md
Model status API:
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]
示例:
https://demo.service.xxx/v1/models/my_model1/versions/20210924
Model Metadata API:
GET http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]/metadata
示例:
https://demo.service.xxx/v1/models/my_model1/versions/20210924/metadata
Classify and Regress API:
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}]:(classify|regress)
Predict API:
POST http://host:port/v1/models/${MODEL_NAME}[/versions/${VERSION}|/labels/${LABEL}]:predict
示例:
http://xx.xx.xx.xx/v1/models/my_model1/versions/20210924:predict
生产中建议 api 调用不使用版本,这样能做到无缝切换版本:
http://xx.xx.xx.xx/v1/models/my_model1:predict
shell 示例:
curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://xx.xx.xx/v1/models/my_model1/versions/20210924:predict
python 示例 json:
req_json = {
"instances":[
{
'input_name1':xx,
'input_name2':xx,
...
}
]
}
predict_request = json.dumps(req_json)
response = requests.post(SERVER_URL, data=predict_request)
response.raise_for_status()
print(response.json())
python 推理图片:
jpeg_rgb = Image.open(io.BytesIO(open(IMAGE_PATH,"rb").read()))
jpeg_rgb = np.expand_dims(np.array(jpeg_rgb) / 255.0, 0).tolist()
predict_request = json.dumps({'instances': jpeg_rgb})
response = requests.post(SERVER_URL, data=predict_request)
response.raise_for_status()
print(response.json())
最小示例(mnist 训练 → 检查 → 启动服务)
以下是从训练保存模型到本地起服务的最小命令链(见 images/serving/tfserving/example/,含 mnist_saved_model.py、mnist_client.py 等脚本):
启动训练,保存模型:
python mnist_saved_model.py --training_iteration 10 --model_version 1 export_dir
检查模型(确认服务签名):
saved_model_cli show --dir export_dir/1 --all
启动服务(本地裸跑 tensorflow_model_server,REST 端口 8501):
tensorflow_model_server --rest_api_port=8501 --model_name=fashion_model --model_base_path=export_dir
该示例直接用
--model_base_path指向模型目录裸跑;平台云原生部署则通过上文的models.config等配置文件指定模型,二选一。