老肥近期参加Kaggle平台的比赛,因为比赛类型为Code Competition
,测试数据并不可见,我们需要将notebook代码在线提交进行推理,而因为测试集不可以见经常会遇到提交Error,同时报错完整的日志并不返回,只返回错误大类类型,在Debug时有一定程度上的困难。今天我便将之前遇到过的一些报错以及如何排查来做一个简单的总结回顾,使得自己在今后的提交尽量避免出错。
我们首先假设我们所要提交notebook在kaggle的notebook环境上能够正常运行,并且成功保存为新的版本,接下来对以下报错进行逐一分析(通常我们碰到的为前三类报错)。
因为比赛所给出的sample_test文件仅包含极少量数据,最后线上用来预测的测试集可能和公开的数据集有差异的情况,这便是导致异常的罪魁祸首。举个曾经遇到过的例子,当我们使用Label Encoder
对类别变量进行编码时,测试集中可能存在未曾出现过的类别,导致异常抛出。我们需要提高代码的健壮性,以应对未知测试集可能带来的异常情况。
根据不同比赛的时间限制不同,我们需要在指定的时间内完成推理。为了避免超时错误,我们需要合理估计模型的推理时间,根据测试集的长度使用训练集来模拟推理(可以采用1/5、1/10的测试集数量的训练集以节约GPU时长)。超时错误经常发生在比赛后期多个模型进行融合时,我们应该控制整个推理时长在指定的时间内。除此之外,我们可以对代码进行优化,提升模型推理的速度,例如在Feedback
比赛中,根据@hengck23在讨论区所提到的,我们可以对text的长度进行排序,将长度相仿的数据放入同个batch中,在batch中取最长的token来进行padding的方法以减少不必要的时间消耗(此方法提升推理速度约为6倍)。
出现这种计算资源耗尽的问题通常有两种情况,一是显存在推理时超出16G
爆掉,二是内存在推理时超出13G
。
我近期遇到的主要是使用内存超过容量,我们可以通过训练集制作与测试集大小相仿的数据,模拟进行推理,(模拟推理的时候可以采用输出与模型推理生成的结果形状尺度相同的随机数以节约宝贵的GPU时间),并时刻检查notebook的内存情况。
def memory_used_to_str():
# https://stackoverflow.com/questions/61366458/how-to-find-memory-usage-of-kaggle-notebook
pid = os.getpid()
processs = psutil.Process(pid)
memory_use = processs.memory_info()[0] / 2. ** 30
return 'ram memory gb :' + str(np.round(memory_use, 2))
我们需要及时清除中间变量,并且尽可能的将代码调优以使用更小的内存空间。
对于显存超过容量的问题,我们可以使用较小的batch_size
, 并且在加载完前一个模型并且完成推理保存结果后,及时清除显存
,然后加载下一个模型。对于huggingface中预训练模型的加载,我们可以通过使用from_config
而不是from_pretrained
,后者可能会有异常的显存泄露导致OOM(来自@阁老师的discuss)。
该错误是指比赛所指定的submission.csv文件未能找到。一种情况是我们生成的文件名不符合要求,注意生成的提交文件一定需要命名为submission.csv
而不是其他;另外一种情况是notebook在运行时,遇到错误停止运行,未能生成提交文件。
我们需要按照比赛要求生成对应的提交文件,保证该提交文件的行数以及列数满足要求,保证输出的内容符合规范,以避免提交值无效,造成得分异常。
这种错误情况非常罕见,主要是平台内部导致的一些异常错误,我们仅需重新提交运行即可。
如果在以上错误排查后,仍然未能成功提交,请毫不犹豫地在Discuss区说出自己遇到的问题,热心的社区网友会给予有用的建议。最后,祝大家上分快乐,Happy Kaggling!