这是OpenAI官方的cookebook最新更新的一篇技术博客,里面说明了为什么我们需要使用embeddings-based的搜索技术来完成问答任务。


Image

尽管GPT的能力很强,但是OpenAI认为,基于embeddings的搜索依然十分重要。甚至,这种方式比模型做fine-tuning更好。本篇博客将简单介绍一下为什么OpenAI认为目前基于embeddings的搜索是GPT的最强补充能力!

一、GPT的缺点

尽管目前GPT-4或者ChatGPT的能力已经很强大,但是目前它依然有很大的缺陷:

  • 训练数据是基于2021年9月之前的数据,缺少最新的数据

  • 无法访问我们无法公开的文档

  • 基于历史会话中获取信息

因此,OpenAI发布了这样一篇文档,说明如何使用两步搜索回答来增强GPT的能力:

  • 搜索:搜索您的文本库以查找相关的文本部分。

  • 请求:将检索到的文本部分插入到发送给GPT的消息中,并向其提出问题。

二、为什么搜索比fine-tuning更好?

GPT可以通过两种方式学习知识:

  • 通过模型权重(即在训练集上微调模型)

  • 通过模型输入(即将知识插入到输入消息中)

尽管微调可能感觉更自然——毕竟,通过数据训练是GPT学习所有其他知识的方式——但OpenAI通常不建议将其作为教授模型知识的方式。微调更适合于教授专业任务或风格,对于事实回忆来说则不太可靠。

注意,这里说的是事实回忆,也就是说,如果你有自己的数据,只想从数据中获得知识或者获得相关的内容,那么搜索比微调可能更好。举个例子来说,如果你有大批的历史数据,你只想找到数据中你需要的部分,包括某些概念在哪里出现过,为什么使用了它等等。这些都算是事实回忆。

但是,如果你希望模型可以基于某种模式生成某些内容。例如,你希望模型可以基于XX风格生成某些工作日志甚至是宣传内容,那么微调可能效果更好。

类比来说,模型权重就像长期记忆。当您对模型进行微调时,就像为一周后的考试而学习。当考试到来时,模型可能会忘记细节,或者错误地记住它从未读过的事实。

相比之下,消息输入就像短期记忆。当您将知识插入消息时,就像带着开放的笔记参加考试。有了笔记,模型更有可能得出正确的答案。

相对于微调,文本搜索的一个缺点是每个模型一次只能读取有限数量的文本,以OpenAI为例,其一次输入的内容限制如下:

模型名称文本最长输入
gpt-3.5-turbo4096个tokens(大约5页)
gpt-48192个tokens(大约10页)
gpt-4-32k32768个tokens(约40页)

延续这个比喻,您可以将模型想象成一位学生,尽管可能有许多参考书可供借鉴,但一次只能查看几页笔记。

因此,为了构建一个能够利用大量文本回答问题的系统,OpenAI建议使用“搜索-提问”方法。

三、文本检索

搜索文本的方法很多,包括:

  • 基于词汇的搜索(Lexical-based)

  • 基于图形的搜索(Graph-based)

  • 基于嵌入的搜索(Embedding-based)

OpenAI推荐的词嵌入方法。嵌入很容易实现,并且在问题中表现尤为出色,因为问题通常在词汇上不会与它们的答案重叠。

可以考虑将仅使用嵌入的搜索视为作为整个系统的起点。更好的搜索系统可能会结合多种搜索方法,以及特性,如受欢迎程度、最近性、用户历史记录、与先前搜索结果的冗余、点击率数据等。

通过将问题首先转换为假设的答案然后再进行嵌入的技术,如HyDE,也可以提高问答检索的性能。同样,GPT还可以通过自动将问题转换为一组关键词或搜索术语来潜在地改善搜索结果。

四、如何建立基于embeddings的搜索系统来解决问题

总的来说,这样的系统包含3个步骤:准备需要检索的知识、检索、提问即可:

  • 准备搜索数据(仅一次)

    • 收集:即获取你要用的数据,例如OpenAI的案例是下载几百篇有关2022年奥运会的维基百科文章

    • 切块:将文档分成短小的、大多是自包含的部分以进行嵌入

    • 嵌入:使用OpenAI API对每个部分数据获得embeddings结果

    • 存储:存储embedding是(对于大型数据集,可以使用向量数据库)

  • 搜索(每次查询一次)

    • 给定用户问题,从OpenAI API生成查询的embeddings

    • 使用embeddings,按照与查询相关性对文本部分进行排序

  • 提问(每次查询一次)

    • 将问题和最相关的部分插入到发送给GPT的消息中

    • 返回GPT的答案

简单总结一下就是将原始数据用嵌入的方式存储,然后针对问题获取embeddings结果,再利用这个结果检索最相似的内容,把这个提问和最相似的结果发给GPT,获得GPT的回答即可。也就是说,这是另一种解决GPT无法回答最新数据和长文本内容的方法!

成本

这个方法比原始的方法来说多了几个步骤,但是成本并不一定更多,因为GPT的接口比embedding的接口更贵。如果系统中查询次数比较多,那么成本主要在步骤上面的步骤3(提问)。有个简单的计算方法:

gpt-3.5-turbogpt-4

但是这只是简单估算,具体的成本可能还要看系统什么样子。

总结

这是一个非常棒的idea。可以解决目前GPT或者其它大模型没有最新数据或者输入限制的问题。在AutoGPT中,作者也有一个思路,就是每次都把最近的问题以及最相关的目标一起发送给GPT,获得答案,以此来获得更长记忆的能力。但是从实现效果来说,OpenAI这种利用Embeddings先获取最相关文本再提问的方式可能是比较优雅的。而且也可以控制输入和输出的tokens。

官方有代码实现案例:https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb