Jupyter Lab GPU运行异常:代码报错且nvidia-smi显示GPU闲置
问题:PyTorch模型未实际调用GPU且设备不匹配报错
Jupyter Lab显示正在使用GPU,但nvidia-smi显示GPU处于闲置状态;运行GPU密集型代码时,两块GPU利用率均为0%,进程列表无对应脚本,说明GPU未被实际调用。
通过PyTorch检测设备的代码及输出如下:
import torch # 显示PyTorch版本 print(torch.__version__) # 检查CUDA是否可用 print('Is CUDA available?', torch.cuda.is_available())
输出:
1.13.1+cu117 Is CUDA available? True
核心Net类代码如下:
class Net(nn.Module): device = torch.device("cuda") # 手动添加的设备定义 def __init__(self, n_vocab, embedding_dim, hidden_dim, dropout=0.2): super(Net, self).__init__() self.embedding_dim = embedding_dim self.hidden_dim = hidden_dim # dim = dimension embedding_dim.to(device) # 手动添加的代码 self.embeddings = nn.Embedding(n_vocab, embedding_dim) # LSTM层 (input_size, hidden_size) self.lstm = nn.LSTM(embedding_dim, hidden_dim, dropout=dropout) # 全连接层,将隐藏状态映射到输出 self.hidden2out = nn.Linear(hidden_dim, n_vocab) def forward(self, seq_in): seq_in.to(device) # 手动添加的代码 embeddings = self.embeddings(seq_in.t()) lstm_out, _ = self.lstm(embeddings) ht = lstm_out[-1] out = self.hidden2out(ht) return out
代码运行时在embeddings = self.embeddings(seq_in.t())行抛出RuntimeError:
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! (when checking argument for argument index in method wrapper__index_select)
解决方案
错误根源在于模型参数与输入Tensor的设备不匹配,同时存在几处无效的设备操作,具体修改如下:
修改后的Net类代码
import torch import torch.nn as nn class Net(nn.Module): def __init__(self, n_vocab, embedding_dim, hidden_dim, dropout=0.2): super(Net, self).__init__() # 定义设备,增加CPU fallback逻辑 self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") self.embedding_dim = embedding_dim self.hidden_dim = hidden_dim # 定义模型层 self.embeddings = nn.Embedding(n_vocab, embedding_dim) self.lstm = nn.LSTM(embedding_dim, hidden_dim, dropout=dropout) self.hidden2out = nn.Linear(hidden_dim, n_vocab) # 将所有模型参数移动到指定设备 self.to(self.device) def forward(self, seq_in): # 将输入Tensor移动到模型所在设备,必须重新赋值(to()默认不原地修改) seq_in = seq_in.to(self.device) # 转置后传入Embedding层 embeddings = self.embeddings(seq_in.t()) lstm_out, _ = self.lstm(embeddings) ht = lstm_out[-1] out = self.hidden2out(ht) return out
关键修改点说明
- 移除无效的
embedding_dim.to(device):embedding_dim是整数,不是Tensor,to()方法仅对Tensor和Module有效,这行代码完全没用。 - 类属性
device改为实例属性self.device:避免类属性共享导致的潜在问题,同时增加CPU fallback,确保无GPU环境也能运行。 - 添加
self.to(self.device):在初始化时将所有模型层(Embedding、LSTM、Linear)的参数统一移动到GPU,这是模型调用GPU的核心步骤。 - 修改
seq_in.to(device)为seq_in = seq_in.to(self.device):to()方法默认返回新的Tensor,原Tensor仍在CPU上,必须接收返回值才能让输入Tensor真正移动到GPU。
验证步骤
实例化模型后,可通过以下代码确认模型参数是否已在GPU上:
# 替换为你的实际参数值 model = Net(n_vocab=1000, embedding_dim=128, hidden_dim=256) print(next(model.parameters()).device) # 正常输出应为 cuda:0
内容的提问来源于stack exchange,提问作者Raptor
相关产品推荐
相关产品推荐

