Pytorch踩坑:RuntimeError: cuda runtime error (59) : device-side assert triggered at /home/tv/pytorch

PyTorch 的即时执行模型的美妙之处在于可以实际调试程序。但是,有时 CUDA 执行的异步特性使调试变得困难。下面是调试程序的一个小技巧。

当使用 CUDA 操作运行 PyTorch 程序时,程序通常不会等到计算完成,而是继续向 GPU 投掷指令,直到它需要实际结果(例如,使用 .item() 或 .cpu() 或打印进行评估)。

虽然这种行为是PyTorch程序性能极快的关键,但有一个缺点:当cuda操作失败时,你的程序早就继续做其他事情了。通常的症状是,在触发错误的指令之后,在或多或少的随机位置出现非常非描述性错误。它通常如下所示:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
 in ()
      1 loss = torch.nn.functional.cross_entropy(activations, labels)
      2 average = loss/4
----> 3 print(average.item())

RuntimeError: cuda runtime error (59) : device-side assert triggered at /home/tv/pytorch/pytorch/aten/src/THC/generic/THCStorage.cpp:36

这个报错很难理解,我们只能知道有些地方出错了。
下面是导致此输出的错误程序:

import torch
device = torch.device('cuda:0')
activations = torch.randn(4,3, device=device) # usually we get our activations in a more refined way...
labels = torch.arange(4, device=device)
loss = torch.nn.functional.cross_entropy(activations, labels)
average = loss/4
print(average.item())

其中一种调试方法是移动到 CPU执行。
但是,通常,我们使用库或有复杂的东西,这不是一个好的选项。那现在怎么办?如果我们能得到一个详细的追溯(traceback),我们应该能立即发现问题。

获得良好的追溯的方法:
1. 您可以把环境变量CUDA_LAUNCH_BLOCKING设置为 1 启动程序。
但你可以看到,我喜欢用Jupyter做我的很多工作,所以这没有那么容易。
2. 但是,这也可以解决:在程序的顶部,在导入所有包(特别是 import PyTorch)之前,插入

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

在加入了上面这句话之后,我们对错误有了更好的追溯(traceback):

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
 in ()
----> 1 loss = torch.nn.functional.cross_entropy(activations, labels)
      2 average = loss/4
      3 print(average.item())

/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in cross_entropy(input, target, weight, size_average, ignore_index, reduce)
   1472         >>> loss.backward()
   1473     """
-> 1474     return nll_loss(log_softmax(input, 1), target, weight, size_average, ignore_index, reduce)
   1475 
   1476 

/usr/local/lib/python3.6/dist-packages/torch/nn/functional.py in nll_loss(input, target, weight, size_average, ignore_index, reduce)
   1362                          .format(input.size(0), target.size(0)))
   1363     if dim == 2:
-> 1364         return torch._C._nn.nll_loss(input, target, weight, size_average, ignore_index, reduce)
   1365     elif dim == 4:
   1366         return torch._C._nn.nll_loss2d(input, target, weight, size_average, ignore_index, reduce)

RuntimeError: cuda runtime error (59) : device-side assert triggered at /home/tv/pytorch/pytorch/aten/src/THCUNN/generic/ClassNLLCriterion.cu:116

很显然,是损失函数处报错。事实上,我们的输入的形状为:batch x 3,所以我们只允许三个类别 (0, 1, 2), 但标签值取到了3!

这种方法的好处是,也适用于有一定复杂度的例子。

原文链接:Debugging CUDA device-side assert in PyTorch

你可能感兴趣的:(Pytorch神经网络)