AI 文摘

完结篇!从0开始实现LLM:81、RAG代码实战(TinyRAGFlagEmbeddingQAnything讲解)





作者: AI科技解析 来源: AI科技解析

🌻🌻🌻

  • 1、为什么要使用RAG?

  • 2、RAG是什么?

  • 3、怎么使用RAG?

akaihaoshuai,公众号:AI科技解析从0开始实现LLM:8、RAG(理论学习)

上一篇介绍了RAG的相关理论,这一篇通过代码进行更深刻的理解。

TinyRAG

一个相对简单的RAG实现。

TinyRAG demo

其中VectorStore()为知识库创建过程,vector.query()为知识库查询过程,OpenAIChat()为生成回答过程。

创建知识库VectorStore()

整理本地文件到内存中。可以是加载文件,通过Embedding模型转换为文本向量。也可以直接加载已经通过Embedding转换后的文本向量(节省耗时)。

doc->特征向量

查询知识库(Retrieval)

对当前的文本特征和知识库的全部文本特征进行相似度查询,获取相似度最近的k个结果的对应文档。

比如当前的查询结果为:

LLM生成答案(Generation)

🌻小结

从上面代码中可以看出,Embedding模型是一个比较重要的点,模型的好坏直接影响了特征向量是否真正的表示了文本的含义。相似度的评价方法也很重要。

这里就引入一个问题?Embedding Model和LLM的Embedding都可以将文本转化为特征向量,他们有什么区别???

答:LLM的Embedding是在LLM中训练的,只是简单的查表处理,后面有transformer结构处理,最终生成回答。Embedding Model是专门为向量检索而训练的模型,有更加复杂的模型结构,可以将任意长度的输入文本输出为指定长度的特征。LLM的Embedding结果修改一下也可以用,但是得到的嵌入特征并不是最适合于做相似性计算的结果(肯定没专门用相似性loss监督训练出来的好)。

FlagEmbedding

如上面所说,🎈Embedding model是专门将任意输入文本信息转换为指定长度的特征向量,便于相似度检索的模型🎈。

FlagEmbedding中包含了Embedding的从预训练、微调到评测整套流程。

  1. 拓展长上下文LLM训练方法:Activation Beacon

  2. LM微调方法:LM-Cocktail

  3. Embedding模型:Visualized-BGE, BGE-M3, LLM Embedder, BGE Embedding

  4. Reranker模型:llm rerankers, BGE Reranker

  5. 评测标准:C-MTEB

支持的Embedding模型:GitHub - FlagOpen/FlagEmbedding: Retrieval and Retrieval-augmented LLMs

下面具体介绍模型内容

Activation Beacon

《Soaring from 4K to 400K: Extending LLM’s Context with Activation Beacon》

FlagEmbedding/Long_LLM/activation_beacon at master · FlagOpen/FlagEmbedding

Activation Beacon是作为一个插件模块引入的拓展LLM长上下文的微调方法。它完全保留了LLM在短上下文中的原始功能。它与滑动窗口一起工作,以流式处理长上下文,从而在训练和推理中具有竞争性的记忆和时间效率。

它将LLM的原始激活(即键和值)压缩为高度紧凑的形式,对于长度为l的上下文,一组k(k < l)个信标令牌被分派到它的末端,压缩比α(α = l/k)。使得LLM即使在有限的上下文窗口中也可以从广泛的上下文范围中感知信息。

为了有效地处理长上下文,我们提出了滑动窗口流处理。长上下文被划分为长度为l的多个区间。采用滑动窗口一次顺序处理一个间隔。当处理下一个间隔时,前一个间隔的原始激活被丢弃,而其浓缩的激活被累积。

具体代码实现预计为:自定义CacheMemory,设定bacon_win_size,当cache_size超出bacon_win_size,reset cache缓存排布,新的cache添加到缓存中,旧的超出长度的cache部分进行压缩(超出1个长度,压缩为1,压缩比0%;超出10个token,压缩为1,压缩比90%;超出512个token,压缩比99%以上),当压缩的原始cache长度超过设定长度,可以重新开始新一组压缩。因此对于短上下文不进行压缩从而保持原始效果,长上下文通过检索压缩,提高推理效果。

