我的学习笔记

土猛的员外

LangFlow--可视化的LangChain

将llm嵌入到您的应用程序中,无需代码.

LangChain是一个Python库,它可以更容易地将大语言模型的功能与应用程序的逻辑结合起来。LangChain允许用户创建和组合模块化组件,如prompt序列化器、代理和链,以实现各种自然语言任务。然而,如果没有用户友好的界面,设计和测试LangChain流可能是具有挑战性的。

这就是LangFlow的用武之地。LangFlow是一个针对LangChain的GUI,它采用了反应流设计,提供了一种轻松的方式,通过拖放组件和聊天框来实验和原型化流程。LangFlow允许您探索不同的大语言模型、prompt参数、链配置和代理行为,并跟踪代理的思维过程。您还可以将流导出为JSON文件,以便与LangChain一起使用。

在本文中,我们将向您展示如何使用LangFlow用LangChain创建您自己的会话代理。

LangFlow安装

正如GitHub库中所描述的,你可以通过pip install langflow安装它,前提条件如下:

然后,运行命令langflow:它将打开LangChain GUI的本地部署界面。

7MyigPT4h4P1rQxIX1E-5A

在GUI中,在左边的栏中,你可以看到所有你可以使用的工具:

  • Agent→他们将大语言模型的决策与工具结合起来,使他们能够实施和执行行动;

  • Chains→允许组合人工智能应用程序的不同组件,如prompts,大语言模型和存储器;

  • Loaders→允许与外部源集成以上传信息(如pdf);

  • Embeddings→将文本嵌入到向量潜在空间的模型;

  • LLMs→用于理解和生成文本的模型,包括今天的OpenAI模型和hug Face Hub;

  • Memories→LangChain组件,能够维护会话的记忆;

  • Prompts→用于定义prompts框架的模板;

  • Text Splitters→将文本分割成更小的块并避免tokens限制问题的实用程序;

  • Toolkits→为特定用例与外部系统集成,例如,CSV文件或Python Agent;

  • Tools→代理可以用来与外部工具交互的功能,如必应搜索或本地文件系统;

  • Utilities→对SQLDB或Bing API等系统有用的包装器;

  • Vector Stores→数据库,文本Embeddings可以保存,然后与用户的输入进行匹配;

  • Wrappers→请求库的轻量级包装器

然后,每个框都带有入站和出站链接,并用颜色标记,以便更容易理解可以链接到哪些其他块。您还可以从每个块的右上角看到链接是成功还是失败(包括失败的原因)。

fHdjaHYnGbZ2b9ojjcAdPA

最后,无论何时完成流程,都可以直接使用基于聊天的GUI进行测试:

7fmLp7B-3zxPQbXPZ0H-BA

很好,现在我们已经熟悉了这个工具,让我们从头开始构建第一个代理。

构建一个简单的代理

在本教程中,我将构建一个由OpenAI GPT3驱动的简单代理,它也能够浏览互联网。这是整个流程:

nTyNjaSZV1dszs4ZUdhZrw

让我们一块一块地检查它:

现在让我们测试一下,询问2021年之后发生的事情:

98mbQO6iGK7LtmuL3g7R6A

这样做的好处是,如果您单击消息图标,您还可以展示LLM背后的思维过程,以及使用外部工具(在我们的示例中是Bing)和观察的一组操作。

x9QOCC2nDSdyp_KL1viQvA

正如您所看到的,代理执行了一个web搜索来回答这个问题,因为它没有这个参数内存。

结论

最近,Langflow已经展示了强大的功能,它也有与llm进一步集成的路线图(包括Azure OpenAI!)。另外,你可以通过SDK使用整个流程,并将其嵌入到进一步的应用程序中,如下所示:

1
2
3
4
5
from langflow import load_flow_from_json

flow = load_flow_from_json("your_flow_name.json")
# Now you can use it like any chain
flow("What is the plot of Avatar 2?")

OK,结束,有兴趣的朋友可以试起来。

(2023-08-05)译者:最近发现了另外一个更好的LangChain可视化实现,而且是基于低代码的,拖拽即可完成开发,支持的组件也非常丰富。本人已经安装亲测,效果很好。大家可以看这里:Flowise—基于低代码的LLM应用敏捷开发LangChain实现


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



当知识图谱遇上大模型——多跳问答

原文:Knowledge Graphs & LLMs: Multi-Hop Question Answering

在之前的文章中,我们学习了检索增强方法来克服大型语言模型(Large Language Models, llm)的局限性,比如幻觉和有限的知识。检索增强方法背后的思想是在提问时引用外部数据,并将其提供给LLM,以增强其生成准确和相关答案的能力。

1_zydD2GKzjpEyvL-d_cP0vA

当用户提出问题时,智能搜索工具会在提供的知识库中查找相关信息。例如,您可能遇到过在pdf文件或公司文档中搜索相关信息的情况。这些例子中的大多数使用向量相似性搜索来识别哪些文本块可能包含准确回答用户问题的相关数据。实现相对简单。

1_oMLZ5s8OHftzqPEVreTd_g

pdf文件或文档首先被分割成多个文本块。一些不同的策略包括文本块应该有多大,以及它们之间是否应该有重叠。在下一步中,使用任何可用的文本Embedding模型生成文本块的向量表示。这就是在查询时执行向量相似性搜索所需的所有预处理。剩下的唯一步骤是在查询时将用户输入编码为向量,并使用余弦或任何其他相似性来比较用户输入和嵌入文本块之间的距离。最常见的是,您将看到返回前三个最相似的文档,为LLM提供上下文,以增强其生成准确答案的能力。当向量搜索可以产生相关的文本块时,这种方法非常有效。

然而,当LLM需要来自多个文档甚至多个块的信息来生成答案时,简单的向量相似性搜索可能是不够的。

例如,考虑以下问题:

OpenAI的前员工中有谁创办了自己的公司吗?

如果你仔细想想,这个问题可以分为两个问题。

  • 谁是OpenAI的前雇员?

  • 他们中有人开了自己的公司吗?

1_rFlThhafYxQ-Q2z2rfJyQA

回答这些类型的问题是一个多跳问答(可在文末查看什么是多跳问题)任务,其中单个问题可以分解为多个子问题,并且可能需要向LLM提供大量文档以生成准确的答案。

上述简单地将文档分块和Embeddings到数据库中,然后使用纯向量相似度搜索的工作流程可能会遇到多跳问题,原因如下:

  • 前N个文档中的重复信息:所提供的文档不保证包含回答问题所需的补充和完整信息。例如,排名前三的类似文件可能都提到shaariq曾在OpenAI工作,并可能成立了一家公司,而完全忽略了所有其他成为创始人的前员工

  • 缺少引用信息:根据块大小,您可能会丢失对文档中实体的引用。这可以通过块重叠部分解决。但是,也有引用指向另一个文档的例子,因此需要某种形式的共同引用解析或其他预处理。

  • 很难定义理想的检索文档数量:有些问题需要向LLM提供更多的文档才能准确地回答问题,而在其他情况下,大量提供文档只会增加噪音(和成本)。

1_vrvcRRrsVrtAK8L_zye5Rg

因此,简单的向量相似性搜索可能会遇到多跳问题。然而,我们可以采用多种策略来尝试回答需要来自不同文档的信息的多跳问题。

作为压缩信息存储的知识图谱

如果您非常关注LLM空间,那么您可能会想到使用各种技术来压缩信息,以便在查询期间更容易地访问信息。例如,您可以使用LLM提供文档摘要,然后嵌入并存储摘要而不是实际文档。使用这种方法,您可以消除大量噪声,获得更好的结果,并且不必担心prompttoken空间。

有趣的是,您可以在摄取时执行上下文摘要,也可以在查询时执行上下文摘要。查询期间的上下文压缩很有趣,因为它选择了与所提供的问题相关的上下文,因此它更具有指导性。但是,查询期间的工作负载越重,预期的用户延迟就越差。因此,建议将尽可能多的工作负载移动到摄取时间,以改善延迟并避免其他运行时问题。

同样的方法也可以应用于总结会话历史,以避免遇到token限制问题。

我还没有看到任何关于将多个文档合并和汇总为单个记录的文章。问题可能是我们需要合并和总结的文档组合太多了。因此,在摄取时处理所有文档组合的成本可能太高。
然而,知识图谱在这里也可以提供帮助。

从非结构化文本中提取实体和关系形式的结构化信息的过程已经存在了一段时间,更广为人知的是信息提取管道。将信息提取管道与知识图相结合的好处在于,您可以单独处理每个文档,并且当构建或丰富知识图时,来自不同记录的信息可以连接起来。

1_N-TVTbRffy_VQ0DPcx0JKg

知识图使用节点和关系来表示数据。在这个例子中,第一份文件提供了Dario和Daniela曾经在OpenAI工作的信息,而第二份文件提供了他们的Anthropic创业公司的信息。每条记录都是单独处理的,但知识图表示将数据连接起来,并使回答跨多个文档的问题变得容易。

大多数使用大语言模型来回答我们遇到的多跳问题的新方法都侧重于在查询时解决任务。然而,我们相信许多多跳问答问题可以通过在摄取数据之前对其进行预处理并将其连接到知识图中来解决。信息提取管道可以使用大语言模型或自定义文本域模型来执行。

为了在查询时从知识图中检索信息,我们必须构造一个适当的Cypher语句。幸运的是,大语言模型非常擅长将自然语言转换为Cypher图查询语言。

1_mkYvs8_TmzLhUUI1CShNfw

在本例中,智能搜索使用LLM生成适当的Cypher语句,以便从知识图中检索相关信息。然后将相关信息传递给另一个LLM调用,该调用使用原始问题和提供的信息生成答案。在实践中,您可以使用不同的大语言模型来生成Cypher语句和答案,或者在单个LLM上使用各种prompts。

结合图形和文本数据

有时,您可能希望结合文本和图形数据来查找相关信息。例如,考虑以下问题:

关于Prosper Robotics创始人的最新消息是什么?

在本例中,您可能希望使用知识图结构识别Prosper Robotics创始人,并检索提到他们的最新文章。

1_J9LkK_WuH5z00hLJi97_Hw

要回答关于Prosper Robotics创始人的最新消息的问题,您可以从Prosper Robotics节点开始,遍历到其创始人,然后检索提到他们的最新文章。

知识图可用于表示关于实体及其关系的结构化信息,以及作为节点属性的非结构化文本。此外,您可以使用自然语言技术,如命名实体识别,将非结构化信息连接到知识图中的相关实体,如提及关系所示。

我们相信,检索增强生成应用的未来是利用结构化和非结构化信息来生成准确的答案。因此,知识图是一个完美的解决方案,因为您可以存储结构化和非结构化数据,并将它们与明确的关系连接起来,从而使信息更易于访问和查找。

1_AH05dvGA_7db_EMySc9AAw

当知识图谱中包含结构化和非结构化数据时,智能搜索工具可以利用Cypher查询或向量相似度搜索来检索相关信息。在某些情况下,您也可以使用两者的组合。例如,可以从Cypher查询开始识别相关文档,然后使用向量相似性搜索在这些文档中查找特定信息。

在思维链流中使用知识图谱

围绕大语言模型的另一个非常令人兴奋的发展是所谓的思维链问答,特别是LLM代理。LLM代理背后的思想是,它们可以将问题分解为多个步骤,定义计划,并使用所提供的任何工具。在大多数情况下,代理工具是api或知识库,代理可以访问它们来检索其他信息。让我们再考虑一下这个问题:

关于Prosper Robotics创始人的最新消息是什么?

1_xPSKLXVQUyoOhzv1AYDszA

假设在它们提到的文章和实体之间没有明确的联系。文章和实体甚至可以在不同的数据库中。在这种情况下,使用思维链流的LLM代理将非常有帮助。首先,agent将问题分解为子问题。

  • Prosper Robotics的创始人是谁?
  • 关于他们的最新消息是什么?

现在,代理可以决定使用哪个工具。假设我们为它提供一个知识图访问,它可以使用它来检索结构化信息。因此,代理可以选择从知识图谱中检索Prosper Robotics公司创始人的信息。正如我们所知,Prosper Robotics的创始人是shaariq Hashme。现在第一个问题已经回答了,代理可以将第二个子问题重写为:

  • 关于Shariq Hashme的最新消息是什么?

