返回列表

6th Place Solution

573. Kaggle - LLM Science Exam | kaggle-llm-science-exam

开始: 2023-07-11 结束: 2023-10-10 自然语言处理 数据算法赛

感谢Kaggle举办LLM竞赛——它既充满挑战又组织有序。向我们的社区致以诚挚的感谢,感谢你们富有洞察力的讨论,并展示了在有限GPU资源下所能实现的一切。祝贺获胜的团队,我们从解决方案报告中学习了很多。非常感谢我超级有才华的队友们@ubamba98@nbroad@trushk@abhishek,感谢他们惊人的协作和完美的团队合作!

代码链接

总结

从最初开始,我们就采用了检索器-阅读器的框架来回答STEM选择题。

  • 检索器:获取上下文数据
    • 语料库:我们通过过滤维基百科文章的类别元数据,创建了一个自定义的STEM语料库
    • 使用GPT-3.5、GPT4、LLaMA2 70b和Falcon 180b生成合成选择题,用于训练检索器和阅读器(下游选择题模型)
    • 使用交叉编码器对前10个检索到的文本块进行重排序,并将前2到4个重排序后的文本块提供给阅读器以解答选择题
  • 阅读器:解答选择题
    • 我们使用了DeBERTa和LLM的集成
    • DeBERTa:我们探索了不同的训练策略,例如
      • 跨度方法:利用选项间信息
      • DebertaV2ForMultipleChoice:用于多样性
      • PET:用于多样性
    • LLM:我们探索了微调和零样本策略
      • 使用LoRA微调Open-Orca/Mistral-7B-OpenOrca
      • 预测熵排名前5%的选择题(作为选择题难度的代理指标)由70b LLM处理:
        • platypus2-70b-instruct
        • sheep-duck-llama-2

注意:我们在流水线中使用了platypus2-70b-instruct,我们不确定该模型与比赛规则的兼容性。

1. 检索器:获取上下文数据

我们采用了标准的检索和重排序流水线,从自定义的STEM维基百科语料库中查找与选择题相关的文本块。

1.1 STEM维基百科语料库

为了解决现有维基百科语料库中常见的渲染问题(数字、方程和符号)并过滤掉不相关的文章,我们创建了一个自定义的STEM维基百科语料库,具体步骤如下:

  • 定义一组与STEM主题相关的维基百科种子类别,例如Category:Concepts in physics(物理概念)、Category:Physical quantities(物理量)等
  • 对于每个类别,递归收集成员页面和子类别,直到一定深度
  • 使用Wikipedia-API提取收集到的维基百科URL的页面内容(约50万页)

分块:我们首先根据每个文章的不同部分拆分完整文本。较长的部分进一步拆分为包含约300个标记的较小块。我们为每个块维护两种表示形式:

  • 无重叠的简短表示形式——用于嵌入和搜索
  • 有重叠的较长表示形式(与前后块重叠)——用于下游选择题模型中的上下文

1.2 检索器

使用预训练嵌入模型(如thenlper/gte-base、BAAI/bge-base-en-v1.5)检索文本块,为下游选择题模型提供了强大的性能提升。在我们的流水线中,通过微调嵌入模型,我们观察到了进一步的性能改进。我们将生成的合成选择题重新用于检索任务,如下图所示:

检索器使用NCE损失 + 动态计算的同批次困难负样本进行微调。具体来说,我们采用了这个解决方案帖子中的批处理策略。在我们的流水线中,我们使用了微调后的thenlper/gte-baseBAAI/bge-base-en-v1.5模型检索到的前10个文本块的并集。

1.3 重排序器

为了减少提供给下游选择题模型的上下文中的噪声,我们使用交叉编码器(deberta-v3-base)对前10个检索到的候选进行重排序。我们根据重排序器计算的相关性分数的动态阈值选择前2到4个重排序后的上下文。

2. 阅读器:解答选择题

我们探索了几种使用检索到的上下文解答选择题的策略。

2.1 跨度分类

  • 对每个选项的标记进行平均池化,以提取选项特征
  • 使用选项间信息进行分类

2.2 使用LoRA微调LLM

在比赛接近尾声时,我们明显感到DeBERTa模型的性能遇到了瓶颈。因此,我们决定探索微调LLM。尽管我们尝试了多种模型(例如flan-t5-xl (3b)、flan-t5-xxl (11b)、llama-7b、mistral-7b、llama-30b和llama-70b),但我们的最终流水线只包含1个使用LoRA微调的mistral-7b模型。LoRA设置如下:

  • lr 3.e-4(略有变化)
  • rank 16
  • alpha 16
  • 所有线性组件(qkv, out_proj, ffn, gate_proj等)和嵌入层上都应用了LoRA模块
  • dropout 0.1
  • 不使用序列打包
  • bf16

在LLM微调过程中,我们采用了选项间设置,即在给定所有选项的情况下预测正确答案。我们没有探索在二分类设置中训练模型。

2.3 使用70b模型进行零样本学习

非常感谢@simjeg展示了在Kaggle GPU上使用70b LLM的潜力!!

在比赛结束前5天左右,我们开始尝试70b模型。我们意识到我们无法通过这么大的模型运行每个样本,但我们也知道我们的deberta模型在90-95%的问题上表现良好。因此,我们选择最不自信的预测并传递给70b模型,使用@simjeg的代码。在最后几天里,我们进行了一些提示工程,发现使用两个标记(yes/no或true/false)之间的差异会带来稍好的结果。最终,我们同时使用了platypus 70b和sheep-duck-llama-70b。我们根据公开笔记本调整了提示以匹配其训练方式。我们最后的几次提交都是实验,传递5-10%的样本,与其他模型融合,或者直接使用70b预测作为最终预测。我们的运气不错,因为最好的分数出现在最后一天。

在我们的自定义数据集上的交叉验证显示,一次性传递所有选项的性能略好,但我们无法在Kaggle上实现这一点。

使用Sheep-duck-llama的本地验证结果:

  • (一次性所有选项)ABCDE标记:0.91
  • (一次一个选项)仅yes标记:0.886
  • (一次一个选项)仅no标记:0.888
  • (一次一个选项)yes标记 - no标记:0.891

我们确实尝试过使用QLoRA微调70b模型,但在时间耗尽之前无法解决遇到的问题。

团队成员

  • Abhishek Thakur (@abhishek)
  • Trushant Kalyanpur (@trushk)
  • Udbhav Bamba (@ubamba98)
  • Nicholas Broad (@nbroad)
  • Raja Biswas (@conjuring92)
同比赛其他方案