2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)

深度学习环境在Docker上搭建(基于Linux和WSL)

一、深度学习环境配置选择

在深度学习领域,配置环境的常见做法是使用conda来实现环境隔离。conda是一个广泛使用的工具,用于创建和管理特定的环境,通过在不同的环境中设置特定的Python环境变量路径,实现了环境的特异化。为了实现这一目的,需要将终端置于conda的管理之下。如果你已经安装了conda,你可能已经注意到在bash中需要执行conda init bash(在Windows上则是conda init pwsh)来初始化conda的bash或powershell配置。

Docker作为一种虚拟化技术,利用镜像作为基础配置,可以轻松地创建和管理容器。容器是一种轻量级的虚拟化技术,使得应用程序及其依赖可以在独立的运行环境中运行,而不会影响宿主操作系统或其他容器。Docker的出现为服务器管理带来了新的可能性。通过使用容器化技术,我们可以更加灵活地组织和运行应用程序,实现更高效、可靠的服务器管理。越来越多的服务器使用了Docker进行管理,我们就有必要学习一下相关知识。

这里介绍使用Docker作为深度学习环境的配置方法,配置上手比conda多了一点点难度,但是在使用上却方便了很多。

二、为什么使用 Docker 配置深度学习环境

作者的原因是这样的:

  1. 在Windows上编写代码,但是并不想破坏电脑的原有环境。
  2. 服务器资源并不能完全给作者独占太久的时间,因此写完后希望能在本地的Windows电脑上进行Debug和训练时间评估。
  3. 训练仍然是服务器上训练,但是服务器是Linux环境,希望保持环境的一致性,并不想因为Windows和Linux的差异影响代码运行,更专注于代码而不是环境差异性。
  4. conda似乎也能实现上述部分要求,但是如果需要不同版本的cuda环境,就无能为力了。比如作者之前遇到过服务器cuda版本不允许降级,但是安装mindspore框架在高版本的cuda下频繁报错。

不推荐使用Docker的几个方面

  1. 使用Docker作为深度学习环境,首先你的服务器上存在Docker,这样才有意义。如果服务器没有Docker,而是conda环境,完全没必要学习Docker做自己的开发环境。
  2. 使用Docker作为深度学习环境,需要了解制作Docker镜像,和保存镜像的命令。作者在Windows上首先搭建了一个基础镜像,然后通过SSH连进容器中。配置好环境之后,通过docker commit保存当前容器为新的镜像,再通过docker save导出迁移到服务器上。进阶版还需要掌握Dockerfile的语法,如果你觉得这个过程很难理解,也没有必要学习Docker作开发环境。

在硬件方面,首先,在 WSL2 的发布之前,Docker 在 Windows 上完全是以虚拟机的形式实现的,这意味着不小的性能损耗,并且不支持 GPU 的调用,想用 Docker 在 Windows 平台炼丹的复杂程度堪比登天。WSL2 作为微软拥抱 Linux 社区的一份贡献,使得 Docker 现在完全可以通过 WSL2 来原生运行。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第1张图片

在 Win11 环境中大约有 66% 在 Ubuntu2004 中的机器学习速度,而在 WSL2 中则有 80% 的在Ubuntu2004 中的机器学习速度。使用Docker的炼丹更快!

其次,Docker 是跨平台的,如果 80% 的炼丹速度对你有困扰,完全可以在将你的 Docker 炼丹环境上传到云端,在 Linux 服务器上安装 Docker 之后,再从云端拉取下来,完全可以像 Git 使用代码一样使用深度学习环境。使用 Docker 的跨平台兼容性更好!

最后,使用 Conda 配置 Cuda 炼丹环境,通常情况下除去 Conda 不说,还需要安装 Nvidia 显卡驱动,还有cudatools 包、cudnn 包等等。这些包体积都很大,而且服务器都在国外,下载速度很堪忧。而 Docker 的镜像已经包含了这些包,只需要等待 Docker 镜像下载完成,就能实现开箱即用。使用 Docker 搭建环境速度块!

Conda 和 Docker 环境搭建流程:
2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第2张图片

三、Docker 深度学习环境搭建

在 Linux 上搭建

以 Ubuntu2004 版本为例(Docker官方安装教程):

安装 Nvidia 驱动

这里推荐在官网上下载 官方 GeForce 驱动程序 | NVIDIA 。执行前先给驱动文件执行权限

sudo chmod 777 <driver-name>.run
./<driver-name>.run
Docker旧版本卸载(可选)

