大模型时代,通常采用向量召回的方式从文档库里召回和用户问题相关的文档片段,输入到LLM中来增强模型回答质量。
但是很多时候,用户的问题是十分口语化的,描述的也比较模糊,这样会影响向量召回的质量,进而影响模型回答效果。今天给大家带来一篇来自战士金大佬(@知乎战士金)的博文-大模型辅助向量召回。接下来分享两篇通过大模型的能力增强召回效果的文章,这两篇文章的内容都已经加入了langchain的标准组件,易用性还是比较好的,但是都有一些特定的使用场景。
Paper1:https://arxiv.org/abs/2212.10496
Paper2:https://arxiv.org/abs/2305.06983
知乎:https://zhuanlan.zhihu.com/p/653808554
HYDE论文-Precise Zero-Shot Dense Retrieval without Relevance Labels,文章中强调了该文章主要适用于Zero-Shot场景。Zero-Shot指的是模型没有见过某个场景(或者某个数据集)的数据,就应用于该场景,和用数据训练模型以及在语言模型上下文中加入示例相对应。Zero-Shot体现了模型的迁移能力,我猜大部分同学都是在zero shot场景上使用向量化模型的,比如从网上下载个向量化模型权重,直接在自己的业务场景上用。其实,如果自己的业务场景有数据,微调一下向量化模型,在对应业务场景下召回率能提升不少。
既然论文题目强调了zero-shot,论文看的比较多的同学一定能马上反应过来,是不是在非zero shot(比如微调向量化模型)的场景下这方法效果就很一般呢?文章作者也给出了实验结果,该方法在结合微调过的向量化模型时,效果就没那么好了,非常依赖打辅助的LLM的能力。如果您有微调向量化模型的能力,这部分就可以跳过了。再强调一下,这篇文章是篇纯讨论召回的文章,最后的衡量指标也是nDCG和召回率这些指标,使用LLM单纯是为了提高召回效果的。
langchain链接:https://python.langchain.com/docs/use_cases/question_answering/how_to/hyde
论文思路非常简单:
接下来我们从论文中挑一个比较重要的实验结果进行讨论。测试集为TREC DL19/20数据集,向量化模型使用的是Contriever模型,原始的该模型并未在TREC DL19/20数据集上训练过。模型有上标FT指的是向量化模型在TREC DL相关的数据集上微调过的。黄框标出来的是未使用hyde技术的baseline结果。绿框标出来的是未微调的向量化模型使用hyde技术的实验结果。红框标出来的是微调过的向量化模型使用hyde技术的实验结果。
实验指标为NDCG@10,可以发现,对于没有微调过的向量户化模型(zero shot场景),hyde还是非常有用的,并且随着使用的LLM模型的增大,效果不断变好(因为LLM的回答质量提高了)。非常有意思的一点是是对于微调过的向量化模型,如果使用比较小的LLM生成假答案(小于52B参数量),hdye技术甚至会带来负面影响。
因为领域微调过的向量化模型性能已经不错了,NDCG@10指标能达到60多,LLM生成的假答案的知识性错误带来的负面影响大于回答模式信息带来的正面影响。所以向量化模型模型还是能微调就微调吧。
和上一篇文章相比,FLARE论文比较新一点,评估的指标是直接看最后LLM的回答效果的,而非是向第一篇文章那样只讨论召回准确率。这篇文章涉及到针对同一个问题的多次召回,因此比较适合长文本回答。如果您所面对的场景大部分问题用一两句话就能回答,那收益就不是太大了。
langchain链接:https://python.langchain.com/docs/use_cases/question_answering/how_to/flare
对于大模型外挂知识库,大家通常的做法是根据用户query一次召回文档片段,让模型生成答案。只进行一次文档召回在长文本生成的场景下效果往往不好,生成的文本过长,更有可能扩展出和query相关性较弱的内容,如果模型没有这部分知识,容易产生模型幻觉问题。一种解决思路是随着文本生成,多次从向量库中召回内容。
有三种常用的多次召回策略:
已有的多次召回方案比较被动,召回文档的目的是为了得到模型不知道的信息,a、b策略并不能保证不需要召回的时候不召回,需要召回的时候触发召回。c.方案需要设计特定的prompt工程,限制了其通用性。作者在本文里提出了两种更主动的多次召回策略,让模型自己决定啥时候触发召回操作。
通过设计prompt以及提供示例的方式,让模型知道当遇到需要查询知识的时候,提出问题,并按照格式输出,和toolformer的模式类似。提出问题的格式为[Serch(“模型自动提出的问题”)](称其为主动召回标识)。利用模型生成的问题去召回答案。召回出答案后,将答案放到用户query的前边,然后去掉主动召回标识之后,继续生成。当下一次生成主动召回标识之后,将上一次召回出来的内容从prompt中去掉。下图展示了生成拜登相关答案时,触发多次召回的例子,分别面对拜登在哪上学和获得了什么学位的知识点上进行了主动召回标识的生成。
该方法也存在一些缺陷:
策略1存在的第3点缺陷比较知名。因此作者提出了另外一个策略。该策略基于一个假设:模型生成的词对应该的概率能够表现生成内容的置信度。(传统的chatgpt接口是用不了策略2的,因为得不到生成每个词的概率。)
分为4个步骤:
依然针对拜登的问题,下图给出了例子。
接下来介绍一下实验结果。先声明一下,这篇文章用的召回器(向量化模型)是BM25,2009年被提出,基于统计学的原理,属于一种词袋模型,效果一般。笔者认为,如果用一些效果更好的基于神经网络的召回器,本文提出的方法提升就没那么大了。
召回器榜单:
中文:https://github.com/FlagOpen/FlagEmbedding/tree/master/C_MTEB
英文:MTEB Leaderboard - a Hugging Face Space by mteb
多次召回方案在更加开放的任务类型上提升比较小。如果是召回并回答一些模型不知道的垂类知识,FLARE效果提升应该是还不错的。
作者证明了用生成”假答案“进行召回(Next)效果比用前一句进行召回效果更好(印证了HYDE观点)。
当一个句子里生成的所有单词的概率都大于一个阈值t时,才不触发召回文档。当t=0%时,不触发召回文档;t=100%时,每次都触发召回。下图展示了不同的t的情况下LLM回答效果。可以发现t过大或者过小都不是最好的。总体上来看t=50%比较好。
分享的这两篇文章都需要多次调用LLM,来增强召回,虽然在一些场景下比较有效,不过开销感觉有点太大了。其实最简单有效的提高召回效果的方式就是在自己业务的数据集上微调一下向量化模型。
全部0条评论
快来发表一下你的评论吧 !