今天是2024年1月4日,星期四,北京,天气晴。
我们继续来看看RAG召回侧的embedding嵌入问题
文本嵌入是文本的连续低维表示,已被广泛应用于各种下游任务,如信息检索、问题解答和检索增强生成(RAG),尤其是在RAG中,嵌入是一个核心问题,在召回侧很重要。【尤其是在q-d匹配上】
早期的文本嵌入方法包括潜在语义索引LSI和单词加权平均嵌入wordvec,最近的方法则利用自然语言推理和标注查询-文档对(如MS-MARCO段落排序数据集)的监督来训练文本嵌入,然而,有标签的数据在任务多样性和语言覆盖面方面往往是有限的。
为了应对这一挑战,Contriever、OpenAIEmbeddings、E5和BGE等方法采用了多阶段训练模式,其首先使用对比损失在大规模弱监督文本对上进行预训练,然后在小规模但高质量的数据集上进行微调。
但多样性不够好,尤其是针对不同的任务,应该有不同的嵌入表示,因此,我们在昨天的文章 《引入任务Instruction指令的句子向量化方案:Instructor的实现思路及训练数据集构造方案》(https://mp.weixin.qq.com/s/qIh07eU8_lYL2gBVzTFzKA) 中有介绍到instructor的方案,其在每个query上,加上了指令信息,并一次来计算对比学习loss:
这种思路引入了适配特定instruction任务的嵌入方案,这与instruction微调美妙结合。
但是,这种方法,用的是已有的instruction任务数据,能否自动化构造合成数据?
最近的另一个工作,《Improving Text Embeddings with Large Language Models》(https://arxiv.org/abs/2401.00368) 这一工作,利用LLM为近100种语言的文本嵌入任务生成多样化的合成数据,在合成数据上使用标准对比损失对开源模型LLM进行微调,得到更好的嵌入表示。
具体思路上,用了两步提示策略:首先提示LLMs对候选任务库进行头脑风暴,然后提示LLMs从任务库中生成以给定任务为条件的数据。为了涵盖各种应用场景,为每种任务类型设计了多个提示模板,并将不同模板生成的数据结合起来,以提高多样性。对于文本嵌入模型,选择微调功能强大的开源LLM,而不是BERT式的小型模型。
其中涉及到的数据合成思路,跟self-instruc等工作能够连起来了,很有趣,我们先来看看,更特别的,它在关注q-d匹配,并涉及到了short query/long document, long query/short document, short query/shor documenet, long query/long document等场景,这些都是与RAG直接相关的,值得大家关注。
而与此更为相关的,是现有相关NLP开放指令数据集,我们可以看到xp3系列以及coig系列,体量很大,建议大家收藏。
供大家一起参考。
一、基于LLM进行文本嵌入数据合成思路
利用GPT-4进行数据生成已然成了当前大家目前的常规操作,其增强多种任务和语言的多样性方面也有挺多表现。
而就数据合成而言,多样性对于文本嵌入至关重要,这种嵌入可以在不同的任务中表现良好,无论是语义检索、文本相似性还是聚类。
Instructor的训练数据是一个数据集集合MEDI,里面包含330个来自SuperNaturalInstructions的数据集跟30个现存的用于句向量训练的数据集。
每个数据集都包括对应的instruction,数据集中的每个instance都是如下格式:
Instance = {“query”: [instruction_1, sentence_1],“pos”:[instruction_2, sentence_2],
“neg”:[Instruction_2, sentence_3]}
如果是类似句子相似度的对称类任务,那就只有一个instruction,示例中的instruction_1跟instruction_2就是同一个,如果是类似检索的非对称任务,那么query跟doc都各有一个instruction,instruction_1跟instruction_2就是两个不同的instruction。
为了生成多样化的合成数据,该工作则提出了利用大模型生成数据的方案,采用一种简单的分类法,将嵌入任务分为几个组,然后对每个组应用不同的提示模板。
1、非对称任务
此类别包括查询和文档在语义上相关但彼此互不转述的任务。根据查询和文档的长度,进一步将非对称任务分为四个子类型:短长匹配、长短匹配、短短匹配和长长匹配。
例如,短长匹配任务涉及短查询和长文档,这是商业搜索引擎中的典型场景。
对于每个子组,设计一个两步提示模板,首先提示大模型进行头脑风暴列出任务列表,然后根据任务定义生成一个具体示例。
可以使用单个提示生成任务定义和查询文档对,但数据多样性不如所提出的两步方法。
2、对称任务
对称任务涉及具有相似语义但表面形式不同的查询和文档,主要包括两个应用场景:单语语义文本相似性(STS)和双文本检索。
为每个场景设计了两个不同的提示模板,根据其特定目标量身定制。由于任务定义很简单,省略了对称任务的头脑风暴步骤。
为了进一步提高提示和合成数据的多样性,在每个提示模板中合并了几个占位符,其值在运行时随机采样。
例如,在图1中,“{query_length}”的值是从集合“{少于5个单词,5-10个单词,至少10个单词}”中采样的。
为了生成多语言数据,从XLM-R的语言列表中采样“{语言}”的值,为高资源语言赋予更多权重,任何不符合预定义JSON格式的生成数据都会在解析过程中被丢弃,并根据精确的字符串匹配来删除重复项。
最后,利用生成的合成数据和13个公共数据集的集合,采样后生成约180万个示例。
3、模型训练
给定一个相关的查询-文档对(q+,d+),首先将以下指令模板应用于原始查询q+以生成一个新的qinst+:
其中“{task_definition}”是嵌入任务的一句话描述的占位符。对于生成的合成数据,使用头脑风暴步骤的输出。
例如,对应的task_instruction如下包括:
对于其他数据集,例如MS-MARCO,手动制定任务定义并将其应用于数据集中的所有查询。
给定一个预训练的LLM,将[EOS]标记附加到查询和文档的末尾,然后通过最后一个实例将它们输入到LLM以获取查询和文档嵌入最后一层[EOS]向量。
为了训练嵌入模型,对批内负例和难负例采用标准InfoNCE损失
4、模型评估
其中有个很有趣的点,为了评估长上下文能力,引入了一种称为个性化密钥检索(personalized passkey retrieval)的任务【这个很像前面我们说的大海捞针任务】,如图4所示,该任务需要将长上下文中的密钥信息编码到嵌入中。
这块来自:《Landmark Attention: Random-Access Infinite Context Length for Transformers》(https://arxiv.org/abs/2305.16300)
“<前缀填充符 prefix filler>”和“<后缀填充符 suffix filler>”是“The grass is green. The sky is blue. The sun is yellow. Here we go. There and back again”的重复,此外,每个文档都有一个唯一的人名和插入在随机位置的随机密钥。 任务是从100名候选人中检索包含给定人员密钥的文档。
对应的prompt如下:
二、现有开源面向NLP任务的instruction微调数据
实际上,目前已经有许多关于面向中文NLP任务的微调数据出来,构造方式包括有prompt source等。最近在关注这方面的工作,所以也分享出来,供大家一起参考。
1、英文:P3系列
P3(公共提示池)是涵盖各种NLP任务的提示英语数据集的集合。提示是输入模板和目标模板的组合。
数据样例如下:
{ "inputs": "Sentence 1: Fue académico en literatura metafísica, teología y ciencias clásicas.nSentence 2: Fue académico en literatura metafísica, teología y ciencia clásica.nQuestion: Can we rewrite Sentence 1 to Sentence 2? Yes or No?", "targets": "Yes" }
其最关键的部分在于板,模板是将数据示例映射为输入序列和目标序列的自然语言的函数。
地址:https://huggingface.co/datasets/bigscience/P3
2、中文:cogi-c
COIG-PC(Prompt Collection)数据集是智源研究院等全面收集的中文任务和数据集,旨在提供丰富的资源,以提高大语言模型文本生成、信息提取、情感分析、机器翻译等能力,促进中文大语言模型的微调和优化。
COIG: https://huggingface.co/datasets/BAAI/COIG
COIG-PC:https://huggingface.co/datasets/BAAI/COIG-PC
数据样例如下:
{
"instruction": "请把下面的中文句子翻译成英文",
"input": "我爱你。",
"output": "I love you.",
"split": "train",
"task_type": {
"major": ["翻译"],
"minor": ["翻译", "中译英"]
},
"domain": ["通用"],
"other": null
}
总结
本文主要延续昨天的文章,介绍了《Improving Text Embeddings with Large Language Models》(https://arxiv.org/abs/2401.00368)这另一工作,利用LLM为近100种语言的文本嵌入任务生成多样化的合成数据,在合成数据上使用标准对比损失对开源模型LLM进行微调,得到更好的嵌入表示。
而与此更为相关的,是现有相关NLP开放指令数据集,我们可以看到xp3系列以及coig系列,这些数据无论是体量,还是标准化程度,都可以作为我们的数据基础。
参考文献
1、https://cobusgreyling.medium.com/improving-text-embeddings-with-llm-generated-synthetic-data-ee4b32fee262
2、https://arxiv.org/abs/2401.00368
关于我们
老刘,刘焕勇,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。
老刘说NLP,将定期发布语言资源、工程实践、技术总结等内容,欢迎关注。
对于想加入更优质的知识图谱、事件图谱、大模型AIGC实践、相关分享的,可关注公众号,在后台菜单栏中点击会员社区->会员入群加入。