返回列表

8th Place Solution

632. Eedi - Mining Misconceptions in Mathematics | eedi-mining-misconceptions-in-mathematics

开始: 2024-09-12 结束: 2024-12-12 学习效果预测 数据算法赛
第 8 名解决方案 - Eedi 数学误解挖掘竞赛

第 8 名解决方案

作者: Yannan Chen
竞赛: Eedi 数学误解挖掘竞赛 (Eedi - Mining Misconceptions in Mathematics)
排名: 第 8 名
发布日期: 2024-12-13

阅读了顶级解决方案后,我真的对其他团队付出的努力、对训练和推理细节的高度关注,以及高度复杂的提示工程方法印象深刻。作为一名新手,我感到很幸运能取得最终的排名,也很荣幸能分享我的解决方案。我认为我的解决方案虽然简单,但仍然有效,且计算效率相对较高。我只使用了 14B 和 32B 的模型,总运行时间约为 6 小时。

我想向所有在竞赛期间和之后分享代码和见解的人表示感谢。

两个关键参考

  • @sayoulala : 讨论链接
    • 启发了我关于 LoRA 微调、硬负例挖掘(hard negative mining)以及 recall+rerank 训练方案的知识。
  • @cdeotte : 讨论链接
    • 关于模型量化、wise-FT LoRA 适配和 VLLM 推理的启发性的想法。

推理流程

检索器(4 个 Qwen2.5-14b 模型通过加权求和集成)→ 40 个误解 → 重排序器(单个 Qwen2.5-32b 模型)→ 25 个误解

训练细节

总的来说,我发现迭代硬负例挖掘非常有帮助。

  • 使用 few-shot 提示与 ChatGPT 生成额外的训练数据:
    • 添加了 983 个合成数据样本以填补缺失的误解。
    • 训练数据按 "QuestionId" 分为 5 个交叉验证折叠(CV-folds)。对于每个折叠,重新生成额外样本以覆盖验证折叠中的独特误解用于训练。
  • 检索器(Qwen2.5-14b):使用 bnb bit4 + LoRA 微调用于 FEATURE_EXTRACTION 任务。
    • 在 2 块 A100 上训练。
    • LoRA 参数:r=32, alpha=64, target_modules=['q_proj','k_proj','v_proj','o_proj','gate_proj','up_proj','down_proj']
    • 训练参数:train_group_size=4, effective_batch_size=64, epoch=7, lr_scheduler_type="cosine"
    • 分为 5 个交叉验证折叠训练。
      • 在前 4~5 个 epoch,模型在不使用生成数据的情况下训练,专注于提高 map25。
      • 在最后 2~3 个 epoch,将生成数据加入训练,这有助于进一步提高 map25 和 recall25。
    • 当验证分数(map25 & recall25)停止 improvement 时,我通过以下方式进行手动干预:
      • 逐渐降低学习率,从 5e-4 到 1e-5
      • 减少负数据池大小,从 80 到 4,以更专注于区分最难的误解
  • 重排序器(Reranker, Qwen2.5-32b):使用 bnb bit4 + LoRA 微调用于 CASUAL_ML 任务,为每个查询 - 误解对输出一个"Yes"logit。
    • 在 2 块 A100 上训练。
    • LoRA 参数:r=32, alpha=64, target_modules=['q_proj','k_proj','v_proj','o_proj','gate_proj','up_proj','down_proj','down_proj','lm_head']
    • 训练参数:train_group_size=4, effective_batch_size=64, epoch=4, learning_rate=5e-4, lr_scheduler_type="WarmupDecayLR"
    • 使用完整数据集训练重排序器,无验证集。负数据由 4 个检索器(通过加权求和集成)生成,negative_count = 40

量化与推理细节

  • 检索(Retrieving):
    • 4 个检索器(基于 LB 分数从 5 折交叉验证中选择)检索 4 次,然后通过加权求和进行集成。
    • 使用 bnb bit4+LoRA 推理(无需合并),因此每个单个检索器可以 fit 进一块 T4 GPU,4 个检索器只需 2 块 T4 运行两次。
  • 重排序(Reranking):
    • 模型首先与 LoRA 适配器合并,wise-FT 超参数 alpha=0.8
    • 模型然后量化为 AWQ(使用从训练数据中随机选择的 128 个样本进行校准)
    • 使用 VLLM 进行最终推理。每个查询与 40 个检索到的误解配对,生成 40 个查询供重排序器评分。"enable_prefix_caching" 被开启以加速推理。

关键改进(公共排行榜 Public LB)

  • 添加合成数据:单个检索器公共 LB 分数从 0.3~ → 0.49
  • 集成检索器:0.49 → 0.51
  • 添加重排序器:0.51 → 0.57
  • 在重排序器的 LoRA 合并上应用 Wise-FT:0.57 → 0.59

个人反思

整个流程——从 LoRA 微调 to 量化——对我来说都非常新,我不止一次差点放弃。我开始时使用 Qwen2.5-0.5B 来建立一个可行的流程,但 AWQ 量化的模型在推理过程中不断产生随机字母。经过多次挫折后,我发现 autoawq 没有导出 Qwen2.5-0.5B 的 im-head-embed 层参数,迫使我手动添加它们。如果没有 @cdeotte 的论文证明这是可行的,我可能早就彻底放弃了。多亏了那种 reassurance,我坚持了下来,最终让流程顺利运行。

同比赛其他方案