代码之家  ›  专栏  ›  技术社区  ›  ihdv

火炬模块的某些成员不会被移到gpa,即使型号.to(设备)被调用

  •  0
  • ihdv  · 技术社区  · 6 年前

    import torch
    import torch.nn as nn
    
    class model(nn.Module):
        def __init__(self):
            super(model,self).__init__()
            self.mat = torch.randn(2,2)
    
        def forward(self,x):
            print('self.mat.device is',self.mat.device)
            x = torch.mv(self.mat,x)
            return x
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    m = model()
    m.to(device)
    
    x = torch.tensor([2.,1.])
    x = x.to(device)
    
    m(x)
    

    输出是

    self.mat.device is cpu
    

    就在那之后

    Traceback (most recent call last):
      File "Z:\cudatest.py", line 21, in <module>
        print(m(x))
      File "E:\Python37\lib\site-packages\torch\nn\modules\module.py", line 532, in __call__
        result = self.forward(*input, **kwargs)
      File "Z:\cudatest.py", line 11, in forward
        x = torch.mv(self.mat,x)
    RuntimeError: Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_mv
    

    如果我设置代码,代码可以正常工作 device = torch.device('cpu') . 看来问题是 model.mat 即使之后也不会移动到GPU m.to(device)

    1. 即使这个特定的例子可以用 self.mat = nn.Linear(2,2) x = self.mat(x) 相反,在我最初的程序中,我需要一个临时张量来存储一些数据 forward() 这在一些算法中也有使用。如何构造这样一个张量并在调用时发送给GPU m、 至(设备)

    2. 事先不知道计算机是否有GPU。因此,写作 self.mat = self.mat.cuda()

    0 回复  |  直到 6 年前
        1
  •  3
  •   Shai    6 年前

    应用模块的方法,例如 .cpu() , .cuda() .to() parameters buffers 不是 对普通的班级成员。Pythorch不知道这一点 self.mat ,在你的例子中,是一个实际的张量,应该移动。

    一旦你决定 mat 应该是一个参数或一个缓冲区,只需相应地注册它,例如。

    class model(nn.Module):
        def __init__(self):
            super(model,self).__init__()
            self.register_buffer(name='mat', tensor=torch.randn(2,2))