在安装Docker引擎之前,必须首先确保卸载任何冲突的软件包(也就是旧版本的Docker组件)。Ubuntu在apt仓库中提供了Docker软件包的非官方分发版,该版本由Ubuntu负责维护和发行,必须先卸载这些软件包,然后才能安装Docker Engine的官方版本。

要卸载的非官方软件包:

  • docker.io

  • docker-compose

  • docker-doc

  • podman-docker

  for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

apt-get可能会报告没有安装这些软件包,这是因为之前并没有安装过Docker。

安装Docker的apt仓库

添加Docker官方仓库的GPG key:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

配置仓库:

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装Docker Engine

使用apt来进行安装:

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
拉取镜像

docker镜像提倡精简,也同时意味着少了很多必要的库,报错缺少库依赖也很常见。当然作者早就为深度学习定制了更好用的镜像,作者使用的镜像相关信息在 DockerHub可以查询到,镜像相应的 DockerFile 在 GitHub 上也可以查到。

 //无conda,基于cuda12.0内置了pytorch2.0。
 //镜像由于预装好了pytorch2.0,体积比较大,约9.35GB
 docker pull mortals/codeenv:pytorch2.0-cuda12.0
 //预装miniconda,基于cuda12.0,无pytorch
 //镜像体积约4.85GB
 docker pull mortals/codeenv:conda-cuda12.0
 //同时约有基于cuda11.8的镜像
 //镜像体积约为3.78GB
 docker pull mortals/codeenv:conda-cuda11.8

作者在镜像中提供了两个方便的脚本sshstart.shjupyter.sh ,分别用来配置SSH服务自启动和开启Jupyter服务。使用这两个脚本请提前在容器配置对应的端口映射。SSH服务端口为22,Jupyter服务端口在8888

docker run -it -v D:/project:/opt/project -p 8822:22 -p 6006:6006 -p 8888:8888  --gpus all --shm-size 16G --restart=always mortals/codeenv:pytorch2.0-cuda12.0 /bin/bash

如果上述镜像仍不能满足你的需求,可以从Github获取作者的Dockerfile,修改镜像的系统版本,然后自行编译。

 FROM nvidia/cuda:11.8.0-devel-ubuntu20.04
Docker常见题:
  1. 通常情况下会发生没有权限执行Docker命令,需要添加Docker用户组。

    sudo groupadd docker 
    sudo usermod -aG docker ${USER}
    sudo systemctl restart docker
    su root             
    su ${USER}          
    
  2. 如果之前多次重复安装,docker命令会在终端无效,但是在Pycharm中还能使用。这是因为Docker Engine的镜像,容器,卷和自定义配置文件位置在 /var/lib/docker/var/lib/containerd,但是重复安装的Docker在home用户目录中又创建了./docker目录,Docker指令读取的都是home用户下Docker文件,当然会显示无法执行,处理办法很简答:

    sudo rm -rf ~/.docker/
    
  3. 是否要安装nvidia-docker的问题。Docker 19版本之后,就可以原生支持GPU调用,过去GPU Docker所需要的Runtime被集成到Docker中了,使用时只需要添加--gpus参数来控制。这里可能会出现添加完--gpus all参数,将所有GPU都分配给容器,仍然无法使用GPU,或者nvidia-smi成功运行,但是无法调用GPU进行训练。需要添加容器的环境变量NVIDIA_DRIVER_CAPABILITIES=compute,utilityNVIDIA_VISIBLE_DEVICES=all

    例如:

    docker run -itd --gpus all --name 容器名 -e NVIDIA_DRIVER_CAPABILITIES=compute,utility -e NVIDIA_VISIBLE_DEVICES=all 镜像名
    

    或者在Dockerfile中添加:

    ENV NVIDIA_VISIBLE_DEVICES=all NVIDIA_DRIVER_CAPABILITIES=compute,utility\
        LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64
    
开启远程Docker

可选(但是不推荐):如果希望能远程链接到 Linux 上的 Docker 容器,那么执行以下命令:

echo 'export DOCKER_HOST=tcp://0.0.0.0:2375' >> /etc/profile
source /etc/profile

在 Windows 上搭建

写者使用的是 Windows11 ,因此默认已经开启了 WSL2 。请确认已经开启了 hyper-v 虚拟化,这包含两部分:一个是 CPU 虚拟化支持,这个需要在 BIOS 中开启(AMD 为 SVM;Intel 为 Intel-vt)。如果已经开启虚拟化支持,在任务管理器中可以看到虚拟化已启用。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第3张图片

另一个是 Windows 的 Hyper-V 功能开启,这个功能默认是关闭的。(注意,台式机主板重置后会默认关闭)

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第4张图片

