深度学习环境在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 配置深度学习环境
作者的原因是这样的:
- 在Windows上编写代码,但是并不想破坏电脑的原有环境。
- 服务器资源并不能完全给作者独占太久的时间,因此写完后希望能在本地的Windows电脑上进行Debug和训练时间评估。
- 训练仍然是服务器上训练,但是服务器是Linux环境,希望保持环境的一致性,并不想因为Windows和Linux的差异影响代码运行,更专注于代码而不是环境差异性。
- conda似乎也能实现上述部分要求,但是如果需要不同版本的cuda环境,就无能为力了。比如作者之前遇到过服务器cuda版本不允许降级,但是安装mindspore框架在高版本的cuda下频繁报错。
不推荐使用Docker的几个方面
- 使用Docker作为深度学习环境,首先你的服务器上存在Docker,这样才有意义。如果服务器没有Docker,而是conda环境,完全没必要学习Docker做自己的开发环境。
- 使用Docker作为深度学习环境,需要了解制作Docker镜像,和保存镜像的命令。作者在Windows上首先搭建了一个基础镜像,然后通过SSH连进容器中。配置好环境之后,通过
docker commit
保存当前容器为新的镜像,再通过docker save
导出迁移到服务器上。进阶版还需要掌握Dockerfile的语法,如果你觉得这个过程很难理解,也没有必要学习Docker作开发环境。
在硬件方面,首先,在 WSL2 的发布之前,Docker 在 Windows 上完全是以虚拟机的形式实现的,这意味着不小的性能损耗,并且不支持 GPU 的调用,想用 Docker 在 Windows 平台炼丹的复杂程度堪比登天。WSL2 作为微软拥抱 Linux 社区的一份贡献,使得 Docker 现在完全可以通过 WSL2 来原生运行。
在 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 环境搭建流程:
三、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.sh
和jupyter.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常见题:
-
通常情况下会发生没有权限执行Docker命令,需要添加Docker用户组。
sudo groupadd docker sudo usermod -aG docker ${USER} sudo systemctl restart docker su root su ${USER}
-
如果之前多次重复安装,docker命令会在终端无效,但是在Pycharm中还能使用。这是因为Docker Engine的镜像,容器,卷和自定义配置文件位置在
/var/lib/docker
和/var/lib/containerd
,但是重复安装的Docker在home用户目录中又创建了./docker
目录,Docker指令读取的都是home用户下Docker文件,当然会显示无法执行,处理办法很简答:sudo rm -rf ~/.docker/
-
是否要安装nvidia-docker的问题。Docker 19版本之后,就可以原生支持GPU调用,过去GPU Docker所需要的Runtime被集成到Docker中了,使用时只需要添加
--gpus
参数来控制。这里可能会出现添加完--gpus all
参数,将所有GPU都分配给容器,仍然无法使用GPU,或者nvidia-smi
成功运行,但是无法调用GPU进行训练。需要添加容器的环境变量NVIDIA_DRIVER_CAPABILITIES=compute,utility
和NVIDIA_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)。如果已经开启虚拟化支持,在任务管理器中可以看到虚拟化已启用。
另一个是 Windows 的 Hyper-V 功能开启,这个功能默认是关闭的。(注意,台式机主板重置后会默认关闭)
WSL2 安装就比较简单了,直接在 Microsoft Store 中直接搜索 Windows Subsystem for Linux 安装。
再安装你喜欢的 Linux 发行版,写者使用的是 Ubuntu20.04 LTS, 与写者在实验室的环境一致,方便后期到服务器运行代码。这里注意,配置完账户和密码后,一般是不需要进 WSL 内部继续设置了。
安装 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.sh
和jupyter.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常见问题:
-
怎么处理Windows下与WSL虚拟机数据穿透。
- 可以直接把数据复制到WSL中,Docker主要是Linux平台的虚拟化,因此WSL中IO性能损失小。
- 也可以利用Docker的挂载选项,将数据集所在的Windows文件夹映射到Docker中。作者这里时这样用的
-v D:\project:/opt/project
-
Windows中安装的Docker和在WSL中安装的Docker有什么区别,在Windos中安装过Docker后还需要在WSL中安装吗?
Docker Desktop在2021年推出了WSL整合的版本,也就是说Windows的Docker调用的是WSL中Linux 发行版的Docker。在Windos中安装过Docker后不需要在WSL中安装。
-
Windows 中需要安装nvidia-docker吗?
不需要。Docker 19版本之后,就可以原生支持GPU调用,过去GPU Docker所需要的Runtime被集成到Docker中了,使用时只需要添加
--gpus
参数来控制。这里可能会出现添加完--gpus all
参数,将所有GPU都分配给容器,仍然无法使用GPU,或者nvidia-smi
成功运行,但是无法调用GPU进行训练。需要添加容器的环境变量NVIDIA_DRIVER_CAPABILITIES=compute,utility
和NVIDIA_VISIBLE_DEVICES=all
-
WSL有没有图形界面(GUI)
有,WSLg项目,可以自行搜索。但是这里作者觉得没啥用。
开启远程Docker
可选(但是不推荐):如果希望远程链接 Docker 容器,则需要勾选 Docker Desktop 中设置/General/Expose daemon on tcp://localhost:2375 without TLS;
开启 Docker 远程链接
但是作者发现,仅能使用 tcp://localhost:2375 访问,就算是本机局域网 IP 都无法连接到。那么我们可以使用端口转发,并在防火墙中开启这个端口。管理员权限打开 CMD 使用以下指令修改:(注意修改your-public-ip)
netsh interface portproxy add v4tov4 listenport=2375 connectaddress=127.0.0.1 connectport=2375 listenaddress=<your-public-ip> 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 支持不完整。
添加 Docker 连接。在左下角边栏有“服务”(service)选项,选中该选项中顶部 “+”选项
添加 Docker 连接,弹出菜单对话框,Windows 默认使用 Docker for WIndows,Linux 可以使用 Unix socket点击确定;如果是远程链接,使用 tcp 套接字,填入自己的ip后,点击确定。
新建 Docker 连接
添加 Docker 注册表 ,这个是为了添加自己的 Docker 账户,拉去和推送镜像更方便。
容器管理
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的配置来管理,最后完成之后的配置结果如下图:
Python解释器添加
添加 Docker 镜像的 Python 编译器。点击右下角的编译器名字,可以添加解释器。
添加容器中SSH的Python解释器
这里作者更推荐使用SSH连接容器,方便配置环境,以及运行程序。
这里选择系统解释器,并找到你的系统解释器路径。如果是使用作者的镜像conda-cuda11.8
,那么请先在容器内创建环境之后,再添加下图中的"系统解释器",路径为/opt/conda/envs/环境名称/bin/python3
,请注意配置好你的同步文件夹路径,不然你的代码就无法正常同步。
添加Docker的Python解释器
如果使用Docker请按照下面这个步骤:
因为之前已经连接过了 Docker ,因此可以在这里选择”拉取或使用现有内容“,之后点击确定就可以完成了。
这里选择系统解释器,并找到你的系统解释器路径。如果是使用作者的镜像conda-cuda11.8
,那么请先在容器内创建环境之后,再添加下图中的"Conda环境",路径为/opt/conda/envs/环境名称/bin/python3
。
这样在你的Python解释器列表中就存在这些编译器了。
Run配置
如果使用SSH的Python编译器,只需要选择默认编译器为指定编译器即可。
如果想直接使用Docker作为Python解释器,可以参考作者的设置(这需要上一步你的Docker环境配置好,不然还是建议通过SSH连接如容器中使用)。
到此位置,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,utility
和NVIDIA_VISIBLE_DEVICES=all
Docker 也支持了 WSL2 GPU 透传,这就不需要再专门下载 Nvidia-docker ,使用方法就是加入运行参数--gpus
WSLg 支持
这是 Linux 原生图形化支持。需要将 \wsl$\Ubuntu-20.04\mnt\wslg.X11-unix\ 映射到 /tmp/.X11-unix。(这里是路径选择方式)文章来源:https://www.toymoban.com/news/detail-739188.html
文章来源地址https://www.toymoban.com/news/detail-739188.html
到了这里,关于2023保姆级:深度学习环境在Docker上搭建(基于Linux和WSL)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!