首页
未知分类正文内容

如何用自己的数据创建自己的ChatGPT

2023年09月19日
阅读时长 2 分钟
阅读量 18
如何用自己的数据创建自己的ChatGPT

它会这么简单吗?(由text-davinci-003生成的回答)(作者图片)

随着像ChatGPT和GPT-4这样的大型语言模型的崛起,许多人都在问是否可以使用自己的企业数据训练私人ChatGPT。但是这可行吗?这种语言模型能够提供这些功能吗?

在本文中,我将讨论创建“您的私人ChatGPT”的架构和数据要求,以便利用您自己的数据。我们将探讨这项技术的优势以及如何克服其当前的限制。

免责声明:本文提供了一些非特定于Azure的架构概念的概述,但是使用Azure服务作为示例,因为我是微软的解决方案架构师。

1. 使用自己的数据进行微调LLM的缺点

通常,人们将微调(训练)称为在预训练的语言模型之上添加自己的数据的解决方案。然而,这样做会有一些缺点,比如在最近的GPT-4公告中提到的出现偏执的风险。除此之外,GPT-4只经过了2021年9月的数据训练。

对于微调LLM,常见的缺点有:

  • 上述答案的正确性和可追溯性

  • 访问控制,将某些文档限制为特定的用户或组不可能

  • 成本,新的文档需要重新训练模型和模型的托管

这将使使用微调几乎不可能实现问题回答(QA)的目的。我们如何克服这些限制并仍然受益于这些LLM呢?

大脑(代表知识)和人工智能(计算机)相互分离的形象-(DALL·E 2的图像)

2. 将知识与语言模型分离

为了确保用户收到准确的答案,我们需要将我们的语言模型与我们的知识库分离开来。这样,我们既可以利用语言模型的语义理解能力,又可以向用户提供最相关的信息。这一切都发生在实时中,不需要模型训练。

在运行时将所有文档提供给模型可能看起来是个好主意,但由于一次只能处理一定数量(以标记计数为单位)的字符(以令牌为单位),这是不可行的。例如,GPT-3支持多达4K个令牌,GPT-4支持多达8K或32K个令牌。由于定价是按1000个令牌计费,使用较少的令牌也有助于节省成本。

这种方法的步骤如下:

  1. 用户提出问题

  2. 应用程序找到(最有可能)包含答案的最相关文本

  3. 将包含相关文本的简明提示发送给LLM

  4. 用户将收到答案或“找不到答案”的响应

(作者图片)

此方法通常称为模型接地或检索增强生成(RAG)。应用程序将为语言模型提供附加上下文,以便根据相关资源回答问题。


现在您已经了解了开始构建这样一个场景所需的高级架构,现在该深入了解技术细节了。

3. 检索最相关的数据

上下文是关键。为了确保语言模型具有正确的信息,我们需要建立一个知识库,用于通过语义搜索找到最相关的文档。这将使我们能够为语言模型提供正确的上下文,从而使其生成正确的答案。

3.1 切分和分割数据

由于回答提示有令牌限制,我们需要确保将我们的文档切分成较小的块。根据块的大小,您还可以共享多个相关章节并在多个文档上生成答案。

我们可以从简单地按页拆分文档开始,或者使用文本分割器在固定的令牌长度上进行拆分。当我们以更可访问的格式拥有文档时,就可以创建一个可以通过提供用户问题进行查询的搜索索引。

除了这些块,您还应该向索引中添加附加的元数据。存储原始源和页码以将答案链接到原始文档。存储可用于访问控制和过滤的其他元数据。

选项1:使用搜索产品

构建语义搜索索引的最简单方法是利用现有的作为服务的搜索平台。在Azure上,您可以使用Cognitive Search,该服务提供了托管的文档摄取管道和使用Bing背后的语言模型的语义排序

选项2:使用嵌入来构建自己的语义搜索

嵌入是一种由浮点数(列表)组成的向量。两个向量之间的距离测量它们的相关性。较小的距离表示高相关性,较大的距离表示低相关性。[1]

如果您想利用最新的语义模型,并对您的搜索索引具有更多控制权,您可以使用OpenAI的文本嵌入模型。对于所有的章节,您将需要预计算嵌入并存储它们。

在Azure上,您可以将这些嵌入存储在托管的向量数据库中,如Cognitive Search with Vector Search(预览版),Azure Cache for Redis(RediSearch)或开源的向量数据库,如Weaviate或Pinecone。在应用程序运行时,您将首先将用户问题转换为嵌入,以便我们可以将问题嵌入的余弦相似性与之前生成的文档嵌入进行比较。像Cognitive Search这样的高级搜索产品可以进行混合搜索,将关键字搜索和向量搜索的优势结合起来。

(关于嵌入的深入研究可以在Towards Data Science上找到)

(Image by author)

3.2 使用不同的切分策略提高相关性

为了能够找到最相关的信息,重要的是要了解您的数据和可能的用户查询。您需要什么样的数据来回答问题?这将决定如何最好地切分您的数据。

