[Pytorch] RuntimeError: Attempting to deserialize object on CUDA device 2

Error description

raise RuntimeError('Attempting to deserialize object on CUDA device '
RuntimeError: Attempting to deserialize object on CUDA device 2 but torch.cuda.device_count() is 2. Please use torch.load with map_location to map your storages to an existing device.

Solved

  • 加载的模型是用两个GPU训练的,而加载模型的电脑只有一个GPU,所以会出错。
    我这里的配置是2张卡,所以torch.cuda.device_count的结果是2,可能因为训练/评估时–gpu_idx设置的都是0号卡,只有一张卡,所以还是不能满足两个GPU的要求。
    在这里插入图片描述
  • 修改:
model = torch.load(model_path)
改为:model = torch.load(model_path, map_location='cuda:0')

using map_location='cuda:0' to map all of your storages to cuda:0.

  • 愚蠢的问题:看走眼了,改了半天放在了torch.load函数括号外面了,怎么改都没用,真是被自己蠢哭了。qwq
    在这里插入图片描述

多GPU处理机制

  • PyTorch多GPU的处理机制
1.在各个GPU上初始化模型。
2.前向传播时,把batch分配到各个GPU上进行计算。
3.得到的输出在主GPU上进行汇总,计算loss并反向传播,更新主GPU上的权值。
4.把主GPU上的模型复制到其它GPU上。
  • pytorch 在保存训练模型的时候,会把训练过程中使用的设备号(例如gpu卡号cuda:0 ,cpu)也一并保存下来。

  • 当pytorch重新载入历史模型时,模型默认根据训练时的设备卡号,把权值载入到相应的卡号上。

  • 然而,有的时候测试过程和训练过程的设备情况是不一致的。

举个例子,A主机有四块GPU卡,然后我们用cuda:3 训练模型,并保存模型。
在测试时候,我们需要在客户的B主机跑模型,但是B主机只有一块gpu卡:cuda:0。

如果按照默认方式载入模型的话,pytorch会报找不到gpu设备,或其他一些错误。
此时,载入的时候需要做一个变换,为torch.load指定gpu设备的映射方式:

#模型的保存和加载
import torch
import json
import logger_wrappers
import os
destination_device='cuda:0'  #目标设备
model_CKPT = torch.load(path,map_location={
    
    'cuda:0':destination_device,'cuda:1':destination_device,'cuda:2':destination_device,'cuda:3':destination_device})

map_location是一个dict,里面的key表示存储模型的源设备号,value表示目的设备号。
{cuda:3:cuda:0}表示把历史模型里面原来放在cuda:3 的权重全部加载到cuda:0 设备上
{cuda:3:cpu}表示把历史模型里面原来放在cuda:3的权重全部加载到cpu 设备。

References

  1. PyTorch错误解决方案及技巧RuntimeError: Attempting to deserialize object on CUDA device 2
    https://blog.csdn.net/CVAIDL/article/details/105331886

  2. pytorch 载入历史模型时更换gpu卡号,map_location设置
    https://blog.csdn.net/jmh1996/article/details/111041108

猜你喜欢

转载自blog.csdn.net/weixin_44145782/article/details/117987307