最近在研究Tensorflow Serving生产环境部署,尤其是在做服务器GPU环境部署时,遇到了不少坑。特意总结一下,当做前车之鉴。

1 系统背景

系统是ubuntu16.04

ubuntu@ubuntu:/usr/bin$ cat /etc/issue
Ubuntu 16.04.5 LTS \n \l

或者

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的P40

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版本。

2 背景知识

在介绍如何部署之前,先来了解一下相关的概念。

2.1 TensorFlow Serving

参考资料

TensorFlow Serving是google提供的一种生产环境部署方案,一般来说在做算法训练后,都会导出一个模型,在应用中直接使用。

正常的思路是在flask这种web服务中嵌入tensorflow的模型,提供rest api的云服务接口。考虑到并发高可用性,一般会采取多进程的部署方式,即一台云服务器上同时部署多个flask,每个进程独享一部分GPU资源,显然这样是很浪费资源的。

Google提供了一种生产环境的新思路,他们开发了一个tensorflow-serving的服务,可以自动加载某个路径下的所有模型,模型通过事先定义的输入输出和计算图,直接提供rpc或者rest的服务。

  • 一方面,支持多版本的热部署(比如当前生产环境部署的是1版本的模型,训练完成后生成一个2版本的模型,tensorflow会自动加载这个模型,停掉之前的模型)。
  • 另一方面,tensorflow serving内部通过异步调用的方式,实现高可用,并且自动组织输入以批次调用的方式节省GPU计算资源。

因此,整个模型的调用方式就变成了:

客户端 ----> web服务(flask或者tornado) --grpc或者rest--> tensorflow serving

如果我们想要替换模型或者更新版本,只需要训练模型并将训练结果保存到固定的目录下就可以了。

2.2 Docker

参考资料:

docker简单来说就是一种容器技术,如果有做过技术支持的朋友肯定了解安装软件的痛苦——各种系统环境,导致各种安装报错...docker解决的问题就是,只要你再服务器上安装上docker,那么它会自动屏蔽所有的硬件信息,拉取一个镜像,就能直接启动提供服务。

搭建docker也很简单,如果是mac直接下载dmg文件就可以双击运行;如果是ubuntu直接运行

sudo apt-get install docker

不过Ubuntu安装后只能通过root使用,如果想让其他用户使用,需要调整docker组,细节百度一下即可。

常用的命令也比较少:

# 查看当前部署的服务
docker ps
# 运行一个容器服务
docker run
# 删除一个服务
docker kill xxx

2.3 Nvidia-docker

参考资料:

因为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 &

3 部署实战

下面就进入部署的实战篇了:

3.1 Docker\Nvidia-Docker、Tensorflow部署

主要参考:

首先安装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占用的显存比例!

4 总结

搞深度学习还是需要全栈基础的,涉及到各种linux底层动态库、硬件、容器等等相关的知识,虽然踩了不少坑,但是很多概念性的东西都得到了实践,这才是工作最大的意义。

