你的 PyTorch 代码触发了 CUDA 设备端断言(device-side assert),导致 GPU 计算出错。这个错误通常发生在以下情况下:


1. 主要原因

  1. 索引超界(Index Out of Bounds)

    • 可能是 tensor[index] 访问的 index 超出了 tensor 的维度范围。
    • 典型示例:
      import torch
      x = torch.tensor([1, 2, 3], device="cuda")
      print(x[10])  # 超出索引范围
      
    • 解决方案:
      • 打印 index,确保索引在范围内。
      • 添加 assert 语句检查索引:
        assert index < x.size(0), f"Index {index} is out of bounds"
        
  2. 类别索引越界(分类任务)

    • 如果你的 target 变量(真实标签)超出了 num_classes 范围,可能导致错误:
      criterion = torch.nn.CrossEntropyLoss()
      logits = torch.randn(5, 10).cuda()  # 10 类
      target = torch.tensor([0, 1, 2, 15, 3]).cuda()  # 15 超出了 [0,9] 范围
      loss = criterion(logits, target)
      
    • 解决方案:
      assert target.max() < logits.size(1), f"Target index {target.max()} out of range"
      
  3. 张量 dtype 错误

    • CrossEntropyLoss 要求 targetLongTensor(整数索引)。
    • 错误示例:
      target = torch.tensor([0.0, 1.0, 2.0], device="cuda")  # float 类型错误
      
    • 解决方案:
      target = target.long()
      
  4. CUDA 计算溢出

    • 如果计算时发生 溢出(overflow)无效操作(NaN/Inf),CUDA 可能崩溃:
      x = torch.tensor([1e10, 1e20, 1e30], device="cuda")
      print(x.exp())  # 可能导致 NaN/Inf
      
    • 解决方案:
      • 使用 torch.isnan()torch.isinf() 进行检查:
        assert not torch.isnan(x).any(), "NaN detected!"
        assert not torch.isinf(x).any(), "Inf detected!"
        

2. 如何调试

由于 CUDA 错误是异步的,可能不会立即报错,建议使用 同步模式 进行调试:

方法 1:启用 CUDA_LAUNCH_BLOCKING=1

在终端运行:

export CUDA_LAUNCH_BLOCKING=1

或者在 Python 代码开头添加:

import os
os.environ["CUDA_LAUNCH_BLOCKING"] = "1"

这样可以 同步执行 CUDA 计算,让错误出现在真正的代码行,而不是异步 API 调用后才触发。


方法 2:启用 TORCH_USE_CUDA_DSA

从 PyTorch 1.9+ 开始,你可以启用 设备端断言(DSA),让 CUDA 提供更详细的错误信息:

export TORCH_USE_CUDA_DSA=1

然后运行代码,它可能会提供更具体的断言信息。


方法 3:在 CPU 上运行

如果你的模型可以在 CPU 上运行,尝试用 CPU 运行代码:

device = torch.device("cpu")
model.to(device)
inputs, labels = inputs.to(device), labels.to(device)

如果错误 只在 GPU 上发生,那么问题可能出在 CUDA 内核计算,例如:

  • 非法内存访问
  • 数据格式错误
  • GPU 计算中溢出/NaN

3. 总结

问题解决方案
索引超界assert index < tensor.size(0)
分类任务 target 越界assert target.max() < num_classes
target 数据类型错误target = target.long()
计算溢出(NaN/Inf)assert not torch.isnan(x).any()
CUDA 计算错误运行 export CUDA_LAUNCH_BLOCKING=1
获取详细调试信息运行 export TORCH_USE_CUDA_DSA=1
确保不是 GPU 问题先在 CPU 运行代码

你可以尝试 逐步检查数据,看看 target 是否越界、tensor 是否有 NaN,然后用 CUDA_LAUNCH_BLOCKING=1 定位具体错误行。
如果还有问题,可以贴上你的代码和错误日志,我可以帮你进一步分析!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