原帖在 NVIDIA Docker 内用 RTX 2070 执行一个小 Conv1d,CPU 正常而 GPU 失败:
RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED
原题的小卷积本身就是有用的对照组
输入 [20,16,50] 与 Conv1d 的 16 个输入通道一致,规模也很小。优先在新容器进程独立运行它,再与项目失败情况比较。容器标注 CUDA 10.2 并不足以确认 torch 实际加载的 cuDNN 来源,更不能直接推出必须降到某个版本。
这段输入与卷积的通道数看起来一致。应先确认容器中的运行库、驱动可见性和是否已有 CUDA 错误,不能仅凭状态码认定某个版本缺陷。
在新启动的容器 Python 进程中执行最小检查:
import torch
from torch import nn
print("josh050608")
print("versions:", torch.__version__, torch.version.cuda, torch.backends.cudnn.version())
print("available:", torch.cuda.is_available())
m = nn.Conv1d(16, 33, 3, stride=2).cuda()
x = torch.randn(20, 16, 50, device="cuda")
y = m(x)
torch.cuda.synchronize()
print("output:", y.shape)
在宿主机和容器内分别运行 nvidia-smi,确认容器真正拿到 GPU;再记录容器镜像、torch 版本以及驱动。原帖只说容器 CUDA 10.2,不能据此推定 torch 实际加载了哪套 cuDNN。
如果最小例子失败,可以在另一个全新进程中临时设置 torch.backends.cudnn.enabled = False 再测试。若原生实现能运行,这只把问题缩小到 cuDNN 相关路径,不代表永久关闭就是最佳修复。结合显存占用、环境中的库搜索路径以及官方匹配构建继续检查。
如果最小例子正常,恢复项目代码直到第一次失败,排除更早的越界和上下文错误。不要一边替换系统 CUDA 库一边保留另一来源的 torch 二进制。
验证时应重新启用预期后端,完成同步前向与反向;仅 CPU 正常不能证明容器 CUDA 环境正常。
两次独立测试区分 cuDNN 路径
先使用默认后端运行前面的最小卷积;若失败,在另一个新 Python 进程中把 torch.backends.cudnn.enabled = False 放在模型调用前。两次记录同一组构建、驱动、输入与输出 shape,避免在已失败上下文里来回切设置。
以下是 CPU 上可独立运行的形状与梯度基准,保留原题参数,不验证 cuDNN:
import torch
from torch import nn
conv = nn.Conv1d(16, 33, kernel_size=3, stride=2)
x = torch.randn(20, 16, 50)
y = conv(x)
assert y.shape == (20, 33, 24)
loss = y.square().mean()
loss.backward()
assert conv.weight.grad is not None
assert torch.isfinite(conv.weight.grad).all()
print("CPU reference:", y.shape, loss.item())
当 CPU 基准通过、CUDA 小张量通过、只有 cuDNN 卷积失败,继续查匹配构建、显存和库加载来源。若连 CUDA 小张量都失败,应先解决容器 GPU 映射和驱动;若小卷积正常而真实模型失败,再定位具体输入和首个失败算子。
在宿主机及容器内分别记录 nvidia-smi 与镜像标识,容器中再运行 python -m torch.utils.collect_env。不要随意把系统目录的 cuDNN 复制进环境,让新旧来源混用。关闭 cuDNN 只是诊断分支;最终要在预期后端上完成前向、反向和真实小批次测试。
参考:原始求助帖;技术依据:PyTorch CUDA 语义(2.5)、PyTorch 后端设置(2.5)、PyTorch 历史安装组合;Conv1d 官方源码(2.5.1)。