代理可以使用任何可用的工具来回答随后的问题。这些工具的范围包括知识图、文档或矢量数据库、各种api等等。对结构化信息的访问允许LLM应用程序在需要聚合、过滤或排序的情况下执行各种分析工作流。考虑以下问题:

  • 哪一家创始人一人的公司估值最高?
  • 谁创办的公司最多?

纯向量相似性搜索可能难以解决这些类型的分析问题,因为它搜索的是非结构化文本数据,因此很难对数据进行排序或聚合。因此,结构化和非结构化数据的组合可能是检索增强LLM应用程序的未来。此外,正如我们所看到的,知识图也非常适合表示连接的信息,因此也适合多跳查询。

虽然思维链是大语言模型的一个引人入胜的发展,因为它显示了LLM如何进行推理,但它并不是最用户友好的,因为由于多个LLM调用,响应延迟可能很高。然而,我们仍然非常兴奋地了解更多关于将知识图合并到各种用例的思维链流中的知识。

总结

检索增强生成应用程序通常需要从多个源检索信息以生成准确的答案。虽然文本摘要可能具有挑战性,但以图形格式表示信息可以提供几个优点。

通过单独处理每个文档并将它们连接到知识图中,我们可以构建信息的结构化表示。这种方法允许更容易地遍历和导航相互连接的文档,支持多跳推理来回答复杂的查询。此外,在摄取阶段构造知识图减少了查询期间的工作负载,从而改善了延迟。

使用知识图的另一个优点是它能够存储结构化和非结构化信息。这种灵活性使其适用于广泛的语言模型(LLM)应用程序,因为它可以处理各种数据类型和实体之间的关系。图结构提供了知识的可视化表示,促进了开发人员和用户的透明性和可解释性。

总的来说,在检索增强生成应用程序中利用知识图提供了一些好处,比如提高查询效率、多跳推理能力以及对结构化和非结构化信息的支持。

附加

多跳问题(来源于《一文带你入门知识图谱多跳问答》

通俗来说,多跳问题 (Multi-hop Questions) 指的是那些需要知识图谱 「多跳推理」 才能回答的问题。例如,若要回答 ”成龙主演电影的导演是哪些人?“ 这一问题,则需要多个三元组所形成的多跳推理路径 <成龙,主演,新警察故事>, <新警察故事,导演,陈木胜> 才能够回答。

这种类型的问题在实际应用中十分普遍,但想要构建出一个高准确率的知识图谱多跳问答系统却并非易事。下图展示了一个谷歌搜索中的 Bad Case。

WX20230619-171827






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



使用GPT4ALL和LangChain构建本地大模型应用

私有化大语言模型的想法肯定会引起我们的共鸣。其吸引力在于,我们可以查询信息并将信息传递给大语言模型,而无需我们的数据或响应通过第三方——安全,可靠,完全控制我们自己的数据。运营我们自己的大语言模型也有成本优势。

对我们来说幸运的是,在训练开源大语言模型(LLM)的世界里有很多激动人心的事情可以供我们使用。一些著名的例子包括Meta的LLaMA系列、EleutherAI的Pythia系列、Berkeley AI Research的OpenLLaMA模型、BigScience的BLOOM和MosaicML。

举一个例子来说明这个想法的受欢迎程度,一个名为PrivateGPT的Github回购允许你使用LLM在本地阅读你的文档,拥有超过两万四Star了。

对于那些想要处理大量数据而不需要通过第三方传输的企业来说,这是一个非常有吸引力的。

所有这些对于喜欢构建内容的开发人员来说都是好消息!
有很多开源的大语言模型可以用来创建私人聊天机器人。

GPT4All是这些流行的开源大语言模型之一。它还获得了商业用途的完全许可,因此您可以将其集成到商业产品中而不必担心。这与其他模型不同,例如基于Meta的Llama的模型,这些模型仅限于非商业研究用途。

在本文中,我们将通过使用GPT4All在本地机器上使用LangChain创建聊天机器人,然后探索如何使用Cerebrium将私有GPT4All模型部署到云中,然后在我们的应用程序中使用LangChain再次与之交互。

但首先,让我们了解更多关于GPT4All和指令调优的知识,指令调优是使其成为一个出色的聊天机器人风格模型的原因之一。

内容

  • GPT4All和指令调优

  • 在本地使用GPT4All的聊天机器人UI应用程序

  • 使用LangChain在本地与GPT4All交互

  • 使用LangChain和Cerebrium在云端与GPT4All交互

GPT4All

一个免费使用,本地运行,隐私意识聊天机器人。不需要GPU或互联网。

这就是GPT4All网站的出发点。很酷,对吧?它继续提到以下内容:

GTP4All是一个生态系统,用于训练和部署强大的定制大型语言模型,这些模型在消费级cpu上本地运行。

太好了,这意味着我们可以在电脑上使用它,并期望它以合理的速度工作。不需要gpu。分数!基本型号只有3.5 GB左右,所以我们可以在普通电脑上使用。到目前为止,一切顺利。

目标很简单——成为任何个人或企业都可以自由使用、分发和构建的最佳指令调优助手式语言模型。

它有一个非商业许可,这意味着你可以用来赚钱。并非所有开源大语言模型都共享相同的许可,因此您可以在此基础上构建产品,而不必担心许可问题。

它提到,它想成为“最佳的教学调整助手式”语言模型。如果你和我一样,你会想知道这意味着什么。什么是指令调优?让我们深入研究一下。

指令调优

在大型文本数据集上训练大型语言模型(LLM)。他们大多是这样训练的:给定一串文本,他们可以统计地预测下一个单词序列。这与被训练成善于回答用户问题(“助手风格”)是非常不同的。

然而,在足够大的数据集上进行训练后,大语言模型开始形成能够回答比最初基于较小数据集的性能预测更复杂的响应的能力。这些被称为突发能力,使一些大型大语言模型成为非常有说服力的谈话者。

所以,我们的想法是,如果我们不断扩大这些模型所训练的数据集的规模,随着时间的推移,我们应该开始获得越来越好的聊天机器人风格的能力。

然而,研究发现,使语言模型变得更大并不一定会使它们更好地遵循用户的意图。例如,大型语言模型可能生成不真实的、有害的或对用户没有帮助的输出。换句话说,这些模型与用户提供有用的问题答案的意图不一致。

2022年,人们发现了另一种创建性能良好的聊天机器人式大语言模型的方法。这种方法是用几个问答式的prompts对模型进行微调,类似于用户与它们的交互方式。使用这种方法,我们可以使用在更小的信息基础上训练的基本模型,然后用一些问答、指令风格的数据对其进行微调,我们得到的性能与在大量数据上训练的模型相当,有时甚至更好。

让我们把GPT4All模型作为一个具体的例子来看看,让它更清晰一些。

如果我们检查GPT4All-J-v1.0模型上的拥抱脸,它提到它已经在GPT-J上进行了微调。GPT-J是EleutherAI公司的一个模型,它训练了60亿个参数,与ChatGPT的1750亿个参数相比,这是微不足道的。

让我们来看看GPT-J和GPT4All-J所使用的数据类型,并比较它们之间的差异。

正如在它的拥抱脸页面上提到的,GPT-J是在Pile数据集上训练的,这是一个825 GB的数据集,同样来自EleutherAI。

如果我们看一下数据集预览,它本质上只是模型训练的信息块。基于这种训练,它可以使用统计方法猜测文本字符串中的下一个单词。然而,它并没有赋予它出色的问答能力。

1_q5zbB5oMro_26Lg6_-aPYQ

现在,如果我们看一下GPT4All训练的数据集,我们会发现它是一个更多的问答格式。GPT4All数据集的总大小在1gb以下,这比GPT-J模型最初训练的825gb要小得多。

1_4BGQxB3QhGdcf0nMrHq-fA

GPT-J被用作预训练模型。我们正在使用比初始数据集小得多的数据集,使用一组问答风格的prompts(指令调优)对该模型进行微调,结果GPT4All是一个功能更强大的问答风格聊天机器人。

1_r1TkuU-PRj9sAk5O-vqs9w

要真正了解性能改进,我们可以访问GPT-J页面,阅读有关该模型局限性的一些信息和警告。这里有一个例子:

检查使用

GPT-J-6B不打算在没有微调、监督和/或调节的情况下部署。它本身并不是一个产品,也不能用于与人面对面的交互。例如,模型可能产生有害或冒犯性的文本。请评估与您的特定用例相关的风险。

GPT-J-6B还没有针对通常部署语言模型的下游环境进行微调,比如写作体裁散文或商业聊天机器人。这意味着GPT-J-6B不会像ChatGPT那样对给定的prompt做出反应。

局限性和偏见

GPT-J的核心功能是获取一串文本并预测下一个token。虽然语言模型被广泛用于其他任务,但这项工作还有很多未知之处。

因此,从一个没有被指定为可以很好地工作的聊天机器人、问题和答案类型模型的基本模型,我们用一些问题和答案类型prompts对它进行微调,它突然变成了一个功能更强大的聊天机器人。

这就是指令微调的力量。

在本地开始使用GPT4All聊天机器人UI

GPT4All非常容易设置。开始时,您甚至不需要任何编码。他们有一个非常好的网站,你可以在那里下载他们的Mac、Windows或Ubuntu的UI应用程序。

下载并打开应用程序后,它将要求您选择要下载的LLM模型。它们具有不同的模型变体,具有不同的能力级别和特性。你可以在描述中读到每个型号的特征。

ggml-gpt4all-j-v1.3-groovy.bin

目前最好的商业许可模型基于GPT-J,并由Nomic AI在最新策划的GPT4All数据集上训练。

1_JvOW_UCqaRKvey83IOfXVw

让我们试试这个可以应用于商业的模型。它是3.53 GB,所以下载需要一些时间。这个UI应用程序的想法是,你有不同类型的模型可以使用。该应用程序是一个聊天应用程序,可以与不同类型的模型进行交互。

下载后,您就可以开始交互了。

在开箱即用的情况下,ggml-gpt4all-j-v1.3-groovy模型的响应很奇怪,给出非常突兀的、一个单词类型的答案。我必须更新prompt模板以使其更好地工作。即使在指令调优的LLM上,您仍然需要良好的prompt模板才能正常工作..。

要更新prompt,请单击右上方的齿轮图标,然后更新Generation选项卡中的prompt模板。这是我设置的,开始得到一些不错的结果。

1
2
3
4
5
6
# You are a friendly chatbot assitant. Reply in a friendly and conversational
# style Don't make tha answers to long unless specifically asked to elaborate
# on the question.
### Human:
%1
### Assistant:

一旦完成了这些,聊天开始变得更好。

1_uU4EZ4m_8NRi4Q7GvJG8Lg

总的来说,据我所知,它运行得很好。漂亮的界面。速度也不错。这很酷。您正在与本地LLM进行交互,所有这些都在您的计算机上,并且数据交换是完全私有的。我的电脑是英特尔Mac,内存为32gb,速度相当不错,虽然我的电脑迷们肯定要进入高速模式..。

尽管如此,在不涉及gpu的普通消费级CPU上运行LLM还是很酷的。

使用LangChain和GPT4All在本地构建

我们是黑客,对吧?我们不要现成的美国!我们想自己建造它!朗链救援!:)

LangChain确实有能力与许多不同的资源进行交互;这真是令人印象深刻。它们有一个GPT4All类,我们可以使用它轻松地与GPT4All模型进行交互。

如果您想直接下载项目源代码,您可以使用下面的命令克隆它,而不是按照下面的步骤。确保按照自述在.env文件中正确设置Cerebrium API。

1
https://github.com/smaameri/private-llm.git

因此,首先让我们设置项目目录、文件和虚拟环境。我们还将创建一个/models目录来存储我们的LLM模型。

1
2
3
4
5
6
7
mkdir private-llm
cd private-llm
touch local-llm.py
mkdir models
# lets create a virtual environement also to install all packages locally only
python3 -m venv .venv
. .venv/bin/activate

