CUDA 运行时错误 (59):触发设备端断言


THCudaCheck FAIL file=/opt/conda/conda-bld/pytorch_1524584710464/work/aten/src/THC/generated/../generic/THCTensorMathPointwise.cu line=265 error=59 : device-side assert triggered
Traceback (most recent call last):
File "main.py", line 109, in <module>
train(loader_train, model, criterion, optimizer)
File "main.py", line 54, in train
optimizer.step()
File "/usr/local/anaconda35/lib/python3.6/site-packages/torch/optim/sgd.py", line 93, in step
d_p.add_(weight_decay, p.data)
RuntimeError: cuda runtime error (59) : device-side assert triggered at /opt/conda/conda-bld/pytorch_1524584710464/work/aten/src/THC/generated/../generic/THCTensorMathPointwise.cu:265

如何解决此错误?

这通常是一个索引问题。

例如,如果真实面标签从 1 开始:

target = [1,2,3,4,5]

然后,您应该为每个标签减去1,以便:

target = [0,1,2,3,4]

通常,当遇到cuda runtine error时,建议使用CUDA_LAUNCH_BLOCKING=1标志再次运行程序以获得准确的堆栈跟踪。

在您的特定情况下,数据的目标对于指定数量的类来说太高(或太低)。

我在运行BertModel.from_pretrained('bert-base-uncased')时遇到了这个错误。当错误消息更改为"索引错误:索引超出自身范围"时,我通过移动到 CPU 找到了解决方案。 这让我想到了这篇文章。 解决方案是将句子截断为长度 512。

引发"CUDA 错误:设备端断言触发"RuntimeError的一种方法是使用具有维度外索引的list索引到 GPUtorch.Tensor

因此,此代码段将引发一个IndexError,并显示消息"索引错误:索引 3 超出大小为 0 的维度 3 的界限",而不是 CUDA 错误

data = torch.randn((3,10), device=torch.device("cuda"))
data[3,:]

然而,这将引发 CUDA"设备端断言触发"RuntimeError

data = torch.randn((3,10), device=torch.device("cuda"))
indices = [1,3]
data[indices,:]

这可能意味着,在类标签的情况下,例如在 @Rainy 的答案中,当标签从 1 而不是 0 开始时,导致错误的是最终的类标签(即label == num_classes时)。

此外,当设备"cpu"抛出的错误是IndexError例如第一个代码段引发的错误。

当我有一个具有无效值的标签时,我发现我遇到了此错误。

如果您先切换到 CPU,此错误可能会更加详细。切换到 CPU 后,它将显示确切的错误,这很可能与索引问题有关,即 IndexError:目标 2 在我的情况下越界,在您的情况下可能相关。 问题是"你当前使用了多少个类,你的输出形状是什么?",你可以找到这样的类

max(train_labels)
min(train_labels)

在我的情况下给了我 2 和 0,问题是由缺少 1 个索引引起的,所以一个快速的技巧是快速将所有 2 替换为 1s ,这可以通过以下代码完成:

train_=train.copy()
train_['label'] =train_['label'].replace(2,1)

然后你运行相同的代码并查看结果,它应该可以工作

class NDataset(torch.utils.data.Dataset):
def __init__(self, encodings, labels):
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx):
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
item['labels'] = torch.tensor(self.labels[idx])
return item
def __len__(self):
return len(self.labels)
train_dataset = NDataset(train_encodings, train_labels)
val_dataset = NDataset(val_encodings, val_labels)
test_dataset = NDataset(test_encodings, test_labels)

当实例的输入令牌长度大于模型的最大值时,以及当输入长度大于max_output_length预测参数时,我就会发生这种情况。

另一种情况可能会发生这种情况:您正在训练的数据集的类数比上一层预期的要多。这是另一个意想不到的指数情况

当bce 或 ce 损失的目标或标签为 <= 0 时,我多次发生。

这也可能是由模型输入数据中的 nan 值引起的。"处理"此问题的一种简单方法是将任何弹出的内容即时转换为零:

batch_data = batch_data[batch_data != batch_data] = 0

我希望你的问题得到解决,但我面对这个问题,花了将近 2 个小时来解决它,所以我将在这里为像我这样的人解释问题和解决方法。
由于类标签,我遇到了这个问题。
我的项目是关于三个类的情绪分析,所以我用值标记数据集:-1、0、1(输出层中的 3 个节点),它导致了我的问题!
所以我用值 0、1、2 重新标记数据集,它得到了解决。从 0 开始标记样本很重要(PyTorch 使用 index 作为类标签,所以你应该小心)。
对于遇到错误说 set CUDA_LAUNCH_BLOCKING = 1 的人,您应该在导入 PyTorch 之前使用此命令:os.environ['CUDA_LAUNCH_BLOCKING'] = "1",如果您遇到相同的错误(没有更多关于错误的信息),您应该按 CPU 运行脚本并重试(这次您可能会获得有关问题的新信息)。

当我使用拥抱面变压器模型LongformerEncoderDecoder (LED)并且将解码器长度设置得太大时,我遇到了此错误。在我的情况下,解码器的默认最大长度为 1024。

希望这对某人有所帮助

最新更新