返回列表

15th Place Solution Writeup

673. MAP - Charting Student Math Misunderstandings | map-charting-student-math-misunderstandings

开始: 2025-07-10 结束: 2025-10-15 个性化学习 数据算法赛
第 15 名解决方案报告 - MAP 竞赛

第 15 名解决方案报告

副标题:MAP 竞赛团队解决方案

作者:t fuku (及团队成员)

发布时间:2025-10-16

竞赛排名:第 15 名

首先,感谢我的团队成员:@jjinho@ky8ori@masasato1999@lizhecheng。我们共同努力在私有排行榜上取得了第 15 名的成绩。尽管最终榜单的变动使我们错过了金牌,但在这次伟大的竞赛中我们度过了一段美妙的旅程。

lizhecheng 和 ky8ori 部分

我们使用了 8 张 A100 80GB GPU 进行并行实验。

在第一阶段,我们主要关注以下模型:

  1. Qwen/Qwen3-14B
  2. Qwen/Qwen3-8B
  3. Qwen/Qwen3-4B 和 Qwen/Qwen3-4B-Instruct-2507
  4. google/gemma-2-9b-it
  5. deepseek-ai/DeepSeek-R1-0528-Qwen3-8B
  6. deepseek-ai/deepseek-math-7b-instruct

我们使用五折交叉验证和 LoRA 训练每个模型,采用了 8 种不同的参数设置:

rank=(32 32 32 32 64 64 64 64)

learning rate=(1.75e-4 2.0e-4 2.25e-4 2.5e-4 1.75e-4 2.0e-4 2.25e-4 2.5e-4)

我们将 lora_alpha 固定设置为 32,训练轮次 (epochs) 为 2,学习率调度器 (lr_scheduler) 为 'linear',主要使用以下最简单的输入提示词 (prompt):

def format_input(row):
    x = "Yes" if row['is_correct'] else "No"
    return (
        f"Question: {row['QuestionText']}\n"
        f"Student Answer: {row['MC_Answer']}\n"
        f"Correct? {x}\n"
        f"Student Explanation: {row['StudentExplanation']}\n"
    )

我们的结果显示:

  • Qwen3 系列模型给出了最好的结果,且较大的模型在交叉验证 (CV) 和排行榜 (LB) 上得分都更高。
  • gemma2-9b-it 非常难以训练,通常 CV 较低,存在梯度爆炸等问题,因此我们决定不再继续使用该模型。
  • deepseek-math-7b-instruct 和 Qwen2.5 系列模型不如 Qwen3 系列,我们也放弃了。

我们使用的其他训练方法:

  • 使用完整类别训练:这是最原始的代码,给出了不错的结果。
  • 使用较少类别训练:意味着我们删除了每个标签的 True 或 False 前缀,因为我们都知道答案是否正确。这在 CV 和 LB 上都带来了一些提升,大约在 0.001 左右。
  • 使用掩码损失 (Masked Loss):(这个想法来自 M sato)。我们发现只有某些标签出现在特定问题中,因此我们不计算那些实际上不会出现在特定问题中的标签的预测概率损失。这种方法提高了 CV 分数,但 LB 分数似乎没有提高。
  • 使用高级提示词:例如将选项加入输入或扩展输入问题使其更清晰。这种方法提高了 CV 分数,但 LB 分数下降了。此外,因为输入更长,我们需要将推理长度设置为 300 甚至更长,所以我们放弃了这种方法。
  • 使用不同的损失函数:焦点损失 (focal loss)、自举损失 (bootstrapping loss)、标签平滑 (labeling smoothing)。然而,没有一个能在所有五折验证中给出一致的 CV 提升。我们尝试了一个 5 折 CV 集成训练,使用常规 CE 损失,但替换了一些自举损失给出更好 CV 分数的折。这种方法将 LB 分数提高了 0.001,这可能只是噪声。
  • 使用软标签 (Soft Labels):使用嵌入模型和手动检查,我们将具有相同语义含义的学生误解分组。对于每组,我们根据其 ground truth 误解标签的分布计算软标签。同样,我们看到某些折的 CV 有所改善,但并非所有折。这可能是由于语义分组不足。
  • 使用共享标签:见 'JJ 部分'。