现在,我们想要将GPT4All模型文件添加到我们创建的models目录中,以便我们可以在脚本中使用它。在设置GPT4All UI应用程序时,将模型文件从下载的位置复制到我们项目的models目录中。如果你没有设置UI应用程序,你仍然可以去网站直接下载模型。

1_SivQYxW4CGtuxZblQczXGw

同样,确保将下载的模型存储在项目文件夹的models目录中。

现在,让我们开始编码吧!

让它在本地运行的脚本实际上非常简单。安装以下依赖项:

1
pip install langchain gpt4all

将以下代码添加到local-llm.py中。注意,在设置GPT4All类时,我们将其指向存储模式的位置。就是这样。我们可以在三行代码中开始与LLM交互!

1
2
3
4
5
from langchain.llms import GPT4All

llm = GPT4All(model='./models/ggml-gpt4all-j-v1.3-groovy.bin')

llm("A red apple is ")

现在,让我们运行脚本并查看输出。

1
python3 local-llm.py

首先,我们看到它从我们的模型文件加载LLM,然后继续为我们的问题提供答案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(.venv) ➜  private-llm-test python3 local-llm.py
Found model file.
gptj_model_load: loading model from './models/ggml-gpt4all-j-v1.3-groovy.bin' - please wait ...
gptj_model_load: n_vocab = 50400
gptj_model_load: n_ctx = 2048
gptj_model_load: n_embd = 4096
gptj_model_load: n_head = 16
gptj_model_load: n_layer = 28
gptj_model_load: n_rot = 64
gptj_model_load: f16 = 2
gptj_model_load: ggml ctx size = 5401.45 MB
gptj_model_load: kv self size = 896.00 MB
gptj_model_load: ................................... done
gptj_model_load: model size = 3609.38 MB / num tensors = 285
Paris, France

你会注意到答案非常直率,不像聊天机器人。该模型更像是一个字符串完成模型,而不是聊天机器人助手。您可以随意地通过更改提示符并查看它如何响应不同的输入来探索它的工作原理。

我们希望它更像一个问答聊天机器人,我们需要给它一个更好的提示。同样,即使是经过指令调整的llm也需要好的提示。

我们可以创建一个提示符并将其传递到LLM中,如下所示:

1
2
3
4
5
6
7
8
llm("""
You are a friendly chatbot assistant that responds in a conversational
manner to users questions. Keep the answers short, unless specifically
asked by the user to elaborate on something.

Question: Where is Paris?

Answer:""")

如果每次我们想问问题时都需要传递提示,这将变得乏味。为了克服这个问题,LangChain有一个LLMChain类,我们可以使用它在构造函数中接受llmprompt_template

1
llm_chain = LLMChain(prompt=prompt, llm=llm)

我们现在用它。我们将创建一个名为local-llm-chain.py的新文件,并放入以下代码。它设置了PromptTemplateGPT4All LLM,并将它们作为参数传递给LLMChain

1
touch local-llm-chain.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

from langchain import PromptTemplate, LLMChain
from langchain.llms import GPT4All
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler

template = """
You are a friendly chatbot assistant that responds in a conversational
manner to users questions. Keep the answers short, unless specifically
asked by the user to elaborate on something.

Question: {question}

Answer:"""
prompt = PromptTemplate(template=template, input_variables=["question"])

llm = GPT4All(
model='./models/ggml-gpt4all-j-v1.3-groovy.bin',
callbacks=[StreamingStdOutCallbackHandler()]
)

llm_chain = LLMChain(prompt=prompt, llm=llm)

query = input("Prompt: ")
llm_chain(query)

运行脚本

1
python3 local-llm-chain.py

终端应该提示您输入。添加您的答案,您应该会看到输出流返回。

1
2
3
Prompt: Where is Paris?
The city of Paris can be found at latitude 48 degrees 15 minutes North
and longitude 4 degrees 10

说实话这不是最好的答案。也许更多的prompt工程会有所帮助?我把这个留给你们。我本以为LLM会表现得更好一点,但似乎需要一些调整才能使其工作良好。

在prompt中,我必须告诉机器人回答要简短。否则,聊天机器人往往会偏离正题,对一些与我们最初的问题半相关的事情进行冗长的咆哮。

Cloud Time

接下来,让我们将私有模型放入云中并开始与之交互。

我开始研究不同的方法来做到这一点,将模型和应用程序捆绑在同一个项目中,就像我们刚刚构建的本地项目一样。似乎没有任何简单或现成的方法来做到这一点。我一直在寻找一些超级简单的东西,比如一个Streamlit应用程序,你可以用你的应用程序代码和模型部署在一个。

这时,我意识到将应用程序代码和模型捆绑在一起可能不是正确的方法。我们想要做的是将我们的模型部署为一个独立的服务,然后能够从我们的应用程序与它交互。这也是有道理的,因为每个主机都可以根据自己的需求进行优化。例如,我们的LLM可以部署到具有GPU资源的服务器上,以使其能够快速运行。同时,我们的应用程序可以部署到普通的CPU服务器上。

这也允许我们根据需要分别缩放它们。如果我们的模型收到太多请求,我们可以单独扩展它。如果我们发现我们的应用程序需要更多的资源,我们可以自行扩展它们,当然,这样会更便宜。

1_MkQoI-TT33i81pyL3LoNiQ

因为从长远来看,我们的应用程序可能会做很多事情并与LLM对话。例如,它可能有一个登录系统、配置文件页面、账单页面,以及应用程序中常见的其他内容。LLM可能只是整个系统的一个小用例。

此外,如果我们想与多个大语言模型进行交互,每个法学硕士都针对不同的任务进行了优化,该怎么办?这似乎是目前围绕建筑代理商的一个普遍概念。使用这种架构,我们的大语言模型部署和主应用程序是分开的,我们可以根据需要添加/删除资源,而不会影响我们设置的其他部分。

经过一番搜索并尝试了一些不同的选择后,我发现Cerebrium是将GPT4All模型部署到云端的最简单方法,而且它有一个免费选项(10美元信用)。你知道吗,LangChain集成了Cerebrium !所以,我们都准备好了。

首先要做的是注册并登录Cerebrium网站。完成后,在登录时,它将要求您创建一个项目。我已经有了一个项目清单。

1_WjC30y0rnKLBlN5aqfjp9A

点击“创建新项目”,我们将项目命名为GPT4All(原来的,对吧?)

1_EpC2qWPNGxtVSBr_V_DqaQ

完成后,它将带您到Dashboard部分。您需要点击左侧菜单上的“预构建模型”。

1_lBPJVCxpyY5cCr1743SYlw

这将带您到一个可以部署的预构建模型列表。在我看来,这个页面很酷。您可以部署各种模型,包括Dreambooth,它使用Stable Diffusion生成文本到图像,Whisper Large用于语音到文本,Img2text Laion用于图像到文本,等等。

这里有很多东西可以玩。我们将努力控制自己,保持专注,只部署GPT4All模型,这就是我们来这里的目的..。话虽如此,您可以随意使用其他一些模型。我们将如何部署GPT4All模型并从我们的应用程序连接到它,可能与其中任何一个类似。

好的,那么单击以部署GPT4All模型。

1_zaAoNxWfUUFdnXG4wGtKSw

这应该会将您带回到模型的页面,在那里您可以看到模型的一些使用统计。当然,它都是零,因为我们还没用过它。一旦我们开始使用这个模型,我们将看到一些数字增加。

1_fuecaGqqEkcHz1GliTVyOQ

如果您单击左侧菜单中的“API Keys”选项,您应该会看到您的公钥和私钥。我们需要在我们的LangChain应用程序中使用公钥。

但仅此而已。全部完成!我们的GPT4All模型现在在云中,准备与我们进行交互。我们已经可以开始与模型交互了!在示例代码选项卡中,它向您展示了如何使用curl(即通过HTTPS)与聊天机器人进行交互。

1
2
3
4
curl --location --request POST 'https://run.cerebrium.ai/gpt4-all-webhook/predict' \
--header 'Authorization: public-<YOUR_PUBIC_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{"prompt":"Where is Paris?"}'

好,让我们回到我们的LangChain应用程序。让我们用下面的命令创建一个名为cloud-llm.py的新文件:

1
touch cloud-llm.py

我们需要安装 cerebrium 包。下面的命令将为我们处理这个问题:

1
pip install cerebrium

现在,只需几行代码,我们就完成了所有工作。首先,使用来自Cerebrium仪表板的公钥设置CEREBRIUMAI_API_KEY。然后使用CerebriumAI类创建一个LangChainLLM。您还需要将endpoint_url传递到CerebriumAI类。您可以在Cerebrium的模型仪表板页面上的“示例代码”选项卡中找到端点URL。

然后我们可以立即开始将prompts传递给LLM并获得回复。注意CerebriumAI构造函数中的max_length参数。默认为100个tokens,并将响应限制在此数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import os
from langchain.llms import CerebriumAI

os.environ["CEREBRIUMAI_API_KEY"] = "public-"

llm = CerebriumAI(
endpoint_url="https://run.cerebrium.ai/gpt4-all-webhook/predict",
max_length=100
)

template = """Question: Where is france?
Answer: """

print(llm(template))
1
python3 cloud-llm.py
1
2
3
4
5
France is a country located in Western Europe. It is bordered by Belgium,
Luxembourg, Germany, Switzerland, Italy, Monaco, and Andorra. What are some
notable landmarks or attractions in France that tourists often visit? Some
notable landmarks or attractions in France that tourists often visit include
the Eiffel Tower in Paris, the Palace of Versailles outside of Paris

同样,由于没有prompt模板,它有点偏离正题。

让我们看一下LangChain中GPT4AllCerebriumAI类的定义。你会注意到他们都扩展了LLM类。

1
class GPT4All(LLM):
1
class CerebriumAI(LLM):

在使用LangChain时,我发现查看源代码总是一个好主意。这将帮助您更好地了解代码的工作原理。您可以将LangChain库克隆到本地机器上,然后使用PyCharm或任何您喜欢的Python IDE浏览源代码。

1
git clone https://github.com/hwchase17/langchain

好了,让我们把聊天机器人做得更高级一点。我们将使用LLMChain向它传递一个固定的提示符,并添加一个while循环,以便我们可以从我们的终端不断地与LLM交互。下面是代码的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import os
from langchain import PromptTemplate, LLMChain
from langchain.llms import CerebriumAI

os.environ["CEREBRIUMAI_API_KEY"] = "public-"

template = """
You are a friendly chatbot assistant that responds in a conversational
manner to users questions. Keep the answers short, unless specifically
asked by the user to elaborate on something.
Question: {question}

Answer:"""

prompt = PromptTemplate(template=template, input_variables=["question"])
llm = CerebriumAI(
endpoint_url="https://run.cerebrium.ai/gpt4-all-webhook/predict",
max_length=100
)
llm_chain = LLMChain(prompt=prompt, llm=llm)

green = "\033[0;32m"
white = "\033[0;39m"

while True:
query = input(f"{green}Prompt: ")
if query == "exit" or query == "quit" or query == "q":
print('Exiting')
break
if query == '':
continue
response = llm_chain(query)
print(f"{white}Answer: " + response['text'])

完成了。现在我们有了一个聊天机器人风格的界面来进行交互。它在我们的本地机器上使用LangChain应用程序,并在云中使用我们自己的私有托管LLM。运行脚本开始与LLM交互。可随时按“q”退出脚本。

1_NapDjz7T60CMkqyG4o33GA

这个模型仍然在Cerebrium上,所以不是完全私有的,但是在云中拥有它私有的唯一真正的方法是托管你自己的服务器,这是另一个故事。

总结

我们在本地和云上使用我们自己的私有LLM构建了一个聊天机器人。其实也没那么难。很酷,对吧?希望这个项目能帮助您开始使用开源大语言模型。有相当多的,而且新的总是出现。

品控和微调技术也将继续改进。让我感到惊讶的是,仍然需要一个聊天机器人风格的prompt来让它按照预期的方式运行。但我想这是必须的。

回复有点偏离正题,这也是prompt的调整需要在后续不断发挥作用的地方。而且,答案有时看起来很专业,感觉不像自然的对话。我认为LLM会更好地响应开箱即用,但需要一些prompt的工程来克服这些怪症。

