【问题标题】:RuntimeError: module must have its parameters and buffers on device cuda:1 (device_ids[0]) but found one of them on device: cuda:2RuntimeError:模块必须在设备 cuda:1 (device_ids[0]) 上有其参数和缓冲区,但在设备上找到其中之一:cuda:2
【发布时间】:2020-04-02 14:19:39
【问题描述】:

我有 4 个 GPU (0,1,2,3),我想在 GPU 2 上运行一个 Jupyter 笔记本,在 GPU 0 上运行另一个。因此,在执行后,

 export CUDA_VISIBLE_DEVICES=0,1,2,3

对于我使用的 GPU 2 笔记本,

device = torch.device( f'cuda:{2}' if torch.cuda.is_available() else 'cpu')
device, torch.cuda.device_count(), torch.cuda.is_available(), torch.cuda.current_device(), torch.cuda.get_device_properties(1)

在创建新模型或加载模型后,

model = nn.DataParallel( model, device_ids = [ 0, 1, 2, 3])
model = model.to( device)

然后,当我开始训练模型时,我得到了,

RuntimeError                              Traceback (most recent call last)
<ipython-input-18-849ffcb53e16> in <module>
 46             with torch.set_grad_enabled( phase == 'train'):
 47                 # [N, Nclass, H, W]
 ---> 48                 prediction = model(X)
 49                 # print( prediction.shape, y.shape)
 50                 loss_matrix = criterion( prediction, y)

~/.local/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
491             result = self._slow_forward(*input, **kwargs)
492         else:
--> 493             result = self.forward(*input, **kwargs)
494         for hook in self._forward_hooks.values():
495             hook_result = hook(self, input, result)

~/.local/lib/python3.6/site-packages/torch/nn/parallel/data_parallel.py in forward(self, *inputs, **kwargs)
144                 raise RuntimeError("module must have its parameters and buffers "
145                                    "on device {} (device_ids[0]) but found one of "
--> 146                                    "them on device: {}".format(self.src_device_obj, t.device))
147 
148         inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids)

RuntimeError: module must have its parameters and buffers on device cuda:0 (device_ids[0]) but found one of them on device: cuda:2

【问题讨论】:

  • DataParallel 要求在其device_ids 列表中的第一个设备上提供每个输入张量。它基本上将该设备用作分散到其他 gpus 之前的暂存区域,并且它是在从前向返回之前收集最终输出的设备。如果您希望设备 2 成为您的主要设备,我认为 device_ids = [2, 0, 1, 3] 会起作用,尽管我尚未对此进行测试。
  • 我同意你的观点,因为设置 device_ids = [2] 可以。我希望 DataParallel 文档在这方面做得更好。我将在今天晚些时候将此评论作为答案。谢谢!

标签: parallel-processing pytorch


【解决方案1】:

DataParallel 要求在device_ids 列表中的第一个设备上提供每个输入张量

它基本上将该设备用作暂存区域,然后再分散到其他 GPU,它是在从前向返回之前收集最终输出的设备。如果您希望设备 2 成为主要设备,则只需将其放在列表的前面,如下所示

model = nn.DataParallel(model, device_ids = [2, 0, 1, 3])
model.to(f'cuda:{model.device_ids[0]}')

之后提供给模型的所有张量也应该在第一个设备上。

x = ... # input tensor
x = x.to(f'cuda:{model.device_ids[0]}')
y = model(x)

【讨论】:

  • 不会做model.to(f'cuda:{model.device_ids[0]}') 只使用 GPU 2 并破坏模型并行的目的吗?
  • 我仍然得到RuntimeError: module must have its parameters and buffers on device cuda:1 (device_ids[0]) but found one of them on device: cuda:0
  • 该错误意味着我发布的 model.to 调用实际上是必要的。调用 model.to 后,你对模型参数或层做了什么吗?
  • 请注意,model.to 的重点是将模型中的缓冲区和参数移动到 device_id[0],因此如果您遇到此错误,则会发生导致缓冲区或参数不可用的事情被移动或在错误的设备上添加了新参数或缓冲区。
  • @Coddy 如果您无法弄清楚,请发布一个新问题,重现您所看到的错误,我会看看。
【解决方案2】:

这个错误发生在使用torch时,模型和数据都没有在cuda上:

尝试一些这样的代码在 cuda 上建模和数据集

model = model.toDevice(‘cuda’)
images = images.toDevice(‘cuda’)

【讨论】:

    【解决方案3】:

    对我来说,甚至以下工作:

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    if torch.cuda.device_count() > 1:
        print("Let's use", torch.cuda.device_count(), "GPUs!")
        network = nn.DataParallel(network)
    
    network.to(device)
    tnsr = tnsr.to(device)
    

    【讨论】:

    • 之所以有效,是因为device='cuda'device='cuda:0' 的同义词,DataParallel 是默认的主要设备。
    猜你喜欢
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 2020-11-16
    • 2020-10-06
    • 1970-01-01
    • 2023-01-04
    • 2021-05-31
    相关资源
    最近更新 更多