Pytorch调用显卡的问题在1.0版本前比较明显,建议各位尽量使用1.0以后的版本。其次,对于超大模型的训练,有时会需要多显卡并行运算,使用方法指路另一篇博文 点这里。
在使用Pytorch进行训练的时候,有一个奇怪的问题是,无论怎么在代码里指定显卡,最终运行时始终会在第0块显卡上占用少量的内存。本来是个无伤大雅的问题,但是一旦0号显卡被自己或者别人占满了,就很抓狂?公用服务器的悲伤啊。
查了一下在GitHub上有一个关于这个问题的讨论,Pytorch初始化问题,大概是pytorch在初始化的时候会默认在第0块显卡上进行,会占用一定的显存(在torch/cuda/init.py:110中,拷贝了部分代码过来)。这就导致,在第0块显卡空闲内存不多时,程序会反复报Runtime Error的错,可以通过如下的方法来达到完全不使用第0块显卡的目的。
class device(object): """Context-manager that changes the selected device. Arguments: idx (int): device index to select. It's a no-op if this argument is negative. """ def __init__(self, idx): self.idx = idx self.prev_idx = -1 def __enter__(self): if self.idx is -1: return _lazy_init() self.prev_idx = torch._C._cuda_getDevice() if self.prev_idx != self.idx: torch._C._cuda_setDevice(self.idx) def __exit__(self, *args): if self.prev_idx != self.idx: torch._C._cuda_setDevice(self.prev_idx) return False强制指定GPU的方法不少,但是不是每个都对pytorch有用,我在这里列出我知道的几个。
最好用的、绝对不会出错的device
一般使用device时大多数用来直接指定显卡号,但是pytorch那个尿性在你制定前就用了第0块进行初始化,所以保险的方法是使用with语句,在with块下再写pytorch的调用,亲测有效。
with torch.cuda.device(1): pass 指令运行前设置环境变量 在输入训练指令前加上CUDA_VISIBLE_DEVICES=1,2,即设置环境变量,程序只“看得见”第1、2块显卡,自然就不需要在使用第0块显卡了。但是有一个问题是,在设置环境变量之后,第1、2块显卡在程序的眼里就变成了第0、1块显卡,在后续使用中需要注意序号的问题,不然会出现invalid device ordinal的错误。对,我就是嫌它麻烦所以不用<(^-^)> CUDA_VISIBLE_DEVICES=1,2 python train.py 别人的博客上说有用,但是我自己没实验成功的os指定法 用os指定理论上可以指定pytorch不走第0块GPU,但是我试了一下没成功,不知道是不是还要什么先决条件,有谁成功了欢迎评论指正。 import os os.environ['CUDA_VISIBLE_DEVICES'] = '1,2'Pytorch可真是个小妖精