生成面向 RAG 的合成数据集
RAG 设置中的合成数据
不幸的是,在机器学习工程师的实践中,常常面临标注数据不足或几乎无标注数据的情况。当意识到这一点时,通常情况下项目便不得不启动一个漫长的数据收集和标注过程。往往需要几个月的时间后,才能开始开发解决方案。
然而,随着大型语言模型(LLM)的出现,一些产品的范式发生了转变: 现在可以依赖 LLM 的泛化能力,几乎可以立即开始测试想法或开发由 AI 驱动的功能。如果初步结果显示其效果接近预期,那么传统的开发流程就可以开始了。

图片来源: The Rise of the AI Engineer, by S. Wang (opens in a new tab)
一种新兴的方法是 检索增强生成 (RAG) (opens in a new tab) 。RAG 主要用于知识密集型任务中,模型不能仅依赖于模型自身的知识。RAG 将信息检索组件与文本生成模型相结合。欲了解更多关于这种方法的信息,请参阅 指南中的相关部分 (opens in a new tab).
RAG 的关键组成部分是检索模型,它能够识别相关文档并将其传递给 LLM 进行进一步处理。检索模型的性能越好,最终的产品或功能效果就越佳。理想情况下,检索模型在开箱即用下就已经表现良好。然而,在不同语言或特定领域中,其性能往往会下降。
设想一下: 你需要创建一个基于捷克法律和法律实践回答问题(当然要用捷克语)的聊天机器人,或者设计一个针对印度市场的税务助手(这是 OpenAI 在 GPT-4 演示中提出的案例)。你很可能会发现,检索模型经常错过最相关的文档,整体表现不佳,从而限制了系统的质量。
但有一个解决方案。一种新兴趋势是利用现有的 LLM 来合成数据,以训练新一代的 LLM、Retrievers 或其他模型。这一过程可被视为通过提示式查询生成将 LLM 蒸馏成标准尺寸编码器的过程。虽然蒸馏计算成本较高,但它显著降低了推理成本,并可能大幅提升性能,特别是在资源匮乏的语言或专业领域中。
在本指南中,我们将依赖最新的文本生成模型,如 ChatGPT 和 GPT-4,它们可以根据指令生成大量合成内容 Dai 等人 (2022) (opens in a new tab) 提出了一种方法,只需 8 个手动标注的例子和一个包含未标注数据的大语料库(例如所有解析过的法律文件),即可实现接近最先进的性能。这项研究证实,合成生成的数据有助于在因数据稀缺而难以进行监督领域微调的任务中训练任务专用的检索器。
领域特定数据集生成
要利用 LLM,需要提供简短的描述并手动标注几个例子。需要注意的是,不同的检索任务具有不同的搜索意图,这意味着“相关性”的定义也有所不同。换句话说,对于相同的 (查询, 文档) 对,其相关性可能根据搜索意图完全不同。例如,论证检索任务可能寻求支持性论点,而其他任务则要求反论点(如 ArguAna (opens in a new tab) 数据集 所示)。
请考虑以下示例。尽管该示例使用中文以便于理解,但请注意,数据可以用任何语言编写,因为 ChatGPT/GPT-4 可高效处理甚至低资源语言。
提示词:
任务:为给定的论点识别一个反论点。
论点 #1: {在此插入段落 X1}
与论点 #1 相关的简洁反论点查询: {在此插入手动准备的查询 Y1}
论点 #2: {在此插入段落 X2}
与论点 #2 相关的简洁反论点查询: {在此插入手动准备的查询 Y2}
<- 此处粘贴你的示例 ->
论点 N: 即使罚款与收入成比例,你也无法获得期望的影响平等。这是因为影响并不单纯与收入成比例,还必须考虑许多其他因素。例如,一个养家的人会比没有家庭负担的人受到更大的影响,因为他们有更少的可支配收入。此外,基于收入的罚款忽略了总体财富(即某人实际拥有的资金量:有人可能拥有大量资产但收入不高)。该提案并未考虑到这些不平等现象,这可能会产生更大的偏差效应,因此该论点的应用存在不一致之处。
与论点 #N 相关的简洁反论点查询:
输出:
punishment house would make fines relative income
一般来说,这种提示可以表示为:
, 其中 和 分别是任务特定的文档和查询描述, 是针对 ChatGPT/GPT-4 的任务特定提示/指令, 是一个新的文档,LLM 将为其生成查询。
从这个提示中,只有最后一个文档 和生成的查询将被用于本地模型的进一步训练。此方法适用于目标检索语料库 已知的情况下,但新任务的注释查询-文档对数量有限。
整个流程概览如下:

图片来源: Dai 等人. (2022) (opens in a new tab)
负责任地处理人工标注示例非常重要,最好准备更多(例如 20 个),然后随机选择其中的 2-8 个放入提示中,这可以在不显著增加标注时间成本的前提下提高生成数据的多样性。不过,这些示例应具有代表性、格式正确,甚至详细说明目标查询长度或语气等细节。示例和指令越精确,生成的合成数据就越好,用于训练 Retriever 的效果也就越好。低质量的少量示例会对训练模型的最终质量产生负面影响。
在大多数情况下,使用较为经济的模型如 ChatGPT 就足够了,因为它在非典型领域和非英语语言中也能表现良好。假设一个带有指令和 4-5 个示例的提示通常占用 700 个 token(假设每个段落不超过 128 个 token,由于 Retriever 的限制),生成部分为 25 个 token。因此,为包含 50,000 个文档的语料库生成用于本地模型微调的合成数据集的成本为:50,000 * (700 * 0.001 * $0.0015 + 25 * 0.001 * $0.002) = 55
,其中 $0.0015
和 $0.002
是 GPT-3.5 Turbo API 中每 1,000 个 token 的成本。甚至可以为同一个文档生成 2-4 个查询示例。然而,进一步训练带来的收益通常是值得的,特别是当你使用的 Retriever 不是通用领域(如英文新闻检索)而是特定领域(如前文提到的捷克法律)时。
50,000 这一数字并非随意设定。在 Dai 等人. (2022) (opens in a new tab) 的研究中指出,这是模型匹配使用合成数据训练模型质量所需的大概手动标注数据量。想象一下,在推出产品之前,你至少需要收集 10,000 个示例!这将至少花费一个月时间,人力成本肯定超过一千美元,远高于生成合成数据和训练本地 Retriever 模型的成本。现在,借助今天学到的技术,你可以在短短几天内实现十位数的指标提升!

图片来源: Dai 等人. (2022) (opens in a new tab)
以下是同一论文中 BeIR 基准测试中某些数据集的提示模板。