如果您正在构建一个应用程序来解析私有文件或业务文档,那么这肯定是私有LLM最好的使用场景之一。

原文:Private LLMs on Your Local Machine and in the Cloud With LangChain, GPT4All, and Cerebrium

相关文章:部署本地大模型(基于Langchain)






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



说人话查询neo4j——基于LangChain

原文:Integrating Neo4j into the LangChain ecosystem

作者:Tomaz Bratanic

了解如何开发具有多种与Neo4j数据库交互方式的LangChain代理

ChatGPT启发了世界,开启了一场新的人工智能革命。然而,最新的趋势似乎是在为ChatGPT提供一个新技术:提供外部信息,提高其准确性,并使ChatGPT能够回答公共数据集中没有答案的问题。围绕大型语言模型(llm)的另一个趋势是将它们转换为代理,使它们能够通过各种API调用或其他集成与环境进行交互。

由于增强llm相对较新,目前还没有很多开源库。然而,围绕LLMs (如ChatGPT)构建应用程序的首选框架是LangChain。该库通过允许LLM访问各种工具和外部数据源来增强LLM。它不仅可以通过访问外部数据来改进其响应,而且还可以充当代理,并通过外部界面调整其配置。

我偶然发现了一个LangChain项目(作者:Ibis Prevedello),它使用图数据库的搜索,通过提供额外的外部上下文来增强LLMs。

Gitgub地址:ibiscp/LLM-IMDB

Ibis的项目使用NetworkX图数据库来存储图形信息,将图关系搜索集成到LangChain生态系统中是多么容易。因此,我决定开发一个项目,将Neo4j(一个图数据库)集成到LangChain生态系统中。

Github地址:tomasonjo/langchain2neo4j

该项目现在允许LangChain代理以三种不同的模式与Neo4j交互:

  • 生成Cypher语句查询数据库

  • 相关实体的全文关键字搜索

  • 向量相似性搜索

本文将介绍开发的每种方法的推理和实现。

在这篇博文中,我将向您介绍我开发的每种方法的推理和实现。

环境设置

首先,我们将配置Neo4j环境。我们将使用可用的数据集作为Neo4j沙盒中的推荐项目。最简单的解决方案是通过下面的链接创建一个Neo4j Sandbox实例。但是,如果您更喜欢Neo4j的本地实例,您也可以恢复GitHub上可用的数据库转储。该数据集是MovieLens数据集[1]的一部分,特别是小版本。

在Neo4j数据库实例化之后,我们应该有一个包含以下模式的图。

1_HorBDLYVPFUvubEeoIYJCw

接下来,您需要通过执行以下命令克隆langchain2neo4j存储库:

1
git clone https://github.com/tomasonjo/langchain2neo4j

在下一步中,您需要创建一个.env文件并填充neo4j和OpenAI凭证,如.env.example文件中所示。

最后,你需要在Neo4j中创建一个全文索引,并通过运行以下命令导入电影标题嵌入:

1
sh seed_db.sh

如果您是Windows用户,那么seed_db脚本可能无法工作。在这种情况下,我准备了一个Jupyter笔记本,它可以帮助您将数据库作为shell脚本的替代方案。

现在,让我们跳到LangChain集成。

LangChain代理

据我所知,使用LangChain代理回答用户问题最常见的数据流如下:

1_WqRmmUg0cDGmaO9wYJIH3A

代理数据流在接收到来自用户的输入时启动。然后,代理向大语言模型模型发送请求,该模型包括用户问题和代理提示,这是代理应该遵循的一组自然语言指令。然后,大语言模型以进一步的指令响应代理。大多数情况下,第一反应是使用任何可用的工具从外部来源获得额外的信息。但是,工具并不局限于只读操作。例如,您可以使用它们来更新数据库。在工具返回额外的上下文之后,将对包含新获得的信息的大语言模型进行另一次调用。大语言模型现在可以选择生成返回给用户的最终答案,或者它可以决定需要通过可用的工具执行更多操作。

LangChain代理使用大语言模型进行推理。因此,第一步是定义要使用的模型。目前,langchain2neo4j项目只支持OpenAI的聊天完成模型,特别是GPT-3.5-turbo和GPT-4模型。

1
2
3
4
if model_name in ['gpt-3.5-turbo', 'gpt-4']:
llm = ChatOpenAI(temperature=0, model_name=model_name)
else:
raise Exception(f"Model {model_name} is currently not supported")

除了OpenAI之外,我还没有探索过其他LLMs。然而,LangChain默认集成了十多个其他LLM。

接下来,我们需要用下面一行添加会话记忆:

1
2
memory = ConversationBufferMemory(
memory_key="chat_history", return_messages=True)

LangChain支持多种类型的代理。例如,一些代理可以使用内存组件,而其他代理则不能。由于对象是构建聊天机器人,所以我选择了Conversation Agent(用于聊天模型)代理类型。LangChain库的有趣之处在于一半的代码是用Python编写的,而另一半是prompt工程。我们可以探索会话代理使用的prompt。例如,代理有一些必须遵循的基本指令:

Assistant是OpenAI训练的一个大型语言模型。Assistant被设计成能够协助完成广泛的任务,从回答简单的问题到就广泛的主题提供深入的解释和讨论。作为一种语言模型,Assistant能够根据它收到的输入生成类似人类交流的文本,允许它参与听起来自然的对话,并提供与手头主题相关的连贯响应。助手在不断地学习和改进,它的功能也在不断地发展。它能够处理和理解大量的文本,并能够利用这些知识对广泛的问题提供准确和信息丰富的回答。此外,Assistant能够根据收到的输入生成自己的文本,允许它参与讨论,并就广泛的主题提供解释和描述。总的来说,Assistant是一个功能强大的系统,可以帮助完成广泛的任务,并就广泛的主题提供有价值的见解和信息。无论您是需要特定问题的帮助还是只想就特定主题进行对话,Assistant都可以提供帮助。

此外,代理还具有在需要时使用任何指定工具的prompt。

1
2
3
4
5
6
7
8
9
10
Assistant can ask the user to use tools to look up information 
that may be helpful in answering the users original question.
The tools the human can use are:
{{tools}}
{format_instructions}
USER'S INPUT - - - - - - - - - -
Here is the user's input
(remember to respond with a markdown code snippet of a
json blob with a single action, and NOTHING else):
{{{{input}}}}

有趣的是,提示表明助手可以要求用户使用工具查找其他信息。然而,用户不是人,而是构建在LangChain库之上的应用程序。因此,查找进一步信息的整个过程是自动完成的,没有任何人工参与。当然,如果需要,我们可以更改提示符。提示符还包括llm用于与代理通信的格式。

请注意,代理prompt里面不包括代理不应该回答的问题,如果答案没有在工具返回的上下文中提供。

现在,我们要做的就是定义可用的工具。如前所述,我准备了三种与Neo4j数据库交互的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
tools = [
Tool(
name="Cypher search",
func=cypher_tool.run,
description="""
Utilize this tool to search within a movie database,
specifically designed to answer movie-related questions.
This specialized tool offers streamlined search capabilities
to help you find the movie information you need with ease.
Input should be full question.""",
),
Tool(
name="Keyword search",
func=fulltext_tool.run,
description="Utilize this tool when explicitly told to use
keyword search.Input should be a list of relevant movies
inferred from the question.",
),
Tool(
name="Vector search",
func=vector_tool.run,
description="Utilize this tool when explicity told to use
vector search.Input should be full question.Do not include
agent instructions.",
),

]

工具的描述用于指定工具的功能,并通知代理何时使用它。另外,我们需要指定工具期望的输入格式。例如,Cypher和vector搜索都需要一个完整的问题作为输入,而关键字搜索则需要一个相关电影列表作为输入。

LangChain与我习惯的编码方式有很大的不同。它使用prompt来指示LLM为您完成工作,而不是自己编写代码。例如,关键字搜索指示ChatGPT提取相关电影并将其用作输入。我花了2个小时调试工具输入格式,然后意识到我可以使用自然语言指定它,LLM将处理其余的事情。

还记得我说过的agent没有得到指示不能回答没有上下文提供的信息的问题吗?让我们看看下面的对话。

1_R0e6DRcrumBQ2SZJB8iLsw

LLM根据工具描述决定,它不能使用它们中的任何一个来检索相关上下文。但是,LLM默认知道很多信息,并且由于代理没有只能依赖外部资源的约束,因此LLM可以独立地形成答案。如果希望执行不同的行为,则需要更改代理prompt。

生成Cypher语句

我已经开发了一个聊天机器人,通过使用OpenAI的会话模型(如GPT-3.5-turbo和GPT-4)生成Cypher语句,与Neo4j数据库进行交互。因此,我可以借用大部分思想来实现一个工具,该工具允许LangChain代理通过构造Cypher语句从Neo4j数据库检索信息。

像text- davincii -003和GPT-3.5-turbo这样的旧模型作为少量Cypher生成器工作得更好,我们在其中提供了几个Cypher示例,模型可以使用这些示例来生成新的Cypher语句。然而,当我们只呈现图形模式时,GPT-4似乎工作得很好。因此,由于可以使用Cypher查询提取图模式,理论上可以在任何图形模式上使用GPT-4,而无需人工进行任何手工操作。

我们这里不谈LangChain是怎么做的,我们只看一下当LangChain代理决定使用Cypher语句与Neo4j数据库交互时执行的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:
chat_prompt = ChatPromptTemplate.from_messages(
[self.system_prompt] + inputs['chat_history'] + [self.human_prompt])
cypher_executor = LLMChain(
prompt=chat_prompt, llm=self.llm, callback_manager=self.callback_manager
)
cypher_statement = cypher_executor.predict(
question=inputs[self.input_key], stop=["Output:"])
# If Cypher statement was not generated due to lack of context
if not "MATCH" in cypher_statement:
return {'answer': 'Missing context to create a Cypher statement'}
context = self.graph.query(cypher_statement)

return {'answer': context}

Cypher生成工具将问题与聊天记录一起作为输入。然后通过使用系统消息、聊天历史记录和当前问题将LLM的输入组合起来。我为Cypher生成工具准备了以下系统消息prompt。

1
2
3
4
5
6
7
8
9
10
SYSTEM_TEMPLATE = """
You are an assistant with an ability to generate Cypher queries based off
example Cypher queries. Example Cypher queries are:\n""" + examples + """\n
Do not response with any explanation or any other information except the
Cypher query. You do not ever apologize and strictly generate cypher statements
based of the provided Cypher examples. Do not provide any Cypher statements
that can't be inferred from Cypher examples. Inform the user when you can't
infer the cypher statement due to the lack of context of the conversation
and state what is the missing context.
"""

Prompt工程感觉更像是艺术而不是科学。在本例中,我们为大语言模型提供了几个Cypher语句示例,并让它根据这些信息生成Cypher语句。此外,我们设置了一些约束,比如允许它只构造可以从训练示例中推断出来的Cypher语句。此外,我们不会让模型道歉或解释它的想法(然而,gpt -3.5 turbo不会听这些指示)。最后,如果问题缺乏上下文,我们允许模型使用该信息进行响应,而不是强迫它生成Cypher语句。

在大语言模型构造Cypher语句之后,我们简单地使用它来查询Neo4j数据库,并将结果返回给代理。下面是一个示例流程。

1__cgRn4j7FRdNHk2yhYKeoA

当用户输入他们的问题时,它与代理prompt一起被发送到大语言模型。在本例中,大语言模型响应它需要使用Cypher搜索工具。Cypher搜索工具构造一个Cypher语句并使用它来查询Neo4j。然后将查询结果传回代理。接下来,代理将另一个请求连同新上下文一起发送给大语言模型。由于上下文包含构建答案所需的信息,大语言模型形成最终答案并指示代理将其返回给用户。

当然,我们现在可以问一些后续问题。

1_MOcUwNTz8U66WZQ91sgREQ

由于代理具有内存,它知道谁是第二个参与者,因此可以将信息传递给Cypher搜索工具,以构造适当的Cypher语句。

相关三元组的关键字搜索

