Z Lab数据实验室成员 Tilbur
↑↑↑关注后"星标"kaggle竞赛宝典数据科学竞赛的这一年(NLP)
01
入门
满打满算距离第一次参加NLP数据科学竞赛已经过了一年了,想写一篇自己的经历贴,顺便讲讲我的成长经历和经验。
大概是22年3月左右,当时的我刚复试结束拟录取,加入实验室后面临选择研究方向的困境。思考了很久到底NLP还是CV(或者结构化),但在做完导师发下来的一篇动手学NLP任务实践后,彻底决定了往NLP方向努力。在入门教程指南中,第一次学到了什么叫神经网络、机器学习、树模型和LSTM,教程的最后一章是做一个简单的文本分类任务,当时只能潦草地用LSTM做Encode来完成这个问题,幸好同门以前做过这个项目,给了我一份Bert的baseline指南,而我拿到这份baseline还是束手无策,压根不懂什么是Bert、torch的代码为什么要这么写。犹豫再三后,拿着这份代码去请教我的师兄,很感谢我的几位师兄,一行行代码讲给我听。勉强了解了函数逻辑后,盯着这份代码一行行debug、追踪变量的变化情况,才捋清了一个简单bert分类任务的流程,从文本输入、Tokenize到变成tensor进入bert模型,以及最终的输出。此时的我,勉强了解了NLP届大杀器Bert的基本原理,又去读了Bert的原文,加上知乎的各种解析、讲解,才了解了Transformer大一统的意义。02
第一次比赛(2022WBDC)
2022年7月,刚学完入门指南,和同门就去参加了第一场数据科学竞赛。竞赛的内容是多模态短视频分类,方案十分复杂。当时的我也不懂多模态到底是什么意思,只能勉强跟着赛方发的baseline去做。
当时就是一整个大懵逼状态,第一次接触整个较为完整的方案代码,baseline分了十几个py文件,一块块读的非常吃力。最终也是靠老方法,从输入开始用debug追踪每行代码,了解每一步变量都在怎么变,才勉强读懂baseline。后面又是靠潜水在赛题选手群里,看着大家的讨论才知道要去做bert预训练,才能有一个不错的效果。说到Bert预训练,当时又懵了,完全不知道怎么写。只能去github拉了一份其他类似比赛的bert预训练代码,东拼西凑进去。至于原理如何实现,也是完全不懂的。进了复赛,数据又引入了图片信息,要自己构建图片编码器加入到整套模型流程中,又懵了。当时又去读了几乎所有多模态的sota,了解到比较好使的图片编码器有ResNet、VIT、Swin等等,以及Clip等多模态模型。在不断尝试模型构建,一遍遍预训练调整方案后,最终还是取得了一个不错的成绩(国一)。赛后来看,这场比赛也许到最终我也没弄懂我方案里的所有代码,毕竟有大部分都是cv过来的,整个赛程期间我只做了一件事,就是去搜、去找、去群里偷听大家的idea,然后和队友一起一步步把这些idea全部实践。所有有用的、没用的idea,只要是我了解了过后可以实现的,我都尝试了一遍。准确来说,第一场比赛能拿到前排,完全靠我和队友的十块肝,而没有自己的一点idea。。。经常熬夜到三四点监控丹炉,所有的时间都在做实验和读懂代码。03
第二次比赛(2022BDCI)
2022年9月,刚结束了生涯第一场正式赛,又转身投入了第二场NLP赛。这次的赛题是一道传统的NER+关系抽取题,在刚接触到这个任务的时候,马上回想到之前啃书时了解到的CRF,初步尝试构建Bert+CRF后发现是一坨狗屎。
好巧不巧的是,又有一位伟大的选手,在比赛讨论区开源了他从苏建林的GPLinker Keras版本改成torch版本的baseline代码。然后又是老一套,一行行debug追踪变量和代码,尝试读懂代码逻辑。同时,我也反复读了好几遍苏神在科学空间发的那篇GPLinker的文章,一点点推敲代码,了解详情。后来,在思考的过程中发现baseline的RoPE位置编码压根没有开启,颇为震惊,开启了后分数直线上升到前排,后面就是一套老的EMA、FGM、Rdrop、多模融合套路。正当我兴高采烈地做着实验的时候,突然连续两天从前排掉到了十几名,而且Top5的分数极为蹊跷,远远甩开其他人。纳闷的时候,队友突然大腿一拍,说在寻找外部预训练语料的过程中,在github找到了去年主办方举办上一届的比赛的训练集。令人震惊的是,上一届的训练集居然是这一届的测试集,怪不得前排的分乱涨。在主办方被疯狂抨击后,宣布b榜会采用全新的重新标注的测试集,但我也对这比赛失去了兴趣,草草了事,在比赛结束还有20天的时候转头去做了另一个赛,最终BDCI也只拿到了rk9。04
第三次比赛(2022天马杯)
2022年11月,很感谢这场比赛,这是我的第一场文本生成赛,也让我对文本生成的整体流程有了一定的了解,了解了编码体系和训练格式,最终也只是采用了传统文本生成的一系列trick,比如调整generate参数,模型基座,模型结构,词表扩充等。这场比赛最终是拿了第二名,但感觉方案是平平无奇,但这也让我对文本生成的整体都有了更深的了解,才有了之后的辉煌。
05
第四次比赛(2023GAIIC)
2023年4月,参加的第二场大赛,上一场还是WBDC,竞争非常激烈。比赛任务是做一个条件文本问答,但由于脱敏的问题这题也需要一个良好的预训练任务。
之前积累下来的一切文本生成及Transformer体系的预训练经验都在本次比赛发挥了极为重要的作用。经验让我在比赛前期就很快跳过了调参、调模型、调框架的复杂实验,直接进入了进一步的trick提升阶段。在基本完成一定的方案整理后,我就开始尝试进一步的实验。首先是自己从零手撕了n种预训练任务,真正搞懂了预训练的原理和实现,在这其中MLM、DAE任务是比较亮眼的,带来了极大的分数提升。然后在第一次接触文本生成模型融合的情况下,从原理开始拆解解码流程,一步步从零手撕一个完整的BeamSearch解码器,初赛也是在完成了简单模型融合及预训练后霸占了前排。进入复赛后,就多了一些奇奇怪怪的想法,非常幸运的是这些想法都很work,也为我带来了第一个Top赛事的亚军。比如在BeamSearch中做一些最优性剪枝(这加速了推理让我们能融更多的模型、同时也带来了微弱的指标提升),利用R-drop的思想在曝光偏差问题中应用(解决了一定推理误差的问题),以及对评价指标的深挖知道了长度差异性惩罚的重要性。很感谢的是,在这些奇奇怪怪的想法work后,我一度长期领跑排行榜,虽然后期有点乏力掉了几名,最终还是夺得了亚军。总的来看,这场比赛的经验就是要在打好基本功的情况下针对赛题去搞一些奇奇怪怪的想法,也许就能实现呢?最关键的是,一定不能嫌实现麻烦、复杂就放弃做一些可能会work的想法,比如我写这个解码代码+最优性剪枝花了我复赛1/3的时间,这期间我们的榜单分数没任何提升,最终在做出来后效果还是非常惊艳的。所以,重点还是大胆想、放手做啊!06
前第五、六场比赛
在这之后,我打了两场NLP野鸡赛,吃到了一点点小奖金,但整个比赛过程中就是单纯输出而没有学习到任何新东西,也就不值一提了。
同时,迎来了第一个转折点,加入了zlab,认识了很多比我厉害的小伙伴们,在交流中一步步提升自己。07
第七场比赛(Kaggle LLM Exam)
在这场比赛之前,我迎来了第二个重要转折点,找到了一家大厂的LLM日常实习,正式决定以大模型作为以后的研究方向。在实习的前半段时间,我得以有机会实践了7B的全量微调,知道了一些微调技巧和方法,同时自己还编写了一套LLM7B预训练代码,非常感谢我的mentor给我的这些机会,让我能够窥得这个奇妙世界的一些门路。
在实习后半段,Kaggle迎来了第一个LLM比赛,我马上就带队出征了此次比赛,也是对自己经验的一些实践。在投入这场比赛后,我们全力投入RAG文本检索策略,最终也是收获了一块金牌。这段时间内,我同时要完成工作的事情,以及在工作之外继续肝比赛,由于队友都是老牌NLP大师(上班族),他们的时间不多,但经验丰富,故几乎全部的编码任务都交在了我手上。在两个月的时间内,我根据自己的idea和队友的经验告诫,一步步从零构建起了一套完整的RAG策略,应该可以说我们队伍的RAG策略是所有队伍里数一数二的,但精力不足也让我没有对模型侧有进一步的探索,这也导致了我们从奖金区抖到了金牌末尾,不过还好保住了金牌。两个月的时间内,我尝试了无数可能会起作用的idea,做了n次实验,一步步编码所有实验。也曾肝到过凌晨三点,八点起床去上班;也曾肝到键盘敲着敲着突然开始止不住地流鼻血;也曾在梦呓中思考下一步的策略。最终还是有了好的结局。08
总结
如果你看完了上面的全部内容,那相信你也可以看出来,其实我并没有那么有天赋,也许全部的成绩都是靠我的肝出来的。但NLP竞赛无非就是两个要素:经验和实践。当你没有经验的时候,你就需要去学习、去尝试;当你有了idea后,你就需要不断地去实现。
我相信,任何一个心智健全的人,在一次次比赛的积累后,以及大量的实践后,都能取得不错的成绩。或许这就是数据科学竞赛的考察点或意义,这也是他的魅力。希望这些能帮助到你我,也希望前路能一片光明。而现在,我又接到了另一家大厂的实习offer,在新的地方,也许会有更多新奇的问题、知识等着我去了解,更多奇妙的领域待我去探索。而我,还有很长的学习之路要走。继续努力!!