YP.Lam | Tensorflow Serving Nsfw

Tensorflow Serving Nsfw

两年多前曾经在服务器上部署了个 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,因此模型判断此图片包含不良内容。