原帖在 Windows 的旧 nightly 构建上运行 DQN/LSTM 数小时后失败;改变 deterministic/benchmark 后仍会复现:
RuntimeError: cuDNN error: CUDNN_STATUS_INTERNAL_ERROR
八小时后失败,短测试只能验证其中一部分
原题更换 deterministic/benchmark 后仍复现,不能把这两个开关写成已证实解决方案。应留下随步数变化的内存、输入与回放状态,判断是累积资源问题还是某个特定批次触发。若没有失败前数据,重跑整场训练通常也难解释根因。
状态码不足以判断内存泄漏或 cuDNN bug。先缩小到某一批输入、某一步操作,并区分内存持续增长与特定输入触发。不要为验证猜测直接再跑一遍八小时。
在尚未出错的选动作/训练循环中,每隔固定步数记录版本、输入和分配器统计。state_tensor 是即将送入 LSTM 的张量:
import torch
print("josh050608")
print("versions:", torch.__version__, torch.version.cuda, torch.backends.cudnn.version())
print("state:", state_tensor.shape, state_tensor.dtype, state_tensor.device)
print("memory:", torch.cuda.memory_allocated(), torch.cuda.memory_reserved())
把需要回放的输入在失败前保留 CPU 副本,记录模型参数、随机种子与操作步骤。发生非法访问或 launch failure 后再打印 GPU 张量,可能只报告上下文已损坏的后续错误,应退出进程。
动作选择不需要梯度时,用 with torch.no_grad(): actions = agent.q_eval(state_tensor);经验回放里保存脱离计算图的 CPU 数据,日志保存 Python 数值。若 memory_allocated 持续上升,检查是否保留了带图的输出、hidden 或 loss;如果稳定,则不能据此认定泄漏。
在新进程开启 CUDA_LAUNCH_BLOCKING=1,用保存的小批次复现首个失败操作。再在匹配的稳定构建环境中做对照,每次只改一个因素。临时关闭 cuDNN 可作定位对照,但需要验证性能与数值影响。
最终要求小复现与正常训练都通过,并在计划的运行时长内观察;短测成功不能宣称数小时故障已解决。
先把经验回放与训练图分开
以下 CPU 例子展示经验缓存保存 detached 数据,动作选择关闭求导,训练分支仍能获得梯度。它不运行 DQN 环境,也不复现 cuDNN 的数小时故障:
import torch
from torch import nn
network = nn.Sequential(nn.Linear(3, 5), nn.ReLU(), nn.Linear(5, 2))
state = torch.randn(4, 3)
with torch.no_grad():
action = network(state).argmax(dim=1)
replay_state = state.detach().cpu().clone()
replay_action = action.detach().cpu().clone()
assert not replay_state.requires_grad and replay_state.grad_fn is None
assert replay_action.device.type == "cpu"
prediction = network(replay_state)
loss = prediction.square().mean()
loss.backward()
assert network[0].weight.grad is not None
print("replay/gradient:", replay_state.shape, network[0].weight.grad.norm().item())
真实 DQN 还要按算法正确处理目标网络、终止状态和回报;此例只检查缓存不携带无用计算图。若 LSTM hidden 跨训练片段复用,也需明确截断边界,不能长期积累旧图。
定期记录 memory_allocated 与 memory_reserved,以及回放条目数量和输入 shape。allocated 随步数持续上升时追踪活跃张量引用;reserved 上升后稳定可能是缓存分配行为,不能仅凭一项统计认定泄漏。若内存平稳,保存触发批次与当时模型状态,在新进程同步回放。
最终审核应区分“小例子接口通过”“失败批次可重现”“目标时长内稳定”三个层次。原帖的旧 nightly 可在匹配的稳定构建中做对照,但不能将换版本后一次短测成功写成八小时问题已解决。
参考:原始求助帖;技术依据:PyTorch CUDA 语义(2.5)、CUDA 内存统计(2.5)、PyTorch 后端设置(2.5)、PyTorch 自动求导(2.5)。