大模型 RAG 问答技术架构及核心模块盘点:从 Embedding、prompt-embedding 到 Reranker

对于RAG而言,2023年已经出现了很多工作,草台班子有了一堆,架构也初步走通,2024年应该会围绕搜索增强做更多的优化工作。

因此我们今天来系统回顾下RAG中的模块,包括一些架构,文本嵌入embedding等,供大家一起参考。

如果你是实战派,喜欢实操、技术交流的朋友,文末有实战案例。

一、从RAG的整体架构及开源两阶段RAG项目说起

我们在之前的文章带你全面了解 RAG,深入探讨其核心范式、关键技术及未来趋势中对Retrieval-Augmented Generation for Large Language Models: A Survey进行了介绍,其对于增强大家对RAG的基本理论认知有一定的帮助。

例如,该工作将RAG分成navie RAG, Advanced RAG以及Modular RAG,

图片

而另一个文章:https://blog.llamaindex.ai/a-cheat-sheet-and-some-recipes-for-building-advanced-rag-803a9d94c41b又整理了个图,在圈子里火了起来。

Motivation 与 Basic RAG

图片

Advanced RAG

图片图片

感兴趣的可以去看看。

而最近也有开源一个涵盖到reranker阶段的RAG开源项目QAnything

QAnything (Question and Answer based on Anything) 致力于支持任意格式文件或数据库的本地知识库问答系统,支持PDF,Word(doc/docx),PPT,Markdown,Eml,TXT,图片(jpg,png等),网页链接等。

图片

地址:https://github.com/netease-youdao/QAnything

QAnything使用两阶段检索范式,其提到,知识库数据量大的场景下两阶段优势非常明显,如果只用一阶段embedding检索,随着数据量增大会出现检索退化的问题,二阶段rerank重排后能实现准确率稳定增长,即数据越多,效果越好。

二、再看RAG中的embedding模型

本周,也出现了一些新的文本嵌入模型和RAG项目,例如NetEase Youdao开源了其嵌入项目BCEmbedding以及问答系统QAnything。

EmbeddingModel用于生成语义向量,在语义搜索和问答中起着关键作用,EmbeddingModel支持中文和英文。

EmbeddingModel通常用于粗排,因为其可以预先对文本进行向量表示,并预先建立索引,在真实场景下只需要检索计算相似度即可,很快速,并且各个文本计算相似度可以

from BCEmbedding import EmbeddingModel

# list of sentences
sentences = ['sentence_0', 'sentence_1', ...]

# init embedding model
model = EmbeddingModel(model_name_or_path="maidalun1020/bce-embedding-base_v1")

# extract embeddings

embeddings = model.encode(sentences)

不过EmbeddingModel并为考虑文本之间的交互,并且不同的场景下,相似度阈值并不好控制。

1、BCEmbedding

BCEmbedding(BCEmbedding: Bilingual and Crosslingual Embedding for RAG)是由网易有道开发的双语和跨语种语义表征算法模型库,其中包含EmbeddingModel和RerankerModel两类基础模型。

实际上,与此相对应的更早的模型,有智源开放的BGE模型。

图片

地址:https://github.com/netease-youdao/BCEmbedding

2、BGEEmbedding

BGEEmbedding是一个通用向量模型,基于retroma 对模型进行预训练,再用对比学习在大规模成对数据上训练模型,地址:https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/baai_general_embedding

图片

3、效果对比

可以在https://github.com/netease-youdao/BCEmbedding中找到embedding侧的对比结果。

