AI 文摘

大模型RAG中embedding的两个新进展BGE-M3及MRL:兼看几个有趣的综述及水印工作





作者: 老刘说NLP 来源: 老刘说NLP

今天是2024年1月31日,星期一,北京,天气晴。

转眼间,2024年已经过去1/12,进度8.4931%,真快。

我们继续看看有趣的话题。

我们在之前的文章中有说到当前RAG-embedding上的一些优化工作,比如加入rerank模型,引入任务指令的embedding等,最近这块也出了两个新的工作,一个是怎么将embedding变长、混合建模,另一个是怎么将embedding弄短,本文将先介绍这个工作。

另外,最近也在读一些工作,这些工作包括文本水印、数据增强以及长文本,很有趣,分享出来,供大家一起参考。

一、RAG中embedding进展:变长、变混合

当前,RAG的Embedding嵌入已经陆续发布了许多,例如:

m3e:https://huggingface.co/moka-ai/m3e-base,这个取名很有意思,M3E是Moka Massive Mixed Embedding的缩写:

Moka,表示模型由MokaAI训练,开源和评测,训练脚本使用uniem ,评测BenchMark使用 MTEB-zh;

Massive,表示此模型通过千万级 (2200w+) 的中文句对数据集进行训练

Mixed,表示此模型支持中英双语的同质文本相似度计算,异质文本检索等功能,未来还会支持代码检索。

Embedding,此模型是文本嵌入模型,可以将自然语言转换成稠密的向量

BCE:BCEmbedding: Bilingual and Crosslingual Embedding for RAG,地址:https://github.com/netease-youdao/BCEmbedding/tree/master。

BGE:https://github.com/FlagOpen/FlagEmbedding/。

而最近,Embedding方向也有一定进展,主要有两个方向:

一个是将Embedding的嵌入上下文长度变长

例如,BGE-M3(https://github.com/FlagOpen/FlagEmbedding/blob/master/FlagEmbedding/BGE_M3/BGE_M3.pdf),是一个具有多功能、多语言和多粒度特性的文本检索模型。

高效支持多语言(100+语言)、长文本(至多8192长度的输入文本)、和混合检索(稠密、稀疏、多向量)。

1、关于混合搜索

这里的混合检索在于,M3-Embedding统一了嵌入模型的所有三种常见检索功能,即稠密检索、词性(稀疏)检索和多向量检索。

从形式上看,在给定一个x表示的查询q时,从语料库Dy中检索出以y表示的文档d:dy←fn∗(qx,Dy)。其中:fn∗(-)属于密集检索、稀疏/词汇检索或多维检索中的任何一种函数;y可以是另一种语言,也可以是与x相同的语言。

具体的:

sdense,在密集检索上,根据文本编码器将输入查询q转换成隐藏状态Hq,使用特殊标记"[CLS]“的归一化隐藏状态来表示查询:eq=norm(Hq[0]),使用ep=norm(Hp[0])来表示段落p的嵌入。

查询和段落之间的相关性得分是通过两个嵌入式eq和ep之间的内积来衡量:sdense←⟨ep,eq⟩。

slex,在词汇检索上,输出嵌入式也用于估算每个词条的重要性。词的重要程度,以方便词汇检索。 对于查询中的每个术语t(一个术语对应一个token),术语权重的计算公式为如下:

如果一个术语t在查询中出现多次,只保留其最大权重,用同样的方法计算段落中每个术语的权重。在估算术语权重的基础上,查询和段落之间的相关性得分由查询和段落中共存术语(表示为q∩p,也就是交集)的联合重要性计算得出

smul,在多向量检索上,作为密集检索的扩展,利用整个输出嵌入来表示查询/和段落,并根据Col-Bert使用后期交互来计算细粒度相关性得分。

最后,由于嵌入模型的多功能性,检索过程可以采用混合过程。首先,候选结果可以由每种方法单独检索(多向量方法由于成本高,可以免去这一步骤)。然后,根据综合相关性得分对最终检索结果重新排序:srank←sdense+slex+smul

2、关于训练数据

我们可以尤其关注下训练数据:

在训练数据上,包括弱监督数据以及微调数据。

其中:弱监督数据来自无标签语料库,微调数据来自有标签语料库,而微调数据则通过合成来实现,三种数据源互为补充,分别应用于训练过程的不同阶段。

进一步的:

弱监督数据是通过提取维基百科、S2ORC、xP3、mC4和CC-News等各种多语言语料库中的丰富语义结构(如标题-正文、标题-摘要、指令-输出等)来进行整理

为了学习用于跨语言语义匹配的统一嵌入空间,我们从两个翻译数据集MTP、NLLB中进行处理,总共收集了194种语言的12亿个文本对和2655个跨语言对应。

在微调数据方面。对于英语,包括八个数据集,包括HotpotQA、TriviaQA、NQ、MSMARCO、COLIEE、PubMedQA以及SimCSE收集的NLI数据。

对于中文,包括七个数据集,包括DuReader、mMARCO-ZH、T2-Ranking、LawGPT1、CmedQAv2和LeCaRDv2

对于其他语言,利用来自MIRACL的训练数据。

另外,为了缓解长文档检索任务的性能,通过生成合成数据方式进行处理,并引入额外的多语言微调数据(记为MultiLongDoc)。

这里的实现流程也很有趣,从Wiki和MC4数据集中抽取长篇文章,并从中随机选择段落。然后,使用GPT-3.5根据这些段落生成问题,生成的问题和抽样文章构成微调数据的新文本对。 又是一个常规的GPT4数据蒸馏操作。

这里采用的prompt为:

“You are a curious AI assistant, please generate one specific and valuable question based on the following text. The generated question should revolve around the core content of this text, and avoid using pronouns (e.g., ”this”). Note that you should generate only one question, without including additional content:” 最终得到的数据分布如下:

3、关于模型训练

在训练方式上,跟之前的类似,最小化In-foNCE损失进行处理,损失函数如下:

其中,p∗ 和P′分别代表查询q的正样本和负样本;s(-)是{sdense(-)、slex(-)、smul(-)} 中的任意一个函数,不过,不同检索方法的预测结果可以整合为一个更准确的相关性得分,因为它们具有异质性。在最简单的形式中,整合可以是不同预测得分的总和: sinter ←sdense+slex+smul。

在知识蒸馏阶段,以sinter为教师模型监督信号,其中的任何一个得分作为学生模型。

将每种检索方法的损失函数修改为:

进一步对修正后的损失函数进行积分和归一化处理:

最后使用线性组合推导出自我知识蒸馏的最终损失函数。

整个训练过程是一个多阶段的工作流程,如下所示:

首先,使用弱监督数据对文本编码器进行预训练,其中只有密集检索是以对比学习的基本形式进行训练的。自我知识蒸馏应用于第二阶段,在此阶段对嵌入模型进行微调,以建立三种检索功能。在这一阶段中,将使用标注数据和合成数据,并根据ANCE方法为每个查询引入硬负样本。

二、RAG中embedding进展:缩短嵌入降成本

Embedding嵌入优化的另一方向是把模型的维度打小,也就是缩短嵌入。

OpenAI最近推了两个文本嵌入模型,分别是更小且高效的text-embedding-3-small模型和更大且更强大的text-embedding-3-large模型。

比较有意思的是,当使用仅支持最高1024维嵌入的向量数据存储时,可以使用最好的嵌入模型text-embedding-3-large并指定dimensionsAPI参数的值为1024,使得嵌入维数从3072开始缩短,牺牲一些准确度以换取更小的向量大小

这有点像我们在前面所说的,长文本里线性内插和动态非线形插值NTK式的映射原理。

而再往前回溯,其实际上是一种降维的过程,我们可以使用PCA进行降到特定的维度。

关于这块,实现思路可以看《Matryoshka Representation Learning》 (地址https://arxiv.org/pdf/2205.13147.pdf),实现的官方代码在:https://github.com/RAIVNLab/MRL。

不同于常规的fix的embedding表征,Matryoshka representation learning提出了一个方法,生成的表征是按照x下标进行重要性排序的,所以在资源受限的环境,可以只使用前面top-k维表征就可以

如下所示,对于d∈N,考虑一组表示尺寸M⊂[d]。对于输入数据X中的数据点x,其的目标是学习一个d维表示向量z∈Rd,对于每一个m∈M、MRL目标是让前m维的表征向量z1:m∈Rm独立地成为可转移的通用表征向量。

Matryoshka(简称MRL)表征学习将典型设置修改为同一任务的多尺度表征学习问题。

例如,在ImageNet-1K上训练ResNet50,将224×224像素的图像嵌入d=2048表示向量,然后通过线性分类器在L=1000个标签中进行预测yˆ。

对于MRL,选择M={8,16,.,1024,2048}作为嵌套维度,假设得到了一个带标签的数据集D={(x1,y1),…,(xN,yN)}其中xi∈X是输入点,yi∈[L]是所有i∈[N]中xi的标签。

MRL采用标准的经验风险最小化方法,使用单独的线性分类器优化每个嵌套维度m∈M的多类分类损失,参数为W(m)∈RL×m。

所有损失分别按其相对重要性(cm≥0)m∈M缩放后汇总,尽管只对O(log(d))嵌套维度进行优化,MRL仍能产生精确的表示,并对介于所选表示粒度之间的维度进行插值。

三、最近的一些有趣的进展

最近也在读一些工作,这些工作包括文本水印、数据增强以及长文本,很有趣,分享出来,供大家一起参考。

1、text_blind_watermark文本水印小工具

把隐秘消息嵌入到另一段文本中,这在文本版权保护上有很大的应用 空间,最近看到一个很有趣的项目text_blind_watermark,文本隐水印/盲水印,把信息隐匿到文本中。

具体理解起来,就是把一段信息嵌入到一段明文中,使信息隐密不可见,并且旁人无法察觉到嵌入后明文的变化。

使用案例:

>> from text_blind_watermark import TextBlindWatermark2  
>>> password = '12345678'  
>>> text = '这句话中有盲水印,你能提取出来吗?'  
>>> watermark = '欢迎关注老刘说nlp'  
>>> text_blind_wm = TextBlindWatermark2(password=password, chr_type=(3, 4))  
>>> text_with_wm = text_blind_wm.embed(text=text, watermark=watermark)  
>>> print(text_with_wm)  
这句话中有盲‌‌‍‌‌‍‍‌‌‍‌‍‍‍‍‌‍‍‌‍‌‍‍‌‍‍‍‍‍‌‌‍‌‍‌‍‍‍‍‍‌‌‌‍‌‌‍‌‌‍‍‌‌‌‍‍‌‍‌‍‌‌‌‌‌‌‍‌‍‍‍‌‌‍‌‍‍‍‌‌‍‍‍‍‍‌‍‌‍‍‍‍‌‍‌‍‌‌‍‌‍‌‌‌‌‍‍‌‌‍‌‌‍‌‍‍‌‌‍‌‌‌‌‍‍‌‍‌‌‌‌‍‌‍‍‍‍‌‍‌‍‌‌‍‌‍‌‍‌‍‌‍‍‍‍‌‌‍‍‌‍‍‍‌‍‌‍‌‌‌‍‌‍‌‌‌‍‍‍‍‍‌‍‍‍‍‌‌‌‍‍‍水印,你能提取出来吗?  
>>> text_blind_wm2 = TextBlindWatermark2(password=password, chr_type=(3, 4))  
>>> wm_extract = text_blind_wm2.extract(text_with_wm)  
>>> print('提取内容:', wm_extract)  
提取内容: 欢迎关注老刘说nlp  

地址:github.com/guofei9987/text_blind_watermark,

2、关于长文本的一个经典综述

我们在刚结束的社区分享中有介绍到长文本,其中涉及到长文本中的一些基本问题,具体的,可以参考大模型中上下文长度扩展技术的本质、动因的一个综述:《The What, Why, and How of Context Length Extension Techniques in Large Language Models – A Detailed Survey》 :https://arxiv.org/pdf/2401.07872

此外也有一些博客写的很好,可以看看https://zhuanlan.zhihu.com/p/660073229。

3、关于大模型数据增强的一个经典综述

数据增强,现在叫合成数据,是当前大模型领域的重要话题,关于这块,可以看看最近的工作《A Survey on Data Augmentation in Large Model Era》(https://arxiv.org/pdf/2401.15422),对应的详细suervey列表放在:https://github.com/MLGroup-JLU/LLM-data-aug-survey

总结

本文主要介绍了当前RAG-embedding上的一些进展,一个是怎么将embeddin变长、混合建模,另一个是怎么将embedding弄短,其中一些数据、算法模型细节可以进一步看看,尤其是关注数据。

此外,第二部分提到的综述也十分值得一读,大家可以结合社区的第二讲分享一起看看,会有更多守候。

参考文献

1、https://github.com/FlagOpen/FlagEmbedding/blob/master/FlagEmbedding/BGE_M3/BGE_M3.pdf)

关于我们

老刘,刘焕勇,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。

老刘说NLP,将定期发布语言资源、工程实践、技术总结等内容,欢迎关注。

对于想加入更优质的知识图谱、事件图谱、大模型AIGC实践、相关分享的,可关注公众号,在后台菜单栏中点击会员社区->会员入群加入。

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

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