深度学习Tensorflow生产环境部署(上·环境准备篇)的更多相关文章

  1. 深度学习Tensorflow生产环境部署(下·模型部署篇)

    前一篇讲过环境的部署篇,这一次就讲讲从代码角度如何导出pb模型,如何进行服务调用. 1 hello world篇 部署完docker后,如果是cpu环境,可以直接拉取tensorflow/servin ...

  2. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

  3. 深度学习-tensorflow学习笔记(2)-MNIST手写字体识别

    深度学习-tensorflow学习笔记(2)-MNIST手写字体识别超级详细版 这是tf入门的第一个例子.minst应该是内置的数据集. 前置知识在学习笔记(1)里面讲过了 这里直接上代码 # -*- ...

  4. 深度学习---tensorflow简介

    个core可以有不同的代码路径.对于反向传播算法来说,基本计算就是矩阵向量乘法,对一个向量应用激活函数这样的向量化指令,而不像在传统的代码里会有很多if-else这样的逻辑判断,所以使用GPU加速非常 ...

  5. 深度学习Tensorflow相关书籍推荐和PDF下载

    深度学习Tensorflow相关书籍推荐和PDF下载 baihualinxin关注 32018.03.28 10:46:16字数 481阅读 22,673 1.机器学习入门经典<统计学习方法&g ...

  6. 深度学习入门者的Python快速教程 - 基础篇

      5.1 Python简介 本章将介绍Python的最基本语法,以及一些和深度学习还有计算机视觉最相关的基本使用. 5.1.1 Python简史 Python是一门解释型的高级编程语言,特点是简单明 ...

  7. 深度学习动手入门:GitHub上四个超棒的TensorFlow开源项目

    作者简介:akshay pai,数据科学工程师,热爱研究机器学习问题.Source Dexter网站创办人. TensorFlow是Google的开源深度学习库,你可以使用这个框架以及Python编程 ...

  8. 【深度学习笔记】Anaconda及开发环境搭建

    在学习了一段时间台大李宏毅关于deep learning的课程,以及一些其他机器学习的书之后,终于打算开始动手进行一些实践了. 感觉保完研之后散养状态下,学习效率太低了,于是便想白天学习,晚上对白天学 ...

  9. AI学习---深度学习&TensorFlow安装

    深度学习   深度学习学习目标: 1. TensorFlow框架的使用 2. 数据读取(解决大数据下的IO操作) + 神经网络基础 3. 卷积神经网络的学习 + 验证码识别的案例   机器学习与深度学 ...

随机推荐

  1. 解决在vscode中eslint在vue后缀文件中保存时无法自动格式化的问题

    在setting.json中加入如下内容 { "eslint.autoFixOnSave": true, "eslint.validate": [ " ...

  2. 《剑指Offer》第20题(Java实现):定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

    一.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 二.思路解析 首先定义一个Integer类型的栈,记为stack,此栈用来完成数据 ...

  3. SQL Server 异常解决:语句被终止。完成执行语句前已用完最大递归 100。

    问题出现业务场景: 我司有个缺料分析报表,有一个字段是适用机种,需要通过BOM递归读取顶层父物料.这个错就是缺料分析报表执行时报的错: 原因分析定位: 通过网上一些资料,猜测应该是某个递归查询语句,遇 ...

  4. win10无法访问服务器上的共享文件夹怎么设置,提示:你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问

    此问题需要修改Win10 网络策略 按window+R键输入gpedit.msc 来启动本地组策略编辑器. 依次找到“计算机配置-管理模板-网络-Lanman工作站”这个节点,在右侧内容区可以看到“启 ...

  5. 设计模式学习心得<适配器 Adapter>

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能. 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接 ...

  6. 分布式一致性的基石---Paxos算法(1)

    分布式一致性的基石---Paxos算法(1) Paxos算法是由微软的工程师Lamport提出,Lamport依靠Paxos算法获得图灵奖: Paxos算法旨在解决相互信任的分布式系统中,多个节点能快 ...

  7. gambit软件license文件

    最近自己的gambit软件license文件已经到期,后面采用fluent的license文件后,可以使用,但不能导入文件.不过通过努力,终于找到了可以实现导入文件的代码,并且可以实现无限期的使用fl ...

  8. 茶杯头开枪ahk代码

    ;说明这个工具是为了茶杯头写的,F1表示换枪攻击,F3表示不换枪攻击,F2表示停止攻击. $F1::loop{ GetKeyState, state, F2, Pif state = D{break ...

  9. 初识“FireBug”

    今天学习前端知识又一次提到“FireBug”这款插件,现在,把今天学到的一点东西简单记录下来. 什么是FireBug FireBug是一个用于网站前端开发的工具,它是FireFox浏览器的一个扩展插件 ...

  10. C#将结构体和指针互转的方法

    . 功能及位置 将数据从托管对象封送到非托管内存块,属于.NET Framework 类库 命名空间:System.Runtime.InteropServices 程序集:mscorlib(在 msc ...