准备工作
- 拉取 tensorflow servering 的 docker 镜像:
sudo docker pull tensorflow/serving
,一般是已经有的 - 进入到一个测试目录:
cd /home/q/test_dir/
- 然后下载官方Demo目录:
git clone https://github.com/tensorflow/serving
- 如果无法下载,去网站 down 下来(附件),然后 deploy 上传到 linux 实体机中
部署启动
sudo docker run -t --rm -p 8501:8501 -v "/home/q/test_dir/serving-master/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu:/models/half_plus_two" -e MODEL_NAME=half_plus_two tensorflow/serving &
模型预测
curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://localhost:8501/v1/models/half_plus_two:predict
实际模型
接下来我使用自己训练的模型,部署了一个实际的例子,可参考:
模型保存
将已存在的 h5 文件,换成 SaveModel 文件(或者直接训练完保存 SaveModel 格式的文件)
from keras.models import Sequential
from keras import backend as K
import tensorflow as tf
from keras.models import load_model
model_test = load_model("../model/model_test.h5")
# export_path 后面一定要加一个版本号的目录,不然会报错 No versions of servable test found under base path
export_path = '../models_dir/00000123/'
tf.keras.models.save_model(
model_test,
export_path,
overwrite=True,
include_optimizer=True,
save_format=None,
signatures=None,
options=None
)
保存后的文件结构类似这样:其中 model_dir 和 model_test.h5 的前缀一样(model_test),1 和保存的版本号一样(00000123)
启动模型容器
启动模型 docker 容器:sudo docker run -t --rm -p 8501:8501 -v "/home/q/model_dir/model_test:/models/model_test" -e MODEL_NAME=model_test tensorflow/serving &
- 其中 -p 8501:8501 是指端口号
- -v 后面的是模型目录,:前的是实际硬盘目录,后的是容器的目录
- tensorflow/serving 是 docker 镜像
使用日志里这行的端口号进行调用: 2021-12-20 07:13:30.936441: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ...
查看模型信息
curl http://localhost:8501/v1/models/model_test
使用 saved_model_cli 命令查看模型相关信息(需要在安装有 tensorflow 包的虚拟环境执行,否则会报错:-bash: saved_model_cli: command not found ):
saved_model_cli show --dir /home/q/model_dir/model_test --all
然后会打印如下日志:默认使用的是 serving_default 这个 signature_def,通过 tf-serving 使用的时候,方法名是 predict,入参是(-1, 314) 的 matrix ,出参是一个 (-1, 4)的 matrix
调用
正确使用的命令是:curl -d '{"instances": [[0.508474576, 0.316053512, xxx]]}' -X POST http://localhost:8501/v1/models/model_test:predict
。返回模型的结果:
其中,需要注意的是:
- 入参的 key 是 instances 不可以换别的
- 入参的 array 需要是 matrix 二维数组
- 需要用 POST 请求
- 端口号需要是 docker 容器的端口号,一般是 8501,
- 路径是 /v1/models/xxx (其中 xxx 表示的是上文中启动模型 docker 时对应的 MODEL_NAME)
- 方法名是:predict,也就是 saved_model_cli show 里的 Method name
报错解决
以下报错是因为入参 shape 不对,或者 key 不对(应该是 instances 而不是 input)
以下报错是因为端口号不对:
以下报错是因为:key = instances 引号未加对:
以下报错是因为输入用的是 array 而不是 matrix:
python 调用
import numpy as np
# dnn feature_handle 将 json 特征处理为 matrix 格式
feature_list = feature_handle_dnn(features)
feature_matrix = np.array([feature_list])
feature_matrix
import json
import requests
data = json.dumps({
"instances": feature_matrix.tolist()
})
headers = {"content-type": "application/json"}
json_response = requests.post(
'http://ipipip:8501/v1/models/model_test:predict',
data=data, headers=headers)
json.loads(json_response.text)
部署多个模型
部署完一个模型,之后换端口号,按照同样的方法部署其他的模型时,会报错(截图里指的是部署完上文第一个模型后的第二个不同模型):
正确启动的方法:sudo docker run -p 8501:8501 -v "/home/q/model_dir/multi_models:/models/multi_models" -t tensorflow/serving --model_config_file=/models/multi_models/model.config
,其中
- -v 表示 Linux 硬盘绝对路径,绑定容器的路径,
- -t 后的是镜像名
- –model_config_file 是 config 的路径(用的是容器路径),固定写法/models/,后面加上配置文件的路径,如果写绝对路径或者相对路径找 models.config,会报错找不到文件或者路径
- multi_models 是个文件夹目录,里面放的是所有模型目录(相当于在上文单模型外层套一层文件夹)
- model.config 放在 multi_models 的子目录里(也就是和多个模型文件夹同一级目录)
- model.config 里面的路径,也需要用容器路径,而不是 Linux 路径,不然会报错
- 如果报错 :curl: (56) Recv failure: Connection reset by peer 则加上参数: --net=host
model.config 例子:
model_config_list:{
config:{
name:"model1",
base_path:"/models/multiModel/model1",
model_platform:"tensorflow"
},
config:{
name:"model2",
base_path:"/models/multiModel/model2",
model_platform:"tensorflow"
},
}
multi_models 目录结构如下:
启动成功的日志:
其中遇到的问题:
如果按照起一个模型的方法,会报错 unknown flag: --model_config_file:
model.config 路径要写对,是容器绝对路径,不然会报错(配置文件未找到):
model.config 里的路径也要写容器路径,不然会报错(加载的模型未找到):
模型 docker 启动后,curl 时报错:curl: (56) Recv failure: Connection reset by peer(解决办法:启动多模型 docker 容器时增加 --net=host 参数)