可能会提高相关性的常见模式有:

  • 使用滑动窗口;按页或按令牌进行切块可能会导致丢失上下文的不良效果。使用滑动窗口在块中具有重叠内容,增加了在块中具有最相关信息的机会。

  • 提供更多上下文;非常结构化的文档,其包含多级嵌套的节(例如1.3.3.7节)可能会从额外上下文(如章标题和节标题)中获益。您可以解析这些节并将此上下文添加到每个块中。

  • 摘要,创建包含较大文档部分摘要的块。这将使我们能够捕获最重要的文本并将其合并到一个块中。


4. 编写简明提示以避免幻觉

设计您的提示是如何“编程”模型的方式,通常是通过提供一些指示或几个示例。[2]

您的提示是ChatGPT实现的重要部分,以防止不希望的回应。现在,人们将提示工程视为一项新的技能,并且每周都会分享更多的示例。

在提示中,您希望明确指出模型应该简明并仅使用提供的上下文中的数据。当它无法回答问题时,它应该提供预定义的“无答案”响应。输出应包含脚注(引文)指向原始文档,以允许用户通过查看源进行验证其事实准确性。

一个示例的提示:

"You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. " + \
"Use 'you' to refer to the individual asking the questions even if they ask with 'I'. " + \
"Answer the following question using only the data provided in the sources below. " + \
"For tabular information return it as an html table. Do not return markdown format. "  + \
"Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. " + \
"If you cannot answer using the sources below, say you don't know. " + \
"""
###
Question: 'What is the deductible for the employee plan for a visit to Overlake in Bellevue?'
Sources:
info1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.
info2.pdf: Overlake is in-network for the employee plan.
info3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.
info4.pdf: In-network institutions include Overlake, Swedish and others in the region
Answer:
In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].
###
Question: '{q}'?
Sources:
{retrieved}
Answer:
"""

来源:azure-search-openai-demo中使用的提示(MIT许可证)

使用单次学习来改进回答;我们提供了一个用户问题应该如何处理的示例,我们提供了一个具有唯一标识符和由多个源文本组成的示例答案,用于生成最终提示。

如果您想要更多重复性和确定性的响应,可以通过参数设置较低的温度。增加温度将导致更多意外或创造性的回应。

最终,此提示将用于通过(Azure)OpenAI API生成响应。如果使用gpt-35-turbo模型(ChatGPT),您可以在每个轮次中传递对话历史,以便能够提出澄清问题或使用其他推理任务(例如摘要)。了解更多关于提示工程的资源,请参阅GitHub上的dair-ai/Prompt-Engineering-Guide


5. 下一步

在本文中,我讨论了构建实现所需的架构和设计模式,但没有涉及特定的代码细节。这些模式在当今常用,并且以下项目和笔记可以作为启发,帮助您开始构建这样的解决方案。

  • Azure OpenAI Service - On Your Data,新功能允许您将ChatGPT和GPT-4等OpenAI模型与您自己的数据完全托管地结合在一起。不需要复杂的基础架构或代码。

  • ChatGPT Retrieval Plugin,让ChatGPT访问最新的信息。目前,这仅支持公共ChatGPT,但希望将来可以将添加插件的功能添加到ChatGPT API(OpenAI + Azure)中。

  • LangChain,用于结合LLMs和其他计算或知识来源的流行库

  • Azure Cognitive Search + OpenAI accelerator,在您自己的数据上提供类似ChatGPT的体验,可以快速部署

  • OpenAI Cookbook,一个示例,演示如何在Jupyter笔记本中利用OpenAI嵌入进行问答(无需基础架构)

  • Semantic Kernel,新的库,将传统编程语言与LLMs混合在一起(提示模板化、链接和计划能力)

最终,您可以通过像LangChain或Semantic Kernel这样的工具将“您自己的ChatGPT”与更多系统和功能相连接。可能性是无限的。


结论

总之,仅依靠语言模型生成事实性文本是错误的。微调模型也无济于事,因为它不会为模型增加任何新的知识,并且无法提供验证其响应的方式。要在LLM上构建问答引擎,必须将知识库与大型语言模型分开,并仅基于提供的上下文生成答案。

(Image by author)

如果您喜欢本文,请随时在LinkedIn上联系我,或GitHubTwitter


参考资料

[1] 嵌入 - OpenAI API. March 2023, https://platform.openai.com/docs/guides/embeddings

[2] 介绍 - OpenAI API. March 2023, https://platform.openai.com/docs/introduction/prompts

[3] Bubeck, S., Chandrasekaran, V., Eldan, R., Gehrke, J., Horvitz, E., Kamar, E., Lee, P., Lee, Y. T., Li, Y., Lundberg, S., Nori, H., Palangi, H., Ribeiro, M. T., Zhang, Y. "Sparks of Artificial General Intelligence: Early experiments with GPT-4" (2023), arXiv:2303.12712

[4] Schick, T., Dwivedi-Yu, J., Dessì, R., Raileanu, R., Lomeli, M., Zettlemoyer, L., Cancedda, N., Scialom, T. "Toolformer: Language Models Can Teach Themselves to Use Tools" (2023), arXiv:2302.04761

[5] Mialon, G., Dessì, R., Lomeli, M., Nalmpantis, C., Pasunuru, R., Raileanu, R., Rozière, B., Schick, T., Dwivedi-Yu, J., Celikyilmaz, A., Grave, E., LeCun, Y., Scialom, T. "Augmented Language Models: a Survey" (2023), arXiv:2302.07842

免责声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。