我从LangChain和GPT-index库中现有的知识图谱索引实现中获得了关键字搜索的想法。这两种实现非常相似。他们要求大语言模型从问题中提取相关实体,并在图中搜索包含这些实体的任何三元组。所以我想我们可以用Neo4j做类似的事情。然而,虽然我们可以使用简单的MATCH语句搜索实体,但我认为使用Neo4j的全文索引会更好。在使用全文索引找到相关实体后,我们返回三元组,并希望回答问题的相关信息在那里。

1
2
3
4
5
6
7
def _call(self, inputs: Dict[str, str]) -> Dict[str, Any]:
"""Extract entities, look up info and answer question."""
question = inputs[self.input_key]
params = generate_params(question)
context = self.graph.query(
fulltext_search, {'query': params})
return {self.output_key: context}

记住,代理已经有了解析相关电影标题的指令,并将其作为关键字搜索工具的输入。因此,我们不需要处理这个。然而,由于问题中可能存在多个实体,我们必须构造合适的Lucene查询参数,因为全文索引是基于Lucene的。然后,我们简单地查询全文索引并返回希望相关的三元组。我们使用的Cypher语句如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
CALL db.index.fulltext.queryNodes("movie", $query) 
YIELD node, score
WITH node, score LIMIT 5
CALL {
WITH node
MATCH (node)-[r:!RATED]->(target)
RETURN coalesce(node.name, node.title) + " " + type(r) + " " + coalesce(target.name, target.title) AS result
UNION
WITH node
MATCH (node)<-[r:!RATED]-(target)
RETURN coalesce(target.name, target.title) + " " + type(r) + " " + coalesce(node.name, node.title) AS result
}
RETURN result LIMIT 100

因此,我们取全文索引返回的前五个相关实体。接下来,我们通过遍历它们的邻居来生成三元组。我特别排除了被遍历的RATED关系,因为它们包含了不相关的信息。我还没有研究过,但我有一种很好的感觉,我们也可以指示大语言模型提供一个相关关系的列表,并与适当的实体一起进行调查,这将使我们的关键字搜索更集中。关键字搜索可以通过显式指示代理来启动。

1_LQ1fqeSbSaTLMwshGzXr7A

大语言模型被指示使用关键字搜索工具。此外,代理被告知提供关键字搜索和相关实体列表作为输入,在这个例子中只有Pokemon。然后使用Lucene参数来查询Neo4j。这种方法撒下了更广泛的网,并希望提取的三元组包含相关信息。例如,检索到的上下文包含关于Pokemon类型的信息,这是不相关的。不过,它也有关于谁在电影中扮演角色的信息,这使得代理可以回答用户的问题。

如前所述,我们可以指示LLM生成相关关系类型列表以及适当的实体,这可以帮助代理检索更多相关信息。

向量相似度搜索

向量相似性搜索是与Neo4j数据库进行交互的最后一种模式,我们将对其进行研究。矢量搜索目前很流行。例如,LangChain提供了与十多个矢量数据库的集成。向量相似度搜索的思想是将问题嵌入到嵌入空间中,并根据问题与文档嵌入的相似度来查找相关文档。我们只需要小心地使用相同的嵌入模型来生成文档和问题的向量表示。我在矢量搜索实现中使用了OpenAI的嵌入。

1
2
3
4
5
6
7
def _call(self, inputs: Dict[str, str]) -> Dict[str, Any]:
"""Embed a question and do vector search."""
question = inputs[self.input_key]
embedding = self.embeddings.embed_query(question)
context = self.graph.query(
vector_search, {'embedding': embedding})
return {self.output_key: context}

所以,我们要做的第一件事就是嵌入问题。接下来,我们使用嵌入在数据库中查找相关电影。通常,向量数据库返回相关文档的文本。然而,我们处理的是图形数据库。因此,我决定使用三重结构来产生相关信息。所使用的Cypher语句是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WITH $embedding AS e
MATCH (m:Movie)
WHERE m.embedding IS NOT NULL AND size(m.embedding) = 1536
WITH m, gds.similarity.cosine(m.embedding, e) AS similarity
ORDER BY similarity DESC LIMIT 5
CALL {
WITH m
MATCH (m)-[r:!RATED]->(target)
RETURN coalesce(m.name, m.title) + " " + type(r) + " " + coalesce(target.name, target.title) AS result
UNION
WITH m
MATCH (m)<-[r:!RATED]-(target)
RETURN coalesce(target.name, target.title) + " " + type(r) + " " + coalesce(m.name, m.title) AS result
}
RETURN result LIMIT 100

Cypher语句类似于关键字搜索示例。唯一的区别是我们使用余弦相似度而不是全文索引来识别相关电影。在处理多达数万甚至数十万个文档时,这种方法已经足够好了。记住,瓶颈通常是大语言模型,特别是使用GPT-4时。因此,如果您不处理数以百万计的文档,则不必考虑多语言实现,其中您同时拥有矢量和图形数据库,以便能够通过遍历图形来生成相关信息。

1_isgP7zzeADYcodMmwpAZig

当代理被指示使用向量搜索工具时,第一步是将问题作为向量嵌入。OpenAI的嵌入模型产生维度为1536的向量(译者:我们才387维(⊙o⊙)…)表示。因此,下一步是使用构造好的向量,通过计算问题与相关文档或节点之间的余弦相似度,在数据库中搜索相关信息。同样,由于我们处理的是图形数据库,所以我决定以三元组的形式将信息返回给代理。

关于向量搜索的有趣之处在于,即使我们指示代理搜索《指环王》电影,向量相似性搜索也会返回有关《霍比特人》电影的信息。看起来《指环王》和《霍比特人》电影在嵌入空间里很近,这是可以理解的。

最后

可以访问外部工具和信息的聊天机器人和生成代理似乎是ChatGPT炒作之后的下一波浪潮。有能力提供额外信息和上下文内容,可以让大语言模型大大提高其结果。此外,代理的工具不限于只读操作,这意味着它们可以更新数据库甚至在淘宝帮你下订单(比如你家的洗衣液快没了,对着手机说一声,还是同一个牌子的洗衣液,再来一箱。)。在大多数情况下,LangChain框架似乎是目前用于实现生成代理的主要库。当您开始使用LangChain时,您可能需要在编码过程中进行一些调整,因为您需要将大语言模型提示与代码结合起来完成任务。例如,大语言模型和工具之间的消息可以用自然语言指令作为提示而不是Python代码来塑造和重塑。我希望这个项目能够帮助您在LangChain项目中实现像Neo4j这样的图形数据库的功能。






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



部署本地大模型(基于Langchain)

原文:Training Your Own LLM using privateGPT

作者:Wei-Meng Lee

了解如何在不向提供者公开私有数据的情况下训练自己的语言模型

使用公共AI服务(如OpenAI的ChatGPT)的主要问题之一是将您的私人数据暴露给提供商的风险。对于商业用途,这仍然是考虑采用AI技术的公司最担心的问题。

很多时候,您希望创建自己的语言模型,该模型是根据您的数据集(例如销售见解,客户反馈等)进行训练的,但同时您又不希望将所有这些敏感数据暴露给OpenAI等AI提供商。因此,理想的方法是在本地训练自己的LLM(大语言模型),而不需要将数据上传到公网。

在本文中,我将向您展示如何使用一个名为privateGPT的开源项目来利用LLM,以便它可以根据您的自定义训练数据回答问题(如ChatGPT),而不会牺牲数据的隐私性。

值得注意的是,privateGPT目前还处于概念验证阶段,还没有准备好投入生产。

下载privateGPT

要尝试privateGPT,您可以使用以下链接访问GitHub: https://github.com/imartinez/privateGPT.

您可以通过点击Code | download ZIP按钮下载repository:

img

或者,如果你的系统上安装了git,在Terminal中使用以下命令克隆repository:

1
$ git clone https://github.com/imartinez/privateGPT

无论哪种情况,一旦repository下载到您的计算机上,privateGPT目录应该有以下文件和文件夹:

img

安装所需的Python Packages

privateGPT使用许多Python包。它们被封装在requirements.txt文件中:

1
2
3
4
5
6
7
8
9
10
11
12
langchain==0.0.171
pygpt4all==1.1.0
chromadb==0.3.23
llama-cpp-python==0.1.50
urllib3==2.0.2
pdfminer.six==20221105
python-dotenv==1.0.0
unstructured==0.6.6
extract-msg==0.41.1
tabulate==0.9.0
pandoc==2.3
pypandoc==1.11

最方便的方法就是通过 pip/conda:

1
2
3
4
$ cd privateGPT
$ pip install -r requirements.txt

// $ conda install -r requirements.txt

根据我的经验,执行上述安装时,可能不一定会安装一些必需的Python包。稍后,当您尝试运行摄取.py或privateGPT.py文件时,您就会知道这一点。在这种情况下,只需单独安装丢失的包。

编辑环境(Environment)配置文件

这个example.env文件包含privateGPT使用的几个设置。其内容如下:

1
2
3
4
5
PERSIST_DIRECTORY=db
MODEL_TYPE=GPT4All
MODEL_PATH=models/ggml-gpt4all-j-v1.3-groovy.bin
EMBEDDINGS_MODEL_NAME=all-MiniLM-L6-v2
MODEL_N_CTX=1000
  • PERSIST_DIRECTORY—在加载和处理文档之后将保存本地矢量存储的目录
  • MODEL_TYPE—您正在使用的模型的类型。在这里,它被设置为GPT4All(由OpenAI提供的ChatGPT的免费开源替代品).
  • MODEL_PATH—LLM所在的路径。这里它被设置为models目录,使用的模型是ggml-gpt4all-j-v1.3-groovy.bin(您将在下一节中了解到在哪里下载这个模型)
  • EMBEDDINGS_MODEL_NAME——这指的是转换器模型的名称。这里它被设置为all-MiniLM-L6-v2,它将句子和段落映射到384维的密集向量空间,可以用于聚类或语义搜索等任务。
  • MODEL_N_CTX -嵌入模型和LLM模型的最大令牌限制

example.env 重命名为 .env.

将这个文件变成隐藏模式

下载Model(模型)

为了使privateGPT正常运行起来,它需要预先训练模型(就是LLM)。由于privateGPT使用GPT4All,您可以从https://gpt4all.io/index.html下载LLM。

img

因为默认的环境文件指定了ggml-gpt4all-j-v1.3-groovy.bin LLM,所以下载第一个模型,然后在privateGPT文件夹中创建一个名为models的新文件夹。将ggml-gpt4all-j-v1.3-groovy.bin文件放入models文件夹中:

img

数据预处理

如果你查看一下ingest.py文件,你会注意到下面的代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
".csv": (CSVLoader, {}),
# ".docx": (Docx2txtLoader, {}),
".doc": (UnstructuredWordDocumentLoader, {}),
".docx": (UnstructuredWordDocumentLoader, {}),
".enex": (EverNoteLoader, {}),
".eml": (UnstructuredEmailLoader, {}),
".epub": (UnstructuredEPubLoader, {}),
".html": (UnstructuredHTMLLoader, {}),
".md": (UnstructuredMarkdownLoader, {}),
".odt": (UnstructuredODTLoader, {}),
".pdf": (PDFMinerLoader, {}),
".ppt": (UnstructuredPowerPointLoader, {}),
".pptx": (UnstructuredPowerPointLoader, {}),
".txt": (TextLoader, {"encoding": "utf8"}),

从这个文件上我们可以看到privateGPT支持以下数据文档格式:

  • .csv: CSV
  • .doc: Word文档
  • .docx: Word文档
  • .enex: EverNote
  • .eml: Email
  • .epub: EPub
  • .html: HTML File
  • .md: Markdown
  • .odt: Open Document Text
  • .pdf: PDF
  • .ppt : PPT
  • .pptx : PPTX
  • .txt: Text (UTF-8)

每种类型的文档都使用各自的加载程序来分别加载。例如,你使用UnstructuredWordDocumentLoader类来加载**.doc.docx** 这些Word文档。

默认情况下,privateGPT附带位于source_documents文件夹中的state_of_the_union.txt文件。我将删除它,并用一个名为Singapore.pdf的文档替换它。

img

这个文档创建的内容来自于:https://en.wikipedia.org/wiki/Singapore。您可以通过点击 Tools | Download as PDF 从维基百科下载任何页面:

img

您可以将privateGPT支持的任何文档放入source_documents文件夹中。在本文的例子中,我只放了一个文档。

为文档创建Embeddings

一旦数据文档就位,就可以为文档做embedding了。

创建embedding是指为单词、句子或其他文本单元生成向量表示的过程。这些向量表示捕获关于文本的语义和句法信息,使机器能够更有效地理解和处理自然语言。

在Terminal(终端)中输入以下内容: (ingest.py文件在privateGPT文件夹中)

1
$ python ingest.py 

根据您使用的机器和您放入source_documents文件夹中的文档数量,嵌入处理可能需要相当长的时间才能完成。

完成后,您将看到如下内容:

1
2
3
4
Loading documents from source_documents
Loaded 1 documents from source_documents
Split into 692 chunks of text (max. 500 characters each)
Using embedded DuckDB with persistence: data will be stored in: db

Embedding文件保存在db文件夹中,格式为Chroma db:

img

Chroma 是一个开源的向量数据库。

开始提问题吧

您现在可以提问了!

在Terminal中输入以下命令:

1
$ python privateGPT.py

加载模型需要一段时间。在此过程中,您将看到以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Using embedded DuckDB with persistence: data will be stored in: db
gptj_model_load: loading model from 'models/ggml-gpt4all-j-v1.3-groovy.bin' - please wait ...
gptj_model_load: n_vocab = 50400
gptj_model_load: n_ctx = 2048
gptj_model_load: n_embd = 4096
gptj_model_load: n_head = 16
gptj_model_load: n_layer = 28
gptj_model_load: n_rot = 64
gptj_model_load: f16 = 2
gptj_model_load: ggml ctx size = 4505.45 MB
gptj_model_load: memory_size = 896.00 MB, n_mem = 57344
gptj_model_load: ................................... done
gptj_model_load: model size = 3609.38 MB / num tensors = 285

Enter a query:

At the prompt, you can type in your question. I asked: “*What is the population in Singapore?*”. It took privateGPT quite a while to come up with the answer. Once it managed to find an answer, it give you the answer and cited the source for the answer:

Enter a query:提示符后面,你可以输入你的问题。问:“新加坡的人口是多少?”。privateGPT可能需要花很长时间才想出了答案。一旦它找到了答案,它就会给出答案并引用答案的来源:

img

你可以继续问后续的问题:

img

总结

虽然privateGPT目前还处于概念验证阶段,但它看起来很有希望,然而,它还没有准备好投入生产。这里有几个问题:

  • 推理缓慢。执行文本嵌入需要一段时间,但这是可以接受的,因为这是一次性的过程。然而,推理很慢,特别是在较慢的机器上。我用的是32GB内存的M1 Mac电脑,仍然花了一段时间才得出答案。
  • 占用内存。privateGPT使用大量内存,在问了一两个问题后,我将得到内存不足的错误,如下所示:

