最近在研究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底層動態庫、硬件、容器等等相關的知識,雖然踩了很多坑,可是不少概念性的東西都獲得了實踐,這纔是工做最大的意義。