我们尝试的后处理方法:

在对 OOF 预测进行 EDA 后,我们发现由于类别 Correct:NA 和 Neither:NA 在训练和测试数据中占很大比例,并且在预测是将一个类别放在第一位还是第二位时存在很多错误。

我们从原始训练数据集中提取了属于这两个类别的数据,并训练了一个二元分类后处理模型,试图验证并在这两个类别出现在第一和第二位时切换位置。

{1, 0.5} 的 MAP 分数可以达到 0.965+,但在添加到之前的提交后,LB 实际上下降了,这没有意义,但我们不得不放弃这个想法。

最终提交:

对于最终提交,由于我们决定专注于使用一个在给定训练数据集上完全训练的单一模型,我们主要使用上述有效方法和在 8 种不同设置中取得更高 CV 分数的参数设置重新训练了 Qwen/Qwen3-14B 模型。此外,我们还训练了 microsoft/phi-4 和 microsoft/Phi-4-reasoning,因为我们的队友发现 phi-4 系列模型在这次竞赛中表现良好。

在推理期间,我们只关心输出概率中对应标签会出现在特定问题 ID 的部分。我们主要对所有完全训练的模型使用相同的权重,以确保不过拟合并保持多样性,我们的最终提交主要包含 5-6 个模型。我们确实有超过 15 个私有分数 0.948+ 的提交,但不幸的是,我们没有选择它们。

我们将发布本次竞赛中训练的所有模型,及其性能分数将在模型描述中给出。

t fuku 部分

我使用 RTX5090 GPU 进行实验。

1. 模型

竞赛早期,我测试了 62 个模型(大小 * 模型)和多种类型的提示词。
使用统一提示词训练时的 CV 排名如下:

  • 公共分数是在完成完整训练后测量的。
  • lr: 2e-4
  • scheduler: cosine-scheduler
  • epoch: 3
模型 本地 CV 公共 LB LoRA Rank LoRA Alpha
Phi-4 0.9483 0.948 64 128
Phi-4-reasoning-plus 0.9480 0.948 64 128
Qwen3-32B-4bit-quantization 0.9483 0.946 64 128
Qwen2.5-32B-4but-quantization 0.9485 0.946 64 128

我们还测试了几个较小的模型,32B 模型在 LB 上取得了与 14B 模型相同的分数。然而,当用于集成时,32B 模型产生了更高的 LB 分数。

2. 提示词 (Prompts)

最初,我们列出了所有选项供 LLM 选择。然而,随着提示词变长,训练和推理时间都增加了。
@cdeotte公开代码 中,使用了更简单的提示词,使用该提示词比在提示词中提供所有选项产生了更好的结果。在查看各种公开代码时,我注意到大多数提示词没有利用标签。我继续在构建模型训练和提示词时 incorporating 标签。
我尝试在提示词开头添加诸如"You are a mathematics expert. Please perform the task of identifying student misconceptions"之类的短语,但这并没有显著改善结果。然而,在 ychroneg 标签内包含"Let me analyze this mathematical misconception..."的提示词大幅提高了我的 CV。我最好的提示词如下 (phi-4):

prompt = (
    "<|user|>\n"
    f"[Mathematical Misconception Analysis Task]\n\n"
    f"Question: {row['QuestionText']}\n"
    f"Answer: {row['MC_Answer']}\n"
    f"Correct?: {status}\n"
    f"Explanation: {row['StudentExplanation']}\n"
    "<|end|>\n"
    "<|assistant|>\n"
    "ychroneg>\n"
    "Let me analyze this mathematical misconception...\n"
    "ost switching>\n\n"
)

