You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中model.cuda()执行报错RuntimeError求助

解决PyTorch中调用.cuda()时的RuntimeError:Variable data has to be a tensor, but got torch.cuda.FloatTensor

嘿,我马上就发现了问题的根源!你遇到的这个报错看起来有点迷惑——torch.cuda.FloatTensor明明就是张量啊,怎么会说不是呢?其实问题出在你TR_LSTM模型的init_hidden方法里,咱们一步步拆解:

错误原因分析

在你的init_hidden方法中,你做了两个不该做的操作:

  • 把初始隐藏状态h_0和c_0转换成了torch.nn.Parameter
  • 提前对这两个张量调用了.cuda()

这两个操作结合起来导致了问题:

  1. Parameter的误用:LSTM的初始隐藏状态是每次前向传播的临时输入,不是模型需要训练的参数,完全不需要封装成Parameter。当你把它们定义为Parameter后,PyTorch会把它们当作模型的可训练参数来管理。
  2. 提前移动设备冲突:你提前把h_0和c_0移到了GPU,之后调用model.cuda()时,PyTorch会遍历所有模型参数(包括你错误定义的这两个Parameter),尝试把它们的data再次移到GPU,这就触发了这个看似矛盾的报错。

解决方案:修改init_hidden方法

把init_hidden改成下面这样,移除Parameter封装和提前.cuda()的操作,而是根据当前模型所在的设备来创建张量:

class TR_LSTM(nn.Module):
    def __init__(self,args, use_hidden_average=False, pretrained_emb = None):
        super(TR_LSTM,self).__init__()
        # 参数
        self.emb_dim = args.embed_dim
        self.emb_num = args.embed_num
        self.num_hidden_unit = args.hidden_state_dim
        self.num_lstm_layer = args.num_lstm_layer
        self.use_hidden_average = use_hidden_average
        self.batch_size = args.batch_size
        # 网络层
        self.embed = nn.Embedding(self.emb_num, self.emb_dim)
        if pretrained_emb is not None:
            self.embed.weight.data.copy_(pretrained_emb)
        self.lstm_layer = nn.LSTM(self.emb_dim, self.num_hidden_unit, self.num_lstm_layer, batch_first = True)
        self.fc_layer = nn.Sequential(nn.Linear(self.num_hidden_unit,self.num_hidden_unit),
                                      nn.Linear(self.num_hidden_unit,2))
    def forward(self,x):
        x = self.embed(x) # batch * max_seq_len * emb_dim
        h_0,c_0 = self.init_hidden(x.size(0))
        x, (_, _) = self.lstm_layer(x, (h_0,c_0)) # batch * seq_len * hidden_unit_num
        if not self.use_hidden_average:
            x = x[:,x.size(1)-1,:]
            x = x.squeeze(1)
        else:
            x = x.mean(1).squeeze(1)
        x = self.fc_layer(x)
        return x
    def init_hidden(self,batch_size):
        # 移除Parameter封装,并且使用模型的设备来创建张量
        device = next(self.parameters()).device
        h_0 = torch.zeros(self.num_lstm_layer, batch_size, self.num_hidden_unit, device=device)
        c_0 = torch.zeros(self.num_lstm_layer, batch_size, self.num_hidden_unit, device=device)
        return h_0, c_0

额外说明

  • 你提到修改epoch参数后问题出现,改回去也没解决——这其实是巧合,问题的本质和epoch无关,只是刚好在调整epoch时触发了报错,实际是init_hidden的写法错误导致的。
  • 使用next(self.parameters()).device可以自动获取模型当前所在的设备(CPU或GPU),这样不管你是先调用model.cuda()还是先执行前向传播,隐藏状态都会自动匹配设备,避免设备不匹配的问题。

内容的提问来源于stack exchange,提问作者Peter Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:10:16