Linux+Docker深度学习环境

Docker中搭建深度学习环境

宿主机部分

apt源修改:

1
2
3
4
5
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak

lsb_release -c # 系统版本

sudo vim /etc/apt/sources.list

写入

1
2
3
4
5
6
7
8
9
10
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
1
2
sudo apt-get update
sudo apt-get upgrade

安装python和pip

1
2
apt-get install python3
apt-get install python3-pip

配置软连接

1
2
ln -s /usr/local/python3/bin/python3 /usr/bin/python3
ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
1
2
3
4
5
6
7
8
9
mkdir ~/.pip
cd ~/.pip
touch pip.conf
cat >> ~/.pip/pip.conf << EOF
[global]
timeout = 6000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
EOF

查询CUDA,按照官网指示安装,可选择不同方法,local或者network等

注意!!

云主机上安装cuda时,可能需要加上 --no-opengl-libs

查询驱动版本:可手动下载安装包到本地安装

首先卸载掉之前的显卡驱动:

1
apt-get remove –purge nvidia*

也可使用命令查看推荐驱动

1
ubuntu-drivers devices
1
sudo apt install --no-install-recommends <推荐驱动>

下载不了可添加ppa

1
2
3
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt install <推荐驱动>

之前安装过cuda需要重新安装的话可以选择先卸载,以免和新的 CUDA 版本产生冲突:

/usr/local/cuda/bin 目录下有一个 uninstallcuda*.pl 文件

1
./uninstall_cuda_10.0.pl

可能会卸载不干净, 可以再执行命令删除cuda目录

1
2
rm -rf /usr/bin/cuda
rm -rf /usr/bin/cuda-10.0

查询下载cudnn

解压下载的文件,可以看到cuda文件夹,在当前目录打开终端,执行如下命令:

1
2
3
4
5
cp cuda/include/cudnn.h /usr/local/cuda/include/
cp cuda/lib64/libcudnn* /usr/local/cuda/lib64/

chmod a+r /usr/local/cuda/include/cudnn.h
chmod a+r /usr/local/cuda/lib64/libcudnn*

网络下载速度快也可以参考tensorflow官网的教程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# https://www.tensorflow.org/install/gpu#install_cuda_with_apt
# Add NVIDIA package repositories
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804_10.1.243-1_amd64.deb
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
sudo apt-get update
wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt install ./nvidia-machine-learning-repo-ubuntu1804_1.0.0-1_amd64.deb
sudo apt-get update

# Install NVIDIA driver
sudo apt-get install --no-install-recommends nvidia-driver-418 # 可更改为推荐版本
# Reboot. Check that GPUs are visible using the command: nvidia-smi

# Install development and runtime libraries (~4GB)
sudo apt-get install --no-install-recommends --no-opengl-libs \
cuda-10-1 \
libcudnn7=7.6.4.38-1+cuda10.1 \
libcudnn7-dev=7.6.4.38-1+cuda10.1

# 执行inference加速的服务器安装,也可开发调试
# Install TensorRT. Requires that libcudnn7 is installed above.
sudo apt-get install -y --no-install-recommends libnvinfer6=6.0.1-1+cuda10.1 \
libnvinfer-dev=6.0.1-1+cuda10.1 \
libnvinfer-plugin6=6.0.1-1+cuda10.1

云主机挂载新分区

查看是否有多余的盘比如/dev/vdb

1
fdisk -l

如果有则进行分区

1
fdisk /dev/vdb

进入交互:

1.输入 n 并按回车键:创建一个新分区。 2.输入 p 并按回车键:选择主分区。因为创建的是一个单分区数据盘,所以只需要创建主分区。 3.输入分区编号并按回车键。可以输入 1。 4.输入第一个可用的扇区编号:按回车键采用默认值 1。 5.输入最后一个扇区编号:因为这里仅创建一个分区,所以按回车键采用默认值。 6.输入 wq 并按回车键,开始分区。

1
2
#是否有新分区 /dev/vdb1
fdisk -l

挂载文件系统

1
2
#/mnt是宿主机的目录
mount /dev/vdb1 /mnt

查看挂载是否成功

1
df -h

Docker部分

安装docker ce,根据官网教程


目前已经不推荐使用nvidia-docker2了,直接使用 nvidia-container-toolkit 即可。

1
2
3
4
5
6
7
# Add the package repositories
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
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-container-toolkit
sudo systemctl restart docker

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
#### Test nvidia-smi with the latest official CUDA image
docker run --gpus all nvidia/cuda:10.01base nvidia-smi

# Start a GPU enabled container on two GPUs
docker run --gpus 2 nvidia/cuda:10.1-base nvidia-smi

# Starting a GPU enabled container on specific GPUs
docker run --gpus '"device=1,2"' nvidia/cuda:10.1-base nvidia-smi
docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:10.1-base nvidia-smi

# Specifying a capability (graphics, compute, ...) for my container
# Note this is rarely if ever used this way
docker run --gpus all,capabilities=utility nvidia/cuda:10.1-base nvidia-smi

nivdia官方镜像:https://gitlab.com/nvidia/container-images/cuda/blob/master/doc/supported-tags.md

pytorch镜像:https://hub.docker.com/r/opencompetition/opencompetition

tensorflow镜像:https://www.tensorflow.org/install/docker


(Optional)修改Docker本地镜像与容器的存储位置

