Python PyTorch嵌入层提高了“;期望…cuda…但得到…cpu“;错误
我正在将PyTorch模型从CPU()转换为GPU()。错误消息(剪切到重要位)如下所示:Python PyTorch嵌入层提高了“;期望…cuda…但得到…cpu“;错误,python,gpu,pytorch,Python,Gpu,Pytorch,我正在将PyTorch模型从CPU()转换为GPU()。错误消息(剪切到重要位)如下所示: --------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-12-a7bb230c924c> in <module&
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-12-a7bb230c924c> in <module>
1 model = FeedforwardTabularModel()
2 model.cuda()
----> 3 model.fit(X_train_sample.values, y_train_sample.values)
<ipython-input-11-40b1edae7417> in fit(self, X, y)
100 for epoch in range(self.n_epochs):
101 for i, (X_batch, y_batch) in enumerate(batches):
--> 102 y_pred = model(X_batch).squeeze()
103 # scheduler.batch_step() # Disabled due to a bug, see above.
104 loss = self.loss_fn(y_pred, y_batch)
[...]
/opt/conda/lib/python3.6/site-packages/torch/nn/functional.py in embedding(input, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq, sparse)
1482 # remove once script supports set_grad_enabled
1483 _no_grad_embedding_renorm_(weight, input, max_norm, norm_type)
-> 1484 return torch.embedding(weight, input, padding_idx, scale_grad_by_freq, sparse)
1485
1486
RuntimeError: Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_index_select
这种类型的错误通常发生在模型中存在张量时,该张量应位于GPU上,而不是CPU上。但据我所知,我已经在所有必要的地方调用了.cuda()
:每次声明torch.tensor
,并在model.fit
之前运行model.cuda()
导致此错误的原因是什么?您是否可以尝试将X\u batch、y\u batch也移动到cuda,如
X\u batch.cuda()
和y\u batch.cuda()
,数据加载程序可能需要首先在CPU上处理数据(无序),这可能会导致问题
希望它能帮助其他论坛上的人提供解决方案: Pytorch要求您执行
self.module_name=module
,以确保各项工作正常进行。把它们列在一个清单上是可以的。只需对循环中的每个步骤执行类似于setattr(self,'emb{}.format(i),emb)
的操作
因为我在列表中管理嵌入层,而PyTorch要求所有层都注册为模型对象上的属性,所以调用
model.cuda()
时,它们不会自动移动到GPU内存中。狡猾 这段简单的代码显示了我如何解决错误:
device = 'cuda'
x = torch.LongTensor([0, 1, 2])
x = x.to(device)
emb = nn.Embedding(3, 5)
emb.weight = nn.Parameter(emb.weight.to(device)) # Moving the weights of the embedding layer to the GPU
x = emb(x)
不确定这是否是一种有效的方法,但目前看来似乎有效。更好的方法:
class DeepLinear(nn.Module):
def __init__(self, dim: int, depth: int):
super(DeepLinear, self).__init__()
self.depth = depth
self.linear = []
for _ in range(depth):
self.linear.append(nn.Linear(dim, dim))
self.linear = nn.ModuleList(self.linear)
def forward(self, inputs):
for i in range(self.depth):
inputs = self.linear[i](inputs)
return inputs
正如上面的代码,使用nn.ModuleList包装包含层的列表变量是一个好主意,但不幸的是,这并没有解决错误。嗨@AlekseyBilogur,你仍然会遇到同样的错误吗?其他论坛上的某个人回答了我的问题,我已将其作为答案发布。顺便说一句,你的建议是一批一批地移动数据,而不是一次移动所有数据。非常感谢分享你的答案。这解决了我的问题。@Fardin另一个更好的方法:nn.ModuleList(self.linear)
class DeepLinear(nn.Module):
def __init__(self, dim: int, depth: int):
super(DeepLinear, self).__init__()
self.depth = depth
self.linear = []
for _ in range(depth):
self.linear.append(nn.Linear(dim, dim))
self.linear = nn.ModuleList(self.linear)
def forward(self, inputs):
for i in range(self.depth):
inputs = self.linear[i](inputs)
return inputs