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

如何解决PyTorch RuntimeError: 张量分属cpu和cuda:0设备报错

报错根因

该设备不匹配报错由3处代码错误导致,和权重文件本身无关:

  • 变量名混用是本次报错的核心诱因:加载模型时你新实例化的对象变量名为model,但修改分类头、循环推理时调用的都是训练阶段遗留的model_ft变量,两个是完全独立的对象。你检查到在GPU上的是新加载的model,实际跑前向传播的model_ft设备状态、结构、权重都和你预期的不一致。
  • 张量设备未对齐:推理循环中你仅将输入inputs移到了GPU,labels默认加载在CPU;同时模型输出的预测索引indices属于GPU张量,你直接将其赋值给CPU内存初始化的y_pred张量,触发跨设备操作报错。
  • 冗余设置:model.eval()被放在循环内部,每次迭代都会重复调用,虽然不会直接触发报错,但属于无意义的冗余操作。
修正后可运行代码

模型加载段

import torch
import torch.nn as nn
from torchvision import models

# 统一使用model_ft作为模型实例变量名,避免和旧变量混淆
model_ft = models.densenet161(pretrained=False, num_classes=11)
# 显式指定分类头结构,和训练时保持一致
model_ft.classifier = nn.Linear(2208, 11)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 加载权重时直接映射到目标设备,避免额外的设备转换开销
model_ft.load_state_dict(torch.load('/content/drive/My Drive/Stanford40/densenet161.pth', map_location=device))
model_ft = model_ft.to(device)
# 评估模式仅需设置一次,移到循环外部
model_ft.eval()

评估推理段

from torchvision import datasets

test_dataset = datasets.ImageFolder('/content/drive/My Drive/Stanford40/body/valid', transform=data_transforms['valid'])
test_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=1, shuffle=True)

class_names = test_dataset.classes
sample_count = len(test_dataset)
# 初始化结果存储张量时直接分配到对应设备,避免跨设备赋值报错
y_true = torch.zeros((sample_count, 1), device=device)
y_pred = torch.zeros((sample_count, 1), device=device)

# 关闭梯度计算,降低显存占用、提升推理速度
with torch.no_grad():
    for idx, (inputs, labels) in enumerate(test_dataloader):
        # 输入、标签均迁移到目标设备
        inputs = inputs.to(device)
        labels = labels.to(device)

        outputs = model_ft(inputs)
        y_true[idx][0] = labels

        _, pred_indices = torch.max(outputs, dim=1)
        y_pred[idx][0] = pred_indices

# 后续如果需要用CPU端的库(如sklearn)计算指标,再将结果迁回CPU即可
# y_true = y_true.cpu().numpy()
# y_pred = y_pred.cpu().numpy()
关键修改说明
  • 全程统一模型变量名为model_ft,彻底解决新旧变量混用导致的模型对象不匹配问题,从根源上避免“模型在GPU但实际推理用的是CPU上另一个模型”的问题
  • 加载权重时增加map_location=device参数,确保权重直接加载到目标设备,不会出现权重先加载到CPU再迁移的中间状态问题
  • 所有参与运算的张量(输入、标签、结果存储张量)均分配到和模型一致的设备上,完全消除跨设备操作的可能
  • 增加torch.no_grad()上下文管理器,推理阶段不保存梯度,可大幅降低显存占用
  • 直接通过数据集对象的内置方法获取样本总数,不依赖外部可能未定义的dataset_sizes变量,减少额外报错可能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:39:15