返回列表

Efficiency Track 1st Place Solution - Model Merging

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

开始: 2024-09-12 结束: 2024-12-12 学习效果预测 数据算法赛
效率赛道第一名解决方案 - 模型合并

效率赛道第一名解决方案 - 模型合并

作者: Dipam Chakraborty

发布时间: 2024-12-17

竞赛排名: 效率赛道第 1 名,主赛道第 33 名

开篇注记

感谢竞赛主办方和 Kaggle 团队组织了这次竞赛以及效率赛道。这是一次关于数据科学和工程学的绝佳学习体验。

推理代码分享 点击此处查看代码

效率赛道时间与分数的权衡

我首先要提到效率赛道分数内置的权衡。具体来说,如果你假设最大私有排行榜 (Private LB) 分数接近 0.6,而我们知道“ baseline "LB 分数接近 0。那么权衡结果是 LB 分数每提升 0.01 需要 9 分钟。到了某一点之后,在分数方面变得极其难以处理,问题本质上归结为时间优化,或者我是这么想的,直到我的解决方案的主要区分点带来了巨大的提升。

对于这次竞赛,似乎相当容易在大约 30 分钟内获得 ~0.27-0.29 的私有排行榜 (Private LB) 分数。这可以通过结合提供的训练数据,使用一些关于缺失概念的高质量合成数据,训练一个约 4 亿 (400m) 大小的单一嵌入模型来实现。

在此之后,人们可以朝多个方向优化时间或分数。

分数/时间改进思路

  • 仅解码器模型 (Decoder only model) - 问题/主题/结构对于 3 个答案选项是相同的,这意味着它们的 K-V 缓存可以通过前缀缓存 (prefix caching) 重用。因此,我从 BGE/GTE 等仅编码器模型切换到了 Qwen2.5-0.5B。通过前缀缓存,时间减少到了 14 分钟。
  • 缓存误解嵌入 (Caching misconception embeddings) - 预计算并保存误解嵌入是很直接的。
  • 重排序器 (Reranker) - 天真地运行一个 4 亿 (400m) 大小的重排序器可以提高分数,但相当慢。较小的模型在分数上的提升不足以证明时间增加的合理性。
  • 共享模型重排序器 (Shared model Reranker) - 克服这个问题的一种方法是重用嵌入模型,添加几层额外的层来对误解序列应用注意力机制。然而,由于数据集有限,在已经训练和过拟合嵌入模型后,这个模型更难训练,因此可能需要联合训练两个模型。我没有时间实现这个想法。
  • CPU 优化 - 像 OpenVINO 这样的 CPU 优化可能会使模型更快而不会降低分数,我没有尝试。需要记住的一个小细节是,CPU 模型在 FP16/BF16 下运行非常慢,所以坚持使用 FP32。

核心思路 - 模型合并

使用 mergekit 中提供的 SLERP 或 TIES 等技术进行模型合并,可以通过合并训练于不同数据集/折叠的不同模型来提高分数,有时甚至与基础模型合并也会有所帮助。由于这提高了分数而不改变运行时,这是分数的免费提升。权重合并曲线有点碰运气,更多的是因为我在这方面没有太多经验。

即使合并训练于相同数据但具有不同超参数(如批量大小或权重衰减)的模型,分数也有所提高。对于我的最终提交,我使用 SLERP 合并了 6 个模型,进行了 4 个合并步骤。这些都是 Qwen2.5-0.5B-Instruct 的不同全量微调模型。

虽然我预计使用合并会带来适度的分数提升,但提升是巨大的,仅合并 2 个模型就将公共排行榜 (Public LB) 的分数从 0.305 提高到了 0.330

使用此方法的两个主要注意事项:

  1. 仅当合并的模型具有相似性能时才有效。当与基础模型合并时,需要注意分配更高的权重给微调模型,同时不要分配太多以至于没有改进。
  2. 由于交叉验证 (CV)/测试集分数是评估合并模型的唯一方法,人们肯定会在调整合并曲线参数时变得过于激进,从而过拟合 CV 分数。这确实发生在我身上,CV 和公共排行榜 (Public LB) 都在 4 次合并后有所提高,但最好的私有排行榜 (Private LB) 来自 3 次合并。

仅这个分数就是一个巨大的提升,以至于我没有在效率赛道上花更多时间,我预计将其与共享重排序器和 CPU 优化相结合可以进一步提高模型的分数/时间比。

P.S - 不得不对 mergekit 做一点黑客修改才能使合并工作,因为它主要是为文本生成配置制作的。

关于模型合并的更多心得

我对合并结果非常感兴趣,以至于我停止关注竞赛去学习更多关于合并的知识。首先我想知道它是否也适用于更大的模型。我在我为主赛道训练的一些 7B Qwen 的 LoRA 模型上尝试了它,起初根本不起作用,但我做错了什么。对于这种设置,使用 SLERP 的正确方法是首先将 LoRA 权重合并到基础模型中(注意合并 LoRA 不同于使用 SLERP 合并两个模型)。所以首先,加载 PEFT 模型并使用 merge_and_unload 获得全量微调权重,然后对另一个 LoRA 执行相同操作,这将给出两组模型权重。现在我们可以使用 SLERP 组合这些权重。随着模型大小的增加,这个过程变得资源密集,使得调整 SLERP 曲线变得困难。

以这种方式合并 7B LoRA 的结果只带来了很小的改进,与在 0.5B 模型上这样做时的巨大改进形成对比。我甚至尝试了一个 7B 模型的全量微调,看看是否会更好,但没有花足够的时间在这方面获得任何重大改进。

主赛道第 33 名解决方案

我的主赛道解决方案相当直接:

  • 使用 Claude-3.5-Sonnet/GPT-4o 生成缺失的误解 + 使用 GPT-4o 过滤 poor 数据。通过将来自不同 LLM 的数据集保留在不同的训练/验证拆分中进行 CV 会有所帮助。
  • 32B 嵌入器 - 使用 CachedMultipleNegativesRankingLoss 训练,以限制为单 GPU 训练。
  • 32B 点对点 (pointwise) 重排序器与二元分类器 - 重排序前 5 名。
  • 32B 列表式 (listwise) 重排序器用于前 2 个候选者 - 限制为 2 个,因为我担心位置偏差,没有做太多实验。

所有模型都是简单的 LoRA。由于资源限制,我主要在 7B 模型上做实验,并在最后 2 天训练了所有 32B 模型。

我也做了一些关于 32B 模型输入的思维链 (CoT) 推理的实验,但没有获得太多分数提升/没有花足够的时间在上面。

对效率赛道的个人看法

有点令人失望的是效率赛道不颁发奖牌,我认为大多数顶级团队都没有在这里花时间。最后我在合并解决方案上有点太幸运了。如果效率赛道颁发奖牌,解决方案会更强,竞争会更难/更有趣。高额奖金 certainly 表明组织者希望更多团队关注这里。

该指标似乎更倾向于时间优化而不是分数,任何超过单一嵌入器的东西可能都太慢了。仅用 9 分钟换取 0.01 的分数提升似乎不是一个平衡的权衡。我可能在这里错了,也许这正是主持人想要的权衡。

同比赛其他方案