运行时错误:输入类型(torch.FloatTensor)和权重类型(torch.cuda.FloatTensor)应该相同。

170
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for data in dataloader:
    inputs, labels = data
    outputs = model(inputs)

出现错误:

RuntimeError: 输入类型 (torch.FloatTensor) 和权重类型 (torch.cuda.FloatTensor) 应该相同

9个回答

283

你会遇到这个错误是因为你的模型在GPU上运行,但数据在CPU上。因此,你需要将输入张量发送到GPU。

inputs, labels = data                         # this is what you had
inputs, labels = inputs.cuda(), labels.cuda() # add this line

或者像这样,与您的其余代码保持一致:

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

inputs, labels = inputs.to(device), labels.to(device)

如果您的输入张量在GPU上,但模型权重不在GPU上,则会出现相同的错误。在这种情况下,您需要将模型权重发送到GPU。

model = MyModel()

if torch.cuda.is_available():
    model.cuda()

查阅cuda()的文档以及它的反义词cpu()


33

新的API是使用.to()方法。

优点明显且重要。 您的设备明天可能不再是“cuda”:

  • cpu
  • cuda
  • mkldnn
  • opengl
  • opencl
  • ideep
  • hip
  • msnpu
  • xla

因此请尽量避免model.cuda()。 检查设备并没有错。

dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

或者硬编码它:

dev=torch.device("cuda") 

同....一样:

dev="cuda"

一般情况下,您可以使用以下代码:

model.to(dev)
data = data.to(dev)

2
即使使用 to(device) 将模型和数据移动到 GPU 上,我仍然会收到错误信息 RuntimeError: Input, output and indices must be on the current device - Evan Zamir

4

注意(来自PyTorch文档):

如果self张量已经具有正确的torch.dtype和torch.device,则返回self。否则,返回的张量是具有所需的torch.dtype和torch.device的self的副本。

也就是说,您可能需要执行以下操作:

model = model.to("cuda")
data = data.to("cuda")

不要仅仅是:

model.to("cuda")
data.to("cuda")

采用第一种方法,你将会更安全。


这真是太准确了,正是我遇到的问题。供参考,以下链接显示了文档中引用的段落,来自回答作者 - https://pytorch.org/docs/stable/generated/torch.Tensor.to.html#torch.Tensor.to - undefined

4

如前面的回答中已经提到的,问题可能是您的模型在 GPU 上训练,但在 CPU 上测试。如果是这种情况,则需要将您的模型权重和数据从 GPU 移植到 CPU,方法如下:

device = args.device # "cuda" / "cpu"
if "cuda" in device and not torch.cuda.is_available():
    device = "cpu"
data = data.to(device)
model.to(device)

注意:这里仍然检查配置参数是否设置为GPU或CPU,以便此代码片段可用于训练(在GPU上)和测试(在CPU上)。


2

加载模型时,权重和输入必须在同一设备上。我们可以使用其他人指出的.to(device)来实现这一点。

然而,保存的权重和输入张量的数据类型可能不同。如果是这种情况,那么我们还必须更改模型权重和输入的数据类型:

model = torch.load(PATH).type(torch.FloatTensor).to(device)
input = input.type(torch.FloatTensor).to(device)

1

我有同样的问题,我的CNN模型:

class CNN(nn.Module):
   def __init__(self):
      super(CNN,self).__init__()
      self.device = torch.device(device)
      self.dummy_param = nn.Parameter(torch.empty(0))
      l1 = nn.Conv2d(3, 64,    kernel_size=(3, 3), stride=(1, 1), padding= (1,1)).to(device)
      l2 = nn.Conv2d(64, 128,  kernel_size=(3, 3), stride=(1, 1), padding=(1,1)).to(device)
      l3 = nn.Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)).to(device)
      l4 = nn.Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)).to(device)
      l5 = nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)).to(device)
      self.layers = [l1,l2,l3,l4,l5]
      self.layers = [l1,l2]

  def forward(self,x):
    features = []
    for l in self.layers:
  
      x = l(x)
      features.append(x)
  return features

我在Conv2d.to(device)中加入了代码,它对我很有效。


3
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人了解如何回答问题。在帮助中心中可以找到有关如何编写好答案的更多信息。 - Community

1
   * when you get this error::RuntimeError: Input type 
   (torch.FloatTensor) and weight type (torch.cuda.FloatTensor should 
   be the same
   # Move tensors to GPU is CUDA is available
   # Check if CUDA is available

  train_on_gpu = torch.cuda.is_available()

  If train_on_gpu:
      print("CUDA is available! Training on GPU...")
  else:
      print("CUDA is not available. Training on CPU...")

 -------------------
 # Move tensors to GPU is CUDA is available
if train_on_gpu:

model.cuda()

0
x = x.to(device, dtype=torch.float32)

y = y.to(device, dtype=torch.float32)

运行良好,没有问题...


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community
在我的情况下,这也很好用 :) - undefined

-1

首先检查是否可用cuda:

  if torch.cuda.is_available():
      device = 'cuda'
  else:
      device = 'cpu'

如果您想加载某些模型,请执行以下操作:
  checkpoint = torch.load('./generator_release.pth', map_location=device)
  G = Generator().to(device)

现在你可能会遇到这个错误:

RuntimeError: 输入类型(torch.FloatTensor)和权重类型(torch.cuda.FloatTensor)应该相同

需要将输入数据的类型从torch.tensor转换为torch.cuda.tensor:

if torch.cuda.is_available():
  data = data.cuda()
result = G(data)

然后将结果从torch.cuda.tensor转换为torch.tensor:

if torch.cuda.is_available():
    result = result.cpu()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接