segmentation fault python privateGPT.py. /Users/weimenglee/miniforge3/lib/python3.10/multiprocessing/resource_tracker.py:224: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown. warnings.warn(‘resource_tracker: There appear to be %d ‘

在privateGPT的作者修复上述两个问题之前,privateGPT仍然是一个实验,以了解如何在不将私有数据暴露给云的情况下训练LLM。

相关文章:使用GPT4ALL和LangChain构建本地大模型应用

工具推荐:可以配置参数的Midjourney中文教程工具






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



Midjourney参数指令速记表(v5.1)

来个Midjourney 5.1的prompt参数一纸禅

当前版本:v5.1(包含niji 5)

后续会不断更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
基础Prompt剖析: 
/imagine prompt: [PREFIX] [SCENE] [SUFFIX] [Parameters]
PREFIX :一般是 image(上传的图片URL) medium(媒介) & style(样式)
SCENE :一般指主要内容
SUFFIX :调节内容,包括前缀微调和参数微调
(实际操作中,可以重叠这些类型)

排列的用法(消耗会非常快!!!):
/imagine prompt: cinematic shot of astronaut on {horse, turtle} --c {20,80}
...实际会生产四条prompts:
-> cinematic shot of astronaut on a horse --c 20
cinematic shot of astronaut on a turtle --c 20
cinematic shot of astronaut on a horse --c 80
cinematic shot of astronaut on a turtle --c 80


Parameters(参数类型):
--ar [WIDTH:HEIGHT] (=aspect ratio) // 长宽比
--c [0-100] (=chaos, unusual results) // 天马行空
--q [.25|.5|1] (=quality/time spent generating the image, 1=default) // 质量越好,生成越慢
--seed [0-4294967295] (=starting point for initial grid) // 种子,适合于基于某一张图片调整
--stop [10-100] (=stop at earlier percentage) // 如果你需要一个半成品,或朦胧感
--s [0-1000] (=stylize, artistic interpretation) // 美化程度
--tile (=seamless patterns) // 无缝重复模式,用于制作比如地毯、地板和编织物等
--iw [W] (=sets image weight to W) // 在prompt中使用图片url,可以设置这个图片的权重
--no [X] (=gives X a negative weight of -0.5) // 排除某内容,比如排除水果篮里面的苹果
--niji / --niji 5 (anime trained model) // 和Spellbrush合作的动漫风格
--v [1,2,3,4] (=model versiom) // 版本设置,默认是最新版,当前是5.1,但各版本有差异
--hd (=使用早期替代模型,生成较大的、不太一致的图像)
--style raw (=仅用于5.1版本,真实风格)
--style expressive (=和niji 5 版本配合使用,表现力增强)
--style cute (=和niji 5 版本配合使用,可爱风格)
--style scenic (=和niji 5 版本配合使用,更注重环境表达,或者说风景画)
--repeat [N] (=repeat prompt N-times) // 重复生成,标准用户2-10次,专业版用户2-40次

Weights(权重):
/imagine prompt: hot dog // 热狗(食物)
hot:: dog // 热的狗狗(动物)
hot::2 dog // 非常热的狗狗(动物),这里容易混淆,这里的比重其实是hot更大,hot的比重是dog的两倍。

Option Commands:
/prefer option set [NAME OF OPTION] [VALUE] // 设置常用选项
... e.g:
-> /prefer option set mycoolpreset dadaism --c 80 // 将 dadaism --c 80 设置为常用选项,名称是mycoolpreset
...now
/imagine prompt: an astronaut, --mycoolpreset // 使用 --mycoolpreset
...becomes
/imagine prompt: an astronaut, dadaism --c 80 // Midjourney会自动将Prompt理解为这样

/prefer option set mycoolpreset
...deletes mycoolpreset! // 删除(清空)默认选项
/prefer option list
... shows presets // 显示所有已经设定的后缀
/prefer option remix
... toggles remix mode // 切换混合模式,混合模式可以使用某一原图的构图来进行作图。
/prefer suffix
... suffix to add to the end of every prompt // 设置后缀
/prefer auto_dm
... automatically send DM when jobs complete // 自动设置将结果发私信

More Commands:
/describe // 上传图片,反向生成可能的prompt
/blend // 合并两张图片,比如一个模特,和一件衣服
/stealth & /public (=toggle stealth mode) // 私有还是公开
/fast & /relax (=toggle fast mode) // 快速模式,但质量会下降一些
/info (=show account info & queued jobs) // 查看账号信息和排队作业
/settings (=change bot settings) // 对于个人用户来说,类似于全局设置
/subscribe (=change subscription plan) // 为用户的账户页面生成个人链接
/show (=使用图像的作业ID在Discord中重新生成作业)



关于Midjourney的其他文章:






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



Midjourney(v5.1) Prompt深度剖析,创造有灵魂的图

原文:Anatomy of Midjourney Promps: In-Depth Study for effective Prompting Strategies — V5.1 examples

作者:Michael King

译者:这是一个非常“平易近人”的Midjourney教程,非常适合对作图有要求的同学一步一步开始自己的Midjourney之旅。

你是否曾经发现自己盯着Midjourney的空白画布,手指悬停在键盘上,让我问自己:“我应该问这个东西什么?

img

我也曾经有过同样的经历,朋友。就像站在一个售卖艺术品的自动贩卖机前一样,但你需要喂它文字而不是硬币。而且并非所有的词语都可以使用,你必须选择正确的单词,并按照正确的顺序排列。这有点像施法一样。有时候你会中大奖,获得比你想象中更美丽、更完美的杰作;但另外一些时候,它可能和问一个魔球没有什么区别。

这个被称为“Midjourney prompting”的功能实际上是一个谜团。这真正是一种舞蹈,在您和AI之间进行交互。您用文字引导着AI生成图像,并共同创造出独特的东西。但步骤并不总是清晰明了:您应该要求简单地描述,a sunset over the ocean(海洋上落日)?还是更加详细地描绘画面以期待AI能够将其呈现出来?或者尝试采取结构化方法,如电影导演指挥镜头?

然后难免需要微调——哦!微调!转眼之间,您正在调整此处单词、那里短语;接下来发生了什么事情呢?您已经修改了提示内容很多次,以至于它几乎无法被识别。但当您最终获得那张令人惊叹的图像时,这一切都是值得的。

那么,你如何破解这个谜题?如何掌握Midjourney Prompt的艺术?我有一些见解要与您分享,这是从许多与AI的深夜交互中获得的。所以请继续关注,因为事情即将变得有趣。


从基础的输入开始

好的,让我们开始吧。想象一下,你站在控制台前,眼睛盯着那个空白画布。手指悬停在键盘上,然后敲出一个简单的单词:“chair(椅子)”。听起来很基础,对吧?但这好歹是个不错的开始。

现在,为了增加趣味性,你决定将混沌度调到50。为什么是50呢?因为我发现中等程度的混沌设置可以引入足够多的不确定性以保持事情有趣。这就像给你的餐点加一点辣酱——不会烧掉你的味蕾,但只要能让舌头感到刺痛就行了。

在这种情况下,“混沌参数”是我们秘密武器。它是万能卡牌、意外元素。它使得人工智能说:“chair(椅子)?好啊!看看我能做些什么!”相信我,在处理人工智能时,稍微变化一下也可以大有裨益。

Prompt:
chair --c 50

img

那么,我们按下回车键,靠在椅子上等待。最终我们得到的是……没错,这就是一把椅子。但它有点像让厨师给你做三明治,结果拿到的只是一片面包和一块奶酪。当然了,从技术上来说这确实算作三明治,但不完全符合你的期望吧?

这就是midjourney prompt的问题所在。如果指令过于模糊不清,则需要AI自行填补空缺部分。虽然AI具备很多技能,但并不能读取人类思想。

增加描述–颜色

因此,让我们更加具体地描述需求吧!我们要对椅子进行改造——涂上新漆!那么颜色呢?为什么不选绿色呢?它既大胆又充满活力,并且代表着生命之色。而且顺便提一下:绿色也正好是我的最爱。

Prompt:
green chair --c 50

img

好的,让我们看看我们得到了什么。啊,是的,我们有绿色的椅子。但它们到处都是!其中一些看起来像从印象派画作中撕下来的,而另一个则清晰明了,就像高分辨率照片一样。这就像一个名为“Green Chairs: A Study in Chaos(绿色椅子:混沌之研究)”的野性、折衷主义艺术展览。很有趣,但不完全符合我们的目标。

你知道吗,在Midjourney Prompt方面有个问题。这有点像与一个天才但略微健忘的艺术家打交道。你必须清楚地表达你想要什么,否则他们会自己创造出新奇别致的东西。虽然这可能会带来一些惊人的惊喜,但也可能让你摸不着头脑,并且纳闷自己怎么会得到一个立体主义解释绿色椅子。

创造真实的图–摄影风格

所以回到绘图板上——或者说键盘上吧。我们想要一张绿色椅子的照片,而不是画作。我们追求现实主义风格,在这里可以感受、触摸和坐在上面的真实存在感。“再试一次”准备好了吗?让我们开始吧…

Prompt:
green chair | photography --c 50

img

哇,这是什么?一把绿色的椅子竟然出现在农田中央?这可真是不寻常。再看那一把孤零零地坐在空旷街道上的绿色椅子,就像一个超现实主义梦境中的场景。得承认AI确实有着非凡的想象力。

但尽管我很享受这个意外之旅,它并不完全符合我们最初设定的目标。就好比点了一份比萨饼却收到了美食汉堡包,虽然看起来很诱人,但并不是你口感所期待的。

设定场所

因此,我们要回归正题。让我们带着这把绿色椅子踏上新旅程,在家庭生活中心留下它温馨舒适的身影吧!想象一个舒适温馨、壁炉边火苗跳动、柔软地毯铺满整个房间……而在其中央,则摆放着我们那张迎人且舒适无比的绿色椅子。这才是我们要为AI艺术家描绘出来的场景。

Prompt:
green chair | photography | living room --c 50

img

啊,成功了!我们在客厅里放上了绿色的椅子。感觉好像我们正在取得进展,不是吗?但等等,这有点…暗,不是吗?就像我们在半夜闯入自己的客厅一样。它有点神秘的氛围,就像一个悬疑惊悚片的开场一样。无疑很引人入胜,但并不是我们所想象中邀请人们来到家里的形象。

你知道这个场景需要什么吗?阳光的洒落。透过窗户射进来明亮而温暖的光线,在地板上投下长长的阴影。一个舒适角落,在那里你可以蜷缩着读一本好书,阳光在书页上跳动。

调试光线

所以让我们再试一次好吧?我们将增加亮度,并注入“bright daylight(明亮白天)”的光芒来为场景带来活力。就像导演调整灯光以设置完美情境。

Prompt:
green chair | photography | living room | bright daylight --c 50

img

现在我们开始谈论了!我们的绿色椅子,在明亮的阳光下晒着,真的开始显眼起来。它有一种积极的氛围和能量,以前是没有的。但是…还缺少一些东西。这个东西可以让它从“”变成“很棒”。

所以,我告诉你一个小秘密。你知道吗?我们的Midjourney AI艺术家可以模仿相机拍摄效果!不是名人,而是相机模型。没错!它可以模仿不同相机模型独特的特点,为您的图像增添特殊风格。

想象一下吧。每台相机都有自己独特捕捉世界方式,“个性”,如果您愿意这么说。有些可能会给您提供清晰、高清晰度图像;其他则可能使您拥有怀旧、略微模糊质感图片。

尝试设定具体的相机(和镜头)

那么,让我们来测试一下Midjourney AI吧!我们将输入两个新提示语句,并分别对应不同相机模型进行仿制处理:尼康D850经典Polaroid即时成像相机——前者因其锐利、鲜艳图像而闻名于世;后者则因其柔软、梦幻般的质感而广受认可。

Prompt:
green chair | photography | living room | bright daylight | Camera: Nikon D850 --c 50

img

Prompt:
green chair | photography | living room | bright daylight | Camera: Polaroid --c 50

img

现在这才像样!我们的绿色椅子,通过两个不同相机的镜头捕捉,每一个都为图像增添了自己独特的风味。就像我们给一件杰作添加了最后的润色。但你知道吗?我还没有准备好放下我的画笔。

为什么只停留在一把绿色椅子上呢?让我们为场景增加更多生气吧!让我们再加入另一个角色来丰富故事情节。对于我们的绿色椅子来说,有什么比泰迪熊更好的配合者呢?这是经典组合,就像花生酱和果冻、电影和爆米花。

想象一下:明亮阳光下沐浴着温暖舒适感觉家庭氛围中,泰迪熊舒适地栖息在我们的绿色椅子上。这是一个唤起人们温馨、舒适、家庭感觉场景。就像我们不仅创造了一幅图像,而且创造了一个记忆。

增加一点摆设

那么让我们重新开始吧! 我们不只是进入了兔子洞里面,在泰迪熊洞里也要深入探索。准备好为我们的杰作增添更多魔力了吗?让我们开始吧……

Prompt:
teddy bear on a green chair | photography | living room | bright daylight | Camera: Nikon D850 --c 50

img

嗯,这很有趣。我们要求一把带小熊的绿色椅子,但是我们得到了一把带小熊的蓝绿色(turquoise)椅子。就像点了一个青苹果却拿到了蓝莓一样,接近但不完全正确。

但你知道吗?这就是整个过程的美妙之处。它充满不可预测性、惊喜和挑战你的思维方式。虽然我们的椅子可能经过了“蓝绿镇(Turquoise Town)”的弯路,但这也是旅程中必须经历的部分。

改变视角

所以,我们将再次调整提示内容。但这次,我们不仅会调整颜色,还会玩转视角。想想看吧!观察事物的方式可以彻底改变你对它的看法。

Prompt:
teddy bear on a green chair | photography | living room | bright daylight | Camera: Nikon D850 | low angle view | --c 50

img

现在这才像话!从新的角度看,我们的绿色椅子和泰迪熊真正开始活起来了。就像我们自己走进了场景,亲眼目睹一样。但是,既然已经到了这一步,为什么要停下呢?

增加一些艺术效果

让我们给场景增加一点戏剧性、特效的调味吧。还有什么比水滴更具戏剧性呢?想象一下,在明亮的阳光下每个水滴反射出闪耀光芒,窗户上雨滴轻柔地拍打声音,绿色椅子和泰迪熊带来舒适温馨感觉。就好像我们正在创造自己的小电影场景。

Prompt:
teddy bear on a green chair | photography | living room | bright daylight | Camera: Nikon D850 | low angle view | Effects: water drops --c 50

img

哇,真的起作用了。我们的绿色椅子场景现在加上了水滴,看起来非常棒。但是你知道吗?我想再推动一下创新边界。

让我们向Midjourney AI艺术家投掷另一个曲线球。我们有绿色椅子、泰迪熊、日光、新鲜视角和水滴。但是让我们再加点料吧!怎么样,在这个场景中添加一些落叶呢?

如果换个场景会怎么样?

想象一下,明亮的彩叶飘落,随着它们的降落捕捉到光芒。我们的场景不再只是简单地展示一个椅子图像,而是变成了生活片段,充满了色彩、运动和能量。就好像我们正在为AI创造注入生命。

Prompt:
brown teddy bear on a green chair | photography | living room | bright daylight | Camera: Nikon D850 | close-up view | Effects: water drops | surrounded by falling leaves --c 50

img

哇,这不是一道令人眼前一亮的景象吗?树叶飘落,阳光透过枝叶洒下来,水滴溅起涟漪……这里有着丰富多彩的视觉和声音。但等等……我们的绿色椅子变得不再那么绿了。还有,难道里面不应该有一个客厅吗?

你看,这就是中途提示的问题所在。它就像赶集场上放羊儿一样棘手。你必须关注所有细节,否则事情很快就会失控。

调整美化参数(stylize)

但别担心。我还有一个法宝——“stylize(美化参数)”。把它想象成导演剪辑版。它让我们可以微调场景,并确保每个细节都符合我们的要求。

而且我们并不只是稍微调整一下。“stylize(美化)”值将被提高到1000!这就像给AI艺术家喊话:“让我们的愿景变为现实!”

因此,请回到键盘前准备好:绿色椅子、泰迪熊、日光、新鲜视角、水滴和落叶以及最大限度地提高stylize的数值——准备好看接下来会发生什么了吗?我知道我准备好了。

Prompt:
teddy bear on a green chair | photography | living room | bright daylight | Camera: Nikon D850 | close-up view | Effects: water drops | surrounded by falling leaves --c 50 --s 1000

img

大家看到了吗!这就是我们一直追求的完美画面。有绿色的椅子,小熊玩具,阳光、水滴和落叶……就像我们经历了一次视觉之旅,最终抵达目的地。Midjourney真是太棒了。

总结

那么这里有什么要点呢?当你开始Midjourney时,可能没有明确的想法。没关系!只需加入一个简短提示词或两个单词,并看看它会带给你什么灵感。就像坐上过山车而不知道将去何方一样刺激。

但也许你属于计划型人格你已经在脑海中形成了清晰的愿景和画面。在这种情况下,您需要从较长的提示开始,例如四五个单词。然后随着进展逐渐添加更多元素作为构建模块,在每个步骤中都能看到您所创建内容正在成形、演变并越来越精致。

但是,请注意一旦得到完美图像,请勿停止尝试新事物!删除某些元素或添加其他元素可能会带来意外结果——请参见下面的图片示例:我们移除了小熊玩具和绿色椅子,看看我们得到了什么——一个全新的杰作!

归根结底,成功的Midjourney提示都是关于实验和探索。从小处开始,并逐渐建立您的想法。逐个修改参数并观察图像如何演变。这是一次发现、创造和乐趣之旅。

那么,准备好开始自己的Midjourney了吗?我已经准备好了!让我们开始创作吧

Prompt:
photography | living room | bright daylight | Camera: Nikon D850 | close-up view | Effects: water drops | surrounded by falling leaves --c 50 --s 1000 --ar 16:9

img


关于Midjourney的其他文章:






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



Midjourney高级技巧的极简教程

原文:An advanced guide to writing prompts for Midjourney ( text-to-image)

作者:Lars Nielsen

How to write prompts for Text to Image generation by Midjourney , text prompt , #midjourney prompt engineering

Midjourney生成的图像,文本Prompt:beautiful, fantasy city unreal engine

一句话介绍midjourney ?

对于那些还没有听说过Midjourney的人,这里是一个简短介绍:Midjourney是一款文本到图像生成应用程序,类似于OpenAI的DALLE-2和Stable Diffusion的DreamStudio,它使用互联网上发现的大量图片(约6.5亿张)来根据提供的文本提示生成令人惊叹的图像。目前处于测试阶段 - 但每周都在添加更多功能…未来还有很多想象空间!(当前他们的AI引擎为v5.1)

原始的prompt

如果您使用 midjourney 应用程序,则会知道您在文本中越详细描述,输出结果就越生动独特。用户通常使用原始和直接的提示词语,例如:a cowboy wearing a tuxedo on the moon(一个穿着礼服在月球上骑马的牛仔)”,将生成这样的内容:

A guide to writing text prompts for Midjourney , prompt engineering

但是除了简单的原始prompt文本之外,还有更多选项可以创建可预测和一致的图像输出!

现在直接进入文本提示的高级选项列表!

以下是您可以生成图像变体的一些方法以及相应的高级设置:(每个设置的详细信息在列表下方)

  1. 提供风格关键字 — ‘style’
  2. stylize(美化)
  3. chaos(随机性)
  4. Resolution
  5. Aspect ratio(长宽比)
  6. 将图像作为URL prompt上传
  7. 应用权重到图像prompt。
  8. 为某些词加权
  9. 过滤掉某些词

简而言之,您的风格受到所选关键词的影响——您可以指定选择何种类型的风格——此图显示了风格类型的广泛分类。

guide to writing prompts for Midjourney — style groups , prompt engineering

  1. Style — keyword

提供一组与“style”(风格)相关的prompt关键词,可以根据您选择的风格类型创建不同的输出。以下是一些基于您可能想要选择为样式的艺术形式/设计/艺术家/流派的关键词和子类型:

  • 使用不同的设计流派作为style(风格)关键字

A guide to writing text prompts for Midjourney. Text to image generation . Different artist styles , prompt engineering

  • 使用艺术家名称作为style(风格)关键字

您还可以将艺术家指定为样式输出。以下是一些相同prompt的示例:

1
/imagine horse galloping at sunset painting Andy Warhol style

A guide to writing text prompts for Midjourney. Text to image generation . Different artist styles Da Vinci , Salvador Dali

  • 使用渲染/光线属性作为style(样式)关键词

A guide to writing text prompts for Midjourney. Text to image generation . Different artist styles

2. stylize the output(美化输出)

您可以添加设置--s <某个数字>(表示样式)

以下图片来自相同的提示 - 低和高风格化选项。

1
/imagine firefighters --s 6000

A guide to writing text prompts for Midjourney. Text to image generation . stylize option

3. chaos — 提高抽象程度

接受0到100之间的数字,以增加或减少主题中的抽象程度。

1
/imagine Eiffel tower --chaos 60

A guide to writing text prompts for Midjourney. Text to image generation . Different options , chaos

4. Resolution(分辨率)

为了指定输出分辨率,您可以使用一些常用的关键词,如8K、4K、逼真、超逼真、超详细复杂细节等。

或者您也可以选择标准设置以获得可预测的输出。hdquality / --q 是其中两个设置指令。

1
2
/imagine red rose flower --hd
/imagine red rose flower --quality 5

5. Aspect ratio(长宽比)

你可以指定输出图像的宽高比,这被称为纵横比。默认输出是一个正方形图像(1:1 纵横比)。但如果你想要更具电影感的视角——或者只是想制作一张适合笔记本电脑桌面的壁纸,你可以改变纵横比。

1
/imagine jasmine in the wild flower --ar 4:3

如果您想指定自定义图像大小,请使用以下示例。

1
/imagine jasmine in the wild flower --w 600 --h 300

您无法指定自定义的宽高比,但可以指定一些标准的宽高比以及一些非标准的宽高比!(以下是一些示例)

A guide to writing text prompts for Midjourney. Text to image generation . Aspect ratio

6. Image as a prompt

如果您想要在多张图片上获得类似图像风格的输出(当您需要获得一致的输出时),请传递一个图像的URL。

1
/imagine http://www.imgur.com/Im3424.jpg box full of chocolates

生成的图像将同时参考种子图像(来自您传递的URL)和文本prompt。

  • 您可以提供多张图片作为prompt

  • 您可以为这些图片指定权重(请参见下一条)

7. 为图片加权(重)的prompt

如果您希望输出结果更接近于您的提示图像(减少midjourney自己的想象力,请参见上一点),则应该给予该图像更高的权重。 (keyword : --iw <number>) .

1
/imagine http://www.imgur.com/ks34f24.jpg chocolates --iw:4

8. 为prompt中的文本加权

1
/imagine wild animals tiger::2 zebra::4 lions::1.5

9. 从图像中过滤掉词语

使用 --no 关键字来丢弃任何不想要的主题。

1
/imagine KFC fried chicken --no sauce

A guide to writing text prompts for Midjourney. Text to image generation . Negative prompt text

10. 最后,这里有一些你可以尝试使用的有趣关键词

1
2
3
4
5
6
7
Sony Alpha α7, ISO1900, Leica M = 指定任何镜头类型或相机类型。

photorealistic(逼真照片级别) , ultra photoreal(超逼真) , ultra detailed(超详细), intricate details(错综复杂的细节) = 为了指定一些可能的细节和更加现实而不是艺术化的外观。

unreal(虚幻) = 指定虚幻引擎的感觉。

volumetric light(立体光) , cinematic lighting(电影级照明) = 指定一些光线条件。

最后

我们谈论了如何在中途实验的输出图像上获得一定程度的控制。但这还不够。Midjourney 的工作人员为您留下了很大的想象和实验空间。祝您尝试不同的提示并享受创造过程。

译者注:本站后续会提供更多Midjourney相关的文章,包括最新的v5.1的官方教程、一些特殊技巧(模特换衣、家居设计、人物制作等),以及色彩搭配等方面的内容,敬请期待!


关于Midjourney的其他文章:






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



使用GFPGAN将Midjourney生成的人脸精细化

原文:Taking generated Midjourney (MJ) images to the next level

作者:Lars Nielsen

关于本文

本文将简要介绍使用midjourney生成更逼真的合成人脸的操作流程。

糟糕的面部重建

任何使用Midjourney创建涉及人脸图像的人都非常清楚,当涉及到人脸时,使用Midjourney生成的图像效果很差。

例如-下面的图片是使用Midjourney应用程序(升级版)生成的,几乎每个逼真的人脸图像最终都会变形。

text-to-image generation using midjourney #midjourney

由midjourney生成的图像:不良面部构造示例(1)

Restoring face images for text-to-image generation using midjourney

由midjourney生成的图像:不良面部构造示例 (2)

一条面部修复流水线

为了减少面部重建的畸变并使其更有用,这里提供一个快速的图像生成流水线供您尝试 —

text-to-image generation pipeline using midjourney and GFPGAN

使用GFPGAN进行人脸修复的图像生成流程

步骤1:提供一个图片链接作为您的图像prompt,在您的文本prompt中。通过此处的链接学习如何进行高级文本提示生成。(Midjourney写作提示的高级指南)

步骤2:使用关键词和属性进行细化。

步骤3:将经过细化处理后的图像输入GFPGAN。

步骤4:您可以将这个新恢复的图像反馈到图像提示中,或在GFPGAN中继续几次迭代。

.. 注意:这可能需要从面部重建软件(GFPGAN)进行几次迭代,因此最好为此创建一个小型Python脚本。

GANS

GANs(生成对抗网络)是一种神经网络,通过迭代尝试多轮比上一次更好的输出来从随机噪声中生成图像(物体、人脸和几乎任何东西)。经过几次迭代后,它们会生成合成图像,这些图像与最初在训练集中存在的真实图像几乎相似。

很遗憾,我们不会详细介绍GAN的工作原理。)你可以在这本精彩的书中学习GAN(《GANs in Action: Deep learning with Generative Adversarial Networks》——Jakub Langr和Vladimir Bok著)。