WSL2 安装就比较简单了,直接在 Microsoft Store 中直接搜索 Windows Subsystem for Linux 安装。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第5张图片

再安装你喜欢的 Linux 发行版,写者使用的是 Ubuntu20.04 LTS, 与写者在实验室的环境一致,方便后期到服务器运行代码。这里注意,配置完账户和密码后,一般是不需要进 WSL 内部继续设置了。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第6张图片

安装 Docker Desktop ,这里是官网下载:Docker Desktop release notes | Docker Documentation;

如果有其他安装问题,这是官方指导文档:Install Docker Desktop on Windows | Docker Documentation;

拉取镜像

docker镜像提倡精简,也同时意味着少了很多必要的库,报错缺少库依赖也很常见。当然作者早就为深度学习定制了更好用的镜像,作者使用的镜像相关信息在 DockerHub可以查询到,镜像相应的 DockerFile 在 GitHub 上也可以查到。

 //无conda,基于cuda12.0内置了pytorch2.0。
 //镜像由于预装好了pytorch2.0,体积比较大,约9.35GB
 docker pull mortals/codeenv:pytorch2.0-cuda12.0
 //预装miniconda,基于cuda12.0,无pytorch
 //镜像体积约4.85GB
 docker pull mortals/codeenv:conda-cuda12.0
 //同时约有基于cuda11.8的镜像
 //镜像体积约为3.78GB
 docker pull mortals/codeenv:conda-cuda11.8

作者在镜像中提供了两个方便的脚本sshstart.shjupyter.sh ,分别用来配置SSH服务自启动和开启Jupyter服务。使用这两个脚本请提前在容器配置对应的端口映射。SSH服务端口为22,Jupyter服务端口在8888

docker run -it -v D:/project:/opt/project -p 8822:22 -p 6006:6006 -p 8888:8888  --gpus all --shm-size 16G --restart=always mortals/codeenv:pytorch2.0-cuda12.0 /bin/bash

如果上述镜像仍不能满足你的需求,可以从Github获取作者的Dockerfile,修改镜像的系统版本,然后自行编译。

 FROM nvidia/cuda:11.8.0-devel-ubuntu20.04
Windows Docker常见问题:
  1. 怎么处理Windows下与WSL虚拟机数据穿透。

    1. 可以直接把数据复制到WSL中,Docker主要是Linux平台的虚拟化,因此WSL中IO性能损失小。
    2. 也可以利用Docker的挂载选项,将数据集所在的Windows文件夹映射到Docker中。作者这里时这样用的-v D:\project:/opt/project
  2. Windows中安装的Docker和在WSL中安装的Docker有什么区别,在Windos中安装过Docker后还需要在WSL中安装吗?

    Docker Desktop在2021年推出了WSL整合的版本,也就是说Windows的Docker调用的是WSL中Linux 发行版的Docker。在Windos中安装过Docker后不需要在WSL中安装。

  3. Windows 中需要安装nvidia-docker吗?

    不需要。Docker 19版本之后,就可以原生支持GPU调用,过去GPU Docker所需要的Runtime被集成到Docker中了,使用时只需要添加--gpus参数来控制。这里可能会出现添加完--gpus all参数,将所有GPU都分配给容器,仍然无法使用GPU,或者nvidia-smi成功运行,但是无法调用GPU进行训练。需要添加容器的环境变量NVIDIA_DRIVER_CAPABILITIES=compute,utilityNVIDIA_VISIBLE_DEVICES=all

  4. WSL有没有图形界面(GUI)

    有,WSLg项目,可以自行搜索。但是这里作者觉得没啥用。

开启远程Docker

可选(但是不推荐):如果希望远程链接 Docker 容器,则需要勾选 Docker Desktop 中设置/General/Expose daemon on tcp://localhost:2375 without TLS;

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第7张图片

开启 Docker 远程链接

但是作者发现,仅能使用 tcp://localhost:2375 访问,就算是本机局域网 IP 都无法连接到。那么我们可以使用端口转发,并在防火墙中开启这个端口。管理员权限打开 CMD 使用以下指令修改:(注意修改your-public-ip)

netsh interface portproxy add v4tov4 listenport=2375 connectaddress=127.0.0.1 connectport=2375 listenaddress= protocol=tcp

如果不用这个 IP ,管理员权限打开 CMD 使用以下指令删除端口转发 :(注意修改your-public-ip)

netsh interface portproxy delete v4tov4 listenaddress=192.168.191.6 listenport=2375

最后如果发现不能访问,打开防火墙端口:

