使用 Docker 在无网络环境下搭建深度学习环境
前言
最近需要在一个特殊的环境下训练模型, 虽然硬件设备都不错, 也可以向服务器拷贝东西, 但是重要的一个问题是, 服务器端没有连接外网, 这导致搭建深度学习模型训练环境的时候, 不能自动通过网络来安装特定的软件了. 虽然说, 可以将代码用到的所有的包都下载好, 将其安装传输到服务器中安装, 但是由于 python 包的迁移太过麻烦琐碎, 实操起来并不方便. 于是就尝试利用独立配置好的容器环境来作为服务器端运行代码的环境.
最终, 通过借助于 Docker, 成功的在服务器端训练起了模型.
下面记录下大致的步骤和细节.
安装过程
Docker 本体
首先准备好 Docker 的安装包.
查阅官方文档可以看到有提供关于安装方法的指引:
https://docs.docker.com/engine/install/ubuntu/#installation-methods.
这里我们选择手动安装:
https://docs.docker.com/engine/install/ubuntu/#install-from-a-package
64 位 Ubuntu18.04 的系统对应的安装包下载仓库:
https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/
要注意, 这里存放了三个包, containerd.io
docker-ce-cli
docker-ce
这些都是需要安装的. 都需要下载, 如果没有特别需求的话, 直接都选最新版本下载即可.
GPU 相关插件
这里主要为 Docker 提供 GPU 的基础支持.
从 Docker 的文档https://docs.docker.com/config/containers/resource_constraints/#gpu中可以看到相关内容.
首选需要确保你的服务器已经装好了显卡驱动. 并留意驱动版本(最好版本新一些, 这样可以用更新的 NVIDIA 提供的具有针对性优化的框架的 Docker 镜像).
之后准备下载相关的插件. 由上面的页面中可以看到提供了一个 github.io 的页面:
https://nvidia.github.io/nvidia-container-runtime/
这个页面中可以看到对应的 linux 发行版的支持情况, 如果确保无误, 可以直接略过该页面的其他内容, 直接进入对应的 github 仓库https://github.com/NVIDIA/nvidia-container-runtime/tree/gh-pages/stable/ubuntu18.04/amd64下载包文件.
这里要注意到, 这里同样提供了多个包, 我们需要下载的是:
nvidia-container-toolkit
nvidia-container-runtime
另外, 我们还需要去https://github.com/NVIDIA/libnvidia-container/tree/gh-pages/stable/ubuntu18.04/amd64下载依赖包:
libnvidia-container-tools
libnvidia-container1
这下基础的环境就准备好了, 接下来开始准备打包镜像.
构建并导出镜像
由于使用的是 pytorch, 并且想要使用由 NVIDIA 提供的镜像, 所以我们需要从https://ngc.nvidia.com/catalog/containers/nvidia:pytorch这里查找对应版本的镜像.
这里https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/index.html提供了不同镜像发布版本具体的内部的包含的库的版本信息. 选择对应版本下载.
注意, 这里需要保证使用的镜像中的 CUDA 和服务器实际的驱动互相兼容. 可见各个页面下的 Driver Requirements 一节中的提示.
这里我们选择使用https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/rel_20-09.html#rel_20-09这一版本的镜像.
本地需先执行: sudo docker pull nvcr.io/nvidia/pytorch:20.09-py3
.
之后通过 sudo docker images
查看对应镜像的名字和标签(tag).
将镜像 pull 到本地后, 基于它首先启动一个容器:
在容器里, 我们首先将代码需要安装的依赖包全部安装好, 之后输入 exit
退出后, 使用 sudo docker ps -a
查看这个退出的容器的 ID.
然后使用 sudo docker commit <CONTAINER ID> <NEW_IMAGE_NAME: NEW_IMAGE_TAG>
将之前更新后的容器打包成一个新的名字为 <NEW_TAG>
的镜像.
最后使用 sudo docker save -o <NEW_IMAGE_TAR_NAME>.tar <NEW_IMAGE_NAME: NEW_IMAGE_TAG>
这里我们将其打包为 TAR 文件.
拷贝大文件
一般这个导出的镜像文件会>10G, 这对于某些特定的文件系统而言, 可能无法拷贝(假设我们这里使用 U 盘拷贝数据). 所以我们首先切割成小文件再拷贝.
本地 -> U 盘:
cat <NEW_IMAGE_TAR_NAME>.tar | split -b 3G - <NEW_IMAGE_TAR_NAME>.tar.gz.
这里将文件切割成了数个最大为 3G 的文件.(注意这里的-
不可忽略)U 盘 -> 服务器: 拷贝到服务器后, 使用
cat <NEW_IMAGE_TAR_NAME>.tar.gz.*> <NEW_IMAGE_TAR_NAME>.tar
合并文件.
服务器端安装
服务器端就很简单了, 直接按照下面几部操作即可:
进入容器后便可以开始进行正常的代码训练了.
后台运行容器
为了后台运行容器, 这里可以首先将容器中的程序后台运行, 或者是不用管, 直接运行后, 在容器里按快捷键 ctrl+p+q
来将容器放入后台. 这时查看容器状态可以看到它是 UP
.
(可参考:https://www.cnblogs.com/davis12/p/14456227.html)
如果再次进入, 即通过 sudo docker exec -it <YOUR_CONTAINED_ID> bash
进入后, 可以看到, 没有了实时的输出. 所以请确保训练脚本会自动将训练过程中的日志写到文件中, 以便于后续查看.
那么, 这里是否可以将训练过程中的内容再次打印到终端中呢? 这时可以考虑终端复用工具 screen
或者是 tmux
.
结束
一切 OK, 就让程序慢慢跑着吧!
版权声明: 本文为 InfoQ 作者【Lart】的原创文章。
原文链接:【http://xie.infoq.cn/article/5794bc164e83a6cb69510c02a】。
本文遵守【CC BY-SA】协议,转载请保留原文出处及本版权声明。
评论