出现的问题
写了一个Seq2Seq的中英翻译模型,使用Encoder-Decoder模式。训练时发现总是训练一段时间后就会报显存溢出的错误,训练终止。

根据报错信息可知,pytorch欲分配12.88G的显存,但我的显存只有4G,显然是不够的
寻找原因
从异常栈来看,报错问题出在我创建一个大小为 len(y) * batch_size * 30000
的tensor上
将 len(y) 和 batch_size 打印出来,发现异常处 len(y)=1579 ,正常情况下应该为35左右

pytorch为每个float类型数据分配4
字节内存,故上述tensor共需 1579 * 73 * 30000 *4 / (1024^3) = 12.88 G 的内存,这与错误信息相符。
len(y) 表示的是英语句子的分词长度(即把一个句子拆分成单词数组的长度),故去语料数据集中找到该条数据
找到出问题的语料(一个句子)发现是双引号导致的问题,句子中包含一个双引号,处理是误认为是字符串开始的标识符。关于这一点参见
问题解决
通过代码追踪发现,这个tsv文件是我自己生成的,生成过程中忽略了引号的转义,故重新生成并加上转义即可(删掉 quoting=csv.QUOTE_NONE 即可)

其他
如果是训练一段实际后才出现溢出问题,很有可能是代码或数据问题
如果是一开始就有问题,则可能是由于batch size过大导致
pytorch显存使用
- pytorch会根据代码需要向GPU申请显存空间
- 使用完该空间后pytorch并不会立即将其返还给GPU,而是继续保留
- 当代码继续向pytorch申请空间时,pytorch会先分配预留的空间,不够的话再向GPU申请
_故GPU显示的显存占用 = 代码的真实占用( torch.cuda.memory_allocated() ) + pytorch的预留空间( torch.cuda.memory_reserved() )_
这也是为什么训练过程已经结束,但代码并未退出时,查看显存占用依然很大的原因(用jupyter时很明显,不手动重启或终止内核它就会一直占用着)