天天看點

深度學習Tensorflow生産環境部署(上·環境準備篇)

最近在研究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技術架構
  • tensorflow serving使用教程
深度學習Tensorflow生産環境部署(上·環境準備篇)

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實戰
深度學習Tensorflow生産環境部署(上·環境準備篇)

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

  • nvidia-docker github官網
深度學習Tensorflow生産環境部署(上·環境準備篇)

因為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部署

主要參考:

  • 1 nvidia-docker2-deploy-ubuntu-16.04LTS.md
  • 2 nvidia-docker github官網

首先安裝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底層動态庫、硬體、容器等等相關的知識,雖然踩了不少坑,但是很多概念性的東西都得到了實踐,這才是工作最大的意義。

作者:xingoo

出處:http://www.cnblogs.com/xing901022

本文版權歸作者和部落格園共有。歡迎轉載,但必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接!

繼續閱讀