返回列表

4th solution

515. Google AI4Code – Understand Code in Python Notebooks | AI4Code

开始: 2022-05-11 结束: 2022-11-10 基础软件 数据算法赛
第4名方案

第4名方案

作者: gezi (Grandmaster) | 比赛排名: 第4名

召回模型

(推理耗时 2小时+,使用 2 T4 显卡耗时 1小时)

  • 成对式,双塔结构,骨干网络使用 sentence-transformers/all-mpnet-base-v2。
  • 在训练数据上继续进行 MLM(掩码语言模型)预训练。
  • 预测每个 markdown 后面是否紧接着某个代码单元(同时添加了一个内容为 'the end of notebook' 的伪造末尾代码单元)。
  • 在同一个 notebook 内选择 9 个负样本(相比使用 4 个负样本,离线和在线效果都更好)。
  • 对于代码单元,编码其自身以及前后各 2 个代码单元。
  • 交叉熵损失,以余弦相似度 / 学习到的温度参数(最终约为 0.002)作为输入 logits。
  • 离线 tau 分数 897(对每个代码位置的平均召回分数)。
  • 延迟提交分数为 8936。
  • 召回模型是关键模型,因为排序模型和上下文排序模型都使用了它的输出。
  • 这里的主要缺点是如果使用 9 个负样本,召回模型会非常消耗 GPU 资源。我使用了 8*V100,在所有训练数据上训练 1 个模型大约需要 30 小时。

成对排序模型

(推理耗时 2小时+)

  • 成对式,拼接输入,骨干网络使用 deberta-v3-small。
  • 仅对召回模型最大概率 < 0.8 的 markdown 进行推理,因此只对约 50% 的 markdown 进行推理(重排序)。
  • 离线 tau 分数 905。

上下文排序模型

(推理耗时 2.5小时+)
修改自 Stronger Baseline with Code Cells

  • 骨干网络使用 deberta-v3-small。
  • 将 3 个 markdown 作为一个组(对每个实例一次性推理)
    这些组是利用召回模型选择的,选择具有相似代码分数的 markdown 组成一个组。
  • 通过召回模型选择 40 个代码(训练时使用召回模型的 OOF)
    这也是一个关键点,训练时使用召回模型提供的采样概率进行负采样,推理时只需选择召回概率最高的代码。比赛结束后我了解到大多数顶尖队伍使用了更多的代码,更多的上下文/代码是获胜的关键。
    训练时仅使用带有一定失真(随机性)的间隔选择代码,然后推理时使用召回模型选择的 top 代码可以提高 0.1+。我在上线前测试了一个上下文模型,从 8806(无召回模型)提升到了 8892(使用召回模型)。
    如果训练时使用召回模型选择,或者带有采样概率,效果会再好 0.05+。
  • 将召回模型的 OOF 分数作为输入添加到 BERT 中,提升了 0.004。
    不确定是否过拟合,所以我选择了一个包含它的提交(9147)和一个不包含它的提交(9143)。我犯了一些错误,没有时间重新训练,只对带有 OOF 分数的模型微调了 3 个 epoch,所以这个 OOF 方法本应该提升更多,我认为应该是 2k+,你可以从第一个 epoch 看到下面巨大的提升。
    最终我们看到从 9162 提升到了 9170。
    训练曲线图
  • 多损失函数(num_classes 为 100 的分类任务 + 用于预测每个 markdown 相对排名的 MAE 回归任务)。
  • 离线 tau 分数 916(有趣的是,这是分类输出)和 tau 分数 914(回归输出)。

GBDT 模型融合

(推理耗时 5分钟)

  • 使用了 CatBoost 和 LightGBM,在线上帮助提升了约 6k。
  • 离线 tau 分数 922,在线分数 9147。
    最重要的特征如下所示:
    xpc 代表成对拼接排序模型
    xc 代表上下文排序模型
    xp 代表成对双塔模型(召回模型)
    特征重要性图

总结与感想

刚刚了解到 deberta-v3-large 配合大输入会更好,更多的上下文(

同比赛其他方案