1. 什么是 Docker
解决 “在我的机器上可以正常工作,为什么在你的机器上不能工作” 的问题。
随着深度学习技术的飞速发展,各种深度学习框架都有大量的粉丝。如何在一台电脑上安装多个深度学习框架?同一深度学习框架的不同版本依赖于不同的GPU版本,但是一台服务器只可能安装唯一版本的GPU。当多名开发人员在统一服务器上使用不同的深度学习框架进行开发时,往往会产生环境冲突。最好的解决方案就是采用虚拟技术。
Docker 是世界领先的软件容器平台,也是目前最流行的 Linux 容器解决方案。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。而且 Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。和虚拟机相比,由于没有臃肿的从操作系统,Docker可以节省大量的磁盘空间以及其他系统资源。
虚拟机通常用于彻底隔离整个运行环境。例如,云服务提供商通常采用虚拟机技术隔离不同的用户。而Docker通常用于隔离不同的应用,例如前端,后端以及数据库。
2. 安装 Docker
(a) 安装依赖包
$ yum install -y yum-utils device-mapper-persistent-data
(b) 配置稳定仓库
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
(c) 安装(默认为最新版)
$ yum install docker-ce
(4) 修改docker运行时的根目录, 解决存储不足的问题
$ vim /lib/systemd/system/docker.service
# 在 ExecStart=/usr/bin/dockerd 后添加 --graph=/home/docker
$ ExecStart=/usr/bin/dockerd --graph=/home/docker
(5) 重新启动docker服务
$ systemctl daemon-reload
$ systemctl status docker
$ systemctl start docker
(7) 测试Docker是否正确安装
$ docker version
$ docker run hello-world
3. 安装 nvidia-docker
深度学习框架需要使用 GPU 加入计算,如果不安装 nvidia-docker 工具,那么在容器中将会无法调用宿主机上的 GPU 硬件设备。
(a) 移除旧版本 nvidia-GPU 和已经存在的 GPU 容器
$ docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
$ sudo yum remove nvidia-docker
(b) 安装依赖包
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ sudo tee /etc/yum.repos.d/nvidia-docker.repo
(c) 安装nvidia-docker
$ sudo yum install -y nvidia-docker2
$ sudo pkill -SIGHUP dockerd
(d) 测试 nvidia-docker 是否安装成功
docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
4. CUDA9-CUDNN7-python3.6 源码安装 Caffe、Caffe2、Tensorflow、 Detectron 和 Darknet
(a) 启动 GPU container 并登录
$ nvidia-docker run -tid --name TestMyGPU --net='host' nvidia/cuda:9.0-cudnn7-devel-centos7 /bin/bash # 启动容器
$ docker exec -it TestMyGPU /bin/bash # 登录容器
(b) 配置变量
$ export http_proxy=http://xx.xx.xx.xx:8080 # 设置网络
$ export https_proxy=https://xx.xx.xx.xx:8080
$ export PYINSTALL=/usr/local/python3 # 设置python3.6安装路径
$ export PATH=$PYINSTALL/bin:$PATH
(c) 安装 python3.6 和 Caffe,参照上一篇博客 Centos7 安装 Caffe
。
(d) 在 /home
下安装 Caffe2、Tensorflow、 Detectron 和 Darknet
# 安装依赖包和 opencv
$ yum install -y cmake3 && pip3 install cython opencv-python==3.4.2.16
# 安装 nccl,GPU分布式通信函数库
$ cd /home && git clone https://github.com/NVIDIA/nccl.git
$ cd nccl && make -j8 src.build CUDA_HOME='/usr/local/cuda-9.0/' NVCC_GENCODE="-gencode=arch=compute_70,code=sm_70"
$ yum install -y rpm-build rpmdevtools && make -j8 pkg.redhat.build && make install
$ echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib' >> /root/.bashrc
$ cd /home && rm -rf nccl && source ~/.bashrc
# 验证nccl是否安装成功
# cd /home && git clone https://github.com/NVIDIA/nccl-tests.git \
# cd nccl-tests && make -j8 && ./build/all_reduce_perf -b 8 -e 256M -f 2 -g 1 \
# cd /home && rm -rf nccl-tests
# 安装 darknet
$ cd /home && git clone https://github.com/pjreddie/darknet.git && cd darknet \
# 修改 Makefile 文件,令 GPU=1,CUDNN=1,OPENCV=1
$ sed -i 's/GPU=0/GPU=1/' Makefile
$ sed -i 's/CUDNN=0/CUDNN=1/' Makefile
$ sed -i 's/OPENCV=0/OPENCV=1/' Makefile
$ make -j32
# 验证 darknet 是否安装成功
# 执行 ./darknet 输出 usage: ./darknet <function>
# 安装 Tensorflow 和 Keras
$ cd /home && pip3 install tensorflow-gpu==1.10 keras==2.2.0
# 安装caffe2
$ pip3 install pyyaml future hypothesis pydot
$ cd /home && git clone https://github.com/pytorch/pytorch.git
$ cd pytorch && git submodule update --init --recursive
# 解决编译时 cmake 的版本问题:
# 将文件 `pytorch/tools/build_pytorch_libs.sh` 复制到 `/home` 路径下
# 修改./tools/build_pytorch_libs.sh 第31和32行 CMAKE_VERSION、CMAKE3_VERSION
# CMAKE_VERSION=$(cmake --version | grep 'version' | awk '{print $3}' | awk -F. '{print $1"."$2"."$3}')
# CMAKE3_VERSION=$(cmake3 --version | grep 'version' | awk '{print $3}' | awk -F. '{print $1"."$2"."$3}')
$ rm -f /home/pytorch/tools/build_pytorch_libs.sh
$ cp -f /home/build_pytorch_libs.sh /home/pytorch/tools/build_pytorch_libs.sh
$ rm -f /home/build_pytorch_libs.sh
$ python setup.py install
$ cd /home && rm -rf pytorch
验证 caffe2 是否安装成功, python 命令窗口执行
>>> import torch
>>> import caffe2
>>> exit()
验证是否能使用 GPU
$ cd /home && python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"
$ python -c 'from caffe2.python import workspace; print(workspace.NumCudaDevices())'
$ python /usr/local/anaconda3/lib/python3.6/site-packages/caffe2/python/operator_test/rnn_cell_test.py
安装 COCO-API
$ cd /home && git clone https://github.com/pdollar/coco
$ pip3 install setuptools==18.4 && yum install -y tkinter
$ cd coco/PythonAPI && make -j8 && make install && python setup.py install
$ cd /home && rm -rf coco
验证 coco-api 是否安装成功, python命令窗口执行
from pycocotools.coco import COCO
安装detectron
$ cd /home && git clone https://github.com/facebookresearch/detectron
$ cd detectron && make -j8
# 验证 detectron 是否正确安装
$ cd /home/detectron && python detectron/tests/test_spatial_narrow_as_op.py
$ python tools/infer_simple.py \
--cfg configs/12_2017_baselines/e2e_mask_rcnn_R-101-FPN_2x.yaml \
--output-dir tmp/detectron-visualizations \
--image-ext jpg \
--wts https://s3-us-west-2.amazonaws.com/detectron/35861858/12_2017_baselines/e2e_mask_rcnn_R-101-FPN_2x.yaml.02_32_51.SgT4y1cO/output/train/coco_2014_train:coco_2014_valminusminival/generalized_rcnn/model_final.pkl \
demo
5. 使用 Anaconda3 安装 Caffe、Pytorch 和 Tensorflow
Anaconda 是一个开源的Python发行版本,包含了conda、Python等180多个科学包及其依赖项,是当前最流行的 Python 数据科学开发平台。 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用 Miniconda 发行版 ( 仅包含 conda 和 Python )。
Anaconda 当前集成了 caffe 和 pytorch,可以利用 Anaconda 快速安装 caffe 和 caffe2 ( 集成在 pytorch ) 中。由于 Docker 容器需要应用程序占用内存尽可能小,因此采用 Miniconda 代替 Anaconda。完成的 Dockerfile 文件如下,在宿主机中含有 Dockfile
文件的当前路径下运行 docker build -t deep_learning_environment:v0.1 .
即可生成满足深度学习环境对应要求的镜像。
FROM nvidia/cuda:9.0-cudnn7-runtime-centos7
ENV LANG=en_US.UTF-8
ARG http_proxy=http://xx.xx.xx.xx:8080
ARG https_proxy=https://xx.xx.xx.xx:8080
# 安装Miniconda3
RUN cd /home \
# 安装依赖包
&& yum install -y epel-release-7-11.noarch wget git make bzip2 && pip install cython \
# 安装nccl
&& cd /home && git clone https://github.com/NVIDIA/nccl.git \
&& cd nccl && make -j8 src.build CUDA_HOME='/usr/local/cuda-9.0/' NVCC_GENCODE="-gencode=arch=compute_70,code=sm_70" \
&& yum install -y rpm-build rpmdevtools && make -j8 pkg.redhat.build && make install \
&& echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/nccl/build/lib' >> /root/.bashrc \
&& cd /home && rm -rf nccl && source ~/.bashrc \
# 验证nccl是否安装成功
# cd /home && git clone https://github.com/NVIDIA/nccl-tests.git \
# cd nccl-tests && make -j8 && ./build/all_reduce_perf -b 8 -e 256M -f 2 -g 1 \
# cd /home && rm -rf nccl-tests
&& wget https://repo.anaconda.com/miniconda/Miniconda3-4.3.30-Linux-x86_64.sh \
&& bash Miniconda3-4.3.30-Linux-x86_64.sh -p /usr/local/miniconda3 -b \
# 将 miniconda 添加到系统路径
&& echo 'export PATH=/usr/local/miniconda3/bin:$PATH' >> /root/.bashrc \
&& echo 'export LD_LIBRARY_PATH=/usr/local/miniconda3/lib:$LD_LIBRARY_PATH' >> /root/.bashrc \
&& source ~/.bashrc && rm -rf Miniconda3-4.3.30-Linux-x86_64.sh \
# 修改yum的链接问题
&& ln -s -f /usr/lib64/liblzma.so.5 /usr/local/miniconda3/lib/liblzma.so.5 \
# conda 安装 caffe-gpu
&& conda install -y caffe-gpu protobuf \
# conda 安装 caffe2
# 直接安装下载速度非常慢,而且有可能失败
&& conda install -y pytorch-nightly -c pytorch \
&& pip install future hypothesis pydot \
# 验证 caffe 和 caffe2 是否安装成功
# $ python && import torch && import caffe && import caffe2
# python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"
# python -c 'from caffe2.python import workspace; print(workspace.NumCudaDevices())'
# python /usr/local/anaconda3/lib/python3.6/site-packages/caffe2/python/operator_test/rnn_cell_test.py
# 安装 detectron
&& cd /home && git clone https://github.com/facebookresearch/detectron \
&& cd detectron && pip install cython && make -j8 \
# 验证 detectron 是否安装正确
# cd /home/detectron && python detectron/tests/test_spatial_narrow_as_op.py
# 安装darknet, 从 github 上下载darknet源码, 修改 Makefile 文件,令 GPU=1,CUDNN=1,OPENCV=1。
&& cd /home && git clone https://github.com/pjreddie/darknet.git && cd darknet \
&& sed -i 's/GPU=0/GPU=1/' Makefile \
&& sed -i 's/CUDNN=0/CUDNN=1/' Makefile \
&& sed -i 's/OPENCV=0/OPENCV=1/' Makefile \
&& make -j8 \
# 验证 darknet 是否安装成功
# 执行 ./darknet 输出 usage: ./darknet <function>
# 安装tensorflow和keras
&& cd /home && pip install tensorflow-gpu==1.10 keras==2.2.0 -i https://pypi.douban.com/simple/ \
# 验证 tensorflow 和 keras 是否安装成功
# $ python && import tensorflow && import keras
# 删除 minicond3/pkgs 里面的安装包, 降低内存占用
&& cd /usr/local/miniconda3/ && rm -rf pkgs