RuntimeError: 预计所有张量都在同一设备上,但发​​现至少有两个设备,cuda:0 和 cpu!恢复训练时

Ido*_* Do 5 python runtime-error deep-learning pytorch

我在 gpu 上训练时保存了一个检查点。重新加载检查点并继续训练后,我收到以下错误。

Traceback (most recent call last):
  File "main.py", line 140, in <module>
    train(model,optimizer,train_loader,val_loader,criteria=args.criterion,epoch=epoch,batch=batch)
  File "main.py", line 71, in train
    optimizer.step()
  File "/opt/conda/lib/python3.7/site-packages/torch/autograd/grad_mode.py", line 26, in decorate_context
    return func(*args, **kwargs)
  File "/opt/conda/lib/python3.7/site-packages/torch/optim/sgd.py", line 106, in step
    buf.mul_(momentum).add_(d_p, alpha=1 - dampening)
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
Run Code Online (Sandbox Code Playgroud)

我的训练代码是:

def train(model,optimizer,train_loader,val_loader,criteria,epoch=0,batch=0):
    batch_count = batch
    if criteria == 'l1':
        criterion = L1_imp_Loss()
    elif criteria == 'l2':
        criterion = L2_imp_Loss()
    if args.gpu and torch.cuda.is_available():
        model.cuda()
        criterion = criterion.cuda()

    print(f'{datetime.datetime.now().time().replace(microsecond=0)} Starting to train..')
    
    while epoch <= args.epochs-1:
        print(f'********{datetime.datetime.now().time().replace(microsecond=0)} Epoch#: {epoch+1} / {args.epochs}')
        model.train()
        interval_loss, total_loss= 0,0
        for i , (input,target) in enumerate(train_loader):
            batch_count += 1
            if args.gpu and torch.cuda.is_available():
                input, target = input.cuda(), target.cuda()
            input, target = input.float(), target.float()
            pred = model(input)
            loss = criterion(pred,target)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            ....
Run Code Online (Sandbox Code Playgroud)

保存过程发生在每个纪元结束后。

torch.save({'epoch': epoch,'batch':batch_count,'model_state_dict': model.state_dict(),'optimizer_state_dict':
                    optimizer.state_dict(),'loss': total_loss/len(train_loader),'train_set':args.train_set,'val_set':args.val_set,'args':args}, f'{args.weights_dir}/FastDepth_Final.pth')
Run Code Online (Sandbox Code Playgroud)

我不知道为什么我会收到这个错误。args.gpu == True ,我将模型、所有数据和损失函数传递给 cuda,不知何故 cpu 上仍然有一个张量,有人能弄清楚出了什么问题吗?

谢谢。

小智 30

确保添加.to(device)到模型和模型输入。

  • `模型 = model.to(设备)` (18认同)

小智 12

对我来说它可以添加

model.to('cuda')
Run Code Online (Sandbox Code Playgroud)

设置模型后立即:

class Agent:
def __init__(self):
    self.n_game = 0
    self.epsilon = 0 # Randomness
    self.gamma = 0.9 # discount rate
    self.memory = deque(maxlen=MAX_MEMORY) # popleft()
    self.model = Linear_QNet(11,256,3)                         # here
    self.model.to('cuda')                                      # and here
    self.trainer = QTrainer(self.model,lr=LR,gamma=self.gamma)
Run Code Online (Sandbox Code Playgroud)


Aay*_*hah 11

如果您像我一样仍然面临问题,那么该问题可能与“标记器”有关。您将模型带到GPU ,但不是标记化的 ID!

所以,请确保您遵循以下步骤:

model = AutoModelForCausalLM.from_pretrained("EleutherAI/gpt-neo-125M")
model.to(device)

tokenizer = AutoTokenizer.from_pretrained("EleutherAI/gpt-neo-125M")

input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(device) # This line.
Run Code Online (Sandbox Code Playgroud)

然后你就可以安全地从模型中进行推断了!


Sha*_*hai 5

设备参数可能存在问题

如果您需要通过 将模型移动到 GPU .cuda(),请在为其构建优化器之前执行此操作。.cuda()调用之后模型的参数将是与调用之前不同的对象。
通常,在构建和使用优化器时,您应该确保优化的参数位于一致的位置。

  • 将 `.cuda()` 添加到输入数据为我解决了这个问题:`pred = model(x.cuda())` (14认同)