随着大模型的爆火,很多垂域行业都开始使用大模型来优化自己的业务,最典型的方法就是RAG(检索增强生成)了。简单来说就是利用检索技术,找出与用户问题相关性最高的段落,再让LLM基于以上段落,去回答用户的提问。这样的事情,在CSDN的时候其实也做过一次,参考:CSDN问答机器人。只不过当时是在SBERT模型上微调,也取得了不错的效果。这里我们使用的基座模型是BAAI/bge-large-zh-v1.5。
具体的样例参考官方的吧:https://github.com/FlagOpen/FlagEmbedding/tree/master/examples/finetune
其实官方的readme已经说的很明白了,官方说过的我就不赘述了,我这里主要讲一下数据集的构造过程。
我做了两种尝试:
第一种
大概有这么些字段:
说实话有点多,要结合这么多字段筛选数据,也不是件容易的事情
第二种
可见,第二种方法简单很多,利用查询出来的top100设定阈值筛选出训练数据(不同数据集阈值不同,可根据自己的实际情况设置)。
说明一下:
我的场景是,即匹配出与最相关的段落。正例的构造是使用生成的,让LLM根据给定的段落生成问答对,是生成的问题,是给定的段落,构成一个正例对,当然,LLM生成的数据也是需要过滤的,最后生成不到一万条,负例的构造是使用以上两种方法生成。我的(仅供参考)。
上面提到的重排模型用的是
理论上,第一种方法构造出来的数据会更好,但实际操作起来会发现,这种方法会非常耗时,即使使用多GPU并行、多进程等优化处理,二十万数据,还是需要将近一天的时间(因机器性能而异),我使用这种方法构造了一批数据,训练出来的模型效果比基座模型还要差几十个点,主要原因是困难负例样本没有构造好,困难样本量也不够,时间充裕的同学可以尝试下召回Top100试试,理论上应该会效果更好才对!
最后实际使用的是第二种方法,相比基座模型top100召回率提升了,还有优化的空间。
包含了两个字段,分别是,是问题,是包含该问题答案的段落
整体过程挺简单的,最重要的就是合理地构造困难负例,这个过程需要尝试不同地阈值,分析构造出来的数据是否准确。
注: 越小表示越相似
我这里训练时没有加 ,官方建议是说检索任务最好加,效果会更好些,但是在我这个场景中,加了反而效果更差,差了左右。
今天加上又训练了一版,在推理时不加,top50的召回率提升了3%左右,top100召回率只提升了0.3%,整体来说效果更好,因此后续将会使用这一方案在质量更高的数据集上训练。
再来看个大的
1、使用训练好的向量模型去构造困难样例,再重新训练基座模型,效果会不会更好?(套娃?)
2、将负样本从阈值区间采样改为取相对来说更相近的前TopK个