3. 集成 (Ensemble)

一个值得反思的点是我高估了 LB 并过度调整了集成权重。通过集成所有模型:phi-4, phi-4-reasoning-plus, qwen3-32b, 和 qwen3-14b,使用权重设置为 1,使用下面的程序,有可能达到 0.948 的私有分数并瞄准金牌。

4. 代码

模型训练和推理程序保存在下面。
https://github.com/T3pp31/map-charting-student-math-misunderstandings

5. 数据

我在数据中也发现了一些有趣的事情。对于特定的问题编号,Wrong_Fraction 实际上是 Wrong_fraction。我想知道这是否影响了分数。我认为通过在训练中将 Wrong_fraction 标准化为 Wrong_Fraction,模型需要分类的内容就会少一个,从而提高准确性。然而,并没有成功。

M Sato 部分

我们认为在训练和测试数据中使用相同的问题是本次竞赛的关键,所以我们尝试了几种方法。

1. 复现给学生提供的选项 (预处理)

在这次竞赛中,学生实际上有四个选项:a, b, c, 和 d。基于 StudentExplanation,我们手动将每个选项映射到对应的 a, b, c, 或 d 对。→ 这对 CV 或 LB 几乎没有影响。

2. 掩码损失模型 (训练)

在模型训练期间,我们根据训练 ID 动态选择用于损失计算的标签,以专注于每个问题的标签学习。→ 这提高了 CV,但对 LB 没有影响。

3. 基于训练数据中 QuestionID 的误解过滤 (后处理)

模型的泛化输出基于 QuestionId 标签进行了过滤。→ 这对交叉验证和标签平衡都证明是有效的。

JJ 部分

在这次竞赛期间,我可以使用 2 张 4090,并在竞赛结束时使用了一台 RTX 6000 Pro Blackwell Workstation Edition 进行实验。

我还使用各种模型在 LoRA 上进行了多次实验,但与我的队友不同,我在训练 Qwen3 系列模型时遇到了问题,即在我的本地机器上训练和推理效果很好,但在 Kaggle 的基础设施上推理会导致结果 vastly inferior。尽管使用量化来模仿 Kaggle 环境进行训练,情况依然如此。然而 Phi4 系列模型没有给我带来这些问题,所以我坚持使用它们。我还尝试训练 Gemma2/3 系列模型,但 CV 也比 Phi4 差。

我使用了五折交叉验证。设置 LoRA 为 64/128(实验了 alpha/rank 从 8 到 128 的组合),学习率 2e-4(实验了从 5e-5 到 5e-4 的范围),3 个 epochs(实验了从 2 到 4 的范围)。

在提示词方面,也开始使用最简单的提示词,但后来 switched 到适合模型的提示词。

虽然模型是在分类任务上训练的,但在竞赛过程中,我也改变了设置标签的方式。假设是移除 True_/False_ 前缀将帮助模型专注于更少的类别(因为该信息已经提供给我们了)。此外,在随后的错误分析中,我们注意到模型在 Neither/Correct 类型标签之间的错误率最高。一个观察结果是,Neither 类型语言在所有问题中相当恒定,而 Correct 类型语言非常针对特定问题。因此,我创建了标签,其中 Neither 在所有问题中共享(例如"Q:Neither:NA"),而正确标签是针对问题的(例如"31772:Correct:NA")。这一变化给出了最好的 CV (0.9496)。还尝试了该标签方案的其他变体(例如,在所有问题中共享 Correct:NA 并使 Neither:NA 针对问题),但没有达到同样高的 CV(在反转标签情况下为 0.949),但为了获得增加的多样性,将它们添加到了集成中。

结论

在集成训练期间,我们结合了各种模型并调整了它们的权重,在 LB 上达到了 0.952 的分数。这次我们缺乏的是适当的实验管理,以及关于 CV 构建方式的交叉验证技能。我们感谢每一位在竞赛中竞争到最后的人。

同比赛其他方案