目录
我们已经知道可以根据一个现有的镜像创建容器,这个容器同时封装了项目工程所需的依赖和运行环境,当我们准备在不同的集群上运行程序时,无需重新配置环境,只需要把一个配置好的镜像pull下来,就可以直接用了。
基于镜像A创建一个容器b,在b内进行一系列操作(安装各种依赖环境),根据b再创建一个新的镜像B,将B push到Docker Hub上,就实现了对容器b的备份。具体操作过程见下文。
1 pull一个(官方)镜像
在Docker Hub上pull一个官方镜像,也可以是其他用户的镜像,但是具体内部配置是否能够满足你的使用需求就不确定了,因此最好pull官方的再自行修改。
nvidia/cuda的Docker Hub官方账号:https://hub.docker.com/r/nvidia/cuda/tags
docker pull [OPTIONS] IMAGE_NAME[:TAG]
sudo docker pull nvidia/cuda:11.3.1-cudnn8-devel-ubuntu18.04
docker指令前基本都要加sudo,后文省略sudo,实际使用时别忘记加上!
根据项目所需的cuda版本在Docker Hub的nvidia官方账号下选择要pull的镜像,有runtime和devel两个版本,两者最直观的区别就是大小,有的还有base版本,具体差异参考附录,这里我们选择devel版本,Ubuntu也是和本机操作系统相同的18.04版本。
在执行完上述指令后,检查镜像是否成功地pull下来了:
docker image ls -a
2 基于镜像创建一个容器
run是创建并运行一个容器:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run -it -name gait nvidia/cuda:11.3.1-cudnn8-devel-ubuntu18.04 bash
如果一个容器已经存在(之前创建好的,被临时关闭或退出),则使用start指令:
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker start -i gait
docker start gait
前者 -i 进入交互模式,后者是在后台启动容器,不进入交互端。
3 配置容器
现在我们基于镜像创建了一个新的容器,容器里面所需要的依赖都还没有,可以使用inspect查看容器信息(返回好多内容,暂时还都看不太懂):
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
docker inspect gait
配置容器前先检查基于的镜像是否正确,键入:
nvcc -V
返回cuda信息
3.1 安装python
这一步或许可以省略
更新软件包列表和系统:
apt update
apt upgrade
3.1.1 安装构建工具和依赖
安装一些常见的开发和构建工具以及依赖库:
apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget
3.1.2 下载并解压python源代码包
wget https://www.python.org/ftp/python/3.8.16/Python-3.8.16.tgz
tar -xf Python-3.8.16.tgz
3.1.3 进入源代码目录并配置安装选项
cd Python-3.8.16
./configure --enable-optimizations
3.1.4 编译并安装python
make altinstall
这里使用altinstall而非install,可以避免替换系统默认的python版本
3.1.5 检验是否安装成功
python3.8 --version
3.2 安装torch及相关配置
推荐使用whl方式安装,这样会更稳定,不用考虑远程挂代理安装下载慢之类的问题。
3.2.1 安装pip
apt-get install -y python3.8-pip
这里我用的apt-get,其实应该用apt的
3.2.2 安装torch
在官网上找到所需版本的whl文件,本地下载再上传到服务器,最后从服务器copy到容器中
docker cp [OPTIONS] SRC_PATH DEST_PATH
※更新pip(之前版本的pip不能用install指令安装whl文件,不清楚是什么原因,更新一下就好了)
python3.8 -m pip install --upgrade pip
pip install torch-1.10.0+cu113-cp38-cp38-linux_x86-64.whl
检查是否安装成功
python3.8
import torch
print(torch.cuda.is_avalibale())
返回True就对了(也可以pip list看一下)
3.3 安点别的
pyyaml、tensorboard、opencv-python、tqdm、kornia
pip install pyyaml==6.0 tensorboard==2.11.0 opencv-python==4.6.0.66 tqdm==4.64.1 kornia==0.6.10
4 将容器打包成镜像push到Docker Hub上
记得login一下你的Docker Hub账号,前面login或者在这一步都可以
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker push [OPTIONS] NAME[:TAG]
docker commit gait gait_img:v1.0
docker tag gait_img:v1.0 carrothu0727/gait_img:v1.0
docker push carrothu0727/gait_img:v1.0
冒号后面是tag标签,如果没有指定标签,默认是latest
5 集群提交作业,运行报错,补充安装依赖
5.1 集群提交作业
5.1.1 基本设置
任务名称: 一般默认,也可以改成自己便于查看的名称
资源池: claster cloud
多机多卡: 单机(以单机为例)
5.1.2 任务设置
任务角色名称: 默认(没法改)
资源规格: 应该是哪个能用就选哪个,这里我就随便选了
Docker镜像: 如果之前有作业打包容器存储到集群平台上了,可以在下拉菜单里直接选择;如果没有,把右侧的选择开关关掉,输入Docker Hub里的镜像名给它pull下来
命令: 默认sleep infinity
5.1.3 存储配置
新增一个存储卷,下拉菜单选存储节点,存储卷里存放和工程相关的数据集、代码……默认路径是/root/data1
可以自行修改成便于记忆的名称,只有在这一步可以显式地看到路径,提交作业之后还得现查,别忘了。
这里的/root/data1是挂载点,挂载指的是将设备文件中的顶级目录连接到Linux根目录下的某一目录(这个目录最好是空目录),访问此目录就等同于访问设备文件。
5.1.4 环境变量配置
默认就行,都不用选
以上4步(5.1.1~5.1.4)完成后,作业状态显示 “创建中”,一般需要等待10~30分钟不等,时间长短与镜像大小有关。
创建完成后会显示 “运行中”,这样一个作业就提交成功了!
5.2 运行报错及解决方式(跳过)
下面是针对我这个工程文件运行时出现的一些error,纯记录,大家跳过就可以了,因为每个工程文件可能会出现不一样的错误,对症下药即可~
ERROR1——没有_bz2
ModuleNotFoundError: No module named '_bz2'
从系统的python3.8文件中复制到local文件夹下的python3.8文件中,缺啥补啥。
ERROR2——没有_lzma
ModuleNotFoundError: No module named '_lzma'
解决方法同上。
ERROR3——CUDA OOM
RuntimeError: CUDA out of memory.
这是一个大问题,参考这篇文章:
通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题
ERROR4——cuDNN找不着
RuntimeError: Unable to find a valid cuDNN algorithm to run convolution
有很多种原因会导致这种报错,有人说改小batch就行,我忘了最终怎么解决的了,应该就是改batch……
ERROR5——没有ANTIALIAS
AttributeError: module'PIL.Image'has no attribute'ANTIALIAS'
最新版本的pillow没有’ANTIALIAS’,需要降低版本:
pip install pillow==9.4.0
0 ssh连接集群
当我们前面的准备安装配置工作都完成了,就可以在网页上直接打开终端(也就是进入集群中的容器)运行程序了,算是“大功告成”了!但是有一点不容忽视,网页连接不稳定,经常出现终端窗口莫名其妙失去连接的情况,一方面我们可以使用tmux终端复用工具,避免一断连接啥都没了;另一方面更推荐使用ssh连接,不用网页直接连接了,下面简单介绍安装和配置ssh,以及pycharm ssh连接到集群的过程。
0.1 docker容器内安装ssh
还是在本地一开始自己配的那个容器里,不是集群上的那个,集群容器关了下次就没了。
原教程使用的是apt-get,这个是比较旧的包管理工具,现在更推荐使用apt!
apt update
apt install openssh-server
0.2 设置root密码
这个密码在后面本地pycharm远程连接集群的时候要用到
passwd
0.3 修改配置文件
vim /etc/ssh/sshd_config
注释掉PermitRootLogin prohibit-password,这句表示禁止以root用户身份使用密码进行ssh登录;
添加PermitRootLogin yes,这句话表示允许以root身份ssh登录。
0.4 重启ssh服务
/etc/init.d/ssh restart
至此,我们完成了一个具有ssh连接功能的容器,按照上文步骤把它push到Docker Hub中,再进行后文操作。
0.5 集群提交作业时暴露ssh端口
在命令中添加一条ssh开机自启动:
/etc/init.d/ssh restart && sleep infinity
新增端口设置
服务: 其他
容器端口: 22(容器默认端口是22,这一点可以参见附录SFTP连接的介绍)
主机端口: 11111(自己随便输一个就行,在pycharm配置的时候会用到)
0.6 pycharm配置ssh连接
Type: 选SFTP
Host: 集群容器ip(就是集群上的主机IP)
User name: root
Password: 就是前面设置过的
以上内容填写完毕后Test Connection一下,成功!
附录1:runtime、devel、base的区别
runtime | devel | base |
---|---|---|
是用于运行已编译的应用程序的软件包版本。它通常包含了应用程序所需的最低限度的运行时库和依赖项,以确保应用程序能够在目标系统上正常运行。运行时库包含了程序在运行时所需的函数和资源。 | 是用于开发和编译软件的软件包版本。它包含了编译和构建应用程序所需的头文件、静态库、动态库和其他开发工具。开发版本的软件包让开发人员能够在其系统上编译和测试应用程序。 | 是最基本的软件包版本,包含了最少的文件和功能,通常是用于构建其他版本的基础。 |
一般不包含用于开发的头文件、静态库等,因为这些对于正常运行应用程序并不是必需的。 | 通常包含了与运行时库对应的开发文件,以便开发人员能够链接和使用这些库。 | 可能包含一些核心库和工具,但通常没有运行时库或开发工具。它可以作为其他版本的基础,根据需要安装其他组件以实现特定的功能。 |
总的来说,runtime 版本用于运行应用程序,devel 版本用于开发和编译应用程序,而 base 版本是最基础的版本,作为其他版本的基础。在进行软件开发和部署时,根据需要选择合适的版本,以满足开发和运行的需求。
内存大小:devel>runtime>base
附录2:FTP、FTPS、SFTP的区别
FTP(File Transfer Protocol),FTPS(FTP over SSL/TLS),SFTP(SSH File Transfer Protocol)是用于文件传输的不同协议,它们之间的区别如下:
FTP(File Transfer Protocol) | FTPS(FTP over SSL/TLS) | SFTP(SSH File Transfer Protocol) |
---|---|---|
是一种使用明文传输的标准网络协议,用于在客户端和服务器之间进行文件传输。 | FTPS是FTP的扩展,通过在FTP上层添加SSL/TLS加密层来提供安全的文件传输。 | SFTP是通过SSH(Secure Shell)协议在安全通道上进行文件传输的协议。 |
FTP不提供加密功能,意味着文件和凭据在传输过程中可能会以明文形式传输,存在安全风险。 | FTPS使用SSL/TLS加密保护控制连接和数据连接,确保传输的机密性和数据完整性。 | SFTP使用SSH会话进行身份验证和数据加密,提供了对文件传输的安全保护。 |
FTP使用两个独立的连接(控制连接和数据连接)来进行文件传输。 | FTPS使用的默认端口号是990(控制连接),和FTP相同的数据连接端口(通常是20),需要服务器具有SSL/TLS证书,以提供加密和身份验证。 | SFTP使用单个连接,既用于控制命令,又用于数据传输,通过SSH协议在安全通道中进行,使用的默认端口号是22,与SSH默认端口一致。 |
总结:
FTP是最基本的文件传输协议,不提供加密功能;
FTPS通过添加SSL/TLS层在FTP上提供了加密和安全性;
SFTP是使用SSH协议进行加密和安全文件传输的协议。
参考博客:
通过设置PYTORCH_CUDA_ALLOC_CONF中的max_split_size_mb解决Pytorch的显存碎片化导致的CUDA:Out Of Memory问题
AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