netsh advfirewall firewall add rule name="docker_daemon" dir=in action=allow protocol=TCP localport=2375

四、在 PyCharm 使用 Docker 环境

添加Docker服务

在插件中安装 Docker 插件(默认捆绑)。注意,这里需要 PyCharm 专业版,社区版的 Docker 支持不完整。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第8张图片

添加 Docker 连接。在左下角边栏有“服务”(service)选项,选中该选项中顶部 “+”选项

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第9张图片

添加 Docker 连接,弹出菜单对话框,Windows 默认使用 Docker for WIndows,Linux 可以使用 Unix socket点击确定;如果是远程链接,使用 tcp 套接字,填入自己的ip后,点击确定。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第10张图片

新建 Docker 连接

添加 Docker 注册表 ,这个是为了添加自己的 Docker 账户,拉去和推送镜像更方便。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第11张图片

容器管理

Docker容器可以通过命令行进行管理:

docker run -it -v D:/project:/opt/project -p 8822:22 -p 6006:6006 -p 8888:8888  --gpus all --shm-size 16G --restart=always mortals/codeenv:pytorch2.0-cuda12.0 /bin/bash

也可以预设PyCharm的配置来管理,最后完成之后的配置结果如下图:

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第12张图片

Python解释器添加

添加 Docker 镜像的 Python 编译器。点击右下角的编译器名字,可以添加解释器。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第13张图片

添加容器中SSH的Python解释器

这里作者更推荐使用SSH连接容器,方便配置环境,以及运行程序。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第14张图片

这里选择系统解释器,并找到你的系统解释器路径。如果是使用作者的镜像conda-cuda11.8,那么请先在容器内创建环境之后,再添加下图中的"系统解释器",路径为/opt/conda/envs/环境名称/bin/python3 ,请注意配置好你的同步文件夹路径,不然你的代码就无法正常同步。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第15张图片

添加Docker的Python解释器

如果使用Docker请按照下面这个步骤:

因为之前已经连接过了 Docker ,因此可以在这里选择”拉取或使用现有内容“,之后点击确定就可以完成了。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第16张图片

这里选择系统解释器,并找到你的系统解释器路径。如果是使用作者的镜像conda-cuda11.8,那么请先在容器内创建环境之后,再添加下图中的"Conda环境",路径为/opt/conda/envs/环境名称/bin/python3

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第17张图片

这样在你的Python解释器列表中就存在这些编译器了。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第18张图片

Run配置

如果使用SSH的Python编译器,只需要选择默认编译器为指定编译器即可。

如果想直接使用Docker作为Python解释器,可以参考作者的设置(这需要上一步你的Docker环境配置好,不然还是建议通过SSH连接如容器中使用)。

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第19张图片

到此位置,Docker 深度学习环境已经可以使用了。

附注:在 WSL2 中 Docker 调用 Nvidia GPU 使用 CUDA 训练模型

在很多几年前的博客和教程中,大多数是安装使用 nvidia-docker 来调用GPU,然后如果是在 WSL 中还需要安装 Nvidia 显卡的 CUDA 驱动。

作者在多日的研究 WSL2 和 Docker 文档中,发现 WSL2 已经可以透传 GPU 使用。也就是在 Windows 安装过Nvidia 驱动之后,直接可以在 WSL2 中使用 GPU,可以测试 nvidia-smi 来查看驱动。由于驱动向后兼容,尽量把驱动升级到最新,这样支持的 CUDA 的相关工具更多,尽量避免使用容器中的 CUDA 工具包不兼容出现的奇奇怪怪的 bug 。

Docker 19版本之后,就可以原生支持GPU调用,过去GPU Docker所需要的Runtime被集成到Docker中了,使用时只需要添加--gpus参数来控制。这里可能会出现添加完--gpus all参数,将所有GPU都分配给容器,仍然无法使用GPU,或者nvidia-smi成功运行,但是无法调用GPU进行训练。需要添加容器的环境变量NVIDIA_DRIVER_CAPABILITIES=compute,utilityNVIDIA_VISIBLE_DEVICES=all

Docker 也支持了 WSL2 GPU 透传,这就不需要再专门下载 Nvidia-docker ,使用方法就是加入运行参数--gpus

WSLg 支持

这是 Linux 原生图形化支持。需要将 \wsl$\Ubuntu-20.04\mnt\wslg.X11-unix\ 映射到 /tmp/.X11-unix。(这里是路径选择方式)

2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)_第20张图片

你可能感兴趣的:(深度学习,docker,linux,python,pycharm,ssh)