ubuntu18.04从零开始离线搭建基于docker的pytorch环境


任务需要搭建一个pytorch环境调用gpu资源,离线环境,踩坑无数,特地写下此文以备后用。

整体流程

一、安装nvidia驱动
二、安装docker
三、安装nvidia-docker
四、运行pytorch

除离线环境外,需一台联网ubuntu主机进行部分配置及安装包下载,以下步骤可先在联网主机上进行一次,再将安装包拷到离线主机上再进行一次,其中带*符号的步骤在离线主机上必须进行
文中涉及的所有deb安装包:docker、nvidia-docker、gcc、make、build-essential离线包.zip - CSDN下载

配置apt国内镜像源

若联网主机未修改apt镜像源,又不具备科学上网的条件,下载时速度将会非常令人感动:

  1. 备份sources.list(Ubuntu恢复文件很复杂,尽量避免直接删除系统文件):

     sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
    
  2. 修改sources.list:

     sudo gedit /etc/apt/sources.list
    

    替换阿里云镜像源:

     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
    
  3. 更新

     sudo apt update
    

一、安装nvidia驱动

(一)禁用nouveau*

nouveau是ubuntu自带的驱动,如果不禁用可能会导致nvidia驱动装不上。

  1. 创建blacklist-nouveau.conf文件:

     sudo tee /etc/modprobe.d/blacklist-nouveau.conf << EOF
     blacklist nouveau
     options nouveau modeset=0
     EOF
    

    也可以直接用编辑器打开blacklist-nouveau.conf文件,写入两个EOF之间的内容。

  2. 更新配置

     sudo update-initramfs -u
     sudo reboot
    

    重启后建议进入bios,部分教程提到,为避免secure boot可能造成的驱动安装失败,应进入bios将secureboot禁用/disable(仅作为安装失败时的参考,作者就没有设置,也不影响),设置完毕后再验证禁用是否生效。

  3. 验证
    若nouveau禁用成功,开机后分辨率会发生变化,不放心可以执行以下命令确认:

     lsmod | grep nouveau
    

    执行后若没有任何输出则表示禁用成功。

(二)离线安装编译环境gcc、make、build-essential*

离线安装nvidia驱动,通过官网下载.run文件后手动安装(需要gcc、make、build-essential等环境)
其实离线安装gcc、make、build-essential需要下载的依赖很多,只不过作者将所需的依赖都列出来了,不需要一一去找(附:gcc、make、build-essential离线安装及依赖-CSDN下载):
下载前可先执行gcc、make查看是否其已安装。
gcc:

mkdir gcc
cd gcc
sudo apt download cpp gcc gcc-7 libasan4 libatomic1 libcilkrts5 libgcc-7 libitm1 liblsan0 libmpx2 libquadmath0 libtsan0 libubsan0

make:

mkdir make
cd make
sudo apt download make libc6

build-essential:

mkdir build-essential
cd build-essential
sudo apt download build-essential dpkg-dev g++ g++-7 libc6-dev libc-dev-bin libstdc++-7-dev linux-libc-dev

下载完毕后,按gcc、make、build-essential的顺序依次切入目录执行命令进行安装:

sudo dpkg -i *.deb

(三)离线安装nvidia驱动*

官网下载.run文件后手动安装(需要gcc、make、build-essential等环境)

450.66版本支持的显卡类型很多,下载前先在下载页面下方查看是否支持离线主机显卡。
下载完毕后,执行命令进行安装:

sudo sh ./NVIDIA-Linux-x86_64-450.66.run --no-opengl-files

注意:安装过程中,尽量选择默认选项不要修改,同时必须指定–no-opengl-files,否则将会出现输入密码后又返回登录界面的情况。

输入密码后又返回登录界面解决办法
ctrl+alt+f2,进入命令行tty,登录后,执行命令卸载驱动,重启即可:

	sudo /usr/bin/nvidia-uninstall

安装成功后重启,命令行执行nvidia-smi,若出现GPU列表即成功。

二、安装docker

(一)下载安装包

需下载三个文件:docker下载地址