如果根分区太小的话

首先停掉Docker服务:

1
systemctl stop docker

然后移动整个/var/lib/docker目录到目的路径:

1
2
sudo mv /var/lib/docker <目标路径>
sudo ln -s <目标路径> /var/lib/docker

然后

1
systemctl start docker

(Optional)修改用户密码

ubuntu的默认root密码是随机的,每次开机都会有一个新的root密码。

1
sudo passwd

然后会提示输入当前用户的密码。

1
su root

转为root后,修改用户密码

1
sudo passwd user

常用Docker操作

image,镜像,是一个个配置好的环境。 container,容器,是image的具体实例。

docker run [-it] some-image 创建某个镜像的容器

docker ps列出当前运行的容器

docker ps -a列出所有的容器,包括运行的和不运行的

docker rm container-id删除某个容器

docker start [-i] container-id启动某个容器,必须是已经创建的

  -i进入交互模式,还有一种方法:docker attach container-id

CTRL+D或者输入exit,退出

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH 容器到主机

docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH 主机到容器

eg: docker cp /home/racle/package_data nlptools:/home/deepspeed/package_data

停止、重启:

docker stop container-id

docker restart container-id

给镜像打标签

1
docker tag <image id> username/imagename:version

映射

1
2
3
4
5
6
7
8
sudo docker run -it /
--gpus all /
-p 8000:22 /
-p 9999:8888 /
--ipc=host /
-v <主机文件路径>:<容器文件路径> /
--name <名称> /
<image id>

-p 9999:8888 把主机的9999端口映射到容器的8888端口

-p 8000:22 留一个端口映射到容器22端口,因为SFTP默认使用22端口。

--ipc=host 让容器与主机共享内存

-v <主机文件路径>:<容器文件路径> 文件路径映射 e.g. /home/racle/dockerVol/:/home/ralce/

或者容器启动的时候挂载目录

1
--mount type=bind,source=paht,target=path

jupyter notebook

创建了容器之后,启动jupyter notebook:

1
2
3
4
5
6
7
8
9
10
jupyter-notebook --generate-config
sed -i 's/#c.NotebookApp.allow_password_change/c.NotebookApp.allow_password_change/g' ~/.jupyter/jupyter_notebook_config.py

cat >> ~/.jupyter/jupyter_notebook_config.py << EOF
c = get_config()
c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.token='666666'
EOF
1
jupyter notebook --no-browser --ip=0.0.0.0 --notebook-dir=''

--no-browser即不通过浏览器启动

--allow-root允许root模型运行


端口配置

容器里

配置SSH服务,首先安装*openssh-server*:

1
apt install -y openssh-server

建立一个配置文件夹并进行必要的配置:

1
2
3
4
5
6
7
8
9
10
11
$ mkdir /var/run/sshd
$ sudo passwd
# 这里设置的root密码,一定要记住!
# 使用其他用户连接,可用root权限设置密码: passwd username

# 将#PermitRootLogin prohibit-password 替换为 PermitRootLogin yes
$ sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# 将session\s*required\s*pam_loginuid.so 替换为 session optional pam_loginuid.so
$ sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

$ echo "export VISIBLE=now" >> /etc/profile
1
$ sudo service ssh restart

在服务器(宿主机)上

测试刚刚新建docker容器中端口转发的22端口:

1
$ sudo docker port [your_container_name] 22

NOTE:可能ssh默认开启的端口不是22,需要在/etc/ssh/sshd_config中修改 port 为 22

1
netstat -tnlp   # 查看当前机器开启的端口

测试能否用SSH连接到远程docker:

1
$ ssh root@[your_host_ip] -p 8000

下面就可以通过pychram和jupyter远程连接服务器上的docker了

本地与服务器的端口映射,从而远程登录jupyter:(远程链接到宿主机被映射的端口):

1
ssh username@host-ip -L 8888:127.0.0.1:9999

远程可通过宿主机ip的8888端口访问jupyter

docker重启时也需要重启ssh服务:

1
$ sudo service ssh restart

备份

通过docker ps或者docker ps -a来查看你想备份的容器的id, 然后通过:

1
docker commit -p [your-container-id] [your-backup-name]

来将your-container-id的容器创建成一个镜像快照

通过docker images就可以查看到刚刚创建好的镜像快照了

通过:

1
docker save -o [path-you-want-to-save/your-backup-name.tar]] [your-backup-name]

把那个镜像打包成tar文件,保存到服务器上。

恢复: docker load -i your-backup-name.tar

1
docker run -d -p 80:80 your-backup-name

pycharm连接

PyCharm*Tools > Deployment > Configuration*, 新建一个*SFTP*服务器,名字自己取

image

输入如下图配置

image

Mappings中配置路径,这里的路径是你本地存放代码的路径,与刚刚配置的Root Path相互映射(同docker中宿主机与容器的关系)

image

配置远程解释器

点击PyCharm的File > Setting > Project > Project Interpreter右边的设置按钮新建一个项目的远程解释器:

image
image

配置完成。配置完成以后需要等本地和远程的环境同步一下。

本地的文件,修改之后可以随时右键deployment->upload到远程主机,或者直接在本地调试运行。

docker容器停了以后里面的SSH服务也会相应停止,

docker重启时也需要重启ssh服务:

1
$ service ssh restart

参考: Docker中搭建深度学习环境


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!