其采用基于MTEB的语义表征评估基准(https://github.com/embeddings-benchmark/mteb)。

图片

二、再看带有prompt的向量化embedding

知乎文章《https://zhuanlan.zhihu.com/p/661867062》针对这块有了个不错的总结【感兴趣的可以进一步看看】,其提到,在大模型微调这块,有个hard prompt tuning的方式,在进行多任务微调的时候,给不同的任务的input前边都加入固定模式的文字,让模型学会,看到某一段文字之后,就知道要做什么任务了,有助于提高下游不同任务的效果。

图片

举一反三,都是语言模型,当然也可以在向量化模型上用这个trick了,也就是做不同的任务时,分别给不同任务的query和key加上不同的prompt之后在做向量化,因此,母亲也出现了许多很有意思的idea。

1、TART

《Task-aware Retrieval with Instructions》(https://arxiv.org/pdf/2211.09260.pdf)是在2022年很早期的一个工作,该工作目标是利用多任务指令调整技术开发一种通用的任务感知检索系统,该系统可以按照人类编写的指令为给定查询找到最佳文档,首次大规模收集了约40个带指令的数据集(BERRI,Bank of Explicit RetRieval Instructions),并介绍了在带指令的BERRI上训练的多任务检索系统TART(TAsk-aware ReTriever),TART展示了通过指令适应新检索任务的可行性。

图片

2、instructor

我们在之前的文章《引入任务Instruction指令的句子向量化方案:Instructor的实现思路及训练数据集构造方案》(https://mp.weixin.qq.com/s/qIh07eU8_lYL2gBVzTFzKA)** 中有介绍到instructor的方案,其在每个query上,加上了指令信息,并一次来计算对比学习loss:

图片

这种思路引入了适配特定instruction任务的嵌入方案,这与instruction微调美妙结合。

对应的工作《One Embedder, Any Task: Instruction-Finetuned Text Embeddings》(https://arxiv.org/abs/2212.09741)这一工作,提出了INSTRUCTOR(Instruction-based Omnifarious Representations)的思路,是一种根据任务说明计算文本嵌入的新方法:每个文本输入会与解释用例的说明(如任务和领域描述)一起进行嵌入。

在具体实现上,该工作通过构造330种不同任务的说明,并在这种多任务上对INSTRUCTOR进行了对比损失训练,这个和当前大模型的instruction tuning工作很像。

项目地址:https://instructor-embedding.github.io

3、基于合成任务优化embedding

而最近的另一个工作,《Improving Text Embeddings with Large Language Models》(https://arxiv.org/abs/2401.00368) 这一工作,利用LLM为近100种语言的文本嵌入任务生成多样化的合成数据,在合成数据上使用标准对比损失对开源模型LLM进行微调,得到更好的嵌入表示。

图片

具体思路上,用了两步提示策略:首先提示LLMs对候选任务库进行头脑风暴,然后提示LLMs从任务库中生成以给定任务为条件的数据。为了涵盖各种应用场景,为每种任务类型设计了多个提示模板,并将不同模板生成的数据结合起来,以提高多样性。对于文本嵌入模型,选择微调功能强大的开源LLM,而不是BERT式的小型模型。

4、LLM Embedder

LLM-Embedder《Retrieve Anything To Augment Large Language Models》(https://arxiv.org/abs/2310.07554),也就是BGE2。其实,其在第一个版本的时候,就已经引入了instruction的思想,做向量化召回时候只将召回任务分成两类:对称检索(相似句匹配)和非对称检索(QA匹配),如果做是QA匹配,需要在Q进行向量化时候,加入前缀:“为这个句子生成表示(for s2p(short query to long passage) retrieval task, each short query should start with an instruction ),不同版本的模型对应的prompt如下:

图片

例如使用BGE模型时,源代码可以为:

from sentence_transformers import SentenceTransformer
queries = ['query_1', 'query_2']
passages = ["样例文档-1", "样例文档-2"]
instruction = "为这个句子生成表示以用于检索相关文章:"

model = SentenceTransformer('BAAI/bge-large-zh-v1.5')
q_embeddings = model.encode([instruction+q for q in queries], normalize_embeddings=True)
p_embeddings = model.encode(passages, normalize_embeddings=True)
scores = q_embeddings @ p_embeddings.T

在具体实现上,BGE2根据LLM的反馈进行微调,支持大型语言模型的检索增强需求,包括知识检索、记忆检索、示例检索和工具检索,在具体实现上,在6个任务上进行了微调:问题回答、对话搜索、长对话、长文本建模、上下文学习和工具学习。

图片

对应的prompt如下:

INSTRUCTIONS = {
    "qa": {
        "query": "Represent this query for retrieving relevant documents: ",
        "key": "Represent this document for retrieval: ",
    },
    "icl": {
        "query": "Convert this example into vector to look for useful examples: ",
        "key": "Convert this example into vector for retrieval: ",
    },
    "chat": {
        "query": "Embed this dialogue to find useful historical dialogues: ",
        "key": "Embed this historical dialogue for retrieval: ",
    },
    "lrlm": {
        "query": "Embed this text chunk for finding useful historical chunks: ",
        "key": "Embed this historical text chunk for retrieval: ",
    },
    "tool": {
        "query": "Transform this user request for fetching helpful tool descriptions: ",
        "key": "Transform this tool description for retrieval: "
    },
    "convsearch": {
        "query": "Encode this query and context for searching relevant passages: ",
        "key": "Encode this passage for retrieval: ",
    },
}

其在具体实现上很有意思,重点在于基于大语言模型反馈的奖励机制、知识蒸馏的稳定化以及明确指示的多任务微调。具体的:

在基于大语言模型反馈的奖励机制方面,

LLM的期望输出表示为𝑂,检索候选表示为𝐶,候选的奖励表示为𝑟𝐶|𝑂,由以下方程导出:

图片

𝑜𝑖表示期望输出的第𝑖个标记,而LLM(𝑥|𝑦)表示在给定上下文𝑦的情况下,LLM生成𝑥的可能性。换句话说,如果一个检索候选导致期望输出的生成可能性更高,那么将分配更高的奖励。

对于问答任务,奖励计算为在给定一个单一候选段落的情况下,生成答案的可能性;对于指令调整任务,奖励计算为在给定一个候选示例的情况下,生成指定的输出的可能性。对于生成任务,奖励计算为在给定一个候选历史块的情况下,生成新内容的可能性。不过,LLM奖励不适用于会话搜索和工具学习数据集,因为在这些情况下没有对LLM输出的明确期望。

在损失函数方面,使用对比学习的损失函数:

图片

在知识蒸馏方面,通过最小化使用LLM的奖励计算的候选样本分布与由嵌入模型预测的分布之间的差距来提高模型性能,通过计算KL散度,以减小LLM的奖励的波动对蒸馏的负面影响:

图片

最后,在训练数据方面,

图片

三、最后看关于RerankerModel精排模型

交叉编码器将对查询和答案实时计算相关性分数,这比向量模型(即双编码器)更准确,但比向量模型更耗时。因此,它可以用来对嵌入模型返回的前k个文档重新排序。

图片不同于向量模型需要输出向量,直接文本对输出相似度(因为交叉编码器在句子层面的任务上表现非常好,但它存在一个“致命”缺点:交交叉编码器不产生句子嵌入,这个嵌入没有绝对意义),排序准确度更高,可用于对向量召回结果的重新排序,提升最终结果的相关性。

图片

在技术实现上,Query-Passage paire组成的正负样例,一块送入模型,训练目标是,正样例的logits score大于batch内的负样例。

图片

也就是说,其通过句子对及表征其语义相似程度的基本事实标签(可能是离散的类别标签,或者是连续性的相似度数值)来进行有监督训练。

这块的实现可以参考:https://github.com/luyug/Reranker/tree/main

from BCEmbedding import RerankerModel
# your query and corresponding passages
query = 'input_query'
passages = ['passage_0', 'passage_1', ...]

# init reranker model
model = RerankerModel(model_name_or_path="maidalun1020/bce-reranker-base_v1")

# method 1: rerank passages
rerank_results = model.rerank(query, passages)

但是,很现实的是,交叉编码器在实际应用中的速度很慢,所以通常都是作为精排出现,关于rerank精排这块的对比实验,可以查看《Agents大模型外挂检索优化》(https://zhuanlan.zhihu.com/p/657653570),有些结论很有意思:

bge-reRank模型虽然是一个rank模型,但其的score值还是较好的稳定在一个取值范围,业务场景中,可在自己的测评数据上,找到的一个不错的score值,来解决不应该召回的情况。

使用reRank,可显著提升检索效果,前提还是bge-reranker-large效果比较好。笔者对比,阿里的通用reRank模型,效果比检索还差了。

检索的候选多了,效果上限会提高但ReRank效果可能会下降。

通过domain数据finetune,可进一步提升,检索效果,为业务指标提升,展现了一条康庄大道。

而进一步的,在训练数据方面,常用的数据包括

T2ranking:https://huggingface.co/datasets/THUIR/T2Ranking

MMmarco:https://github.com/unicamp-dl/mMARCO

dulreader:https://github.com/baidu/DuReader

Cmedqa-v2:https://github.com/zhangsheng93/cMedQA2

nli-zh:https://huggingface.co/datasets/shibing624/nli_zh

msmarco:https://huggingface.co/datasets/sentence-transformers/embedding-training-data

nq:https://huggingface.co/datasets/sentence-transformers/embedding-training-data

hotpotqa:https://huggingface.co/datasets/sentence-transformers/embedding-training-data

NLI:https://github.com/princeton-nlp/SimCSE

Mr.TyDi:https://github.com/castorini/mr.tydi

1、youdao RerankerModel

RerankerModel擅长优化语义搜索结果和语义相关顺序精排,支持中文,英文,日文和韩文。

地址:https://github.com/netease-youdao/BCEmbedding

2、BGE Reranker

FlagEmbedding(https://github.com/FlagOpen/FlagEmbedding/)在检索增强llm领域做了许多开源工作,Reranker Model也是其中的一个重点,其在在多语言数据上训练了交叉编码器。

图片

地址:https://huggingface.co/BAAI/bge-reranker-large

3、模型对比效果

模型评测方面,使用llamaindex进行测试,可以从https://github.com/netease-youdao/BCEmbedding中找到对应的评测结果,如下表所示:

图片

当然具体的数值还可以参考:《Boosting RAG: Picking the Best Embedding & Reranker models(https://blog.llamaindex.ai/boosting-rag-picking-the-best-embedding-reranker-models-42d079022e83)

总结

本文主要介绍了RAG系统中的一些有趣的话题,包括从RAG的整体架构及开源两阶段RAG项目、带有prompt的向量化embedding、关于RerankerModel精排模型,这些都在2024年开年这一周出现了很多有趣的工作。

搜索增强,在24年会有很多工作,大家可以多跟进。

通俗易懂讲解大模型系列

  • 用通俗易懂的方式讲解:在 Langchain 中建立一个多模态的 RAG 管道

  • 用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

  • 用通俗易懂的方式讲解:一文讲清大模型 RAG 技术全流程

  • 用通俗易懂的方式讲解:如何提升大模型 Agent 的能力?

  • 用通俗易懂的方式讲解:使用 Mistral-7B 和 Langchain 搭建基于PDF文件的聊天机器人

  • 用通俗易懂的方式讲解:ChatGPT 开放的多模态的DALL-E 3功能,好玩到停不下来!

  • 用通俗易懂的方式讲解:结合检索和重排序模型,改善大模型 RAG 效果明显

  • 用通俗易懂的方式讲解:基于扩散模型(Diffusion),文生图 AnyText 的效果太棒了

  • 用通俗易懂的方式讲解:在 CPU 服务器上部署 ChatGLM3-6B 模型

  • 用通俗易懂的方式讲解:ChatGLM3-6B 功能原理解析

  • 用通俗易懂的方式讲解:使用 LangChain 和大模型生成海报文案

  • 用通俗易懂的方式讲解:一个强大的 LLM 微调工具 LLaMA Factory

  • 用通俗易懂的方式讲解:ChatGLM3-6B 部署指南

  • 用通俗易懂的方式讲解:LangChain Agent 原理解析

  • 用通俗易懂的方式讲解:HugggingFace 推理 API、推理端点和推理空间使用详解

  • 用通俗易懂的方式讲解:使用 LangChain 封装自定义的 LLM,太棒了

  • 用通俗易懂的方式讲解:使用 FastChat 部署 LLM 的体验太爽了

  • 用通俗易懂的方式讲解:基于 Langchain 和 ChatChat 部署本地知识库问答系统

  • 用通俗易懂的方式讲解:使用 Docker 部署大模型的训练环境

  • 用通俗易懂的方式讲解:在 Ubuntu 22 上安装 CUDA、Nvidia 显卡驱动、PyTorch等大模型基础环境

  • 用通俗易懂的方式讲解:Llama2 部署讲解及试用方式

  • 用通俗易懂的方式讲解:LangChain 知识库检索常见问题及解决方案

  • 用通俗易懂的方式讲解:基于 LangChain 和 ChatGLM2 打造自有知识库问答系统

  • 用通俗易懂的方式讲解:代码大模型盘点及优劣分析

  • 用通俗易懂的方式讲解:Prompt 提示词在开发中的使用

  • 用通俗易懂的方式讲解:万字长文带你入门大模型

技术交流

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

相关资料、数据、技术交流提升,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、添加微信号:mlc2060,备注:来自CSDN + 技术交流
方式②、微信搜索公众号:机器学习社区,后台回复:加群

在这里插入图片描述

参考文献

1、https://www.datagrand.com/blog/技术干货:如何训练高性能语义表示模型-交叉.html

2、https://zhuanlan.zhihu.com/p/661867062

3、https://www.sbert.net/examples/applications/retrieve_rerank/README.html

4、https://blog.llamaindex.ai/a-cheat-sheet-and-some-recipes-for-building-advanced-rag-803a9d94c41b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/310860.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB根据数据拟合曲线

MATLAB根据数据拟合曲线 MATLAB根据数据拟合曲线视频观看 MATLAB根据数据拟合曲线 x1[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,6…

深入浅出Android dmabuf_dump工具

dmabuf是什么? 可以参考我之前写的一篇文章,在这篇文章中有介绍dma_buf:BufferManager_驱动的buffermanager-CSDN博客 dmabuf_dump工具介绍(基于Android 14) dmabuf_dump是一个可执行文件,接收参数调用libdmabufinfo.a的接口完成…

C#,入门教程(15)——类(class)的基础知识

上一篇: C#,入门教程(14)——字符串与其他数据类型的转换https://blog.csdn.net/beijinghorn/article/details/124004562 物以类聚,凡物必类。 类的使用,须遵循几个简单的原则: (1)能类则类&a…

宏集案例丨宏集PC Runtime软件助推食品行业生产线数字化革新

来源:宏集科技 工业物联网 宏集案例丨宏集PC Runtime软件助推食品行业生产线数字化革新 原文链接:https://mp.weixin.qq.com/s/DwzVzifUiidNr-FT3Zfzpg 欢迎关注虹科,为您提供最新资讯! 01 前言 近年来,中国食品行业…

想进入游戏开发领域,应该先学习C++编程还是C#编程?

想进入游戏开发领域,应该先学习C编程还是C#编程? 当你决心踏入游戏开发者的行列时,最先迎接你的将是引擎的选择。引擎是游戏的心脏,所有精彩的画面和内容都是脉脉游戏血液从引擎中流淌而出。Unity、Unreal Engine、Cocos等引擎盛…

牛客字符串

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:…

存储卷(数据卷)—主要是nfs方式挂载

1、定义 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的,一旦容器被删除,数据会丢失。k8s基于控制器创建的pod,delete相当于重启,容器的状态会恢复到原始状态。一旦回到原始状态,后天编辑的文件…

二叉树的层序遍历(C++详解)

文章目录 写在前面解题思路具体做法 写在前面 本篇文章使用C实现了二叉树的层序遍历。在实现二叉树层序遍历时,一般情况下,大家可能直接输出遍历结果。然而,在解决在线评测(OJ)问题时,有时要求将每一层的遍…

这7个设计素材网站太好用了,特别是第一款!

网页设计师在使用网页设计素材时,会优先考虑那些免费优质的网页设计素材网站。找到一个免费优质的网页设计素材网站并不容易。有些网站要么需要开设材料网站的会员,要么设计素材质量差。即时设计整理总结了 7 个免费的网页设计素材网站,对 “…

GENMARK控制器维修SMALL SMC4092

晶圆转移机器人SMALL CONTROLLER控制器维修 SMC1100 半导体设备机械臂GENMARK控制器维修 eSensor特点: (1)基于DNA杂交和电化学检测原理; (2)电化学传感检测,并非荧光或光学检测。 电子信号的…

中国光伏展

中国光伏展是中国最大的光伏产业展览会,每年在国内举办一次。该展览会汇集了国内外光伏行业的领先企业和专业人士,展示最新的光伏技术、产品和解决方案。 中国光伏展旨在促进光伏行业的发展和创新,提升光伏产业的国际竞争力。展览会涵盖了光伏…

一、Sharding-JDBC系列01:整合SpringBoot实现分库分表,读写分离

目录 一、概述 二、案例演示-水平分表 (1)、创建springboot工程 (2)、创建数据库和数据表 (3)、application.yaml配置分片规则 (4)、测试数据插入、查询操作 4.1、插入-控制台SQL日志 4.2、查询-控制台SQL日志 三、案例演示-水平分库 (1)、创建数据库和数据表 (2…

React07-路由管理器react-router-dom(v6)

react-router 是一个流行的用于 React 应用程序路由的库。它使我们能够轻松定义应用程序的路由,并将它们映射到特定的组件,这样可以很容易地创建复杂的单页面应用,并管理应用程序的不同视图。 react-router 是基于 React 构建的,…

离线安装telnet-server

telnet下载地址: https://vault.centos.org/ 需要下载telnet 和 telnet-server 确认自己的服务器版本,我这里使用的是(Red Hat Enterprise Linux Server release 7.0 (Maipo))对应的是Centos 7.0,所有到 https://vault.centos.or…

平面光波导_三层均匀平面光波导_射线分析法

平面光波导_三层均匀平面光波导_射线分析法 三层均匀平面光波导: 折射率沿 x x x 方向有变化,沿 y y y、 z z z 方向没有变化三层:芯区( n 1 n_1 n1​) > > > 衬底( n 2 n_2 n2​) ≥ \geq ≥ 包层( n 3 n_3 n3​)包层通常为空…

许战海矩阵战略洞察:如何解决3亿调味品企业朱老六的增长难题

​长春市朱老六食品股份有限公司,是一家以生产腐乳、酸菜等生物发酵品为主的民营企业。 创始人团队自1991年起开发腐乳产品,并于1997年创立“朱老六”品牌。公司专研地道东北味,有着多年的专业经验和深厚的行业积淀,2019年腐乳产…

创建ROS模型与小机器人地图规划

1、打开自己的VM系统 2、安装小机器人的安装包,输入如下命令,回车输入密码(自己设的): sudo apt install ros-noetic-turtlebot3-simulations ros-noetic-turtlebot3-slam ros-noetic-turtlebot3-navigation 提示我之前安装过了 3、用rosla…

Redis相关报错信息:Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连接。

报错信息: Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连接。 报错原因: 访问不到Redis服务 解决方案: 将Redis服务打开! 使用cmd命令行打开本机服务管理: services…

全志T113开发板Qt远程调试

1引言 通常情况下工程师在调试Qt程序时,需要频繁制作镜像烧录到核心板来测试Qt程序是否完善,这样的操作既费时又费力。这时我们可以通过QtCreator设备功能,定义设备后,在x86_64虚拟机上交叉编译qt程序,将程序远程部署到…

el-form中一个el-form-item需要规则校验多个input

我的数据的格式&#xff1a; formData: {ipAddress: {one: ,two: ,}, }, 代码结构&#xff1a; <el-form-item label"IP地址" prop"ipAddress"><el-input-numberv-model"formData.ipAddress.one"class"ip-address":contro…
最新文章