GFPGAN(生成式面部先验GAN)

GFPGAN是一种专门用于恢复人脸的GAN实现。正如他们网站上所提到的,他们

它是开源的,可以在这里获取。 (https://github.com/TencentARC/GFPGAN )

但是对于那些没有支持GPU的机器或不太懂技术(万一你遇到了一些需要修复错误的麻烦),这里有GFPGAN在Hugging Face Spaces上的实现。链接在这里 - https://huggingface.co/spaces/akhaliq/GFPGAN

回到midjourney

这里是我们从midjourney恢复的一些真实输出样本。

Image generated by text prompt through midjourney , facial restoration by GFPGAN

通过midjourney文本提示生成的图像,使用GFPGAN进行面部修复

Image generated by text prompt through midjourney , facial restoration by GFPGAN

通过midjourney文本提示生成的图像,使用GFPGAN进行面部修复

Image generated by text prompt through midjourney , facial restoration by GFPGAN

通过midjourney文本提示生成的图像,使用GFPGAN进行面部修复

有潜力创造出惊人的面部图像

以下是通过midjourney生成的一些人脸图像 - 经过几次迭代。

Sample faces generated and iterated through midjourney + GFPGAN face restoration


关于Midjourney的其他文章:






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!



使用Midjourney制作专业级LOGO

原文:Best Logo Prompts for Midjourney V5 AI Image Generator: Blueprint for Amazing Logo included!
作者:Michael King

今天我们将探索一些超棒的提示,帮助你使用最新版本、最强大的Midjourney,像专业人士一样轻松制作出独特、引人注目的标志!


但等等,还有更多!作为这个美妙蛋糕上的额外樱桃,我还会提供一个Blueprint模板,您可以混合、匹配和调整它来创建自己的标志设计杰作。请耐心阅读本文直到最后,因为那里将会有这个时髦的Blueprint。

logo制作的魔法开始了

Prompt:
Design of abstract logo featuring a dog in blue on a pink background. Include lines as an additional design element. --v 5

Prompt:
Design of sketchy logo featuring a bird in green on a blue background. Include pattern as an additional design element. --v 5

Prompt:
Design of professional logo featuring a leaf in green on a brown background. Include curves as an additional design element. --v 5

Prompt:
Design of professional logo featuring a leaf in green on a brown background. Include curves as an additional design element. --v 5

Prompt:
Design of professional logo featuring a leaf in green on a brown background. Include curves as an additional design element. --v 5

Prompt:
Design of sketchy logo featuring a queen in black on a silver background. Include highlights as an additional design element. --v 5

Prompt:
Design of professional logo featuring a fish in yellow on a purple background. Include circle as an additional design element. --v 5

Prompt:
Design of sketchy logo featuring a knight in purple on a black background. Include texture as an additional design element. --v 5

Prompt:
Design of wild logo featuring a heart in multicolored on a red background. Include square as an additional design element. --v 5

Prompt:
Design of futuristic logo featuring a spaceship in white on a brown background. Include star as an additional design element. --v 5

Prompt:
Design of whimsical logo featuring a cat in silver on a gold background. Include diamond as an additional design element. --v 5

Prompt:
Design of vintage logo featuring a star in gray on a blue background. Include pattern as an additional design element. --v 5

Prompt:
Design of professional logo featuring a triangle in pink on a gold background. Include pattern as an additional design element. --v 5

Prompt:
Design of professional logo featuring a computer in blue on a yellow background. Include highlights as an additional design element. --v 5

Prompt:
Design of futuristic logo featuring a cat in purple on a gray background. Include hexagon as an additional design element. --v 5

Prompt:
Design of fancy logo featuring a galaxy in green on a gold background. Include pattern as an additional design element. --v 5

Prompt:
Design of futuristic logo featuring a zombie in green on a purple background. Include pattern as an additional design element. --v 5

Prompt:
Design of abstract logo featuring a skull in blue on a white background. Include highlights as an additional design element. --v 5

Prompt:
Design of playful logo featuring a bird in black on a black background. Include moon as an additional design element. --v 5

Prompt:
Design of watercolor logo featuring a circle in black on a purple background. Include geometric shapes as an additional design element. --v 5

现在,正如承诺的那样,这是我之前提到的超级棒的蓝图模板。使用这个家伙作为起点,并进行自定义以创建一个独一无二的标志:

Prompt Blueprint:

Design of [style风格] logo featuring a [symbol标志] in [color颜色] on a [background背景] background. Include [additional_element额外元素] as an additional design element.

这是一个Logo设计prompt的主要公式,使用下面的 YAML 内容替换方括号中的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
style:  
- modern
- minimalist
- vintage
- retro
- fun
- futuristic
- abstract
- cartoon
- geometric
- hand-drawn
- typographic
- tribal
- text-based
- illustrative
- photorealistic
- 3D
- grunge
- sketchy
- watercolor
- comic
- cute
- fancy
- feminine
- masculine
- playful
- professional
- simple
- traditional
- trendy
- vibrant
- whimsical
- wild
symbol:
- star
- circle
- triangle
- square
- heart
- diamond
- moon
- hexagon
- leaf
- tree
- wave
- cloud
- sun
- skull
- deer head
- lion head
- bear head
- cat
- dog
- car
- train
- pizza
- coffee cup
- coffee bean
- cupcake
- ice cream cone
- computer
- phone
- camera
- book
- rocket
- airplane
- house
- castle
- sword
- crown
- flower
- bird
- fish
- butterfly
- dragon
- unicorn
- mermaid
- alien
- robot
- spaceship
- planet
- galaxy
- zombie
- ghost
- witch
- wizard
- knight
- princess
- queen
- king
- wheel
- gear
- clock
color:
- red
- orange
- yellow
- green
- blue
- purple
- pink
- brown
- black
- white
- gray
- silver
- gold
- multicolored
background:
- red
- orange
- yellow
- green
- blue
- purple
- pink
- brown
- black
- white
- gray
- silver
- gold
- multicolored
additional_element:
- gradient
- shadow
- border
- pattern
- texture
- geometric shapes
- lines
- curves
- highlights
- 3d effects
- star
- circle
- triangle
- square
- heart
- diamond
- moon
- hexagon

大家看到了吗!有了这些技巧、诀窍和超棒的蓝图,你就可以用Midjourney V5 AI图像生成器征服标志设计世界。记住,熟能生巧,所以不要害怕尝试并让你的创造力奔放!

但在你开始创作标志杰作之前,请帮我一个忙关注我的频道。我承诺会继续提供最新的技巧和诀窍,让您娱乐和知情。

愉快的设计,下次再见并保持好奇心!

作为对您耐心的小小奖励,这里有一个Python脚本,可以动态随机地创建标志提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import random  
import yaml


def get_options(file_path):
with open(file_path, 'r') as file:
options = yaml.load(file, Loader=yaml.FullLoader)
return options

input_data = get_options('input.yaml')

command = input_data['command']
for key in input_data.keys():
if key != 'command':
command = command.replace(f'[{key}]', input_data[key][random.randint(0, len(input_data[key]) - 1)])

print(command)

关于Midjourney的其他文章:






关注我的微信公众号,可收到实时更新通知

公众号:土猛的员外


TorchV AI支持试用!

如您有大模型应用方面的企业需求,欢迎咨询!