原帖训练一段时间后,在验证阶段创建 h0 时失败;错误同时提示 CUDA 异步报告:
RuntimeError: CUDA error: an illegal memory access was encountered
随机时刻报错,要保存首次失败所需的信息
原题训练一段时间后在验证阶段创建 hidden 报错。CUDA 异步执行时,显示的行可能只是同步或分配时发现更早的非法访问。set_device 和 benchmark 只能改变特定配置,不能据此证明已修复根因。先让失败批次可回放,再做后端对照。
不能据此认定 torch.zeros 本身非法。先重启进程,在任何 CUDA 调用之前开启 CUDA_LAUNCH_BLOCKING=1,寻找真正的首个失败操作。Windows PowerShell 可先执行 $env:CUDA_LAUNCH_BLOCKING="1",再运行脚本。
在 LSTM 的 forward 开头检查输入与参数:
p = next(self.parameters())
print("josh050608")
print("x:", x.shape, x.dtype, x.device, x.stride())
print("parameter:", p.dtype, p.device)
print("finite:", bool(x.isfinite().all()))
这里 x 是当前序列输入,self 是原题 LSTM 模型。对 batch_first=True,确认布局为 [N,L,input_dim],不要把所有训练集样本误作为一个无法承受的大 batch。
原题每次先建 CPU hidden 再 .cuda(),还先启用梯度再 detach。可简化为从输入派生设备和类型:
h0 = x.new_zeros(self.num_layers, x.size(0), self.hidden_dim)
c0 = x.new_zeros(self.num_layers, x.size(0), self.hidden_dim)
out, (hn, cn) = self.lstm(x, (h0, c0))
这能消除硬编码设备与无用图操作,但不能保证修复非法访问。若仍失败,保存失败前的 CPU 批次、shape 与版本,在新进程复现;检查更早的索引、扩展算子及后端路径。损坏的 CUDA 上下文中继续打印 GPU 张量可能只产生更多后续错误。
验证先用相同小批次连续做训练和验证,再观察长时间运行。原帖没有足够信息证实具体后端 bug,切换 benchmark 或 set_device 不应被当成通用答案。
hidden 按输入派生,再验证训练与预测
下面是可独立运行的 CPU 小模型,保留 batch_first 的序列布局,并让 hidden 的设备与 dtype 跟随输入。它不复现非法访问,只验证这段状态初始化及反向逻辑:
import torch
from torch import nn
class SequenceNet(nn.Module):
def __init__(self):
super().__init__()
self.rnn = nn.LSTM(3, 5, num_layers=2, batch_first=True)
self.fc = nn.Linear(5, 1)
def forward(self, x):
h0 = x.new_zeros(2, x.shape[0], 5)
c0 = x.new_zeros(2, x.shape[0], 5)
out, _ = self.rnn(x, (h0, c0))
return self.fc(out[:, -1, :])
model = SequenceNet()
x = torch.randn(2, 4, 3)
model.train()
loss = model(x).square().mean()
loss.backward()
assert model.rnn.weight_ih_l0.grad is not None
model.eval()
with torch.no_grad():
prediction = model(x)
assert prediction.shape == (2, 1)
print("train/eval:", loss.item(), prediction.shape)
在真实流程里记录失败前输入的 CPU 副本、shape、dtype、模型版本与随机状态;不要等 CUDA 上下文已损坏后才尝试 .cpu() 保存。输入有限性检查可发现脏数据,但数值含 NaN 本身也不能证明非法访问根因。
新进程同步定位后,若失败是索引或自定义扩展,先修具体越界;若集中在某个后端算子,再用相同输入与稳定匹配构建对照。短小例子通过只能说明布局和状态构造可行,原题的长时间 GPU 故障仍需要相应运行时长和失败数据验证。
参考:原始求助帖;技术依据:PyTorch CUDA 语义(2.5)、PyTorch CUDA 环境变量(2.5)、PyTorch 自动求导(2.5);LSTM 官方源码(2.5.1)。