containerd.io_1.2.10-3_amd64.deb
docker-ce-cli_19.03.5~3-0~ubuntu-xenial_amd64.deb 
docker-ce_19.03.5~3-0~ubuntu-xenial_amd64.deb 

(二)安装*

执行命令进行安装:

sudo dpkg -i *.deb

(三)配置*

docker命令需要root权限运行,配置免sudo:

sudo groupadd docker				# 添加docker用户组,安装默认添加,报错可跳过
sudo gpasswd -a $USER docker        # 将当前用户加入docker用户组中
newgrp docker                       # 更新用户组
docker ps -a 			 			# 测试是否成功

踩过的坑:有些教程指导利用tar包进行安装,但在之后安装nvidia-docker时可能会出现报错:

nvidia-docker2 依赖于 docker-ce (=~版本号~) 或docker-ee (=~版本号~);然而…未安装…

反复尝试,依旧不行,改用deb包安装后成功,不信邪的朋友尝试成功后欢迎分享经验~
若docker.service未注册,根据以下步骤进行注册,若已注册则可开始安装nvidia-docker:

sudo systemctl status docker.service    # 测试服务是否注册

若未注册,创建docker.service:

sudo gedit /etc/systemd/system/docker.service

将以下配置写入docker.service中:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
 
[Install]
WantedBy=multi-user.target

保存后,启动服务:

sudo chmod +x /etc/systemd/system/docker.service          # 添加文件权限并启动docker
sudo systemctl daemon-reload                          	  # 重载unit配置文件
sudo systemctl start docker                               # 启动Docker
sudo systemctl enable docker.service              		  # 设置开机自启

三、安装nvidia-docker

(一)下载安装包

共需要下载五个包,包括:

libnvidia-container1_1.2.0-1_amd64.deb
libnvidia-container-tools_1.2.0-1_amd64.deb
nvidia-container-runtime_3.3.0-1_amd64.deb
nvidia-container-toolkit_1.2.1-1_amd64.deb
nvidia-docker2_2.4.0-1_all.deb

通过命令依次下载deb包:

sudo apt download libnvidia-container1
sudo apt download libnvidia-container-tools
sudo apt download nvidia-container-runtime
sudo apt download nvidia-container-toolkit
sudo apt download nvidia-docker2

apt搜索安装包的版本及指定下载版本

sudo apt-cache madison nvidia-docker2       # 将nvidia-docker2换成其它想要搜索版本的包
# 搜索到版本后,使用-y选项,在包后加‘=’指定包的版本
sudo apt download -y nvidia-docker2=2.0.3+docker18.09.1-1

不出意外,你将在下载时遇到如下错误:

$ sudo apt-get install -y libnvidia-container1
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package libnvidia-container1

若未遇到“E:Unable to locate package …”的问题,可跳过以下步骤,直接安装nvidia-docker2。

  1. 创建文件/etc/apt/sources.list.d/nvidia-docker.list:

     sudo gedit /etc/apt/sources.list.d/nvidia-docker.list
    
  2. 若系统为ubuntu18.04,将下列配置写入文件中:

     deb https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/$(ARCH) /
     # deb https://nvidia.github.io/libnvidia-container/experimental/ubuntu18.04/$(ARCH) /
     deb https://nvidia.github.io/nvidia-container-runtime/stable/ubuntu18.04/$(ARCH) /
     # deb https://nvidia.github.io/nvidia-container-runtime/experimental/ubuntu18.04/$(ARCH) /
     deb https://nvidia.github.io/nvidia-docker/ubuntu18.04/$(ARCH) /
    

    若系统为其他版本,对应https://nvidia.github.io/nvidia-docker/中的系统版本,将配置中的ubuntu18.04换成网址中的Identifier那一列下对应系统版本的名称即可。

  3. 如果直接进行下载,将报错:

     W: GPG 错误:https://nvidia.github.io/libnvidia-container/stable/ubuntu18.04/ 
     Release: 由于没有公钥,无法验证下列签名: NO_PUBKEY …
    

    对应系统版本,ubuntu18.04执行以下命令添加公钥:

     curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    

    其他系统版本在https://nvidia.github.io/nvidia-docker/中找到系统对应的相应命令执行即可。

(二)安装*

