两年多前曾经在服务器上部署了个 Tensorflow 模型,由于 Tensorflow serving 刚公布不久,并且还没阅读相关文档,所以当时就粗暴的用 Flask 写了个接口就放到线上跑了两年。
最近又需要在服务器上部署些模型,决定用回比较官方的方式,研究一下 Tensorflow serving。
安装
使用 docker compose 安装,需要注意的是,由于 Tensorflow 的接口不断在变化,Tensorflow serving 的版本需要与模型训练、模型导出的版本一致,否则可能会出现某些操作符不存在的错误。
docker-compose.yml
version: '3.7'
services:
tensorflow_serving:
build:
context: ./bin/TensorflowServing
ports: ["127.0.0.1:8501:8501"]
volumes:
- ./models:/models
environment:
- MODEL_NAME=nsfw
bin/TensorflowServing/Dockerfile,虽然是默认镜像,但习惯加个 Dockerfile
FROM tensorflow/serving:1.12.0
测试
在此测试的是 tensorflow-open_nsfw 模型,此模型提供模型导出以及数据请求格式生成相关的脚本,适合用来快速测试。
用 virtualenv 安装 tensorflow 1.12 版本,以及 numpy==1.16.1 ,然后运行下面命令导出模型:
python tools/export_savedmodel.py -i base64_jpeg -v 1 -m data/open_nsfw-weights.npy nsfw
使用以下命令查看模型输入输出格式:
saved_model_cli show --dir nsfw/1 --all
结果如下,输入是一个 base64 encode 的 jpeg 图片字符串:
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['inputs'] tensor_info:
dtype: DT_STRING
shape: (-1)
name: input:0
The given SavedModel SignatureDef contains the following output(s):
outputs['outputs'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 2)
name: predictions:0
Method name is: tensorflow/serving/predict
将导出的模型放到 docker compose 工作目录下的 models 下,然后启动 docker :
docker-compose up --build
拿一张需要测试的jpeg图片,运行下面命令:
python tools/create_predict_request.py -i base64_jpeg -l tensorflow -t tf-serving test.jpg > test.txt
test.txt 中会生成用于请求 Tensorflow serving 的格式,大概如下:
{"instances": ["_9j_4AAQSkZ......UUCP__Z"]}
需要注意的是这里的base64 encode图片需要为urlsafe格式,如果客户端为PHP的话需要对encode的字符串做替换处理。
然后测试一下:
curl -d '@test.txt' -X POST http://localhost:8501/v1/models/nsfw:predict
会返回类似下面结果:
{
"predictions": [[0.337196, 0.662804]
]
}
结果中第一个代表 sfw,第二个代表 nsfw,因此模型判断此图片包含不良内容。