代码

在原始llamaconfig的基础上增加一些参数

在LLaMAmodel处增加Memory类进行内存管理。

在forward函数中增加

训练过程大概为:将输入的长文本,保留最近的N个token,将先前的seq_len-N和token划分到长度为L的多个group中,增加额外的模块对每个group处理得到压缩后的token。通过将前面多个压缩token和最近的N个token拼接到一起生成回答,计算loss,更新模型权重(原始LLM模型权重冻结)。

🌻小结

通过自定义cache缓存和额外增加模型结构,对超出预训练长度的长上下文进行压缩。可以认为是在斜A形的稀疏注意力基础上,对较靠前部分的token,不进行舍弃而是增加层进行压缩。提高长上下文推理速度,提升长上下文推理能力。若上下文长度较短,则不会进行token压缩,相比原始模型,推理速度会慢一些。不改变原始模型权重,插拔式拓展。

LM-Cocktail

《LM-Cocktail: Resilient Tuning of Language Models via Model Merging》

Yhyu13/LMCocktail-10.7B-v1 · Hugging Face

LM-Cocktail通过加权平均合并微调模型、预训练基础模型和来自其他领域的同行模型的参数,解决进行微调时可能出现的通用任务性能显著下降的问题。

mix_models

按照权重合并模型参数。

merge_param

要求原始模型和微调模型的模型架构相同。

Embedding Model

BGE-M3

《BGE M3-Embedding: Multi-Lingual, Multi-Functionality, Multi-Granularity Text Embeddings Through Self-Knowledge Distillation》

BAAI/bge-m3 · Hugging Face

BGE-M3是智源发布的一个Embedding model,支持100多种语言,它可以同时执行嵌入模型的三种常见检索功能:密集检索,多向量检索和稀疏检索。

代码示例:FlagEmbedding/FlagEmbedding/BGE_M3/README.md at master · FlagOpen/FlagEmbedding

它能够处理不同粒度的输入,从短句到长达8192个标记的长文档。它提出了一种新的自我知识蒸馏方法,其中不同的检索功能的相关性得分可以集成为教师信号,以提高训练质量。我们还优化了嵌入策略,实现了大批量和高训练吞吐量,以确保嵌入的区分度。M3-Embedding是第一个实现如此强大通用性的嵌入模型。

BGE-M3

模型结构为

使用的预训练数据集(194种语言、12亿个文本对、2655个跨语言对)和微调数据集如下所示。

Specification of training data.

预训练过程只进行稠密检索,微调阶段同时进行三种检索。

推理检索阶段也会进行混合检索(多向量检索由于耗时较长,有时候会去掉),得到综合相似性得分。

模型训练目标为:期望{查询,正样本}的相似性得分比{查询,负样本}的相似性得分更高。则每种检索的loss函数均如下所示

其中 分别代表正样本和负样本。表示计算相似性的各种检索方法。

嵌入模型的训练质量可以受益于知识蒸馏,其利用了来自另一个排名模型的细粒度软标签。在这里,我们简单地使用积分分数 作为老师,其中每个检索方法的损失函数被修改为:

最终蒸馏的loss代码为

loss

蒸馏的消融实验结果如下图所示,对于稀疏检索的影响较大。也表明密集和稀疏检索方法之间的不兼容性。

不同的微调策略影响,可以看出RetroMAE对微调效果提升较大。

  • Efficient Batching

为了解决不同序列之间长度变化较大,导致GPU利用率过低的问题。提前根据序列长度将数据分组,每次只在某一个长度段内随机采样数据,使得不同batch之间的数据长度相差较小,提高GPU利用效率。

Efficient Batching

  • MCLS Method

由于缺少长文本数据或计算资源,提出了一种简单但有效的方法:MCLS(多CLS),而无需微调长文本。MCLS方法旨在利用多个CLS标记来联合捕获长文本的语义。具体来说,我们为每一个固定数量的标记插入一个CLS标记(在实验中,为每256个标记插入一个“[CLS]”),每个CLS标记可以从其相邻的标记中捕获语义信息。最终,通过平均所有CLS令牌的最后隐藏状态来获得最终的文本嵌入。

👑代码实战👑

