搭建深度学习的 docker 环境

介绍

深度学习一般依赖比较复杂的环境,每个项目需要的底层库各有不同,有时在 github 中下载的代码只能运行在版本较低的的工具链之上。想在一台机器上建立适合所有项目的环境非常困难,大多数情况下使用 docker 维护不同项目针对的不同环境。

CUDA 是 NVIDIA 推出的运算平台,一般通过它调用 GPU,CUDA 的主要版本有 7.x, 8.x,9.x,10.x,目前最常用的是 9 和 10,它们对接的上层软件版本也各不相同。如:

1
2
3
4
torch 1.1.0/1.1.0 + torchvision 0.2.* + CUDA 9
torch 1.2.0/1.3.0 + torchvision 0.3.* + CUDA 10
torch 1.2.0/1.3.0 + torchvision 0.4.* + CUDA 10
torch 1.4.0 + torchvision 0.5.* + CUDA 10

除了 CUDA 基础库以外,还需安装相关工具包。可以在同一个操作系统中安装多个 CUDA 版本,使用时切换即可。

在 Docker 中使用 GPU 除了在 Docker 内部安装 CUDA 及相关工具以外,还需要使用 nvidia-docker 启动镜像,并且要在宿主机上安装 CUDA 的底层支持(注意版本兼容)。

###宿主机安装 Nvidia 驱动

1
2
3
4
5
6
7
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt-get update
$ sudo ubuntu-drivers devices # 查看当前显卡及推荐的驱动
$ sudo apt-get install nvidia-driver-435 # 选择其中一个推荐安装,尽量安装较高版本
$ sudo apt install nvidia-utils-435 # nvidia-smi支持(查看显卡信息)
$ sudo apt install nvidia-cuda-toolkit # nvcc支持(nv环境下的C语言编译器,注意:这个包比较大,一般在docker里使用,在宿主机不一定非要安装)
$ sudo reboot

(后来再安装的时候,有时 nvidia-cuda-toolkit 和 nvidia-utils-435 冲突)

重启之后,使用 nvidia-smi 命令即可看到机器上的显卡及当前使用情况:

安装支持 CUDA 的 Docker 工具

安装 Docker

1
2
3
4
5
6
7
8
9
10
11
12
# 安装系统工具
$ sudo apt-get update
$ sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 安装GPG证书
$ curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 写入软件源信息
$ sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu (lsb_release -cs) stable"
# 着情修改, 具体形如
$ sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu jammy stable"
# 更新并安装 Docker-CE
$ sudo apt-get -y update
$ sudo apt-get -y install docker-ce

安装 Nvidia-docker2

1
2
3
4
5
6
7
8
9
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/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
$ sudo docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi # 测试

测试时自动从网上下载镜像 nvidia/cuda,该镜像大小为 2.83G,只包含基本的 9.1 版本的 CUDA 环境,不含 Python 相关工具。

###推荐 Docker 镜像

目前最常用的是 CUDA 9.x 和 CUDA 10.x,推荐下面两个镜像。下载方法:

1
2
$ docker pull registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:1.1.0-cuda10.0-py3
$ docker pull registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:latest-cuda9.0-py3

运行方法:

1
$ nvidia-docker run --rm -it registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:latest-cuda9.0-py3 bash

它们的大小分别是 4.17G 和 3.56G,以 cuda-10.0 版本为例,其内部为 Ubuntu 16.04 系统,可使用 apt-get 安装软件,其 Python 版本为 3.6.5。pytorch 版本为 1.0.0。

在 Docker 中使用 Jupyter 开发

在 pytorch:1.1.0-cuda10.0-py3 的基础上安装 jupyter 开发环境:

在当前目录下创建 Dockerfile,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM registry.cn-shanghai.aliyuncs.com/tcc-public/pytorch:1.1.0-cuda10.0-py3
ADD . /
RUN mkdir ~/.pip \
&& echo "[global]\nindex-url = https://mirrors.aliyun.com/pypi/simple/" > ~/.pip/pip.conf
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
RUN apt-get clean
RUN apt-get update -y
RUN pip install jupyter

ENV PASSWORD=123456
ENV CONFIG_PATH="/root/.jupyter/jupyter_notebook_config.py"
COPY "jupyter_notebook_config.py" ${CONFIG_PATH}
WORKDIR /notebooks/
#CMD ["sh", "run.sh"]

在当前目录下创建 jupyter 配置文件 jupyter_notebook_config.py,用于设置密码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
from IPython.lib import passwd
# c = c # pylint:disable=undefined-variable
c = get_config()
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.port = int(os.getenv('PORT', 8888))
c.NotebookApp.open_browser = False
# sets a password if PASSWORD is set in the environment
if 'PASSWORD' in os.environ:
password = os.environ['PASSWORD']
if password:
c.NotebookApp.password = passwd(password)
else:
c.NotebookApp.password = ''
c.NotebookApp.token = ''
del os.environ['PASSWORD']

创建名为 test:0.1 的 Docker 镜像:

1
$ sudo docker build . -t test:0.1

启动方法

1
$ sudo nvidia-docker run --rm -v 宿主机目录:docker内部目录 -p 8891:8888 -it test:0.1 jupyter notebook --allow-root -y --no-browser --ip=0.0.0.0 --config=/root/.jupyter/jupyter_notebook_config.py

此时,用网络上任意一台机器可以访问 docker 启动的 jupyter 环境:http://宿主机 IP 地址:8891

天池竞赛上传镜像

下面为参加阿里天池大数据比赛时上传镜像的方法:

登录阿里云:https://www.aliyun.com/product/acr?

进镜像仓库:https://cr.console.aliyun.com/cn-shanghai/instances/repositories

具体流程见:https://tianchi.aliyun.com/competition/entrance/231759/tab/174?spm=5176.12586973.0.0.547d780b0Cgnoh

创建一个镜像仓库,复制其公网地址。

在本地登录

1
$ sudo docker login --username=您的用户名 registry.cn-shenzhen.aliyuncs.com

上传镜像

1
2
$ sudo docker tag test:0.1 公网地址
$ sudo docker push 公网地址

问题及解决

问题一:安装证书报错

问题:运行 $ sudo add-apt-repository ppa:graphics-drivers/ppa,报错:Cannot add PPA: 'ppa:~graphics-drive/ubuntu/ppa'. ERROR:'~graphics-drive' user or team does not exist.

解决:CA 证书损坏,可以通过命令 sudo apt-get install --reinstall ca-certificates 修复。

问题二:显卡支持问题

问题:查看 NVIDIA 驱动版本:$ sudo dpkg --list | grep nvidia-* 时没有显示

解决:查看 GPU 型号:$ lspci| grep -i nvidia 自动安装驱动:$ sudo ubuntu-drivers autoinstall

(感谢 sfthejia@buu.edu.cn 反馈的问题及解决方法)