最近在研究Tensorflow Serving生产环境部署,尤为是在作服务器GPU环境部署时,遇到了很多坑。特地总结一下,当作前车可鉴。html
系统是ubuntu16.04python
ubuntu@ubuntu:/usr/bin$ cat /etc/issue Ubuntu 16.04.5 LTS \n \l
或者linux
ubuntu@ubuntu:/usr/bin$ uname -m && cat /etc/*release x86_64 DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.5 LTS" NAME="Ubuntu" VERSION="16.04.5 LTS (Xenial Xerus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 16.04.5 LTS" VERSION_ID="16.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" VERSION_CODENAME=xenial UBUNTU_CODENAME=xenial
显卡是Tesla的P40git
ubuntu@ubuntu:~$ nvidia-smi Thu Jan 3 16:53:36 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 384.130 Driver Version: 384.130 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla P40 Off | 00000000:3B:00.0 Off | 0 | | N/A 34C P0 49W / 250W | 22152MiB / 22912MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 108329 C python 4963MiB | | 0 133840 C tensorflow_model_server 17179MiB | +-----------------------------------------------------------------------------+
TensorFlow则是当下最新的1.12.0版本。github
在介绍如何部署以前,先来了解一下相关的概念。web
参考资料算法
TensorFlow Serving是google提供的一种生产环境部署方案,通常来讲在作算法训练后,都会导出一个模型,在应用中直接使用。docker
正常的思路是在flask这种web服务中嵌入tensorflow的模型,提供rest api的云服务接口。考虑到并发高可用性,通常会采起多进程的部署方式,即一台云服务器上同时部署多个flask,每一个进程独享一部分GPU资源,显然这样是很浪费资源的。json
Google提供了一种生产环境的新思路,他们开发了一个tensorflow-serving的服务,能够自动加载某个路径下的全部模型,模型经过事先定义的输入输出和计算图,直接提供rpc或者rest的服务。flask
所以,整个模型的调用方式就变成了:
客户端 ----> web服务(flask或者tornado) --grpc或者rest--> tensorflow serving
若是咱们想要替换模型或者更新版本,只须要训练模型并将训练结果保存到固定的目录下就能够了。
参考资料:
docker简单来讲就是一种容器技术,若是有作过技术支持的朋友确定了解安装软件的痛苦——各类系统环境,致使各类安装报错...docker解决的问题就是,只要你再服务器上安装上docker,那么它会自动屏蔽全部的硬件信息,拉取一个镜像,就能直接启动提供服务。
搭建docker也很简单,若是是mac直接下载dmg文件就能够双击运行;若是是ubuntu直接运行
sudo apt-get install docker
不过Ubuntu安装后只能经过root使用,若是想让其余用户使用,须要调整docker组,细节百度一下便可。
经常使用的命令也比较少:
# 查看当前部署的服务 docker ps # 运行一个容器服务 docker run # 删除一个服务 docker kill xxx
参考资料:
由于docker是虚拟在操做系统之上的,屏蔽了不少底层的信息。若是想使用显卡这种硬件,一种思路是docker直接把操做系统上的驱动程序和算法库映射到容器内,可是这样就丧失了可移植性。
另外一种方法就是在docker启动的时候挂载一个相似驱动的插件——这就是nvidia-docker的做用。
总的来讲,若是想要在docker中使用tensorflow-gpu,须要首先安装docker-ce(社区版,其余版本nvidia-docker不必定支持),而后安装nvidia-container-runtime,最后安装nvidia-docker2。
当使用的时候,须要直接指定nvidia-docker2运行, 如:
sudo nvidia-docker run -p 8500:8500 --mount type=bind,source=/home/ubuntu/data/east_serving/east_serving,target=/models/east -e MODEL_NAME=east -t tensorflow/serving:1.12.0-gpu &
下面就进入部署的实战篇了:
主要参考:
首先安装docker-ce:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo apt-key fingerprint 0EBFCD88 sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt-get update sudo apt-get install docker-ce sudo service docker restart
若是以前安装了nvidia-docker1须要删除掉:
docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f sudo apt-get purge -y nvidia-docker
修改docker的镜像地址vi /etc/docker/daemon.json
:
{ "registry-mirrors":["https://registry.docker-cn.com","http://hub-mirror.c.163.com"] }
而后重启docker配置服务systemctl restart docker.service
。
更新nvidia-docker地址:
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update
执行安装命令:
sudo apt-get install -y nvidia-docker2 sudo pkill -SIGHUP dockerd
测试:
ubuntu@ubuntu:~$ sudo nvidia-docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi Thu Jan 3 09:52:06 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 384.130 Driver Version: 384.130 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla P40 Off | 00000000:3B:00.0 Off | 0 | | N/A 35C P0 49W / 250W | 22152MiB / 22912MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| +-----------------------------------------------------------------------------+
能够看到,已经能再docker内部看到显卡的使用信息了。
在docker容器外,执行nvidia-smi
能够看到有个tensorflow serving的服务
ubuntu@ubuntu:~$ nvidia-smi Thu Jan 3 17:52:43 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 384.130 Driver Version: 384.130 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla P40 Off | 00000000:3B:00.0 Off | 0 | | N/A 35C P0 49W / 250W | 22152MiB / 22912MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | 0 108329 C python 4963MiB | | 0 133840 C tensorflow_model_server 17179MiB | +-----------------------------------------------------------------------------+
注意正常须要配置docker占用的显存比例!
搞深度学习仍是须要全栈基础的,涉及到各类linux底层动态库、硬件、容器等等相关的知识,虽然踩了很多坑,可是不少概念性的东西都获得了实践,这才是工做最大的意义。