574. CommonLit - Evaluate Student Summaries | commonlit-evaluate-student-summaries
我按照 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,而不是使用 [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,而每次4折实验在Kaggle P100上耗时很长(特别是使用长序列训练时),因此我订阅了Paperspace Gradient,可以间歇性使用RTX5000或A4000,这两种GPU都比Kaggle GPU快约4倍。
由于这些GPU都不超过16GB显存,我只能在1024最大长度下使用批量大小为1进行训练。为此,我使用了梯度累积。最初每8步累积一次梯度进行优化器更新,但发现16步效果更好。
这个帖子指出在回归任务中关闭dropout可能有用。我尝试后发现,关闭全连接层的dropout略有帮助,但在注意力层中无效。
我看到一些公开的Notebook使用了平均池化或GeM池化,但在我的实验中,这些方法都不如 transformers.DebertaV2ForSequenceClassification 内置的 ContextPooler 默认池化效果好。
以下是我自己尝试或从公开Notebook和讨论中借鉴但未见明显改进的想法:
prompt_titleprompt_text 长度。这确实略微改善了我的CV分数,但严重损害了公开LB分数,这是一个很好的警告。我决定这风险太大,因为在私有测试数据评分时无法验证生成的摘要。如果生成模型出现一次幻觉,就可能毁掉最终的LB分数。我本来想尝试抽取式摘要,因为这可以避免幻觉问题,但没想出训练模型来对每个 prompt_text 中最重要的句子进行排序的好方法。这会是很有趣的方向,但与单纯增加最大序列长度相比,可能最终是浪费时间。