返回列表

8th place solution

574. CommonLit - Evaluate Student Summaries | commonlit-evaluate-student-summaries

开始: 2023-07-12 结束: 2023-10-11 智能评测 数据算法赛
作者:Adam Montgomerie
排名:第8名
发布时间:2023-10-12

解决方案概述

我按照 prompt_id 将数据分为4折并计算了4折交叉验证。但提交时没有使用全部4个模型进行推理,而是在100%的训练数据上重新训练。最终的提交结果是6个DeBERTa-v3-large模型的集成:从我得分最高的3组实验中,每组选取2个不同随机种子的模型。我采用了6个模型预测结果的简单平均值。

源代码

我主要使用Python脚本而非Notebook工作。这里有一个包含我训练和推理脚本的代码库:https://github.com/AMontgomerie/commonlit-summaries-competition

输入与最大长度

除了使用摘要文本外,我发现加入 prompt_question 能略微提升分数,而使用 prompt_text 在同时增加最大长度的情况下帮助相当大。增加最大长度在训练时只对1024个token以内有效,但在推理时增加到1536个token既改善了CV分数(在 ebad26 提示上)也提高了LB分数。

很难判断是否值得继续增加到1536以上,因为训练集中的提示都不够长,而且当我增加到2048时,LB分数也没有持续改善。

特殊Token

另一个有效的改进是为输入的每个部分添加特殊token,而不是使用 [SEP]。我在训练前向tokenizer添加了 <text><question><summary> token,然后对它们进行微调。输入格式如下:

"<question> 这里放提示问题文本。 <summary> 这里放学生摘要文本。 <text> 这里放原始提示文本。"

我将提示文本放在最后,以应对需要截断的极长文本情况。

我也尝试过添加提示标题和 <title> token,但这并没有改善CV分数。

推理过程

比赛早期,我提交的是每组实验中4个训练模型的平均值。然而,当我开始将最大长度增加到1024个token以上时,发现推理时间显著增加。使用1个DeBERTa-v3-large模型在1024最大长度下推理需要约1小时,在1280或1536长度下需要约1.5小时。

这意味着在1536长度下,4折平均需要6小时或更久。为了能够提交更多样化的集成,我决定改为在100%训练数据上重新训练。我发现这些100%数据训练的模型LB分数与75%数据训练的模型相当。这使得我能够提交表现最好的3组CV实验的集成。我对每组实验都在100%训练数据上重新训练了两次,使用不同的随机种子。

GPU资源

我没有可用的专用GPU,而每次4折实验在Kaggle P100上耗时很长(特别是使用长序列训练时),因此我订阅了Paperspace Gradient,可以间歇性使用RTX5000或A4000,这两种GPU都比Kaggle GPU快约4倍。

由于这些GPU都不超过16GB显存,我只能在1024最大长度下使用批量大小为1进行训练。为此,我使用了梯度累积。最初每8步累积一次梯度进行优化器更新,但发现16步效果更好。

Dropout

这个帖子指出在回归任务中关闭dropout可能有用。我尝试后发现,关闭全连接层的dropout略有帮助,但在注意力层中无效。

池化

我看到一些公开的Notebook使用了平均池化或GeM池化,但在我的实验中,这些方法都不如 transformers.DebertaV2ForSequenceClassification 内置的 ContextPooler 默认池化效果好。

无效尝试

以下是我自己尝试或从公开Notebook和讨论中借鉴但未见明显改进的想法:

  • 使用 prompt_title
  • 冻结嵌入层
  • 冻结编码器层
  • 最大、平均或GeM文本池化
  • 额外的注意力头
  • MSE、SmoothL1或(修改后的)MarginRankingLoss(我主要使用MCRMSE损失)
  • 训练独立模型分别预测内容和表达分数
  • 使用超过1024的最大序列长度进行训练
  • 使用LoRA的DeBERTa-v2-xlarge(即使使用大alpha值)
  • 自动拼写纠正
  • 与线性模型或手工特征的梯度提升回归器集成(我没花太多时间在这上面,但尝试了一些高分公开Notebook的特征,似乎不太有用)
  • 使用抽象摘要缩短 prompt_text 长度。这确实略微改善了我的CV分数,但严重损害了公开LB分数,这是一个很好的警告。我决定这风险太大,因为在私有测试数据评分时无法验证生成的摘要。如果生成模型出现一次幻觉,就可能毁掉最终的LB分数。

我本来想尝试抽取式摘要,因为这可以避免幻觉问题,但没想出训练模型来对每个 prompt_text 中最重要的句子进行排序的好方法。这会是很有趣的方向,但与单纯增加最大序列长度相比,可能最终是浪费时间。

同比赛其他方案