Tensorflow Serving 填坑记

Author Avatar
Travon 7月 23, 2018
  • 在其它设备中阅读本文章

  之前用TensorFlow写了一个基于Bi-LSTM-CRF的临床命名实体识别模型,最近要求把模型部署API,供其他应用调用。本来打算直接用TensorFlow的Model saver和load配合flask框架实现。查询资料的时候发现TensorFlow官方出品了TensorFlow Serving工具可以实现相同的功能,于是尝试安装Serving,并跑通官方示例。在安装和调试过程中出现了诸多问题,记录一下。

安装环境

Ubuntu 16.04
Python 3.5

TensorFlow Serving 简介

  Tensorflow Serving 是面向产品环境开发的机器学习模型的服务系统,具有灵活、高效的特点。能够在保持相同的框架和API的基础上,比较容易地部署新的算法和实验。TensorFlow Serving为模型提供了开箱即用的集成环境,也十分容易扩展到其他类型的模型和数据上。它使用 gRPC 作为接口供外部调用。与此同时,它支持模型热更新与自动模型版本管理,意味着一旦部署 TensorFlow Serving 后,再也不需要为线上服务操心,只需要关心线下模型训练,实现模型版本的迭代更新。
参考:https://www.tensorflow.org/serving/

TensorFlow Serving 安装及示例调试

  安装也是按照官方文档的指导进行,在完全装好之后,才反应过来官方给出的是两种不同的安装方式,为了便于后面表述,这里简称为BazelPIP,下面详细介绍两种方式,以及相应的实例调试。

Bazel安装方式及示例调试

  1. 从github下载Bazel,链接:https://github.com/bazelbuild/bazel/releases,根据自己的系统选择相应的版本,我选择的版本是 bazel-0.15.1-installer-linux-x86_64.sh
  2. 安装Bazel,应该是用来编译的
    cd ~/Downloads
    chmod +x bazel-0.5.4-installer-linux-x86_64.sh
    ./bazel-0.5.4-installer-linux-x86_64.sh --user
    
    建立环境
    export PATH="$PATH:$HOME/bin"
    
  3. 安装gRPC(版本>1.0.0),应该是用来开放端口供调用的
    pip install grpcio
    
  4. 安装TensorFlow Serving所需依赖软件包
    sudo apt-get update && sudo apt-get install -y \
         automake \
         build-essential \
         curl \
         libcurl3-dev \
         git \
         libtool \
         libfreetype6-dev \
         libpng12-dev \
         libzmq3-dev \
         pkg-config \
         python-dev \
         python-numpy \
         python-pip \
         software-properties-common \
         swig \
         zip \
         zlib1g-dev
    
    注意:这一步涉及两条命令sudo apt-get update,这条命令用来更新源地址,以获取最新的软件包。&&的意思是在前一步命令执行成功后,再执行下一条命令,也是就是sudo apt-get install -y XXX,这条命令是用来安装软件包。所以,其实可以将这两条命令分开运行以保证后续build成功,这个ERROR后面再提及。
  5. 用Bazel从源编译安装TensorFlow Serving
    git clone https://github.com/tensorflow/serving
    cd serving
    bazel build -c opt tensorflow_serving/...
    
    注意:这里我出现了好几次错误,也查阅了好多好多博客文章,也没有解决。然后,决定查阅github issue,查关键词“libevent”,最后参考https://github.com/tensorflow/serving/issues/906里的“The Dockerfile does not have ‘automake’ and ‘libtool’ deb packages listed”,才幡然醒悟,有可能是第4步中的依赖没有安装好,因为之前有个错误以安装“automake”解决了,重新安装好依赖之后,最终解决。这也是我在第4步的注意力提及把两条命令分开运行的原因。
  6. 测试Serving是否安装成功
    bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server
    bazel test -c opt tensorflow_serving/...
    

到此,以Bazel安装的方式就结束了,接下来是Serving自带示例的调试,示例代码都在serving/tensorflow_serving/example路径下面,是一个简单的mnist的实现。测试方式也是参考官方文档,具体的代码解释就暂时不做了,只负责跑通。

  1. 把模型导出的路径清空
    rm -rf /tmp/mnist_model
    
  2. 训练并导出模型
    >bazel build -c opt //tensorflow_serving/example:mnist_saved_model
    >bazel-bin/tensorflow_serving/example/mnist_saved_model /tmp/mnist_model
    Training model...
    ...
    Done training!
    Exporting trained model to /tmp/mnist_model
    Done exporting!
    
  3. 部署模型,端口:9000
    bazel build -c opt //tensorflow_serving/model_servers:tensorflow_model_server
    bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_name=mnist --model_base_path=/tmp/mnist_model/
    
  4. 本地测试模型
    bazel build -c opt //tensorflow_serving/example:mnist_client
    bazel-bin/tensorflow_serving/example/mnist_client --num_tests=1000 --server=localhost:9000
    
    如果出现Inference error rate: 10.5%,则测试成功。

PIP安装方式及示例调试

  1. 安装tensorflow-serving-api
    pip install tensorflow-serving-api
    
  2. 安装ModelSaver
    echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | sudo tee /etc/apt/sources.list.d/tensorflow-serving.list
    curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | sudo apt-key add -
    sudo apt-get update && sudo apt-get install tensorflow-model-server
    

到此,PIP方式的安装就结束了,当然跟Bazel方式一样,gRPC和Serving所需的依赖软件包都需要安装。下面是PIP方式的示例调试。

  1. 训练并导出模型
    python3 tensorflow_serving/example/mnist_saved_model.py /tmp/mnist_model
    
    注意:这里使用的是python3,但是mnist_saved_model.py是用python2写的,里面有个xrange,在python3里是不存在,需要改成range,即可以运行成功。
  2. 部署模型,端口:9000
    tensorflow_model_server --port=9000 --model_name=mnist --model_base_path=/tmp/mnist_model/
    
  3. 测试模型
    python3 tensorflow_serving/example/mnist_client.py --num_tests=1000 --server=localhost:9000
    
    注意:在训练和导出模型、启动server时都没出现错误,在使用client调用server的时候出现与 https://github.com/tensorflow/serving/issues/387 相同的情况,本来以为是proxy的问题,将proxy取消(命令:unset http_proxy)之后,问题还是存在。
    于是,再重新阅读了这个issue的讨论,发现一句“Just check on the client side if sudo fixes your problem. Then configure your user permissions accordingly.”,尝试sudo之后,PIP和Bazel的方式都终于调试成功!!!

从这次安装的过程,总结的经验如下:安装的时候需要弄清楚每条命令的含义、目的,才能保证成功;还有就是网上很多教程可能并不准确,而且版本更新较快,很多教程也很容易过时,官方文档和GitHub中的issue是很好的找解决方法的地方。


本文标题: Tensorflow Serving 填坑记
原始链接: http://oyeblog.com/2018/tensorflow_serving/
发布时间: 2018年07月23日 - 20时20分
最后更新: 2018年07月24日 - 22时31分
版权声明: 本站文章均采用CC BY-NC-SA 4.0协议进行许可。转载请注明出处!