632. Eedi - Mining Misconceptions in Mathematics | eedi-mining-misconceptions-in-mathematics
我很高兴终于实现了一年前的目标,那时我开始相对认真地参与 Kaggle 竞赛:单人金牌(Solo Gold)。
虽然我以前曾在公有榜上几次获得单人金牌,但未能成功在私有榜上保住名次。这一次,过去几个月的投入、专注于泛化解决方案以及公有数据和私有数据相对相似的分布,使我实现了这一目标。
我要感谢 Kaggle 和主办方组织了如此有趣的竞赛,我们需要探索不同方法的推理能力,以有效地根据干扰项对数学错误概念(misconceptions)的相关性进行排名。
特别感谢设计了公有/私有数据划分,平衡了来自训练数据的见过(seen)和未见过(unseen)的错误概念数量(我相信保住金牌名次的选手都同意这一点)。这使得开发的方案的稳健性能够在排行榜上得到反映,导致私有榜的排名洗牌非常温和。在经历了之前的几次竞赛后,我真的觉得应该为此表示感谢 :)
从一开始,像大多数参与者一样,我无法找到按题目 ID 分组划分的交叉验证(CV)与公有榜(LB)之间的良好相关性。因此,很明显隐藏数据包含多个训练数据中不存在的未见过的错误概念,我应该以某种方式划分验证集,使其包含一部分训练数据没有的未见过的错误概念。
尽管按题目 ID 的分组划分已经提供了一定比例的未见过的错误概念,但它们通常最多只占折叠中所有错误概念的 20%,这就是为什么很多团队面临对见过的错误概念过拟合的问题,即使未见过的错误概念在检索方面被严重抑制,也能提供良好的总体 CV 分数。
例如,如果折叠由 ~80% 见过 的数据和 20% 未见过 的数据组成,那么对见过的错误概念严重过拟合(如 65% MRR)且对未见过的错误概念检索不佳(如 30% MRR),MRR 的加权平均值为:
0.65*0.8 + 0.3*0.2 = 0.58
这将与 LB 显示的结果相去甚远。
最后,我的验证策略基于一个假设,即隐藏分布在见过/未见过的错误概念方面相当平衡,良好 CV 的关键是赋予见过和未见过的错误概念相等的权重。
为了保持实验的高动态并避免在 VM 上花费过多,我在实验中坚持只使用一个折叠作为验证集。这一策略被证明是足够的,因为不同折叠的结果非常相似。
尝试仅使用提供的训练数据训练检索器模型显示结果不佳,因此为未见过的错误概念生成合成数据变得不可避免。
在使用 Qwen 32/72 instruct 进行 LORA 预训练和 few-shot 生成的实验过程中,我发现 LORA 预训练似乎降低了模型的推理能力(灾难性遗忘?)。最好的方法是 few-shot 生成。后来,我发现了优秀的 EEDI 论文,该论文也得出了类似的结论,即 few-shot 生成对此任务更有效。
Few-shot 生成的主要缺点是生成的样本在表述上与 few-shot 示例非常相似。任何提示工程(prompt engineering)的尝试都无法在不丢失干扰项和错误概念之间正确联系的情况下改变这一点。
生成细节:
数学问题的 LaTex 格式包含许多冗余符号,减慢了收敛速度。因此,我没有手动过滤文本,而是研究了开源库以将 LaTex 转换为纯文本并简化方程。虽然大多数库忽略了大多数冗余符号,但我发现了 pylatexenc 库,它处理转换非常好,基本上没有丢失文本或方程中的重要元素(训练数据中有少数情况包含不遵循 LaTex 格式的冗余符号)。然而,我在最终集成中包含了两个使用未经 LaTex 过滤数据的模型,以确保没有丢失重要信息。
一个有趣的时刻是,尽管在包含生成数据训练后,模型对未见过的错误概念实现了比见过的错误概念高得多的 MRR(由于合成过采样),但见过和未见过的错误概念之间的召回率(Recall)保持不变。我认为根本原因是合成数据允许模型在简单的错误概念上很好地收敛,但难以生成复杂错误概念的数学测试。因此,模型可以很好地检索大多数未见过的错误概念(导致高 MRR),但无法找到其他复杂错误概念的相关性,导致召回率与训练和验证拆分之间数学测试相似的代表性不足的见过的错误概念相同。
检索器细节:
使用 DataCollatorForCompletionOnlyLM 对于从训练中排除提示令牌至关重要。
另一个关键方面是从训练中排除所有测试错误概念。我观察到,仅在训练错误概念上进行训练允许模型有效地泛化到未见过的错误概念。排除测试错误概念给我带来了达到公有榜 0.6 分后最大的 LB 提升 = ~0.61 - 0.63。
临近截止日期,我发现了一个有趣的技巧:首先,在一个种子上训练模型。然后,使用不同的种子创建一个数据集(这通常会改变负样本集和正确错误概念的位置)。使用已经训练好的模型在这个新数据集上推理 logits。最后,结合 KL 散度蒸馏和简单的交叉熵损失重新训练模型。这种方法在公有榜上带来了约 0.01 的提升。
我对此技巧的直觉是,对于某些样本,技术上可能有多个错误概念是正确的。将模型过拟合到单个错误概念会降低其泛化能力。通过蒸馏引入软标签,我们减轻了过拟合并提高了模型对未见过的错误概念的泛化能力。
我从 100 个最相似的错误概念中随机采样了 49 个负错误概念,并将正确的错误概念放在随机位置。然后,我训练模型分类哪个错误概念最相关。通过采样生成的随机顺序有助于避免过拟合初始顺序,在初始顺序中,检索器通常将正确的错误概念放在前几个选项中。
我注意到错误概念差异很大,例如,有些描述了缺乏什么知识,而有些描述了学生相信什么。为了解决这个问题,我将错误概念重述为一种通用格式,包括缺失的知识和与错误概念一致的学生信念。即使重述的错误概念在语义上重复了原始概念,这种重述在模型推理期间也起到了有效的正则化作用。
我使用了来自重述错误概念的推理 logits,并将它们与来自原始错误概念的 logits 相结合,这带来了约 0.01 的公有榜提升。
使用 Qwen 32B-Instruct 来重述错误概念。
分析从第一阶段重排序器获得的 logits 时,我注意到 Qwen 倾向于保留检索器排序的错误概念的初始顺序。我在 这篇优秀的论文 中发现了这一观察结果的进一步验证,这启发我重新训练检索器以更关注 MRR,并开发第二阶段重排序器来细化第一阶段重排序器的结果。
在第二阶段,我从第一阶段重排序器中选择了一个小窗口的 top 排名错误概念,并对它们的顺序应用了所有可能的排列。然后,我在这些排列中平均 logits,并再次对该窗口中的错误概念进行重排序。令我惊讶的是,最佳窗口大小竟然是 2。这意味着我从第一阶段重排序器中选取前 2 个错误概念,对它们进行推理,反转它们的顺序,再次运行推理,最后使用平均 logits 进行最终重排序。
重排序器细节:
由于乌克兰的基础设施受到持续攻击,结果我们每天都有停电,租用 VM 变得不可避免。
我主要使用 A40,对于一些实验,我租用了 A100。
总共花费了我大约 300 美元。