在model.encode()函数中,首先将文本通过tokenizer转换成token_id

'What is BGE M3?'-->[  101,  2054,  2003,  1038,  3351, 29061,  1029,   102]

然后输入模型进行处理。模型结构为

BGE模型

embedding层将[batch,seq_len]变为[batch,seq_len, 768]。然后输入BertEncoder处理,得到[batch,seq_len, 768]。最后通过Pool层输出pooled_output[batch, 768](实际并未使用)。

BertPooler

得到last_hidden_state之后,获取稠密向量(有两种方式:取第一个特征 or 对所有特征进行平均)

dense_embedding

实验测试,使用均值池化将会显着下降性能。

Visualized-BGE

https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/visual

Visualized-BGE是一个多模态的Embedding模型,将图像标记嵌入集成到 BGE 文本嵌入框架中。

文本使用的是bge模型,图像使用的Clip模型。

在encode会根据输入情况选择不同的encoder

当输入图像+文本时,首先通过Clip模型将图像转换为img_token_emb,然后叠加位置编码

然后对文本进行embedding处理

将图像embedding和文本embedding连接,一起encoder处理

得到sequence_output输出结果。

OpenAI Embedding

嵌入(Embeddings) | OpenAI 官方帮助文档中文版

OpenAI 发布的嵌入模型

测试效果可参考:- 派神 -:高级RAG(一):Embedding模型的选择

Voyage Embedding

https://docs.voyageai.com/docs/embeddings

Voyage发布的一系列Embedding模型

示例代码如下GitHub - voyage-ai/voyageai-python: Voyage AI Official Python Library示例代码如下

或者:https://docs.llamaindex.ai/en/stable/examples/embeddings/voyageai/

Reranker Model

与embedding模型不同,Reranker 模型输入query和doc,直接输出相似度而不是embedding特征。Reranker Model是基于交叉熵损失进行优化的,因此相关性得分不受特定范围的限制。

也可以使用基于LLM训练过的Reranker Model

以bge-reranker-base为例,模型架构如下

bge-reranker-base

主要包含embedding编码、encoder处理,以及classifier生成相似度。

可以比较一下Embedding模型和Reranker模型的架构

Embedding vs Reranker

可以看出基本上只有最后不同。Embedding模型最后是一个pooler,得到一个特征向量([bs, seq_len]->[bs, seq_len, 768]->[bs, 768]),一般是通过[bs, 0:1, 768]得到。

而Reranker模型最后是一个classifier,输出相似度得分([bs, seq_len]->[bs, seq_len, 768]->[bs, 768]->[bs, 1]),通常是取[bs, 0:1, 768]通过nn.Linear层映射到[bs, 1]。

QAnything

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

QAnything(Question andAnnswer based onAnything)是网易发布的一个本地知识库问答系统,可以选取本地存储的任意格式文件,并获得准确、快速和可靠的答案。目前支持的格式包括:PDF(pdf)、Word(docx)、PPT(pptx)、XLS(xlsx)、Markdown(md)、Email(eml)、TXT(txt)、Image(jpg,jpeg,png)、CSV (csv)、网页链接(html)和更多格式。

代码结构如下所示

QAnything

运行脚本

bash scrips/run_for_local_option.sh

喵喵喵夏夏:网易有道QAnything开源问答框架-部署文档

BCEmbedding

BCEmbedding是网易发布的支持中英双语和交叉语言输入的Embedding和Reranker双模型。

maidalun:为RAG而生-BCE embedding技术报告

代码示例如下。

🌻总结

1、RAG过程包含:a)、文档整理成知识库;b)、对prompt查询知识库获取相关内容;c)、LLM生成回答。

2、从过程中可以看出,每个过程都可以不断的优化:文档的分段、不同数据格式的统一、大型数据库的查询效率、Embedding模型的选择、文本向量的相关性的评价方法、推理模型的选择等等。

3、FlagEmbedding中包含了Embedding的从预训练、微调到评测整套流程。

  • 拓展长上下文LLM训练方法:Activation Beacon

  • LM微调方法:LM-Cocktail

  • Embedding模型:Visualized-BGE, BGE-M3, LLM Embedder, BGE Embedding

  • Reranker模型:llm rerankers, BGE Reranker

  • 评测标准:C-MTEB

