最近遇到一个神奇的bug,记录一下。
最开始上网搜索这个报错可能得原因,有好几种,我也一一排除了。
报错原因:
- 使用了并行运算,但只有单卡。
- 一部分数据或者模型在cpu上,另外一部分在gpu上。
- CUDNN版本不对
- 超显存了,可以减小batch size看下。
这些问题可以参考其他回答https://blog.youkuaiyun.com/captainAAAjohn/article/details/118162508
我一一检查过了,都不是这些问题,这让我实在是费解啊。
于是开始了漫长的debug过程。先说下我报错的位置:
def forward(self, x, x_patterns, pattern_keys, geo_mask=None, sem_mask=None):
B, T, N, D = x.shape
t_q = self.t_q_conv(x.permute(0, 3, 1, 2)).permute(0, 3, 2, 1)
起初以为是t_q_conv没放在GPU上,但最后还是报错。此处的x可以获取shape,也可以看device,但print的话直接报同样的错(an illegal memory)
大概发现问题了,就是这里传入的x就出问题,于是找到了
def forward(self, x, x_patterns, pattern_keys, geo_mask=None, sem_mask=None):
if self.type_ln == 'pre':
x = x + self.drop_path(self.st_attn(self.norm1(x), x_patterns, pattern_keys, geo_mask=geo_mask, sem_mask=sem_mask))
self.norm1(x)就是上面传入的x,然后发现原来self.norm1在CPU上,而x在GPU上,但self.norm1(x)输出的结果虽然也在GPU上,但已经变成了illegal memory,并且不会报错!!
总结:
某些结构虽然权重和输入不在同一个device,但仍然能运行得到一个 illegal memory且不会报错!!。
为避免这种错误,记得实例化模型的时候就将整个模型与输入放在同一个device上!!我就是在编写测试用例,忘了这回事,才遇到这个奇怪的bug。。。