当前位置:   article > 正文

RuntimeError: Expected all tensors to be on the same device, but found at least two devices

expected all tensors to be on the same device, but found at least two device

运行以下代码时报错:RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! (when checking argument for argument tensors in method wrapper_cat)

这行代码在函数定义里,且当时loss和model都有.to(device)的操作


<code class="language-plaintext hljs">        encoder_Z_distr = self.encoder_result(batch_x)  #从batch-x中生成Z   
        
        #第一个生成的Z,包含Z的过去和现在
        to_decoder = self.sample_encoder_Z(batch=batch_x)
        
        
        padding_num = torch.zeros((1, 2*self.dimZ), dtype=float)
        
        to_decoder1 = to_decoder.view(batch_size, -1)        
        to_decoder_I1 = torch.cat((to_decoder1[:batch_size-1,], to_decoder1[1:batch_size,]), axis=1)        
        to_decoder_I1 = torch.cat((to_decoder_I1, padding_num), axis = 0)
        
        z2_row2 = torch.randn(batch_size-1, 2*self.dimZ)
        to_decoder_I2 = torch.cat((to_decoder1[:batch_size-1,], z2_row2), axis=1) 
        to_decoder_I2 = torch.cat((to_decoder_I2, padding_num), axis = 0)
       
        decoder_logits_mean1 = torch.mean(self.decoder_logits(to_decoder_I1), dim=0)#lower bound L1的计算
        decoder_logits_mean2 = torch.mean(self.decoder_logits(to_decoder_I2), dim=0)#lower bound L2的计算</code>

在网上找了很久都没有找到原因,报错的地方在cat:

即在在数据拼接的时候,即一个数据在GPU0上,一个数据在GPU1上,这就会出现错误

解决办法:

一定要注意,产生随机数的地方也要用.to(device)


<code class="language-plaintext hljs">padding_num = torch.zeros((1, 2*self.dimZ), dtype=float).to(device)
z2_row2 = torch.randn(batch_size-1, 2*self.dimZ).to(device)</code>

哪些数据需要放到gpu上训练:

可以参考这篇文章python指定Gpu_python 指定gpu_三世的博客-CSDN博客


<code class="language-plaintext hljs">import torch
import time
 
 
#1.通常用法
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
data = data.to(device)
model = model.to(device)
'''
    1.先创建device对象
    2.to函数指定数据或者模型放到哪里
'''
 
#2.将构建的tensor或者模型放到指定设备上(GPU)
torch.device('cuda',0) #这里的0指的是设备的序号
torch.device('cuda:0')
 
 
#3.例子 cpu转到GPU
s = time.time()
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
a = torch.rand([1024, 1024, 10]).to(device)
print('time:{:6.3f}'.format(time.time()-s)) # 输出: time: 0.087
 
#4.例子2 Tensor GPU 转到cpu运行
 
 predict_boxes = predictions["boxes"].to("cpu").numpy()
 predict_classes = predictions["labels"].to("cpu").numpy()
 predict_scores = predictions["scores"].to("cpu").numpy()</code>

to(device)需要注意的是:

使用GPU训练的时候,需要将Module对象和Tensor类型的数据送入到device。通常会使用 to.(device)。但是需要注意的是:

对于Tensor类型的数据,使用to.(device) 之后,需要接收返回值,返回值才是正确设置了device的Tensor。

对于Module对象,只用调用to.(device) 就可以将模型设置为指定的device。不必接收返回值。


<code class="language-plaintext hljs"># Module对象设置device的写法
model.to(device)
 
# Tensor类型的数据设置 device 的写法。
samples = samples.to(device)</code>

其他cat可能会遇到的错误:

在多GPU训练时,遇到了下述的错误:
1. Expected tensor for argument 1 'input' to have the same device as tensor for argument 2 'weight'; but device 0 does not equal 1
2. RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:1 and cuda:0!

造成这个错误的可能性有挺多,总起来是模型、输入、模型内参数不在一个GPU上。本人是在调试RandLA-Net pytorch源码,希望使用双GPU训练,经过尝试解决这个问题,此处做一个记录,希望给后来人一个提醒。

经过调试,发现报错的地方主要是在数据拼接的时候,即一个数据在GPU0上,一个数据在GPU1上,这就会出现错误,相关代码如下:
return torch.cat((
self.mlp(concat),
features.expand(B, -1, N, K)
), dim=-3)

上述代码中,必须保证self.mlp(concat)与features.expand(B, -1, N, K)在同一个GPU中。在多GPU运算时,features(此时是输入变量)有可能放在任何一个GPU中,因此此处在拼接前,获取一下features的GPU,然后将concat放入相应的GPU中,再进行数据拼接就可以了,代码如下:
device = features.device
concat = concat.to(device)
return torch.cat((
self.mlp(concat),
features.expand(B, -1, N, K)
), dim=-3)

该源码中默认状态下device是一个固定的值,在多GPU训练状态下就会报错,代码中还有几处数据融合,大家可以依据上述思路做修改。此外该源码中由于把device的值写死了,训练好的模型也必须在相应的GPU中做推理,如在cuda0中训练的模型如果在cuda1中推理就会报错,各位可以依据此思路对源码做相应的修改。

原文链接: PyTorch 多GPU使用torch.nn.DataParallel训练参数不一致问题_runtimeerror: expected all tensors to be on the sa_微凉的衣柜的博客-CSDN博客
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/149501
推荐阅读
相关标签
  

闽ICP备14008679号