Tensor
ValueError: only one element tensors can be converted to Python scalars
我在将一个list中包含有dim>=2
的tensor转化为LongTensor时报错如上,错误原因是只能将含有一个元素的tensor转化为python标量。修改方式为:将list中的tensor改为np.array()
形式,就可以将这个list转化为Tensor了。
nn.Parallel
RuntimeError: Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_addmm
这里需要查看自己的tensor是否全部copy至gpu。
RuntimeError: arguments are located on different GPUs at /pytorch/aten/src/THC/generic/THCTensorMathBlas.cu:270
这里还是需要检查自己的网络层定义是否规范。我在这个坑里爬了半天,建议大家一开始写网络层时还是多多参考主流代码书写习惯,我就是在网络层里乱传tensor,导致一开始的tensor由`DataParallel``分配至gpu,自定义函数里的tensor没有被分到和其他参与运算的tensor于同一块gpu。推一个该问题的详细解决方案:传送门
规范的网络层定义格式:
再补充一点,由于DataParallel
也是Pytorch的nn.Mudule
,因此模型和优化器都需要使用.module
来定义,自定义网络层要注意继承nn.Module
,若不想按照规范格式定义的话也可以直接在变量后加.module
。
RuntimeError: module must have its parameters and buffers on device cuda:0 (device_ids[0]) but found one of them on device: cuda:1
该错误定位在没有设定主GPU的ID。我在GPU使用过程中选择第3,4块,对应的device_ids = [2,3]
,因此在调用dataParallel时申明:
device = toech.device("cuda:{}".format("2,3") if torch.cuda.is_available())
model = torch.nn.DataParallel(model, device_ids = [2,3])
注意在tensor定义时需使用tensor.to(deivce)
,不能直接使用.cuda()
,因为.cuda()
会默认使用gpu0作为主GPU。
RuntimeError: expected condition, x and y to be on the same device, but condition is on cuda:2 and x and y are on cuda:1 and cuda:2 respectively
这个错误定位是由于我的tensor1是网络输入时送入的,其他tensor是在训练过程中通过计算得到或模型定义时初始化的,在dataParallel中,各个tensor被分配的gpu位置不同,从而导致这个错误。
处理方法是简单粗暴的在tensor后面加.cuda()
。
UserWarning: Was asked to gather along dimension 0, but all input tensors were scalars; will instead unsqueeze and return a vector.
说明一下:每张卡上的loss都是要汇总到第0张卡上求梯度,更新好以后把权重分发到其余卡。多卡的时候采用nn.DataParallel训练会出现这个warning,由于计算loss的时候是分别在多卡计算的,那么返回的也就是多个loss,你使用了多少个gpu,就会返回多少个loss。但如果使用gpu的数量为单数,这意味着每块gpu处理的batchsize不同,因此在求平均loss可以使用size_average=False,reduce=True
作为参数。每个GPU上的损失将相加,但不除以GPU上的批大小。然后将所有平行损耗相加,除以整批的大小,那么不管几块GPU最终得到的平均loss都是一样的。
RuntimeError: CUDA error: device-side assert triggered
index
有溢出。建议首要排查预处理代码的索引是否正确。一开始遇到这个错误以为是多块GPU并行计算方面的问题,因为我是在tensor操作这块报错,与百度到的label id
没有从0开始之类的情况不相符,所以一开始排查了内存方面。后来排到还是预处理阶段index设置不规范导致。所以大家还是多去prep阶段找bug呀~
(更新:又遇到这个错了,在标签序列里设置了-1。难受了,再来记一遍。
nn.parallel.DistributedDataParallel
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss. You can ena
ble unused parameter detection by (1) passing the keyword argument `find_unused_parameters=True` to `torch.nn.parallel.DistributedDataParallel`; (2) making sure all `forward` function outputs participat
e in calculating loss. If you already have done the above two steps, then the distributed data parallel module wasn't able to locate the output tensors in the return value of your module's `forward` fun
ction. Please include the loss function and the structure of the return value of `forward` of your module when reporting this issue (e.g. list, dict, iterable).
首先,遇到这个错误了可以先在模型定义这里:
find_unused_parameters=True
。如果模型仍然报这个错,再去自己的模型
init
部分,检查是否有定义参数或者网络层,但是在forward中没有使用到的。一定一定要仔细检查这部分,我的bug就是卡在这里(代码迭代太多,没有及时删除废弃代码部分,太伤了,在这里卡了好久,一开始还以为是我版本的问题...)还有看到一些回答说
forward
的output
不能包含未参与loss计算的tensor,我这里实验的是将所有output
打包到list或者dict里面就可以了~