4、Activation Beacon通过自定义cache缓存和额外增加模型结构,对超出预训练长度的长上下文进行压缩。可以认为是在斜A形的稀疏注意力基础上,对较靠前部分的token,不进行舍弃而是增加层进行压缩。提高长上下文推理速度,提升长上下文推理能力。若上下文长度较短,则不会进行token压缩,相比原始模型,推理速度会慢一些。不改变原始模型权重,插拔式拓展。

5、LM-Cocktail将微调模型和预训练模型(相同模型架构)对参数进行加权合并,解决进行微调时可能出现的通用任务性能显著下降的问题。

6、Embedding Model是专门为向量检索而训练的一类模型,有更加复杂的模型结构,可以将任意长度的输入文本输出为指定长度的特征,能够更加准确的表示文本的含义。有BGE-M3、Visualized-BGE、OpenAI Embedding、Voyage Embedding、CohereAI Embedding (v2.0/ v3.0)和Jina Embeddings等。

7、BGE-M3是智源发布的一个Embedding model,支持100多种语言,它可以同时执行嵌入模型的三种常见检索功能:密集检索,多向量检索和稀疏检索。Visualized-BGE在BGE-M3基础上引入了Clip模型(处理图像),从而支持多模态处理的Embedding model。

8、Reranker Model是直接输出相似性得分的模型。与Embedding模型相比,就是在模型最后接了一个分类器,将输出特征[bs, 768]通过nn.Linear()映射到[bs, 1](相似性得分)。

因为余弦相似性不一定是评估相似性得分最好的方法,因此考虑直接通过模型输出相似度。

9、Reranker Model可以用在Embedding Model后面,对前面召回的文档进行二次筛选。

FlagEmbedding包含了Embedding模型和Reranker模型及其预训练和微调方法,并没有提到数据库和检索速度等相关内容。

10、QAnything(Question andAnnswer based onAnything)是网易发布的一个本地知识库问答系统,可以选取本地存储的任意格式文件,并获得准确、快速和可靠的答案。

11、BCEmbedding是网易发布的支持中英双语和交叉语言输入的Embedding和Reranker双模型。Reranker Model可以对前一阶段得到的召回文档重新计算相似性得分,进行二次排序筛选。准确率稳定提升,数据越多,性能越好。

LLM系列文章:

***从0开始实现LLM:1、大模型训练踩坑**

***从0开始实现LLM:2、大模型技术报告总结(GPT/PaLM/GLM/LLaMA/Skywork)**

*从0开始实现LLM:3、大模型训练之数据扩展+deepspeed优化

***从0开始实现LLM:4、长上下文优化(持续更新中)**

***从0开始实现LLM:5、长上下文优化(代码篇)YaRN/CLEX/LongLoRA/LM-Infinite/Streaming**

***从0开始实现LLM:6、模型量化理论+代码实战(LLM-QAT/GPTQ/BitNet 1.58Bits/OneBit)**

***从0开始实现LLM:8、RAG(理论学习)**

参考文章

  • GitHub - KMnO4-zx/TinyRAG: TinyRAG

  • https://github.com/ZBayes/basic_rag

  • GitHub - FlagOpen/FlagEmbedding: Dense Retrieval and Retrieval-augmented LLMs

  • BGE M3-Embedding 模型介绍

  • 《RetroMAE v2: Duplex Masked Auto-Encoder For Pre-Training Retrieval-Oriented Language Models》

  • 《LM-Cocktail: Resilient Tuning of Language Models via Model Merging》

  • 嵌入(Embeddings) | OpenAI 官方帮助文档中文版

    • 派神 -:高级RAG(一):Embedding模型的选择
  • maidalun:为RAG而生-BCE embedding技术报告

  • https://github.com/netease-youdao/QAnything

  • 喵喵喵夏夏:网易有道QAnything开源问答框架-部署文档

  • https://github.com/langchain-ai/langchain

  • GitHub - run-llama/llama_index: LlamaIndex is a data framework for your LLM applications

更多AI工具,参考Github-AiBard123国内AiBard123

可关注我们的公众号:每天AI新工具