新闻文本数据的语义检索与智能问答比赛的一个baseline分享,这个方法目前排在第3名,作为一个baseline还是ok的。
开源代码链接:https://github.com/DunZhang/DFPassageRetrieve
比赛官网地址:https://www.datafountain.cn/competitions/567
这个任务是个非常经典的文本检索任务:给定一个新闻数据库和一个query,从新闻数据库中找到与该query最相似的100个新闻文档。新闻数据库约有260多万个文档,平均长度是700,语言为英文。此外赛事方对数据做了加密,所有的单词替换成了对应的数字,所以你所看到的数据都是一堆数字。
既然分享的是baseline,那思路还是很朴素,核心做法就是训练一个编码器,然后将文本转为向量并计算相似度值,最后根据相似度值进行排序。训练的整体思路就是:预训练+微调。下面会详细介绍。
既然要训练,肯定需要先构建词表,本方法使用的是基于bert的模型,所以词表的格式也和bert一致。在英文中会使用切片来减小词表体积,但在本比赛中文字进行了加密,无法切片,所以对词频进行了过滤,低于2000一概不要,或许有些糙了,但是对于一个baseline来说足够了。
模型架构采用roformer,为了节省时间没使用base模型,模型的硬盘体积约为100多MB,相比400MB的bert_base模型还是小了很多的。预训练任务wwm,最大长度设置为512,batch_size为256,训练了4轮左右,loss降到了2.7,最好能降到1.5以内。
预训练200多万的长文本确实耗时。算力不足的同学,可以考虑直接拿我开源的预训练模型,tf和torch格式都有提供。 下载链接:https://pan.baidu.com/s/1iY8ezQ1I7wnT0wOvryNVeQ?pwd=6666 ,提取码:6666
相比预训练,微调就省时省力了,一块8G的显卡训练一个多小时也能取到相当不错的效果! 微调也是用的非常经典的方法:对比学习,概括说就是batch内的其他数据都是负例,举个例子,batch_size是16,那么除了正例之外的15都可以作为负例,可以理解成标签是0,直接当成多分类任务去解,这个方法在NLP和CV中都太过经典所以我就不过多赘述了。
毕竟是baseline,整体的思路以及每个步骤所用的方法都属于向量检索领域的入门知识,如果想进一步提升效果,可以看下文的总结的优化项。
torch随便一个版本就行;tf版本需要跟着bert4keras走;此外由于使用faiss向量加速,如果是windows,Python版本需要低于3.8.
预训练的代码直接在roformer的基础上改的,用的是tf,roformer原始训练代码地址是:https://github.com/ZhuiyiTechnology/roformer。
微调代码为pytorch,纯手写,注释丰富便于理解。
Step1:获取词表,运行get_vocab.py
Step2:预训练,TF环境,非常耗时,运行pretrain_roformer.py
Step3:预训练模型转为Torch,运行convert_tf_roformer_to_pt.py
Step4:微调,Torch环境,运行run_finetune.py
Step5:预测结果并生成提交文件,Torch+Faiss,运行run_predict.py
注意1:所有的运行直接使用IDE就行,不需要控制台。
注意2:一些运行参数可能需要根据本机环境进行修改。
注意3:如果不想预训练,可以直接下载本人提供的预训练模型,直接做Step4即可,加载方式同bert。
涉及模型、数据、训练和开源代码的一些优化,本人开源后就歇着了,所以下面的优化项就不再尝试了。