CPU 版本编译

1.需要联网环境,如果是生产环境,最好配置能够连接外网的代理,否则需要 copy 相关依赖安装,费时费力。代理配置方法:

# http://URI:PORT为代理地址,注意需要加上协议名称,如 http://,否则相关编译脚本下载依赖时会报错
export http_proxy=http://URI:PORT
export https_proxy=http://URI:PORT

2.安装相关依赖,依赖列表可以从 tensorflow-serving 的 docker file 中找到,主要需要安装的依赖如下,因 github 上的项目更新较快,请以 docker file 中的为准。:

# 一般会缺失的依赖
yum -y install java-1.8.0-openjdk-devel automake autoconf libtool libicu patch

# python 相关,连接境外源较慢,建议更换成国内源,比如 douban 等
pip install --upgrade pip
pip install numpy grpcio Keras-Applications Keras-Preprocessing h5py requests enum --trusted-host pypi.doubanio.com

3.安装 bazel:在 https://copr.fedorainfracloud.org/coprs/vbatts/bazel/ 中下载对应版本的repo文件,并拷贝到/etc/yum.repos.d/中,使用命令 yum install –downloadonly bazel 就可以下载 bazel 的 rpm 包,缓存在 /var/cache/yum 子目录下,比如/var/cache/yum/x86_64/7/vbatts-bazel/packages,如果有别的机器没有网络,可以将bazel-0.12.0-1.el7.centos.x86_64.rpm上传服务器对应目录下,使用命令 yum install bazel-0.12.0-1.el7.centos.x86_64.rpm 即可安装。如果 yum 下载最后提示 check sum 失败,可以查看 log 找到下载地址,wget 下载,再将 rpm 包复制到上述目录安装

4.下载 tf-serving 代码开始编译,时间较长,主要的错误就是依赖缺失,根据日志提示查找对应包安装即可

git clone --recurse-submoduleshttps://github.com/tensorflow/serving && cd serving
bazel build -c opt tensorflow_serving/...

GPU 版本编译

GPU 版本需要在 cuda 9 环境下编译,cuda 8下编译始终失败,git 上已经有说明。所以以下步骤,请在 Centos 7 + cuda 9 + cudnn 7 for cuda 9的环境下操作。

1.对于联网环境,相关依赖还有 bazel 的安装, 同上文 CPU环境

2.GPU 版本需要安装 TensorRT,在官网下载与 cuda 版本对应的 tar 包(如果 cuda 不是通过 rpm 安装,这里请不要选择 rpm 包,装不上),例如我们的环境是CentOs 7 + cuda 9。下载之后解压即可,将其移到合适位置,后续需要用到 TensorRT 的安装路径。

3.下载 tf-serving 的代码,参照 gpu docker 文件里的编译步骤,整理编译需要的环境变量和编译命令如下:

#!/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/root/bin  #依照自有环境修改
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/         #依照自有环境修改
export LD_LIBRARY_PATH=/usr/local/cuda/lib64/stubs:/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH               #依照自有环境修改,主要是增加 cuda 的依赖
export BAZEL_VERSION=0.23.1                #指定 bazel 的版本
export CUDNN_VERSION=7.5.0                 #指定 cudnn 的版本
export TF_TENSORRT_VERSION=5.0.2           #指定 TensorRT 的版本
export TF_NEED_CUDA=1                      #编译 GPU 版本必须指定的参数
export TF_NEED_TENSORRT=1
export TENSORRT_INSTALL_PATH=/usr/local/tensorRT/lib #依照自有环境修改,指向tensorRT 的 lib 目录
export TF_CUDA_COMPUTE_CAPABILITIES=3.0,3.5,5.2,6.0,6.1  #依照自有环境上的 GPU 修改
export TF_CUDA_VERSION=9.0                 #cuda 版本号
export TF_CUDNN_VERSION=7                  #cudnn 版本号
export TF_NCCL_VERSION=                    #兼容老版本,1.13版本以后可以移除
export TMP="/home/tcheng/serving/tmp"      #编译所需 tmp 目录,请保证磁盘空间足够

cd serving && bazel build \
    --color=yes \
    --curses=yes \
    --config=cuda \
    --copt="-fPIC" \ 
    --verbose_failures \
    --output_filter=DONT_MATCH_ANYTHING \
    --config=nativeopt \
    --incompatible_disallow_data_transition=false \
    tensorflow_serving/model_servers:tensorflow_model_server

我所使用的 bazel 版本是0.23.1,tf-serving 版本为1.13,如上编译应该没有什么问题。编译成功之后的 modelserver 在 bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server目录下。ldd 可以查看编译结果的依赖,如果需要在别出使用,可以用 chrpath 工具修改 RUNPATH 到指定目录,将相关 so 拷贝到该目录即可使用。

4.记录编译过程中出过的一些问题:

* git clone 代码的时候需要recurse-submodules下载全部组件,否则在 bazel build 的时候会下载,慢不说还经常下载失败,提示`Premature EOF`
* bazel 版本更新可能会带来一些不兼容的情况,比如上面命令中的--incompatible_disallow_data_transition=false选项,在 docker file 中并未提到,可以根据编译出错的提示Using cfg = "data" on an attribute is a noop and no longer supported. Please remove it. You can use --incompatible_disallow_data_transition=false to temporarily disable this check,稍加搜索即可解决。