众所周知,炼丹需要强大的计算资源,通常都是在服务器(集群)上进行炼丹。
但是,对于新手来说,Linux命令不熟悉,远程登录软件不会用,python环境不会管理等等,分分钟劝退。曾经的我就是这样一个小小白,跳了许多坑,慢慢摸索着才上了道。
所以就写一篇博客,随手记录一下常见的一些操作,会一直更新,免得自己忘记。这些是我个人使用的一些操作或者解决方案,不是放之四海而皆准的,请酌情参考哈!
我的基本环境是:
- CentOS
- VSCode
- Anaconda(python3.6.2)
文章目录
配置远程登录
远程我使用的是VSCode+Remote SSH拓展+OpenSSH
VSCode远程登录服务器
服务器基本操作
服务器结点间跳转
ssh node2 #当前结点跳转到结点node2
查看服务器GPU使用情况
在终端输入以下命令
nvidia-smi
查看CUDA版本
#终端输入
nvcc -V
#或者
cat /usr/local/cuda/version.txt
打包文件
1、简单打包
tar -zcvf mypackage.tar.gz file1 file2 #file1,file2以tar.gz方式打包到mypackage.tar.gz包内
解包
tar -zxvf mypackage.tar.gz #解压到当前目录
tar -zxvf mypackage.tar.gz -C dir #解压到dir目录
2、打包除指定文件外的文件夹
tar -zcvf mypackage.tar.gz --exclude=aa/b --exclude=aa/c aa/ #打包aa文件夹内除了aa/b和aa/c之外的所有文件及文件夹
3、去除绝对路径打包
默认情况下打包可能会将文件的绝对路径打包进去,这样解压出来的文件就会有一长串的路径,可以使用-C选项去除绝对路径
#打包/public/home/user/路径下的myfiles文件夹,-C选项user/后面加个空格即可去掉/public/home/user/路径
tar -zcvf myfile.tar.gz -C /public/home/user/ myfiles
选项意义
选项 | 意义 |
---|---|
-c | 创建打包文件 |
-t | 查看打包文件内有哪些文件 |
-z | 通过gzip进行压缩或解压,文件明最好为*.tar.gz |
-j | 通过bzip2进行压缩或者解压,文件名最好为*.tar.bz2 |
-v | 在压缩解压过程中显示处理的文件名 |
-f filename | 压缩或者解压的包的路径,-f必须放在选项组合的最后 |
-C | 将文件解压到指定目录 |
-p | 保留文件的原本权限和属性,用于备份数据 |
–exclude=FILE | 压缩时排除指定文件或者文件夹 |
删除文件
Linux下删除文件
rm [-选项] 文件或目录
-f:不做确认提示,忽略不存在的文件,不会出现任何警告
-i:进行确认提示,删除前询问是否确认删除
-r:递归删除,可以删除目录
-v:在删除文件之前打印文件名称
rm -f a.o
删除目录
rm -r dir #dir是指定目录
删除特定开头的文件,只需要在特定开头后面加上*
rm -r P* #删除以P开头的所有文件
统计文件个数
find -type f | wc -l
#如果要统计文件夹个数,将f改成d即可
find -type d | wc -l
将程序放到后台运行
这里有两种方法:1、使用nohup命令将程序放入后台运行。 2、使用tmux将窗口与会话进行分离,这样退出终端时程序依然能在后台运行。
1、nohup
nohup python train.py >train.log 2>&1 &
将train.py运行输出的内容重定向到train.log中,最后一个&表示将程序放入后台运行。
2、使用tmux将会话与窗口分离。
比如,我要将一个python程序放到后台运行,大致步骤如下:
- 新建一个tmux会话: tmux new -s name 这样就新建了一个名为name的tmux会话。
- 在tmux会话中运行程序: python example.py 。
- 然后在tmux中输入: ctrl+b 然后摁下 d 或者输入 tmux detach 将会话与窗口分离,这样程序就能在后台运行了。
- 如果中途想要查看程序运行的状态,需要重新连接到刚刚新建的tmux会话中,使用 tmux a -s name 这里的name时刚刚新建的tmux会话的名称。
- 最后程序运行完后,不再需要该tmux会话,那么使用 tmux kill-session name结束该会话。
更多tmux操作,see tmux操作
查看程序运行时间
先通过nvidia-smi或者top指令找到想查看的程序的pid号。
使用ps指令,按指定格式输出想要查看的信息。
ps -eo pid, tty, user, lstart, etime | grep 25542
其中-eo与|之间的内容表示希望输出的格式,pid表示这个进程的pid号,tty表示终端机连接标准输入设备的文件名称,user表示这个程序属于哪个用户,lstart表示程序开始时间,etime表示程序运行时间,25542表示想要查询的程序的pid。
Python及框架使用
指定GPU训练模型
在你的训练的python文件中加入,指定使用序号为2的GPU
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2" #2代表GPU的序号,可以是一个,也可以是'0,1,2,3'这样的多个
统计程序每个函数运行时间
python -m cProfile -s cumtime yourscript.py #按cumtime时间排序
结果如下
2118852 function calls (2074450 primitive calls) in 52.258 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
2317/1 0.033 0.000 53.050 53.050 {built-in method builtins.exec}
1 2.264 2.264 53.050 53.050 dataset.py:7(<module>)
626 0.002 0.000 45.739 0.073 dataloader.py:344(__next__)
626 0.012 0.000 45.737 0.073 dataloader.py:812(_next_data)
625 0.003 0.000 45.648 0.073 dataloader.py:779(_get_data)
625 0.005 0.000 45.646 0.073 dataloader.py:748(_try_get_data)
625 0.015 0.000 45.641 0.073 queues.py:91(get)
625 0.003 0.000 39.723 0.064 connection.py:253(poll)
625 0.005 0.000 39.719 0.064 connection.py:413(_poll)
625 0.014 0.000 39.714 0.064 connection.py:897(wait)
625 0.014 0.000 39.668 0.063 selectors.py:365(select)
625 39.651 0.063 39.651 0.063 {method 'poll' of 'select.poll' objects}
其中参数意义为:
ncalls:表示函数调用的次数;
tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
percall:(第一个percall)等于 tottime/ncalls;
cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息;
conda安装第三方库
conda install numpy # 最基本的情况将numpy替换成要安装的库即可
conda install numpy==1.14.3 #安装指定的版本
安装指定较老版本的pytorch和torchvision,GPU版。
conda install pytorch==0.4.0 torchvision cuda92 #去掉cuda92安装cpu版本
安装最新的pytorch可以到pytorch官网直接安装。
conda install pytorch torchvision cudatoolkit=10.2 -c pytorch
对于安装cv2,conda好像没有???
#用
conda install opencv
#安装的包在import cv2时会报
ModuleNotFoundError: No module named 'cv2'
说明opencv这个包和cv2是不同的包。
然后我用
conda install opencv-python
发现在conda的channels里面没有找到这个包。
最后,使用pip安装opencv-python成功,能够使用cv2库。
所以安装cv2推荐使用pip:
pip install opencv-python
conda管理虚拟环境
创建一个名为pytorch10,python版本为3.6的新环境
conda create -n pytorch10 python=3.6
查看你创建了多少个虚拟环境
conda env list #或者
conda info -e
激活你创建的环境,这样就可以使用你新建的环境了,可以正常滴安装需要的库。
conda activate pytorch10 #Linux Windows
source activate pytorch10 #Linux下,若上面命令不行,使用这个命令
退出虚拟环境
conda deactivate pytorch10 #退出pytorch10
source deactivate pytorch10 #Linux下
删除不想要的虚拟环境
conda remove -n pytorch10 --all
安装指定版本pytorch,GPU版本的pytorch要和CUDA版本对应。
# CUDA 9.2
conda install pytorch==1.2.0 torchvision==0.4.0 cudatoolkit=9.2 -c pytorch
# CUDA 10.0
conda install pytorch==1.2.0 torchvision==0.4.0 cudatoolkit=10.0 -c pytorch
# CPU Only
conda install pytorch==1.2.0 torchvision==0.4.0 cpuonly -c pytorch
pytorch需要注意的坑
torchvision.transforms.ToTensor()
在加载数据的时候,经常需要用到这个类。其输入可以是PIL Image或者np.ndarray格式(包括cv2)。它会先将图像由HWC格式转换成CHW格式。
对于ndarray,如果输入的数据类型是int型,那么ToTensor之后输出的将会是[0,1]归一化的结果。如果输入的数据类型是 float的,其输出数据范围为[0,255]。很多时候我们的模型输入是归一化的,如果不注意这一点,有可能会使模型loss很大,甚至出现nan。
>>> from torchvision import transforms
>>> import torch
>>> import numpy as np
>>> transform = transforms.Compose([transforms.ToTensor()])
>>>#整型
>>> img1 = np.array([[1,2,3],[4,5,6]], dtype=np.uint8)
>>>#float型
>>> img2 = np.array([[1,2,3],[4,5,6]], dtype=np.float32)
>>>
>>> img1 = transform(img1)
>>> img1 #其数据范围[0-1]
tensor([[[0.0039, 0.0078, 0.0118],
[0.0157, 0.0196, 0.0235]]])
>>>
>>> img2 = transform(img2)
>>> img2 #其数据范围[0-255.]
tensor([[[1., 2., 3.],
[4., 5., 6.]]])
>>>
对于PILImage转化的Tensor,其数据类型是torch.FloatTensor。具体参考博文1、博文2。
THCudaCheck FAIL file=/opt/conda/conda-bld/pytorch_1579022034529/work/aten/src/THC/THCGeneral.cpp line=313 error=98 : invalid device function
新版本pytorch运行旧版本的代码时遇到的问题,我的解决方案是将cuda从9.2更新到10.1 。不知道大家还有什么好办法??
解决方案
torch.load()加载训练好的模型时报错:CUDA out of memory
情况是训练时显存是充足的,但是在测试时加载模型就显示显存不够。
这个问题是torch.load()函数在加载模型参数时会默认加载在服务器的GPU0上,即使你使用了os.environ[“CUDA_VISIBLE_DEVICES”]指定使用了别的显卡也会这样。
解决方法:
net = torch,load(model_path, map_location={'cuda:0' : 'cuda:1'})#映射到别的显卡上
常见报错
RuntimeError: cuda runtime error (59) : device-side assert triggered
Traceback (most recent call last):
File "train_RFB_MLP.py", line 326, in <module>
train()
File "train_RFB_MLP.py", line 283, in train
loss.backward()
File "/lustre/home/jmtang/anaconda3/envs/pytorch12/lib/python3.6/site-packages/torch/tensor.py", line 118, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/lustre/home/jmtang/anaconda3/envs/pytorch12/lib/python3.6/site-packages/torch/autograd/__init__.py", line 93, in backward
allow_unreachable=True) # allow_unreachable flag
RuntimeError: cuda runtime error (59) : device-side assert triggered at /tmp/pip-req-build-p5q91txh/aten/src/THC/generic/THCTensorMath.cu:26
出现这个异常大概率是类别标签的问题,例如数据集共100类,对应的标签是0-99,而在全连接的最后输出维度或者目标检测的num_classes只指定为99,那就会造成类别索引溢出,从而报错。
pytorch训练模型LOSS出现NAN
造成损失值NAN爆炸的情况很多,可能有:
- 数据有问题,例如检测框的位置超出图像范围或者左上角坐标大于右下角坐标。检查数据,剔除脏数据。
- 学习率过大,可以调小学习率。
- 优化器的问题,比如某些模型使用Adam训没问题,相同情况下用SGD可能也会出现NAN。可以更换优化器。
- 计算的数组可能越界,或者除数可能为0 。