sudo dpkg -i libnvidia* nvidia*

将会提示解压安装,若报错请参照上述步骤及核对版本是否准确。

(三)配置runtime*

官方英文网站github.com/docker-engine-setup提供了三种方法对runtime进行注册,且声明nvidia-docker2无需注册,但根据作者经验,还是需要注册才能在docker中启用nvidia驱动。
几种方法中涉及到要修改配置文件,若其中有内容,应当添加而非覆盖。
方法1:创建override.conf文件(较为有效):

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/override.conf <<EOF
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

注意:其中相较于官网上给的方法,作者去掉了–host=fd://,因不知道如何修改为正确的指定host的格式,若不去掉将导致docker重启后报错,无法正常启动。
命令中的“sudo tee … ”也可换成用gedit编辑器打开,将两个EOF之间的内容写入。

方法2:修改daemon.json:

sudo tee /etc/docker/daemon.json <<EOF
{
"runtimes": {
    "nvidia": {
        "path": "/usr/bin/nvidia-container-runtime",
        "runtimeArgs": []
    		}
	 }
}
EOF
sudo pkill -SIGHUP dockerd

方法3:命令行:

sudo dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime [...]

若后期运行docker容器指定runtime时提示:

docker: Error response from daemon: Unknown runtime specified nvidia.

说明nvidia-docker2未注册成功,确认上述步骤及文件内容是否有误。

四、运行pytorch

(一)修改docker国内源

pytorch镜像大约2G以上,作者尝试在不科学上网的条件下从官方源pull该镜像,历经一整晚,下载了1.6G后因网络波动失败。

注册阿里云后,将源修改为阿里云镜像源:
阿里云容器镜像服务地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
点击左侧:镜像中心->镜像加速器,然后可看到“加速器地址”一栏,这是你账号专属的加速器地址,勿随意分享。
找到“加速器地址”后,按照下方的操作文档说明进行操作即可。

(二)拉取pytorch镜像并导出

若未配置docker免sudo,则加上sudo。

docker pull pytorch/pytorch

导出镜像为.tar:

docker save -o pytorch_latest.tar pytorch/pytorch:latest

导出将需要花费一点时间,导出成功后将.tar拷到离线主机导入即可。

(三) 导入镜像、测试*

注意:镜像导出和导入需要使用相匹配的命令,如save对应load,若使用import同样可以正常导入(一个针对镜像一个针对容器),但是导入后的镜像将出现异常,如执行docker run -it pytorch/pytorch /bin/bash 提示容器中不存在/bin/bash等等,这都是血的教训。

docker load -i pytorch_latest.tar

导入后,测试:

docker run -it --runtime=nvidia pytorch/pytorch

将进入容器内的命令行,执行nvidia-smi查看是否输出GPU列表。
输入python,尝试调用torch模块:

import torch
torch.Tensor(3,4).cuda()

若无报错,恭喜你成功了。

参考文档:
1.Linux下离线安装Docker:https://www.cnblogs.com/luoSteel/p/10038954.html
2.docker 和 nvidia-docker 的离线安装和基本使用:https://fanfuhan.github.io/2019/11/22/docker_based_use/
3.“Unable to locate package nvidia-container-toolkit” on Debian x86_64:https://github.com/NVIDIA/nvidia-docker/issues/1238
4.ubuntu16.04/18.04离线安装docker nvidia-docker2:https://blog.csdn.net/guilutian0541/article/details/103568977
5.Docker镜像加速-配置阿里云镜像仓库:https://www.cnblogs.com/gqzdev/p/11736856.html
6.nvidia-container-runtime:https://github.com/nvidia/nvidia-container-runtime#docker-engine-setup
7.Ubuntu18.04安装Nvidia显卡驱动教程:https://blog.csdn.net/weixin_43820996/article/details/100676292
8.ubuntu18.04配置国内apt-get源:https://blog.csdn.net/weixin_39394526/article/details/87935449
9.Ubuntu安装NVIDIA驱动后,无法登录,循环登录,登录界面进不去,回到登录界面:https://blog.csdn.net/wang_ys121/article/details/82881716


版权声明:本文为weixin_40020929原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。