用GPU和Docker搭建高效靈活的深度學習研發平臺
給資料科學家提供最好的工作工具是非常困難的。他們的電腦上幾乎需要有所有的功能,如極致的效能,最新的軟體,以及隨心所欲的試驗。
我們為此開發了一套滿足上述所有需求的方案,並且避免了經常困擾系統管理員和開發團隊構建系統的重複性勞動。
tl;dr - 環境建立程式碼已經上傳至Github上。
它目前仍然是完善中的實驗品,但是已經可以工作。因為它的許多工具目前都還在軟體生存週期的早期,所以它日後會越來越好。
告別雲
對於計算密集型業務,公有云的託管費用高的令人望而卻步。一個AWS上高效能的跑在GPU上的虛擬機器大概要超過正常價格20倍的費用,以日計費會更貴。年費大約是25,000美元。
內部部署的虛擬伺服器會相對便宜點,但是並沒有對這些科學計算的用例而針對性調整,並且也不是共享環境友好的。
當然,還有其他一些問題… …
你好,老朋友
你身邊的伺服器又回來了,並且比以往更好。Nvidia在2015年釋出了“Dev Box”,一種資料科學家的夢想機器。雖然它有一點點小貴,大概15,000美元。
Andrej Karpathy 建立了一個相對完美並且廉價的家庭套裝。並且它可以擴充套件到和Nvidia的機器同樣的效能。我們的產品相當類似,並且給它找了個好地方,就在桌子的右下角。
開發即產品
現在你已經有了合適的硬體。然後你可以參照Nvidia的指示文件來安裝和配置所需的所有軟體。接下來花上幾個小時手工處理軟體包和相互依賴性上。它工作很完美,但是這對系統管理員是個噩夢,因為它是完全定製化的。
你用這個機器的時間越長,你就越難以去重建它。假如它宕機了,或者是你需要做大的版本升級,或者是你需要建立多個一次性使用的臨時方案。
停機時間是你的敵人,但是你引入了一個醜陋的故障點,並且無法享受全自動構建的所有益處。
解決方案
第一步:構建Vanilla CoreOS
假設你已經得到了合適的硬體,然後按照已經驗證的快速入門指南之一構建你的裸機。CoreOS支援PXE(無盤工作站),iPXE或者是有盤工作站。選擇其中任何適合你的方案即可。我們的方案選擇的是PXE構建我們的CoreOS系統
第二步:安裝CUDA驅動以及Nvidia的裝置-一次性操作
克隆Github上的es-dev-stack
$ git clone http://github.com/emergingstack/es-dev-stack.git
Docker映象編譯(大概會花費30分鐘時間,需要下載大約2.5G的資料)
$ cd es-dev-stack/corenvidiadrivers
$ docker build -t cuda .
編譯完成之後,假如這個映象非常好使,你可能會想要把這個映象推送到Docker的registry。從而方便你將來基於這個映象編譯其他的映象。Dockerfile的示例如下:
FROM ubuntu:14.04
MAINTAINER Mike Orzel <mike.orzel@emergingstack.com>
RUN apt-get -y update && apt-get -y install git bc make dpkg-dev && mkdir -p /usr/src/kernels && mkdir -p /opt/nvidia/nvidia_installers
ADD http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.28_linux.run /opt/nvidia/
WORKDIR /usr/src/kernels
RUN git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux
WORKDIR linux
RUN git checkout -b stable v`uname -r` && zcat /proc/config.gz > .config && make modules_prepare
RUN sed -i -e "s/`uname -r`+/`uname -r`/" include/generated/utsrelease.h # In case a '+' was added
# Nvidia drivers setup
WORKDIR /opt/nvidia/
RUN chmod +x cuda_7.0.28_linux.run && ./cuda_7.0.28_linux.run -extract=`pwd`/nvidia_installers
WORKDIR /opt/nvidia/nvidia_installers
RUN ./NVIDIA-Linux-x86_64-346.46.run -a -x --ui=none
RUN sed -i "s/read_cr4/__read_cr4/g" NVIDIA-Linux-x86_64-346.46/kernel/nv-pat.c
RUN sed -i "s/write_cr4/__write_cr4/g" NVIDIA-Linux-x86_64-346.46/kernel/nv-pat.c
CMD ./NVIDIA-Linux-x86_64-346.46/nvidia-installer -q -a -n -s --kernel-source-path=/usr/src/kernels/linux/ && insmod /opt/nvidia/nvidia_installers/NVIDIA-Linux-x86_64-346.46/kernel/uvm/nvidia-uvm.ko
現在執行CUDA的Docker容器
# docker run -it --privileged cuda
確認Nvidia的驅動已經安裝
# lsmod
你應該能看到幾個名為‘Nvidia’的專案已經安裝
安裝裝置
在root下執行‘mkdevs’指令碼來建立裝置
# ./mkdevs.sh
確認Nvidia的裝置已經安裝
# cd /dev
# ls -al | grep -i "nvidia"
現在你應該能夠看到如下的裝置已經存在並準備好對映入Docker的容器
crw-rw-rw- 1 root root 247, 0 Jan 4 05:54 nvidia-uvm
crw-rw-rw- 1 root root 195, 0 Jan 4 05:54 nvidia0
crw-rw-rw- 1 root root 195, 1 Jan 4 05:54 nvidia1
crw-rw-rw- 1 root root 195, 255 Jan 4 05:54 nvidiactl
至此一切完畢。
現在你應該就可以開始使用幾乎一成不變的系統,從而享受容器化帶來的益處。請注意,這裡我們使用的是特權模式來對映GPU裝置到Docker容器,這從共享主機模式角度是一個不安全的方式。
第三步:基於Google TensorFlow的測試案例
警告:這個Dockerfile的編譯產生的Docker映象超過10GB,大概會需要30-40分鐘來生成。
這裡我們已經添加了一個Jupyter的筆記到Docker映象來驗證GPU功能正常。這是個基本的基於TensorFlow的ConvNet,並足以驗證效果。
Docker映象構建如下:
$ cd es-dev-stack/tflowgpu
$ docker build -t tflowgpu .
Dockerfile如下:
FROM b.gcr.io/tensorflow/tensorflow:latest-gpu
MAINTAINER Mike Orzel <mike.orzel@emergingstack.com>
# Add some dependent packages we will need for the build process
RUN apt-get -y update && apt-get -y install git bc make dpkg-dev && mkdir -p /usr/src/kernels && mkdir -p /opt/nvidia/nvidia_installers
# Download the nvidia cuda package
ADD http://developer.download.nvidia.com/compute/cuda/7_0/Prod/local_installers/cuda_7.0.28_linux.run /opt/nvidia/
RUN chmod +x /opt/nvidia/cuda_7.0.28_linux.run
# download the linux kernel source and prepare it for use
WORKDIR /usr/src/kernels
RUN git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux
WORKDIR linux
RUN git checkout -b stable v`uname -r` && zcat /proc/config.gz > .config && make modules_prepare
RUN sed -i -e "s/`uname -r`+/`uname -r`/" include/generated/utsrelease.h # In case a '+' was added
RUN sed -i -e "s/`uname -r`+/`uname -r`/" include/config/kernel.release # In case a '+' was added
# Nvidia drivers setup
WORKDIR /opt/nvidia/
RUN chmod +x cuda_7.0.28_linux.run && ./cuda_7.0.28_linux.run -extract=`pwd`/nvidia_installers
WORKDIR /opt/nvidia/nvidia_installers
RUN ./NVIDIA-Linux-x86_64-346.46.run -a -x --ui=none
RUN sed -i "s/read_cr4/__read_cr4/g" NVIDIA-Linux-x86_64-346.46/kernel/nv-pat.c
RUN sed -i "s/write_cr4/__write_cr4/g" NVIDIA-Linux-x86_64-346.46/kernel/nv-pat.c
RUN ./NVIDIA-Linux-x86_64-346.46/nvidia-installer -q -a -n -s --kernel-source-path=/usr/src/kernels/linux/ --no-kernel-module
# install modules to expected location, cuda will do modprobes in certain situations which require this
WORKDIR /usr/src/kernels/linux
RUN make modules && make modules_install
RUN mv /lib/modules/`uname -r`+ /lib/modules/`uname -r`
WORKDIR /opt/nvidia/nvidia_installers
RUN depmod
# Run jupyter notebook and create a folder for the notebooks
RUN chmod +x /run_jupyter.sh
RUN mkdir /examples
WORKDIR /examples
COPY CNN.ipynb /examples/CNN.ipynb
CMD /run_jupyter.sh
執行TensorFlow的Docker容器
下面這個‘docker run’命令會對映新安裝的GPU裝置到TensorFlow容器中。詳細命令如下:
$ docker run --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidia1:/dev/nvidia1 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm -it -p 8888:8888 --privileged tflowgpu
開啟瀏覽器並訪問Jupyter如下:http://{your dev box IP}:8888,並跑幾個例項。Nvidia Titan X上的效能測試應該比Intel i7 CPU快了十倍不止。
現在就開始使用es-dev-stack,也非常歡迎貢獻你的版本。本解決方案的靈感來源於以下幾個社群,在此感謝:
在文下一篇章,我們將會演示如何容器化的Spark環境和Kubernetes整合的潛力(依賴於標準 issue 19049的狀態)
責編,魏偉,關注Docker,尋求報道和投稿,請聯絡郵箱[email protected]