返回列表

21st Place Solution

647. Al Mathematical Olympiad - Progress Prize 2 | ai-mathematical-olympiad-progress-prize-2

开始: 2024-10-17 结束: 2025-04-01 数学与计算 AI大模型赛
第 21 名解决方案 - AIMO2

第 21 名解决方案

作者: JK-Piece (MASTER)
发布时间: 2025-04-02
竞赛排名: 22

感谢所有参与者,尤其是那些创建了出色的 Notebook、模型和引人入胜讨论的人。我学到了很多。感谢 Kaggle 和主办方在整个漫长、充满挑战但令人兴奋的竞赛过程中提供的持续支持。

我开发了许多方法,其中一些灵感来自讨论和公开的 Notebook。 below 我主要分享我迄今为止成功的方法,公开得分为 28

最终方法:从 Qwen-QWQ 32B 到 DeepSeekR1-Distill-Qwen14B 的 Logits 蒸馏

由于想法是学习 Qwen-QWQ 32B 如何解决问题,我需要与 AIMO2 竞赛相关的问题。因此,我也包含了参考集,见下文。

数据集

  • 来自 OpenR1 数据集 的随机 6% (随机种子 42) 问题,其中 DeepSeek-R1 找到了正确答案 + AIMO2 参考集 + AIME2024 + AIME2025
  • 总数据集大小:5274

主要方法论

1. 在共享 GPU 上初始化三个模型,如下所示

  • Qwen-QWQ 32B-AWQ 通过 vLLM 加载(用于文本生成的教师模型)
  • Qwen-QWQ 32B-AWQ 使用 AutoModelForCausalLM 加载(用于 logits 计算的教师模型)
  • DeepSeekR1-Distill-Qwen14B(学生模型)

2. 生成文本,形成输入,前向传播并计算损失

  • 对于每个输入问题,创建一个提示(prompt),包括系统消息,并要求教师模型解决问题(使用 vLLM 进行更快的推理)
  • 使用教师模型(AutoModelForCausalLM 实例)获取生成文本 + 提示中存在的 token 的 logits
  • 调用学生模型计算相同输入文本的 logits(同样,提示和解决方案都包含在 logits 计算的输入中)
  • 计算学生 logits 和教师 logits 之间的 KL 散度

训练细节

SYSTEM_PROMPT = """你是最强大的数学专家。请用深度推理解决问题。你很细心,总是重新检查你的推导。在足够自信之前,你永远不会直接给出答案。你应该一步一步地思考。在取模 1000 后,将最终答案返回到 \\\\boxed{} 中。"""

MAX_SEQ_LEN = 4096 # 教师文本生成中的最大序列长度

sampling_params = SamplingParams(max_tokens=MAX_SEQ_LEN, temperature=0.7, skip_special_tokens=False)

generated_text = teacher_model.generate(
            prompts=teacher_prompt,
            sampling_params=sampling_params
        )

# 现在使用教师模型和学生模型的分词器获取 input_ids 和 attention_mask

teacher_logits = teacher_logits_model(input_ids=teacher_input_ids, attention_mask=teacher_attention_mask).logits

student_logits = model(input_ids=student_input_ids, attention_mask=student_attention_mask).logits

student_log_logits = torch.nn.functional.log_softmax(student_logits, dim=-1).to('cuda')
teacher_log_logits = torch.nn.functional.log_softmax(teacher_logits, dim=-1).to('cuda')

loss = torch.nn.functional.kl_div(student_log_logits, teacher_log_logits, log_target=True, reduction='batchmean')

training_args = TrainingArguments(
    output_dir="./qwen14b_distilled",
    per_device_train_batch_size=2,
    num_train_epochs=1,
    logging_dir="./logs",
    logging_steps=1,
    learning_rate=1e-6,
    weight_decay=0.01,
    save_strategy="steps",
    save_steps=20,
    remove_unused_columns=False,
    report_to="none",
)

线性权重集成:这才是真正突出的地方

  • 我保留了不同训练步骤的检查点,并平均了这些模型权重
  • 平均后的检查点为:0.1*ckpt-20 + 0.1*ckpt-180 + 0.1*ckpt-260 + 0.1*ckpt-280 + 0.1*ckpt-360 + 0.1*ckpt-640 + 0.1*ckpt-1840 + 0.1*ckpt-2300 + 0.2*last-ckpt

使用量化蒸馏后的 Qwen14B 模型进行评估

  • AIME2024/2025: 43/60

  • 参考集:7/10

  • 公开 leaderboard: 28 (max_seq_len=8192*3//2 + 1024, top_p=0.9, min_p=0.05, temperature=1.0)。我还使用了 vLLM Engine 类(不是 LLM),并且当给定答案达到 33% (频率) 时可以取消请求,相对于 max_num_seqs=12

最终思考

  • 我本可以训练更久。不幸的是,我是在竞赛的最后一周才想到这个主意
  • 训练更久可能会提高性能
  • 较大的学习率 (1e-5) 导致 7B 模型性能较差。没有在 14B 模型上尝试

无效的方法:

  • 使用 DeepSeek-R1-Distill-Qwen7B 进行监督微调 (Supervised Finetuning)
  • 使用 DeepSeek-R1-Distill-Qwen7B 进行 GRPO
  • 使用 mergekit (slerp, sce) 与我的 14B 模型检查点,分数降至 20
同比赛其他方案