我的学习笔记

土猛的员外

32个最佳Midjourney室内设计

原文: 30+ Best Midjourney Prompts For Outstanding Interior Design

技术在进步,跟上室内设计行业的趋势是明智的。在竞争中走在前面,使用让你的工作更轻松的工具是很重要的。

来自世界各地的室内设计师一直在利用Midjourney的能力,快速创建设计,探索无限的可能性,体验没有边界的刺激

这个工具已被证明是一个宝贵的资源,为专业人士寻求产生高质量的工作。

Cafe Interior Design, Midjourney

Midjourney的人工智能艺术生成工具是一个显着的游戏规则改变释放你的创造潜力!

这是一种革命性的方式来挖掘你的想象力和探索创造性的可能性!

如果你是Midjourney的新手,看看这个快速指南开始

今天,我整理了一个伟大的选择32个Midjourney室内设计prompts,它们具有不同的设计风格和独特的功能,以支持您创造令人惊叹的室内设计。

设计风格

1. Art Deco(艺术装饰风格)

艺术装饰风格的室内装饰通常与古老的精致和魅力联系在一起,同时也体现了高质量的工艺和奢侈。

Prompt: Interior design of a living room, art deco style— ar 16:9

img

2. Bauhaus(包豪斯)

包豪斯的设计力求在理性和逻辑的基础上创造简单、实用而又美观的设计。

Prompt: Interior design of a living room, bauhaus style, dark green — ar 16:9

Bauhaus Interior design of a living room, created with Midjourney v5

3. Nordic(北欧风格)

北欧设计的重点通常放在设计功能空间,不加修饰的极简作品,自然的材料,朴素的墙壁和最少的色彩使用。

Prompt: Interior design of a living room, nordic style, blue and white — ar 16:9

Nordic interior design of a living room, created with Midjourney v5

4. Loft

Loft(阁楼)风格的室内设计因其独特的工业仓库氛围而越来越受欢迎。它们的特点是天花板高,没有隔板,并结合了工业部件。

Prompt: Interior design of a living room, loft style, two storey apartment— ar 16:9

Loft style apartment design style, created with Midjourney v5

5. Bohemian(波西米亚)

波西米亚的室内设计是放松的,灵感来自大自然,同时也具有大胆的图案和醒目的色彩。

Prompt: Interior design of a living room, bohemian style — ar 16:9

Boho interior design style of a living room , created with Midjourney v5

6. Contemporary(当代设计)

当代设计永远是时尚的——它反映了当前的趋势和运动。

Prompt: Interior design of a living room, contemporary, black and gold — ar 16:9

a living room, contemporary, black and gold, created with Midjourney

7. Urban Modern(城市风)

城市风现代设计为更工业化的方法提供了一种平衡,增加了温暖和诱人的元素,软化了外观。

Prompt: Interior design of a penthouse, urban modern style — ar 16:9

Urban Modern interior design of a penthouse, created with Midjourney v5

8. Tropical(热带风格)

热带风格侧重于营造轻松的氛围,将户外融入您的空间;考虑添加深绿色和火烈鸟粉来实现充满活力和平静的色调。

Prompt: Interior design of a studio apartment, tropical style — ar 16:9

tropical style living room, created with Midjourney

9. Minimalism(极简主义)

极简主义是室内设计风格的一个关键主题。这意味着家具、调色板和其他方面都应该尽可能地保持简单和必要。

Prompt: Interior design of a kitchen, minimal style, beige and wood — ar 16:9

Interior design of a kitchen, minimal style,, created with Midjourney

10. Coastal(海景风格)

海景装饰就是在你的家里营造一种海滩的氛围。它结合了天然材料和柔和的色彩,创造了一个休闲但平静的氛围。

Prompt: Interior design of a villa, coastal style, beautiful sunlight — ar 16:9

Interior design of a villa, coastal design style, created with Midjourney

11. Hollywood Regency(好莱坞摄政风格)

这种设计风格起源于20世纪30年代的好莱坞电影工业中建立的装饰风格。豪华,独树一帜,不同的纺织品,纹理和图案为该地区提供了独特的外观。

Prompt: Interior design of a bathroom, hollywood regency — ar 16:9

Interior design of a bathroom, Hollywood regency, created with Midjourney

12. The French Style(法式)

优雅的法式室内风格为房间带来了独特的平衡,结合了精致的情调与温馨的家,质朴的触摸。

Prompt: Interior design of a bedroom, french style glossy ceramic granite and polished natural stone — ar 16:9

French style interior design of a bedroom, created with Midjourney

13. Mediterranean(地中海风格)

地中海的设计融合了众多的自然元素,舒适的颜色,和丰富的照明。

Prompt: Interior design of a hotel villa room, mediterranean style, beside the beach, beautiful sunlight shining through — ar 16:9

Interior design of a hotel villa room, Mediterranean style, created with Midjourney

14. Mid-Century(中世纪风格)

中世纪风格的家具以其简洁的线条、几何形状以及天然和人造材料(如木材和Lucite)的混合为特点。

Prompt: Interior design of a library, mid-century style — ar 16:9

Mid century interior design of a library, created with Midjourney

15. Maximalist(极多主义)

极多主义的目标是用色彩、纹理和装饰来利用家里的每一个空间。它的流行可能是因为它是极简主义的对立面。

Prompt: Interior design of a coffee shop, maximalist style, dusk blue and terracotta and cantaloupe color — ar 16:9

Maximalist interior design of a coffee shop, created with Midjourney

16. Shabby Chic(破旧风)

这种破旧别致的趋势以家具为特征,这些家具出于审美目的被有意识地或有机地磨损,并带有古老部件的迷人吸引力。

Prompt: Interior design of a florist shop, shabby chic style, beautiful warm light — ar 16:9

Interior design of a florist shop, shabby chic, created with Midjourney

17. Patterns(使用循环模式)

设计师经常使用图案为任何区域增添独特的美感。图案是赋予空间视觉趣味、深度和质感的绝佳方式。

Prompt: Interior design of a bathroom, with Portuguese blue tiles wall, luxurious — ar 16:9

Interior design of a bathroom, with Portuguese blue tiles wall, created with Midjourney

18. Justina Blakeney(布莱尼克风格)

贾斯蒂娜以她的新波西米亚、折衷主义和充满植物的风格而闻名。

Prompt: Interior design of a coffee shop, designed by Justina Blakeney, with nature tone— ar 16:9

Interior design of a coffee shop, designed by Justina Blakeney, created with Midjourney

19. Kelly Wearstler(凯利·威尔斯特勒

凯利被称为西海岸室内设计的杰出大师,她在浴室设计方面擅长用大理石地板、四帷柱大床和宽大的露天阳台,体现精致。

Prompt: Interior design of a luxury bathroom, designed by Kelly Wearstler, natural color scheme— ar 16:9

Interior design of a coffee shop, designed by Justina Blakeney, created with Midjourney

20. Karim Rashid(卡里姆·拉希德)

卡里姆被誉为全美洲最著名的工业设计师和“塑料王子”。

Prompt: Interior design of a cafe, designed by Karim Rashid, concrete and glass facade, outdoor forest, natural light with warm tones, breathtaking — ar 16:9

Interior design of a cafe, designed by karim rashid, concrete and glass facade, outdoor forest, created with Midjourney v5

21. Vincent Van Duysen(文森特·范·杜伊森)

文森特以高端住宅和永恒的设计风格而闻名,擅长使用灌注的混凝土设计各种室内装饰,如桌子、台灯等

Prompt: Interior view of a bold rammed earth and oak mid century modern house, designed by Vincent Van Duysen, sitting on a desert land facing the mountains, moroccan warm light fixtures — ar 16:9

nterior view of a bold rammed earth and oak mid century modern house, designed by Vincent Van Duysen, created with Midjourney

22. India Mahdavi(印度马达维)

印度被称为“色彩大师”和“完美音高的拥有者”的建筑师和设计师

Prompt: The most Instagrammed bar in the world, designed by India Mahdavi, vivid ceramics — ar 16:9

The most Instagrammed bar in the world, designed by India Mahdavi, vivid ceramics, created with Midjourney

23. UI设计师Leo Natsume

Leo Natsume风格以其独特,生动的插图而脱颖而出,这些插图是喜剧和怪诞的结合。

Prompt: Interior design of a studio, trending color palette, by Leo Natsume, 3D illustration, pop up color, vibrant — ar 16:9

Interior design of a studio, trending color palette, by Leo Natsume, Midjourney

24. Yayoi Kusama(草间弥生)

最著名的现代日本艺术家之一,以她在作品中独特的波尔卡圆点而闻名。

Prompt: Interior design of a bedroom, by Yayoi Kusama — ar 16:9

Interior design of a bedroom, by Yayoi Kusama, created with Midjourney

25. Tim Burton(蒂姆伯顿)

美国导演和动画师,以其黑暗奇幻和恐怖电影而闻名

Prompt: Interior design of a living room, by Tim burton — ar 16:9

Interior design of a living room, by Tim burton, created with Midjourney

我们来看看电影的风格

26. Harry Potter(哈利波特)

Prompt: Interior design of livin room, harry potter theme — ar 16:9

img

27. Alice in Wonderland(爱丽丝梦游仙境)

Prompt: Interior design of a bathroom, in the style of alice in wonderland, dreamy, breathtaking, beautiful sunlight — ar 16:9

img

28. Disney & Cartoon(迪士尼动漫)

迪士尼和卡通风格是为你的小公主和王子创造梦想房间的完美选择。

Prompt: Interior design of a room for a baby boy, pastel color, blue and white, Disney, diorama, cartoon, — ar 16:9

img

也可以用最新的niji5效果,可以让上面的设计发生很有趣的变化.

Prompt: Interior design of a room for a baby boy, pastel color, blue and white, Disney, diorama, cartoon, — ar 16:9 — niji v 5 — style scenic

Disney style baby bedroom, created with Midjounrney Niji mode

29. 未来主义2080

让我们游历未来的室内空间设计

Prompt: Interior design of a bedroom, futuristic, in 2080, sci-fi, C4D rendering, smooth lighting, clean, neon light, advanced technology, intelligent housing appliances — ar 16:9

Interior design of a bedroom, futuristic, created with Midjourney

30. Cyberpunk(赛博朋克)

Prompt: Interior design of a music studio room, cyberpunk — ar 16:9

Interior design of a music studio room, cyberpunk, created with Midjourney

31. Ice Cave(冰洞)

Prompt: Interior design of an ice cave hotel , glowing, translucent, natural lighting, blue and white, hyper detailed, 8k — ar 16:9

Ice cave, created with Midjourney

32. Intertwining Materials(交织设计)

Prompt: An interior inside of a tree, in the style of realistic yet ethereal, monumental architecture, organic forms, muted tones, 32k uhd, intertwining materials, intricate ceiling designs— ar 16:9

An interior inside of a tree, in the style of realistic yet ethereal, created with Midjourney


TorchV AI支持试用!

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



LlamaIndex—正确使用索引

在第一篇文章构建PDF聊天机器人之后,我们需要在第二篇文章之前充分了解Llamaindex的重要性。

与其匆忙进入编码和实现阶段,不如优先深入理解Llamaindex及其基础概念。通过这样做,我们将能够更好地理解如何将这些原则应用到我们的具体项目中,并避免不必要的错误。

img

因此,在继续第2部分之前,我们花一些时间深入研究Llamaindex的复杂性及其在聊天机器人开发中的重要性。通过扩展我们的知识和掌握基础知识,我们将更好地准备创建一个强大而有效的PDF聊天机器人。

在这篇文章中,我将介绍Llamaindex的基本组件,它在聊天机器人开发中的实际应用,以及花时间了解它的好处。

我为什么不去看官方文件?

“你为什么不专注于开发应用程序,而不是解释一些我们可以通过官方文件轻松阅读的东西?”

值得注意的是,官方网站并不总是最新的,可能不会提供详细的信息解释。因此,可能有必要寻求额外的资源或进行进一步的研究,以充分了解内容。这可能是一个耗时的过程,但重要的是要确保获得的信息是准确和可靠的。

我不仅提供了详细的解释,还提供了真实的用例以及使用什么场景和索引,以便您更好地理解将要构建的基础。

LlamaIndex简介

LlamaIndex(也称为GPT Index)是一个用户友好的界面,它将您的外部数据连接到大型语言模型(Large Language Models, llm)。它提供了一系列工具来简化流程,包括可以与各种现有数据源和格式(如api、pdf、文档和SQL)集成的数据连接器。此外,LlamaIndex为结构化和非结构化数据提供索引,可以毫不费力地与大语言模型一起使用。

本文将讨论LlamaIndex提供的不同类型的索引以及如何使用它们。这可能包括列表索引、矢量存储索引、树索引和关键字表索引的分解,以及特殊索引,如图索引、Pandas索引、SQL索引和文档摘要索引。此外,我将详细介绍每个索引的情况,可能有必要讨论使用LlamaIndex的成本,并将其与其他选项进行比较。

为什么我们需要LlamaIndex ?

商业ChatGPT还不够好吗?

是的,它在一般用例中可能足够了,但请记住,我们的目标是在您的文档湖(类比数据湖)上构建通用聊天机器人应用程序。想想你的公司文档可能有超过1000页,那么ChatGPT广告将不足以分析你的东西。主要原因是token的限制。

  • GPT-3: 2000 tokens
  • GPT-3.5: 4000 tokens
  • GPT-4: 提升到32.000 tokens

1,000 tokens大概是750单词

img

GPT-3, GPT-3.5, GPT-4和LlamaIndex被Flyps接受的tokens数量

LlamaIndex是如何适应的?

如果可用的tokens不多,则无法在prompt中输入更大的数据集,这可能会限制您对模型的操作。然而,您仍然可以训练模型,尽管有一些优点和缺点需要考虑。不过别担心,LlamaIndex会帮你的!

使用LlamaIndex,您可以为各种数据集(如文档、pdf和数据库)建立索引,然后轻松地查询它们以查找所需的信息。

想象一下,只需点击几下就可以访问您需要的所有信息!您可以直接向知识库、Slack和其他通信工具以及数据库和几乎所有SaaS内容提出复杂的问题,而无需以任何特殊方式准备数据。最好的部分是什么?您将得到由GPT推理能力支持的答案,所有这些都在几秒钟内完成,甚至不必将任何内容复制和粘贴到prompts符中。

通过正确实现GPT Index,您可以使这一切成为可能!在下一节中,我们将深入研究不同类型的索引,以及为您的应用程序准备的适用代码。

用LlamaIndex索引

在能够有效地用自然语言提出问题并获得准确的答案之前,有必要对相关数据集进行索引。如前所述,LlamaIndex能够索引广泛的数据类型,随着GPT-4即将到来,多模式索引也将很快可用。这一部分,我们将研究LlamaIndex提供的不同类型的索引,看看什么索引用于什么用例。

在深入了解索引的细节之前,您应该知道LlamaIndex的核心是将文档分解为多个Node对象。节点是LlamaIndex中的一等公民。节点表示源文档的“块”,无论是文本块、图像块还是更多。它们还包含元数据以及与其他节点和索引结构的关系信息。当您创建索引时,它抽象了节点的创建,但是,如果您的需求需要,您可以手动为文档定义节点。

让我们先设置一些底层代码。

  • 安装库
1
2
pip install llama-index
pip install openai
  • 安装OpenAI API Key
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import os
os.environ['OPENAI_API_KEY'] = '<YOUR_OPENAI_API_KEY>'

import logging
import sys

## showing logs
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))


## load the PDF
from langchain.text_splitter import RecursiveCharacterTextSplitter
from llama_index import download_loader

# define loader
UnstructuredReader = download_loader('UnstructuredReader', refresh_cache=True)
loader = UnstructuredReader()

# load the data
documents = loader.load_data('../notebooks/documents/Apple-Financial-Report-Q1-2022.pdf',split_documents=False)

列表Index

列表索引是一种简单的数据结构,其中节点按顺序存储。在索引构建期间,文档文本被分块、转换为节点并存储在列表中。

img

来自LlamaIndex官方文件

在查询期间,如果没有指定其他查询参数,LlamaIndex只是将列表中的所有node加载到Response Synthesis模块中。

img

来自LlamaIndex官方文件

列表索引确实提供了许多查询列表索引的方法,从基于嵌入的查询中获取前k个邻居,或者添加一个关键字过滤器,如下所示:

img

来自LlamaIndex官方文件

此列表索引对于综合跨多个数据源的信息的答案非常有用

LlamaIndex为列表索引提供Embedding支持。除了每个节点存储文本之外,每个节点还可以选择存储Embedding。在查询期间,我们可以在调用LLM合成答案之前,使用Embeddings对节点进行最大相似度检索。

由于使用Embeddings的相似性查找(例如使用余弦相似性)不需要LLM调用,Embeddings作为一种更便宜的查找机制,而不是使用大语言模型来遍历节点

这意味着在索引构建过程中,LlamaIndex不会调用LLM来生成Embedding,而是在查询时生成。这种设计选择避免了在索引构建期间为所有文本块生成Embeddings的需要,这可能会导致大量数据的开销。

您很快就会发现,将多个索引组合在一起可以帮助您避免高昂的Embedding成本。但这还不是全部——它还可以提高应用程序的整体性能!另一种方法是使用自定义Embedding(而不是使用OpenAI),但我们不会在本文中研究这种方法,因为它值得另一种方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from llama_index import GPTKeywordTableIndex, SimpleDirectoryReader
from IPython.display import Markdown, display
from langchain.chat_models import ChatOpenAI

## by default, LlamaIndex uses text-davinci-003 to synthesise response
# and text-davinci-002 for embedding, we can change to
# gpt-3.5-turbo for Chat model
index = GPTListIndex.from_documents(documents)

query_engine = index.as_query_engine()
response = query_engine.query("What is net operating income?")
display(Markdown(f"<b>{response}</b>"))

## Check the logs to see the different between th
## if you wish to not build the index during the index construction
# then need to add retriever_mode=embedding to query engine
# query with embed_model specified
query_engine = new_index.as_query_engine(
retriever_mode="embedding",
verbose=True
)
response = query_engine.query("What is net operating income?")
display(Markdown(f"<b>{response}</b>"))

向量存储索引

它是最常见且易于使用的,允许对大型数据语料库回答查询

img

来自LlamaIndex官方文件

默认情况下,GPTVectorStoreIndex 使用内存中的 SimpleVectorStore作为默认存储上下文的一部分初始化。

与列表索引不同,基于向量存储的索引在索引构建期间生成Embeddings

这意味着在索引构建期间将调用LLM端点以生成Embeddings数据。

Query(查询)向量存储索引包括获取top-k最相似的节点,并将它们传递到我们的响应合成模块。

img

来自LlamaIndex官方文件
1
2
3
4
5
6
from llama_index import GPTVectorStoreIndex

index = GPTVectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("What did the author do growing up?")
response

树状索引

它对总结一组文件很有用

树状索引是树结构索引,其中每个节点是子节点的摘要。在索引构建期间,树以自下而上的方式构建,直到我们最终得到一组根节点。

树状索引从一组节点(成为该树中的叶节点)构建层次树。

img

来自LlamaIndex官方文件

查询树状索引涉及从根节点向下遍历到叶节点。默认情况下(child_branch_factor=1 ),查询在给定父节点的情况下选择一个子节点。如果child_branch_factor=2,则查询在每个级别选择两个子节点。

img

来自LlamaIndex官方文件

与向量索引不同,LlamaIndex不会调用LLM来生成Embedding,而是在查询时生成。Embeddings被惰性地生成,然后缓存(如果retriver_mode ="Embedding" query(…)期间指定),而不是在索引构建期间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from llama_index import GPTTreeIndex

new_index = GPTTreeIndex.from_documents(documents)
response = query_engine.query("What is net operating income?")
display(Markdown(f"<b>{response}</b>"))

## if you want to have more content from the answer,
# you can add the parameters child_branch_factor
# let's try using branching factor 2
query_engine = new_index.as_query_engine(
child_branch_factor=2
)
response = query_engine.query("What is net operating income?")
display(Markdown(f"<b>{response}</b>"))

为了在查询期间构建树状索引,我们需要将retriver_moderesponse_mode添加到查询引擎,并将GPTTreeIndex中的build_tree参数设置为False

1
2
3
4
5
6
index_light = GPTTreeIndex.from_documents(documents, build_tree=False)
query_engine = index_light.as_query_engine(
retriever_mode="all_leaf",
response_mode='tree_summarize',
)
query_engine.query("What is net operating income?")

关键词表索引

这对于将查询路由到不同的数据源非常有用

关键字表索引从每个Node提取关键字,并构建从每个关键字到该关键字对应的Node的映射。

img

来自LlamaIndex官方文件

在查询时,我们从查询中提取相关关键字,并将其与预提取的Node关键字进行匹配,获取相应的Node。提取的节点被传递到响应合成模块。

img

来自LlamaIndex官方文件

注意到 GPTKeywordTableIndex-使用LLM从每个文档中提取关键字,这意味着它确实需要在构建期间调用LLM

但是,如果您使用GPTSimpleKeywordTableIndex,它使用regex关键字提取器从每个文档中提取关键字,则在构建期间不会调用LLM

1
2
3
4
from llama_index import GPTKeywordTableIndex
index = GPTKeywordTableIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("What is net operating income?")

可组合性图索引

它对于构建知识图谱很有用

使用LlamaIndex,您可以通过在现有索引之上构建索引来创建复合索引。该特性使您能够有效地索引完整的文档层次结构,并为GPT提供量身定制的知识。

通过利用可组合性,您可以在多个级别定义索引,例如为单个文档定义低级索引,为文档组定义高级索引。考虑下面的例子:

  • 您可以为每个文档中的文本创建树索引。

  • 生成一个列表索引,涵盖所有的树索引为您的整个文档集合。

通过一个场景编写代码:我们将执行以下步骤来演示可组合性图索引的能力:

  • 从多个文档创建树索引

  • 从树索引生成摘要。如前所述,Tree Index对于总结文档集合很有用。

  • 接下来,我们将在3个树索引的顶部创建一个列表索引的图。为什么?因为列表索引适合于合成跨多个数据源组合信息的答案。

  • 最后查询图。

实现:

我会阅读苹果2022年和2023年的10k报告,并在两个季度之间提出财务问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## re
years = ['Q1-2023', 'Q2-2023']
UnstructuredReader = download_loader('UnstructuredReader', refresh_cache=True)

loader = UnstructuredReader()
doc_set = {}
all_docs = []

for year in years:
year_docs = loader.load_data(f'../notebooks/documents/Apple-Financial-Report-{year}.pdf', split_documents=False)
for d in year_docs:
d.extra_info = {"quarter": year.split("-")[0],
"year": year.split("-")[1],
"q":year.split("-")[0]}
doc_set[year] = year_docs
all_docs.extend(year_docs)

为每个季度创建矢量指数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## setting up vector indicies for each year
#---
# initialize simple vector indices + global vector index
# this will use OpenAI embedding as default with text-davinci-002
service_context = ServiceContext.from_defaults(chunk_size_limit=512)
index_set = {}
for year in years:
storage_context = StorageContext.from_defaults()
cur_index = GPTVectorStoreIndex.from_documents(
documents=doc_set[year],
service_context=service_context,
storage_context=storage_context
)
index_set[year] = cur_index
# store index in the local env, so you don't need to do it over again
storage_context.persist(f'./storage_index/apple-10k/{year}')

从树索引生成摘要。如前所述,Tree Index对于总结文档集合很有用。

1
2
# describe summary for each index to help traversal of composed graph
index_summary = [index_set[year].as_query_engine().query("Summary this document in 100 words").response for year in years]

接下来,我们将在3个树索引之上创建一个列表索引的Graph

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
### Composing a Graph to Synthesize Answers
from llama_index.indices.composability import ComposableGraph

from langchain.chat_models import ChatOpenAI
from llama_index import LLMPredictor

# define an LLMPredictor set number of output tokens
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, max_tokens=512, model_name='gpt-3.5-turbo'))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)
storage_context = StorageContext.from_defaults()\

## define a list index over the vector indicies
## allow us to synthesize information across each index
graph = ComposableGraph.from_indices(
GPTListIndex,
[index_set[y] for y in years],
index_summaries=index_summary,
service_context=service_context,
storage_context=storage_context
)

root_id = graph.root_id

#save to disk
storage_context.persist(f'./storage_index/apple-10k/root')

## querying graph
custom_query_engines = {
index_set[year].index_id: index_set[year].as_query_engine() for year in years
}

query_engine = graph.as_query_engine(
custom_query_engines=custom_query_engines
)

response = query_engine.query("Outline the financial statement of Q2 2023")
response.response

想知道我们如何利用Langchain Agent作为聊天机器人,请关注/订阅未来的更多更新:)

Pandas索引和SQL索引

它对结构化数据很有用

简单和非常直接,我将直接进入演示。

Pandas Index:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from llama_index.indices.struct_store import GPTPandasIndex
import pandas as pd

df = pd.read_csv("titanic_train.csv")

index = GPTPandasIndex(df=df)

query_engine = index.as_query_engine(
verbose=True
)
response = query_engine.query(
"What is the correlation between survival and age?",
)
response

img

SQL Index:

考虑一个很酷的应用程序,你可以将你的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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# install wikipedia python package
!pip install wikipedia

from llama_index import SimpleDirectoryReader, WikipediaReader
from sqlalchemy import create_engine, MetaData, Table, Column, String, Integer, select, column

wiki_docs = WikipediaReader().load_data(pages=['Toronto', 'Berlin', 'Tokyo'])

engine = create_engine("sqlite:///:memory:")
metadata_obj = MetaData()

# create city SQL table
table_name = "city_stats"
city_stats_table = Table(
table_name,
metadata_obj,
Column("city_name", String(16), primary_key=True),
Column("population", Integer),
Column("country", String(16), nullable=False),
)
metadata_obj.create_all(engine)

from llama_index import GPTSQLStructStoreIndex, SQLDatabase, ServiceContext
from langchain import OpenAI
from llama_index import LLMPredictor

llm_predictor = LLMPredictor(llm=LLMPredictor(llm=ChatOpenAI(temperature=0, max_tokens=512, model_name='gpt-3.5-turbo')))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

sql_database = SQLDatabase(engine, include_tables=["city_stats"])
sql_database.table_info

# NOTE: the table_name specified here is the table that you
# want to extract into from unstructured documents.
index = GPTSQLStructStoreIndex.from_documents(
wiki_docs,
sql_database=sql_database,
table_name="city_stats",
service_context=service_context
)

# view current table to verify the answer later
stmt = select(
city_stats_table.c["city_name", "population", "country"]
).select_from(city_stats_table)

with engine.connect() as connection:
results = connection.execute(stmt).fetchall()
print(results)

query_engine = index.as_query_engine(
query_mode="nl"
)
response = query_engine.query("Which city has the highest population?")

img

在底层,有一个Langchain库插件可以使用。我们将在另一篇文章中介绍Langchain。

文档摘要索引

这是一个全新的LlamaIndex数据结构,它是为了问答而制作的。到目前为止,我们已经讨论了单个索引,当然我们可以通过使用单个索引或将多个索引组合在一起来构建LLMQA应用程序。

通常,大多数用户以以下方式开发基于llm的QA系统:

  1. 它们获取源文档并将其分成文本块。

  2. 然后将文本块存储在矢量数据库中。

  3. 在查询期间,通过使用相似度和/或关键字过滤器进行Embedding来检索文本块。

  4. 执行响应综合。

然而,这种方法存在一些影响检索性能的局限性。

现有方法的缺点:

  1. 文本块没有完整的全局上下文,这通常限制了问答过程的有效性。
  2. 需要仔细调优top-k /相似性分数阈值,因为过小的值可能会导致错过相关上下文,而过大的值可能会增加不相关上下文的成本和延迟。
  3. Embeddings可能并不总是为一个问题选择最合适的上下文,因为这个过程本质上是分别决定文本和上下文的。

为了增强检索结果,一些开发人员添加了关键字过滤器。然而,这种方法有其自身的挑战,例如通过手工或使用NLP关键字提取/主题标记模型为每个文档确定适当的关键字,以及从查询中推断正确的关键字。

img

这就是LlamaIndex引入文档摘要索引的地方,它可以为每个文档提取和索引非结构化文本摘要,从而提高了现有方法的检索性能。该索引包含比单个文本块更多的信息,并且比关键字标签具有更多的语义含义。它还允许灵活的检索,包括LLM和基于嵌入的方法。

在构建期间,该索引摄取文档并使用LLM从每个文档提取摘要。在查询期间,根据摘要检索相关文档进行查询,使用以下方法:

  • - **基于LLM的检索:**获取文档摘要集合,请求LLM识别相关文档+相关性评分

    - **基于嵌入的检索:**利用摘要Embedding相似度检索相关文档,并对检索结果的数量施加top-k限制。

注意:文档摘要索引的检索类为任何选定的文档检索所有节点,而不是在节点级返回相关块。

看看例子:

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
import nest_asyncio
nest_asyncio.apply()

from llama_index import (
SimpleDirectoryReader,
LLMPredictor,
ServiceContext,
ResponseSynthesizer
)
from llama_index.indices.document_summary import GPTDocumentSummaryIndex
from langchain.chat_models import ChatOpenAI

wiki_titles = ["Toronto", "Seattle", "Chicago", "Boston", "Houston"]

from pathlib import Path

import requests
for title in wiki_titles:
response = requests.get(
'https://en.wikipedia.org/w/api.php',
params={
'action': 'query',
'format': 'json',
'titles': title,
'prop': 'extracts',
# 'exintro': True,
'explaintext': True,
}
).json()
page = next(iter(response['query']['pages'].values()))
wiki_text = page['extract']

data_path = Path('data')
if not data_path.exists():
Path.mkdir(data_path)

with open(data_path / f"{title}.txt", 'w') as fp:
fp.write(wiki_text)

# Load all wiki documents
city_docs = []
for wiki_title in wiki_titles:
docs = SimpleDirectoryReader(input_files=[f"data/{wiki_title}.txt"]).load_data()
docs[0].doc_id = wiki_title
city_docs.extend(docs)

# # LLM Predictor (gpt-3.5-turbo)
llm_predictor_chatgpt = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo"))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor_chatgpt, chunk_size_limit=1024)

# default mode of building the index
response_synthesizer = ResponseSynthesizer.from_args(response_mode="tree_summarize", use_async=True)
doc_summary_index = GPTDocumentSummaryIndex.from_documents(
city_docs,
service_context=service_context,
response_synthesizer=response_synthesizer
)

doc_summary_index.get_document_summary("Boston")

知识图谱索引

它通过在一组文档上以以下形式提取知识三元组(主题、谓词、对象)来构建索引。

在查询期间,它可以只使用知识图作为上下文进行查询,也可以利用来自每个实体的底层文本作为上下文进行查询。通过利用底层文本,我们可以对文档的内容进行更复杂的查询。

把一个图想象成这样,你可以看到所有的边和顶点都是相互连接的。

img

来自LlamaIndex官方文件

你可以看看这个页面作为参考。

需要考虑的事实

在我们的PDF聊天机器人实施大语言模型期间,我提请注意我们想与您分享的重要方面,即:索引成本和索引时间(速度)。

索引的成本

索引费用是需要考虑的一个关键因素,正如我在本文前面所强调的那样。这在处理大量数据集时尤为重要,这也是我提倡使用LlamaIndex的原因。

你可以找到各个OpenAI模型的价格(https://openai.com/pricing)。

索引速度

第二个重要问题是文档索引的时间,即为操作准备整个解决方案的时间。根据我的实验,索引时间各不相同,但这是一次性的,也取决于OpenAI服务器。

通常,40页的pdf大约需要5秒。想象一下,一个拥有超过10万页的庞大数据集,可能需要几天的时间。我们可以利用async方法来减少索引时间。我将在另一篇文章中写这一点。

总结

img


TorchV AI支持试用!

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



LLM品质核心—Embedding Model

使用向量Embeddings优化LLM应用程序

性价比更高的OpenAI API替代品

以及我们如何从LlamaIndex转向Langchain

当我在开发自己的LLM应用程序时,发生了一些事情。我发现我实验的每个Embedding模型都会产生不同的有趣结果。有些简直太好了,而另一些则略低于预期。这让我思考:

我们如何才能真正掌握这些Embedding模型的力量,并理解它们对聊天机器人性能的影响?

所以,我忍不住想通过这篇文章与你分享我的见解。

相信我,在投入到自己的项目之前,用这些基本知识武装自己是非常值得的。毕竟,每座伟大的房子都是建立在坚实的基础上的,对吧?别担心,我保证这不会是一场无聊的大学讲座。我确保包含了大量的实用教程和引人入胜的例子,让你在阅读过程中保持兴奋。

什么是向量Embedding

在AI聊天机器人的开发领域中,向量Embedding在获取文本信息的本质方面起着关键作用。向量Embedding的核心是指在数学空间中将单词、句子甚至整个文档表示为密集的低维向量的过程。与依赖于稀疏表示(如one-hot编码)的传统方法不同,向量Embeddings封装了单词之间的语义关系,并使算法能够理解它们的上下文含义。

img

通过使用词Embeddings、句子Embeddings或上下文Embedding等技术,向量Embeddings提供了文本数据的紧凑而有意义的表示。例如,单词Embeddings将单词映射到固定长度的向量,其中具有相似含义的单词在向量空间中的位置更接近。这允许高效的语义搜索、信息检索和语言理解任务。

向量Embedding的重要性在于它能够将原始文本转换为算法可以理解和推理的数字表示。这种转换过程不仅促进了各种自然语言处理(NLP)任务,而且还作为大型语言模型的基本构建块。向量Embeddings使这些模型能够利用嵌入在文本数据中的丰富语义信息,使它们能够生成更连贯和上下文更合适的响应。

向量Embeddings如何捕获语义信息

向量Embeddings通过将单词、句子或文档表示为数学空间中的密集向量来捕获语义信息。这些向量被设计用于对文本元素之间的上下文和语义关系进行编码,从而允许更细致的理解和分析。

捕获语义信息的过程从在大量文本语料库上训练向量Embedding模型开始。在训练过程中,模型学习以反映其语义相似性和上下文的方式将向量分配给单词或单词序列。这是通过分析训练数据中单词的共现模式来实现的。

img

例如,在单词Embeddings中,例如Word2Vec或GloVe,在相似的上下文中经常一起出现的单词由在Embedding空间中位置更接近的向量表示。这种接近反映了它们的语义相似性。通过利用庞大数据集中单词使用的统计模式,这些Embeddings捕获语义关系,如同义词、类比,甚至更广泛的概念,如性别或情感。

如果你想深入了解向量Embedding的更多信息,你可能会发现这篇文章非常有帮助,感谢parte做了这么好的工作来解释向量Embedding:https://partee.io/2022/08/11/vector-embeddings/

向量Embeddings对大型语言模型应用的重要性

向量Embeddings在大型语言模型(LLM)应用领域中具有非常重要的意义。大语言模型,如GPT-3、BERT或基于transformer的模型,由于其产生连贯和上下文适当的响应的卓越能力,已经获得了显著的关注和普及。

大语言模型的成功取决于他们对自然语言语义复杂性的理解。这就是矢量Embeddings发挥作用的地方。通过使用向量Embeddings,大语言模型可以利用文本数据中嵌入的丰富语义信息,使它们能够生成更复杂和上下文感知的响应。

向量Embeddings是原始文本输入和语言模型神经网络之间的桥梁。Embeddings不是为模型提供离散的单词或字符,而是提供捕获输入的含义和上下文的连续表示。这使得大语言模型能够在更高的语言理解水平上运作,并产生更连贯和上下文合适的输出。

向量Embeddings对大语言模型的重要性超越了语言生成。这些Embeddings还促进了一系列下游任务,如情感分析、命名实体识别、文本分类等。通过结合预训练的向量Embeddings,大语言模型可以利用在Embedding训练过程中捕获的知识,从而提高这些任务的性能。

此外,向量Embeddings可以在大语言模型中实现迁移学习和微调。预训练的Embeddings可以在不同的模型甚至不同的领域之间共享,为在特定任务或数据集上训练模型提供一个起点。这种知识的转移允许更快的训练,改进的泛化,以及在专门任务上更好的表现。

到目前为止,您应该对向量Embedding及其在开发LLM应用程序中的意义有了扎实的掌握。在下面的部分中,让我们直接比较不同的Embedding模型。如果你像我一样,因为太穷而无法支付而寻求OpenAI API的替代方案:(),本指南将帮助您选择最适合您特定任务的Embedding模型。

再次,我将把解释向量Embedding的所有艰苦工作留给专家在这里。我在这个岗位上的工作是带来一些实用的方法和高层次的知识,所以让我们开始吧。

LlamaIndex Embedding选项

默认情况下,LlamaIndex使用OpenAI的text-embedding-ada-002作为默认的Embedding向量模型。甚至OpenAI也建议将此模型用于所有通用用途,因为根据他们的说法,此模型比其他模型“最便宜和最快”。但这是真的吗?

如果您想了解OpenAI提供的不同Embedding模型,您可以在这里这里找到它们。但它到底有多便宜呢?

您可以将tokens视为用于自然语言处理的单词片段。对于英文文本,1个token大约是4个字符或0.75个单词。作为参考,莎士比亚的作品集约有90万字或120万tokens。

img

只要 $0.0004 / 1K token 乍一看很便宜。然而,在现实中,它很快就会变得昂贵。让我举个例子来说明:

假设您想构建一个聊天机器人来与您公司的文档聊天,并且您有10,000文件,平均文本长度为20,000 tokens。在这种情况下,您最终将花费:10,000 x 20,000 x 0.0004 = 80,000美元,仅用于Embeddings

虽然OpenAI模型确实是完美的一般用途,甚至与text- embeddingada -002。如果你只创建一个读取文件的应用程序,那么这是可以的,但想象一下运行一个用户每月提交一定数量的tokens的初创公司:(当然,你将按月向客户收取费用,但仍然没有盈利,因为你已经为API支付了相当多的费用。更不用说

  1. OpenAI的API有时会因为巨大的请求而变慢
  2. 您可能希望对同一个文档多次调用这个API,因为您可能有多个索引构建在彼此之上或单独构建。

这就是为什么,我们将探索其他完全免费的模式,我们可以自己部署。

幸运的是,LlamaIndex允许我们使用其他Embedding模型,而不是使用OpenAI。如果你不想使用OpenAI的Embedding模型,你有两个选择

  1. 使用HuggingFace和HuggingFace提供的所有可用的Embedding模型在这里
  2. 带上你自己的Embedding模型。你可以将你的模型发布到HuggingFace,然后回到步骤1,或者如果你想让你的模型保持私有,那么你需要做很多工作。你需要构建一个使用LlamaIndex检索的自定义代码,而不是使用LlamaIndex的默认选项,目前只支持OpenAIEmbedding和HuggingFaceEmbedding。

如何为你的任务找到正确的Embedding?

如果你仍然想使用OpenAI,因为你负担得起它,并希望使用该领域的领导者,那么你可以找到适合你任务的所有模型在这里

img

虽然OpenAI的Embedding模型广为人知,但有必要认识到还有其他可用的选择。拥抱脸是NLP社区的一个著名平台,拥有大规模文本Embedding基准(MTEB)排行榜。这个排行榜是评估各种文本Embedding模型在不同Embedding任务中的性能的宝贵资源。要全面了解MTEB排行榜及其重要性,我建议参考“MTEB:海量文本Embedding基准”(https://huggingface.co/spaces/mteb)。它全面解释了排行榜的目的和对不同文本Embedding模型的见解。探索此资源将拓宽您对文本Embedding领域的理解,并帮助您根据Embedding需求做出明智的决策。

img

正如您所看到的,text-embedding-ada-002仅在总体上排名第六。但这是否意味着我们应该使用e5-large-v2来完成我们所有的任务?不完全是!!!!

由于我们是在知识库的基础上构建问答,所以我们应该注意标签的检索。

img

毫无疑问,获胜者是强大的text- embeddings -ada-002instructer -large仅落后0.39分,而上面最好的e5-large-v2甚至没有进入前10名。

值得注意的是,最复杂的Embedding模型Text -search- davincic -001跌出了前20名,尽管OpenAI声称它比其他相关模型执行文本相似度模型和文本搜索模型更好,成本比ada-002高500倍。

这是非常有趣的,因为现在我们确实有一些开源模型可以执行类似于强大的text- embeddings -ada-002

自定义Embedding模型

如前所述,我们将使用HuggingFace提供的directive -large模型。为了简单演示,在向量数据库方面我将使用ChromaDB而不是Pinecone。

让我们开始编码。

引入必要的库

1
2
3
4
5
6
7
8
9
10
11
import logging
import sys
import os
os.environ["OPENAI_API_KEY"] = "<your_openai_api_key>"

from llama_index import SimpleDirectoryReader, LLMPredictor, ServiceContext, StorageContext, LangchainEmbedding
from llama_index import GPTVectorStoreIndex
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.embeddings.openai import OpenAIEmbeddings
from llama_index import ResponseSynthesizer

加载instructor-large作为Embedding和存储上下文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import chromadb
from chromadb.config import Settings

chroma_client = chromadb.Client(Settings(chroma_db_impl="duckdb+parquet",
persist_directory="./storage/vector_storage/chormadb/"
))
collection = chroma_client.create_collection("general_knowledge")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

## init llm model
llm_predictor_chat = LLMPredictor(llm=ChatOpenAI(temperature=0.2, model_name="gpt-3.5-turbo"))
## load the model
model_id = "hkunlp/instructor-large"
embed_model = LangchainEmbedding(HuggingFaceEmbeddings(model_name=model_id))

## init storage context and service context
storage_context = StorageContext.from_defaults(index_store=index_store, vector_store=vector_store)
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor_chat, embed_model=embed_model)

获取一些虚拟数据

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
from pathlib import Path
import requests

wiki_titles = ["Toronto", "Seattle", "Chicago", "Boston", "Houston", "New York City"]

for title in wiki_titles:
response = requests.get(
'https://en.wikipedia.org/w/api.php',
params={
'action': 'query',
'format': 'json',
'titles': title,
'prop': 'extracts',
# 'exintro': True,
'explaintext': True,
}
).json()
page = next(iter(response['query']['pages'].values()))
wiki_text = page['extract']

data_path = Path('data')
if not data_path.exists():
Path.mkdir(data_path)

with open(data_path / f"{title}.txt", 'w', encoding="utf-8") as fp:
fp.write(wiki_text)

阅读所有的文件。我只拿纽约和休斯顿做比较。

1
2
3
4
5
6
7
8
9
10
11
docs= ['New York City','Houston.txt']
all_docs = {}
for d in docs:
doc = SimpleDirectoryReader(input_files=[f"./data/{d}"]).load_data()
nodes = parser.get_nodes_from_documents(doc)
doc_id = d.replace(" ","_")
doc[0].doc_id = d
## this can be used for metadata filtering if need
extra_info = {"id":d}
doc[0].extra_info = extra_info
all_docs[d] = doc

创建索引。这将创建一个强大的GPTVectorStoreIndex。如果您愿意,可以尝试使用其他索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
index_existed = False
for d in all_docs.keys():
print(f"Creating/Updating index {d}")
if index_existed:
## update index
print(f"Updating index: {d}")
# index_node.insert_nodes(all_nodes[d])
index.insert(all_docs[d][0])
else:
print(f"Creating new index: {d}")
index = GPTVectorStoreIndex.from_documents(
all_docs[d],
service_context=service_context,
storage_context=storage_context
)
index_existed = True

现在,让我们用几个查询进行实验

1
index.as_query_engine().query("What is population of New York?")

img

没错,这个查询只是简单地从文档中查找纽约市的人口。我们将与休斯顿市再次合作

1
index.as_query_engine().query("What is population of Houston?")

img

太简单了,现在我们来做更难的。我将提出比较这两个城市人口的问题。我们期望的结果是纽约市的人口比休斯顿多。

1
index.as_query_engine().query("Compare the population of New York and Houston?")

结果呢?

img

什么是令人失望的?

这个问题没有提供有关休斯顿人口的信息,因此无法回答。

什么,但你说到2020年休斯顿的人口是2304580。

我们在这里做错了什么?LLM蠢到令人震惊吗?我们是否应该将Embedding模型改为OpenAI text-embedding-ada之类的东西?

我问过这些问题,做过很多实验,坦率地说,这一点帮助都没有。问题是,index.as_query_engine()是一个默认函数。对于这样的查询,您需要定制查询引擎以使其执行得更好。因此,我们将使用自定义检索器和自定义响应模式,而不是默认使用**as_query_engine()**。

欲了解更多信息,可以找到检索器查询引擎的详细信息。

注意如何创建查询引擎,因为它对结果有很大的影响

在更改代码之前,这里有一个快速总结

检索器负责获取给定用户查询(或聊天消息)的最相关上下文。而查询引擎是一个通用接口,它允许您对数据提出问题。查询引擎接受自然语言查询,并返回丰富的响应。它通常(但不总是)通过检索器建立在一个或多个索引上。您可以组合多个查询引擎来实现更高级的功能。

让我们修改一下代码。

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
# configure retriever
from llama_index.retrievers import VectorIndexRetriever
from llama_index.query_engine import RetrieverQueryEngine


# this will simple do the vector search and return the top 2 similarity
# with the question being asked.
retriever = VectorIndexRetriever(
index=index,
similarity_top_k=2,
)

# configure response synthesizer
response_synthesizer = ResponseSynthesizer.from_args(verbose=True)
## if you nee to pass response mode
# response_synthesizer = ResponseSynthesizer.from_args(
# response_mode='tree_summarize',
# verbose=True)

# assemble query engine
query_engine = RetrieverQueryEngine(
retriever=retriever,
response_synthesizer=response_synthesizer,
)

# query
response = query_engine.query("Compare the population of New York and Houston.")
response

结果是

img

纽约市人口为8,804,190人,而休斯顿人口为2,304,580人。纽约市的人口是休斯顿的三倍多.

那太好了。只需做一个简单的更改,我们现在就可以根据我们提供的文档中的一般知识回答比较问题。

如果您想知道ResponseSynthesizer中的tree_summary是什么,这里有一个快速的摘要

  • default: 通过依次遍历每个检索到的“节点”,“创建并细化”一个答案;这将对每个Node进行单独的LLM调用。对于更详细的答案很有用。
  • compact: 在每个LLM调用期间,通过填充尽可能多的“Node”文本块来“压缩”prompt符,这些文本块可以容纳在最大prompt大小内。如果在一个prompt中塞进的问题太多,那就通过多个prompts来“创建和完善”一个答案。
  • tree_summarize: 给定一组’ Node ‘对象和查询,递归地构造一个树并返回根节点作为响应。很适合做总结。
  • no_text: 只运行检索器来获取本应发送到LLM的节点,而不实际发送它们。然后可以通过检查’ response.source_nodes ‘来检查。响应对象将在第5节中详细介绍。
  • accumulate: 给定一组“Node”对象和查询,将查询应用于每个“Node”文本块,同时将响应累积到一个数组中。返回所有响应的连接字符串。当您需要对每个文本块分别运行相同的查询时,这很有用。

默认模式对于大多数情况已经足够好了。

现在,我们试试更酷的。

1
2
3
4
5
# query
response = query_engine.query("""
Compare the population of New York and Houston.
What is the percentage difference between two populations?
""")

Here, I asked a similar question but also ask the LLM model to spit the percentage difference between the two populations. And here is the result

*The population of New York City in 2020 was 8,804,190, while the population of Houston in 2020 was 2,320,268. This means that the population of New York City is approximately 278% larger than the population of Houston.*

It’s quite amusing to witness how LLM excels at retrieving information but falls short in accurately calculating numbers. For instance, the state “***New York City is approximately 278% larger than the population of Houston.”
***is correct but we are not asking how the bigger population of New York compare to Houston. We are asking about the “percentage difference” between the two populations.

So, how do we find the percentage difference (% difference calculator) between two positive numbers greater than 0 anyway?

Here is the correct formula for V1 and V2, assuming V1 is bigger than V2

在这里,我问了一个类似的问题,但也要求LLM模型吐出两个群体之间的百分比差异。这就是结果:

**2020年纽约市人口为8,804,190人,休斯顿人口为2,320,268人。这意味着纽约市的人口大约比休斯顿的人口多278%**。

LLM擅长检索信息,但不擅长精确计算数字,这是一件很有趣的事情。例如,“纽约市的人口大约比休斯顿的人口多278%。”是对的,但我们并不是在问人口更多的纽约与休斯顿相比如何。我们问的是两个人群之间的“百分比差异”。

那么,我们如何找到两个大于0的正数之间的百分比差(%差计算器)呢?

这是V1和V2的正确公式,假设V1大于V2

img

根据这个公式,我们应该得到的数字大约是:117.017% 的差异

那么我们如何解决这个问题呢?

事实证明,LlamaIndex在回答与文档相关的问题方面非常精通。似乎整个项目都围绕着这个目的,在一个全面的文档集合上进行轻松的查询,LlamaIndex完美地处理手头的任务。

为了克服这个限制,我们需要深入研究一个更大的项目,称为Langchain。讽刺的是,考虑到我在第一篇文章中提到我们将使用LlamaIndex构建应用程序。然而,我们遇到了一个主要的障碍,根据所有创业公司的基本原则——快速失败和转向——我们必须寻找一个更合适的替代方案,符合我们的要求。

如果你觉得这是浪费时间,请允许我提供一些激励语录来重新点燃你的热情:)

从不犯错的人从不尝试新事物。——爱因斯坦

如果你没有一次又一次地失败,那就说明你没有做任何创新的事情。——伍迪·艾伦

经常失败才能更快成功。- [Tom Kelley]

Hello Langchain

相信我,这不是另一个关于如何用Langchain构建LLM应用程序的典型项目,我们已经有太多关于这个的文章和视频了。如果我必须再做一次,那就有点无聊了。如果你不知道什么是Langchain,只需在谷歌上快速搜索一下,花几天时间浏览所有的教程和视频,然后浏览官方文档。如果您已经对Langchain有了足够的了解,那么就可以进一步了解了。

由于这篇文章已经很长了,我将只发布一个带有详细解释的代码。

简而言之,我们将使用Langchain的以下组件

  • 向量存储(LLM数据库):类似于LlamaIndex向量存储
  • Langchain的Agent:这就是LangChain走红的原因
  • Langchain的Chain: RetrievalQA仅用于回答问题。
  • Langchain的Chain:当你需要回答数学问题时使用LLMMathChain。

现在,我知道这让你难以接受。同样,请通过官方文件了解组件是关于什么的。在以后的帖子中,我会找一些时间把所有的Langchain教程/文章/视频从初学者到高级。所以请订阅并关注以获取更多信息:)

Langchain拥有令人难以置信的功能,使您能够构建几乎任何您可以想象的LLM应用程序。与LlamaIndex不同,LlamaIndex只专注于文档的LLM应用程序,Langchain提供了大量的功能。它可以帮助您开发各种功能,例如internet搜索、结果整合、API调用、数学计算、甚至复杂的数学运算,以及大量其他可能性。

让我们开始吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import logging
import sys
import os
os.environ["OPENAI_API_KEY"] = “<your openai api key>"


## load all the necessary components
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.document_loaders import PyPDFLoader, TextLoader
from langchain.document_loaders import UnstructuredFileLoader

使用自定义的embedding

1
2
3
4
5
6
7
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.embeddings.openai import OpenAIEmbeddings

model_id = "hkunlp/instructor-large"
embed_model = HuggingFaceEmbeddings(model_name=model_id)
vectorstore = Chroma("langchain_store", embed_model)

加载文档并将它们添加到矢量存储中

1
2
3
4
5
6
7
8
9
10
11
12
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)

docs= ['New York City','Houston.txt']
all_docs = []
for d in docs:
print(f"#### Loading data: {d}")
doc = UnstructuredFileLoader(f"./data/{d}", strategy="hi_res").load()
doc = text_splitter.split_documents(doc)
all_docs.extend(doc)

## add to vector store
vectorstore.add_documents(all_docs)

创建问答链

1
2
3
4
5
qa = RetrievalQA.from_chain_type(llm=ChatOpenAI(temperature=0.2,model_name='gpt-3.5-turbo'),
chain_type="stuff",
retriever=vectorstore.as_retriever())
result = qa({"query": "Compare the population of New York and Houston. What is the percentage difference between two populations?"})
result

结果:

根据2020年美国人口普查,纽约市人口为8,804,190人,而休斯顿人口为2,304,580人。两个种群之间的百分比差异约为282%

尽管如此,还是给我们这282%吧。让我们用LLM-math链和代理来解决这个问题。

增加Math Chain和Agent

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
from langchain import OpenAI, LLMMathChain

llm = OpenAI(temperature=0)
llm_math = LLMMathChain.from_llm(llm, verbose=True)

from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.tools import BaseTool

tools = [
Tool(
name="general knowledge",
func=qa.run,
description="useful for when you need to answer questions about the documents in the database"
),
Tool(
name="llm-math",
func=llm_math.run,
description="Useful for when you need to answer questions about math."
)
]

agent = initialize_agent(tools, ChatOpenAI(temperature=0.2,model_name='gpt-3.5-turbo'),
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)


agent.run("""Compare the population of New York and Houston.
What is the percentage difference between two populations?""")

这是结果:

img

这太好了,你看Agent会先从通用知识工具中找到信息,得到两个城市的人口。在第一步之后,它使用LLM-math来计算两个数字之间的百分比差。

你看到它有多聪明了吗?它足够聪明,知道什么工具用于什么目的。这就是为什么我们全力以赴支持LangChain的原因:)

正如我所说,Langchain比LlamaIndex大得多,而且Langchain项目更侧重于创建AGI应用程序,因为它假设了许多实用程序,如web浏览器,使用OpenAPI模型调用API等。

对我来说,创建另一个Langchain教程没有意义。我相信你们可以查一下官方文件。我会找一些时间来巩固从初学者到高级的所有Langchain教程和视频。

引用

Langchain: https://python.langchain.com/en/latest/index.html
LlamaIndex: https://gpt-index.readthedocs.io/en/latest/index.html
Vector Embedding: https://partee.io/2022/08/11/vector-embeddings/
OpenAI Embedding: https://openai.com/blog/introducing-text-and-code-embeddings
OpenAI Pricing: https://openai.com/pricing
HuggingFace embedding: https://huggingface.co/spaces/mteb/leaderboard
Instructor Large: https://huggingface.co/hkunlp/instructor-large

原文地址:Choosing the Right Embedding Model: A Guide for LLM Applications


Update: 2024-01-26

我们的TorchV Bot产品目前已经开始试用了,详情可以点击:https://www.luxiangdong.com/2024/01/25/lanuch-1
目前只接受企业用户试用,需要您填写一些信息,必要信息如下:

邮箱: 用来接收地址和账号
如何称呼您:
所服务的公司:
您的职位:

当然,如果您可以告诉我们您的使用场景,我们将更加感激!
对了,可以发送到yuanwai@mengjia.net
另外,也可以直接加我微信(lxdhdgss)联系我。


TorchV AI支持试用!

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



向量数据库介绍

Embeddings是由人工智能模型(如大型语言模型)生成的,具有大量的属性或特征,使其表示难以管理。在人工智能和机器学习的背景下,这些特征代表了数据的不同维度,这些维度对于理解模式、关系和底层结构至关重要。

这就是为什么我们需要一个专门为处理这类数据而设计的专门数据库。向量数据库通过为Embeddings提供优化的存储和查询功能来满足这一要求。向量数据库具有传统数据库独立向量索引所不具备的能力,并且具有传统基于标量的数据库所缺乏的处理向量Embeddings的专门化能力。

使用向量Embeddings的挑战在于,传统的基于标量的数据库无法跟上此类数据的复杂性和规模,从而难以提取见解并执行实时分析。这就是向量数据库发挥作用的地方——它们被有意设计为处理这类数据,并提供充分利用数据所需的性能、可伸缩性和灵活性。

向量数据库是如何工作的?

我们都知道传统数据库是如何工作的(或多或少)——它们将字符串、数字和其他类型的标量数据存储在行和列中。另一方面,向量数据库对向量进行操作,因此它的优化和查询方式是完全不同的。

在传统数据库中,我们通常查询数据库中值通常与查询完全匹配的行。在向量数据库中,我们应用相似度度量来找到与我们的查询最相似的向量。

向量数据库使用不同算法的组合,这些算法都参与了近似最近邻(ANN)搜索。这些算法通过散列、量化或基于图的搜索来优化搜索。

这些算法组合成一个管道,提供查询向量的邻居的快速和准确的检索。由于向量数据库提供了近似的结果,我们主要考虑的是准确性和速度之间的权衡。结果越准确,查询速度就越慢。然而,一个好的系统可以提供近乎完美的超快速搜索。

下面是向量数据库的常见管道::

img

  1. 索引:向量数据库使用PQ、LSH或HNSW等算法对向量进行索引。这一步将向量映射到一个数据结构,以实现更快的搜索;
  2. 查询:向量数据库将索引的查询向量与数据集中的索引向量进行比较,以找到最近的邻居(应用该索引使用的相似性度量);
  3. 后处理:在某些情况下,向量数据库从数据集中检索最后最近的邻居,并对它们进行后处理以返回最终结果。这一步可以包括使用不同的相似度度量对最近的邻居重新排序。

有了向量数据库,我们可以为我们的人工智能添加高级功能,比如语义信息检索、长期记忆等等。上图让我们更好地理解了向量数据库在这类应用中的作用。

为什么使用向量数据库?

在生产中,向量搜索是使用向量数据库的最常见原因。向量搜索将多个对象与搜索查询或主题项的相似性进行比较。为了找到相似的匹配项,您可以使用用于创建向量Embeddings的相同ML embedding模型将主题项或查询转换为向量。向量数据库比较这些对象的相似性以找到最接近的匹配,提供准确的结果,同时消除传统搜索技术可能返回的不相关结果。

让我们看看向量搜索的一些常见用例:

1. 语义搜索

搜索文本和文档通常可以通过两种方式完成。词汇搜索查找模式和精确的单词或字符串匹配,而语义搜索使用搜索查询或问题的含义并将其置于上下文中。向量数据库存储和索引来自自然语言处理模型的向量Embeddings,以理解文本字符串、句子和整个文档的含义和上下文,从而获得更准确和相关的搜索结果。

使用自然语言查询来查找相关结果是一种更好的体验,并允许用户更快地找到他们需要的内容,而无需了解数据分类的具体方式。

2. 对图像、音频、视频、JSON和其他形式的非结构化数据进行相似性搜索

图像、音频、视频和其他非结构化数据集在传统数据库中分类和存储非常具有挑战性。这通常需要手动将关键字、描述和元数据应用于每个对象。一个人对一个复杂数据对象进行分类的方式对另一个人来说可能并不明显。因此,搜索复杂的数据可能非常容易出错。这种方法要求搜索者了解数据的结构,并构建与原始数据模型匹配的查询。

3. 排名和推荐引擎

向量数据库是为排名和推荐引擎提供动力的一个很好的解决方案。对于在线零售商来说,它们可以用来推荐与过去购买的商品相似的商品,或者客户正在研究的当前商品。流媒体服务可以应用用户的歌曲评级,为个人量身定制完美匹配的推荐,而不是依赖于协同过滤或流行列表。

基于最接近匹配找到相似项目的能力使向量数据库成为提供相关建议的理想选择,并且可以很容易地根据相似性分数对项目进行排名。

4. 重复数据删除和记录匹配

向量相似性搜索的另一个用例是记录匹配和重复数据删除。使用相似性服务查找几乎重复的记录可以在各种应用程序中使用。考虑一个应用程序,它从目录中删除重复项,以使其更可用和更相关。

5. 数据质检

向量数据库在查找相似对象方面做得很好,但它们也可以查找与预期结果相距甚远或不同的对象。这些异常在用于威胁评估、欺诈检测和IT操作的应用程序中是有价值的。可以识别出最相关的异常以进行进一步分析,而不会因高假警报率而占用大量资源。

最受欢迎的向量数据库:

Pinecone

Pinecone就是这样一个向量数据库,它在整个行业中被广泛接受,用于解决复杂性和维度等挑战。Pinecone是一个云原生向量数据库,用于处理高维向量数据。Pinecone的核心基础方法是基于近似最近邻(ANN)搜索,它可以有效地定位更快的匹配并在大型数据集中对它们进行排序。

Pinecone的一些主要特征包括:

  1. 高度可扩展:Pinecone可以处理数十亿个高维向量和水平缩放,使其适用于最苛刻的机器学习工作负载。

  2. 实时数据摄取:松果支持实时数据摄取,允许您存储和索引新数据,因为它变得可用而没有任何停机时间

  3. 低延迟搜索:Pinecone的高级索引算法确保最近邻查询和相似性搜索操作以低延迟执行,提供快速准确的结果。

  4. 易于集成:Pinecone的API设计简单直观,使其易于与现有的机器学习工作流程和数据管道集成。

  5. 完全管理的服务:Pinecone是一个完全管理的平台,这意味着您不必担心基础设施管理或维护,让您专注于开发和部署机器学习应用程序。

Weavite

Weaviate是一个向量数据库和搜索引擎。它是一个低延迟的向量搜索引擎,支持各种媒体类型(文本、图像等)。Weaviate使用机器学习对数据进行向量化和存储,并找到对自然语言问题的回答。它包括语义搜索、问答提取、分类和可定制模型(PyTorch/TensorFlow/Keras)。您还可以使用Weaviate在生产中扩展自定义机器学习模型。

Weaviate存储媒体(文本,图像。等)对象及其相应的向量,允许将向量搜索与结构化过滤与云原生数据库的容错相结合。编织搜索可以通过不同的方法执行,例如GraphQL、REST和各种语言客户机。Python、Javascript、Go和Go是支持Weaviate客户端的流行编程语言。

如今,Weaviate被软件工程师用作其应用程序的ml优先数据库,数据工程师使用以人工神经网络为核心的向量数据库,数据科学家使用MLOps部署他们的搜索应用程序。

Weaviate特性:

快速查询 -在不到100毫秒的时间内,Weaviate在数百万个项目上运行10个最近邻(NN)搜索。

不同的媒体支持 -使用最先进的AI模型推理(例如变形金刚)图像,文本等。

结合标量和向量搜索 - Weaviate保存您的对象和向量,确保检索始终快速。不需要第三方对象存储系统。

水平可扩展性 - Weaviate可以根据用例在生产中水平扩展。

类图连接 -在数据项之间建立类图连接,以模拟数据点之间的实际连接。GraphQL用于遍历这些连接。

Milvus

Milvus是一个开源向量数据库,为用户提供高效、可扩展的解决方案,用于存储、管理和搜索大规模、高维数据。它的设计目标是满足对高级数据分析和机器学习应用快速增长的需求,这些应用需要快速准确地计算大量复杂数据。Milvus可用于各种行业,包括金融、电子商务、医疗保健等。在本文中,我们将深入了解Milvus及其关键特性、用例和优点。

Milvus的主要功能:

Milvus是一个高度可扩展和灵活的数据库,支持广泛的向量数据类型,包括图像,音频和文本数据。它的主要特点包括:

快速高效: Milvus可以处理大量的向量数据,低延迟和高吞吐量。它使用最先进的算法和技术来优化存储和检索速度,使其成为需要快速响应时间的实时应用的理想选择。

可扩展: Milvus设计为水平扩展,允许用户随着数据增长向集群添加新节点。这使得用户即使使用大量数据集也能获得高性能和可伸缩性。

搜索和相似度: Milvus提供了一个强大的搜索和相似度查询引擎,允许用户在他们的数据集中搜索相似的向量。这对于图像和面部识别、自然语言处理和推荐系统等应用程序尤其有用。

多接口: Milvus支持多种编程接口,包括Python, Java和Go,使其易于与现有的数据分析和机器学习工具集成。

FAISS

Faiss背后的科学原理有详细的描述在这里。Faiss的想法是,向量可以被转换成更像我们习惯搜索的文本的东西——一种码字。一旦有了这个码字,就可以使用标准的颠倒索引技术来检索类似的结果。使用精确的向量比较,结果可以基于这个近似结果集重新排序。

原文:Vector Databases


TorchV AI支持试用!

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



Pandas AI——未来的数据分析工具

想象一下,你可以像和你最好的朋友聊天一样和你的数据交谈。这就是Panda AI所做的!这个Python库具有生成人工智能功能,可以将您的数据框架转换为会话功能。不用再无休止地盯着行和列了。

但别担心,Pandas AI不会取代你心爱的Pandas。它在这里起到了增强的作用!借助Pandas AI,您可以将数据分析和操作提升到一个新的水平。把它想象成一个超级英雄的助手——它会帮助你拯救一天,让你的生活更轻松(好的,知道了,讲重点)。

Pandas AI的可能性是无限的。想象一下,拥有一个可以编写自己的报告的数据框架,或者一个可以分析复杂数据并为您提供易于理解的摘要的数据框架。

在这个快速指南中,无论您在该领域的经验水平如何,您都将逐步了解如何使用这个尖端库。

无论您是经验丰富的数据分析师还是初学者,本指南都将为您提供所需的所有工具,让您充满信心地深入Pandas AI的世界。所以坐下来,放松,让我们探索Pandas AI所提供的令人兴奋的可能性!

GitHub Repository — https://github.com/gventuri/pandas-ai

Colab代码https://colab.research.google.com/drive/1rKz7TudOeCeKGHekw7JFNL4sagN9hon-?usp=sharing

使用pip安装Pandas AI

1
pip install pandasai

我们的数据框架包含了关于各个国家的信息,包括他们的GDP(以百万美元计)和幸福指数得分。它由10行3列组成:

img

导入pandasai和OpenAI

在下一步中,我们将导入之前安装的pandasai库,然后导入LLM(大型语言模型)特性。截至2023年5月,pandasai 只支持OpenAI模型,我们将利用该模型来理解数据。

img

要使用OpenAI API,您必须生成自己唯一的API密钥。如果你还没有这样做,你可以在平台的官方网站platform.openai.com上轻松创建一个帐户。一旦您创建了您的帐户,您将获得即时5美元的信用额度,可用于探索和实验API。

初始化PandasAI和提问

之后,我们将向Pandas AI提供我们的OpenAI模型,并提出各种问题。

img

当使用pandas_ai.run时,两个参数是必需的:您正在使用的数据框和您正在寻求答案的问题,它根据提供的数据框返回前5个最幸福的国家。

提更复杂的问题

让我们检查一下它是否可以为我们绘制图形。

img

是的,根据我问的问题,它确实画出了图表。

img

让我们执行一个复杂的任务,从下面的数据集中删除NAN值:

img

这是我们获得输出:

img

但是当我再次打印df变量时,它确实从数据集中删除了那些NAN值,完全删除了那一行

img

Pandasai库提供了广泛的可能性,您可以通过访问我之前分享的官方存储库页面来探索它们。

原文:Pandas AI — The Future of Data Analysis


TorchV AI支持试用!

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



使用LangChain和大模型与PostgreSQL对话

大型语言模型(大语言模型)的兴起带来了技术上的重大转变,使开发人员能够创建以前不敢想的应用程序。LangChain是一个用于prompts的编排工具,它利用大语言模型(LLM)的功能来转换您与数据库通信的方式。使用LangChain,您可以轻松地与数据库对话,并实时获得精确的响应,就像您在与一位亲密的朋友交谈一样。

在本教程中,我们将连接到PostgreSQL数据库,并使用Langchain启动与它的对话,而不需要通过SQL查询数据库。

本文的内容

  • LangChain介绍
  • 为什么要使用LangChain
  • LangChain的架构
  • 基于LangChain的应用
  • 用LangChain创建一个问答应用
  • 使用LangChain创建一个简单的LLM调用功能
  • 创建prompt模板
  • 使用LangChain与数据库进行交互

LangChain介绍

LangChain是一个开源库,通过建立一种将大语言模型与外部数据源(如个人文档或互联网)链接的机制,为开发人员提供了一套全面的资源,以开发运行在大型语言模型(LLM)上的应用程序。开发人员可以利用LangChain将一系列命令串在一起,以创建复杂的应用程序。简而言之,LangChain作为一个框架,使一系列prompts的执行能够达到特定的结果。

为什么要使用LangChain

对于开发人员来说,LangChain是一个重要的工具,因为它使使用大语言模型构建复杂的应用程序变得更加容易。它允许用户将大语言模型连接到其他数据源。通过将大语言模型连接到其他数据源,应用程序可以处理更广泛的信息。

这使得应用程序更加强大和通用。

Langchain提供的功能特性包括:

  • 灵活性:LangChain是一个高度灵活和可扩展的框架,允许轻松的组件交换和链定制,以满足独特的需求。
  • 速度:LangChain开发团队正在不断提高库的速度,确保用户能够访问最新的LLM功能。
  • 社区:LangChain拥有一个强大的、活跃的社区,用户可以在必要时随时寻求帮助。

LangChain架构

该框架被组织为七个模块,每个模块允许您管理与LLM交互的不同方面。

image-20230704101802963

  • LLM

    LLM是LangChain的基本组成部分。它是大型语言模型的包装器/连接器,可以连接各种模型,做集成工作。

  • Chain(链)

    很多时候,要解决任务,对LLM的单个API调用是不够的。该模块允许集成其他工具。例如,您可能需要从特定的URL获取数据,总结返回的文本,并使用生成的摘要回答问题。该模块允许连接多个工具以解决复杂的任务。

  • prompts模板

    prompts是任何NLP应用程序的核心。它是用户如何与模型交互以尝试从模型中获得输出。知道如何写一个有效的prompt是很重要的。LangChain提供了允许用户格式化输入和其他实用程序的prompt模板。

  • 文件加载器和Utils

    LangChain的文档加载器和Utils模块分别方便连接到数据源和计算。utils模块提供了Bash和Python解释器会话。这些适用于用户需要直接与底层系统交互的应用程序,或者需要代码片段来计算特定的数学量或解决问题而不是立即计算答案的应用程序。

  • Agent(代理)

    代理作为一个中枢,会利用LLM的能力做出决定、采取行动、观测完成的步骤,并循环任务,直到整个任务完成。LangChain库提供了可以根据输入而不是硬编码的确定性序列采取操作的代理。

  • Indexes(索引)

    当与特定于应用程序的数据结合使用时,语言模型会变得更加强大——该模块包含用于加载、查询和更新外部数据的接口和集成。

  • Memory(内存)

    该模块使用户能够在模型调用之间创建持久状态,能够使用记住过去所说的内容的模型来改进我们的应用程序(的任务)。

  • Callbacks(回调)

    使您可以记录和流化任何链的中间步骤,从而易于观察、调试和评估应用程序的内部。

LangChain的一些应用场景

以下是LangChain的一些常见应用:

  • 使用自然语言查询数据集

    大语言模型可以使用自然语言编写SQL查询。LangChain的文档加载器、索引相关链和输出解析器帮助加载和解析数据以生成结果。另外,向LLM输入数据结构是一种更常见的方法。

  • 与api交互

    LangChain的链和代理功能使用户能够将大语言模型与其他API调用一起包含在更长的工作流程中。这对于用例很有用,例如检索库存数据或与云平台交互。

  • 建立一个聊天机器人

    生成式人工智能为行为逼真的聊天机器人带来了希望,LangChain的prompt模板可以控制聊天机器人的个性和反应。消息历史记录工具通过为聊天机器人提供比默认情况下大语言模型提供的更长的内存,可以在会话中甚至跨多个会话中实现更大的一致性。

使用LangChain创建一个问答应用程序

在上一节中,我们介绍了对LangChain的基本理解。在下一节中,我们将使用LangChain构建一个问答应用程序。按照下面给出的步骤,使用LangChain构建一个基本的问答应用程序。

安装依赖

  • 通过执行以下命令创建并激活虚拟环境。
1
2
3
python -m venv venv
source venv/bin/activate #for ubuntu
venv/Scripts/activate #for windows
  • 使用pip安装 langchain,openaipython-environ 库.
1
pip install langchain openai python-environ

设置环境变量

您可以将任何开源模型与langchain一起使用。然而,openai模型给出了比开源模型更好的结果,如果您正在使用任何Openai模型,则需要Openai密钥来访问langchain。本教程使用openai模型设计。按照以下步骤创建一个新的openai密钥。

img

  • 创建一个名称为 .env的文件,使用下面的格式添加你的key。
1
OPENAI_API_KEY=<your_openai_key>

使用LangChain创建简单的LLM调用

创建一个python文件,命名为 langchain_demo.py ,添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
from langchain.llms import OpenAI

# Accessing the OPENAI KEY
import environ
env = environ.Env()
environ.Env.read_env()
API_KEY = env('OPENAI_API_KEY')

# Simple LLM call Using LangChain
llm = OpenAI(model_name="text-davinci-003", openai_api_key=API_KEY)
question = "Which language is used to create chatgpt ?"
print(question, llm(question))

我们从langchain中导入了OpenAI包装器。OpenAI包装器需要一个OpenAI Key。使用environ库从环境变量访问OpenAI key。将其初始化为LLM 变量,模型为text-davinci-003。最后,定义一个问题字符串并生成一个响应( LLM(问题))。

运行脚本

使用以下命令运行LLM调用。

1
python langchain_demo.py

您将得到如下输出。

img

创建prompt模板

创建一个新的python文件 langchain_demo.py ,加入以下代码:

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

# Accessing the OPENAI KEY
import environ
env = environ.Env()
environ.Env.read_env()
API_KEY = env('OPENAI_API_KEY')

# Creating a prompt template and running the LLM chain
from langchain import PromptTemplate, LLMChain
template = "What are the top {n} resources to learn {language} programming?"
prompt = PromptTemplate(template=template,input_variables=['n','language'])
chain = LLMChain(llm=llm,prompt=prompt)
input = {'n':3,'language':'Python'}
print(chain.run(input))

我们从langchain中导入了PromptTemplateLLMChain。通过指定 templateinput_variables ,创建一个prompt模板,用于获取学习编程语言的顶级资源。创建一个LLMChainchain.run()方法来运行LLM链以获得结果。

运行脚本

使用以下命令运行LLM链。

1
python langchain_demo.py

您将得到如下输出。

img

使用LangChain与数据库进行交互

在本节中,我们将创建一个应用程序,以一种自然的方式与postgreSQL交互(不直接查询)。

安装postgres

img

img

img

img

img

img

img

img

img

img

img

创建数据库

已完成postgres软件的安装。创建一个名为tasks的数据库表来保存任务详细信息,该数据库可以用作语言链的数据源。

  • 打开pgAdmin4应用程序。

  • 提供root密码,显示数据库。

img

img

  • 右键单击databases,选择create→Database。提供数据库名称并单击Save以完成数据库创建。

img

img

安装依赖

  • 通过执行以下命令创建并激活虚拟环境。
1
2
3
python -m venv venv
source venv/bin/activate #for ubuntu
venv/Scripts/activate #for windows
  • 使用pip安装 langchain,openai, python-environpsycopg2 库.
1
pip install langchain openai python-environ psycopg2 

创建表并插入数据

创建一个新的python文件 db.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import psycopg2

import environ
env = environ.Env()
environ.Env.read_env()

# Establish a connection to the PostgreSQL database
conn = psycopg2.connect(
host='localhost',
port=5432,
user='postgres',
password=env('DBPASS'),
database=env('DATABASE')
)

# Create a cursor object to execute SQL commands
cursor = conn.cursor()

# Create the tasks table if it doesn't exist
cursor.execute('''CREATE TABLE IF NOT EXISTS tasks
(id SERIAL PRIMARY KEY,
task TEXT NOT NULL,
completed BOOLEAN,
due_date DATE,
completion_date DATE,
priority INTEGER)''')

# Insert sample tasks into the tasks table
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Complete the web page design', True, '2023-05-01', '2023-05-03', 1))
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Create login and signup pages', True, '2023-05-03', '2023-05-05', 2))
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Product management', False, '2023-05-05', None, 3))
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Cart and wishlist creation', False, '2023-05-08', None, 4))
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Payment gateway integration', False, '2023-05-10', None, 5))
cursor.execute("INSERT INTO tasks (task, completed, due_date, completion_date, priority) VALUES (%s, %s, %s, %s, %s)",
('Order management', False, '2023-05-10', None, 6))

# Commit the changes and close the connection
conn.commit()
conn.close()

我们已经安装了’psycopg2库,并从 .env文件中访问了环境变量DBPASS DATABASEconn对象将使用psycopg2.connect()方法建立到PostgreSQL数据库的连接。用于创建任务表和在其中插入一些值的SQL查询将在cursor 对象的帮助下执行。

运行脚本

要创建任务表并向其中插入值,请使用以下命令运行’ db.py ‘脚本。

1
python db.py

设置SQL数据库Chain

创建一个python文件 app.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
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
from langchain import OpenAI, SQLDatabase, SQLDatabaseChain

import environ
env = environ.Env()
environ.Env.read_env()

API_KEY = env('OPENAI_API_KEY')

# Setup database
db = SQLDatabase.from_uri(
f"postgresql+psycopg2://postgres:{env('DBPASS')}@localhost:5432/{env('DATABASE')}",
)

# setup llm
llm = OpenAI(temperature=0, openai_api_key=API_KEY)

# Create db chain
QUERY = """
Given an input question, first create a syntactically correct postgresql query to run, then look at the results of the query and return the answer.
Use the following format:

Question: Question here
SQLQuery: SQL Query to run
SQLResult: Result of the SQLQuery
Answer: Final answer here

{question}
"""

# Setup the database chain
db_chain = SQLDatabaseChain(llm=llm, database=db, verbose=True)


def get_prompt():
print("Type 'exit' to quit")

while True:
prompt = input("Enter a prompt: ")

if prompt.lower() == 'exit':
print('Exiting...')
break
else:
try:
question = QUERY.format(question=prompt)
print(db_chain.run(question))
except Exception as e:
print(e)

get_prompt()

看一下这些代码干什么用:

  • 导入OpenAISQLDatabaseSQLDatabaseChain三个langchain模块
  • 从环境变量文件访问OPENAI_API_KEY
  • 通过指定连接URL,使用SQLDatabase.from_uri()方法建立数据库连接。
  • 通过指定温度和openai_api_key,使用OpenAI()创建LLM对象。
  • 通过指定LLM和数据库对象,使用SQLDatabaseChain()创建名为db_chain的数据库链对象。
  • Get_prompt()从控制台获取用户输入,并通过将问题作为参数提及,以该格式创建查询。它使用db_chain.run()方法运行SQL数据库链。

运行应用

使用以下命令运行SQL数据库链。

1
python app.py

您将得到如下输出:

img

img

好了!你的第一个python langchain应用程序:)

本教程的完整源代码可以在这里找到:SQLDatabaseChain LangChain Demo

原文:Chat with your databases using LangChain






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

公众号:土猛的员外


TorchV AI支持试用!

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



我是怎么用AI提升工作上限的

6月份比较懒(其实是事情比较多),只在月初写了一篇公众号文章。但是让我比较惊讶的是,这个月转发数量不少。关注者也增加了不少,几乎每天都有新增,而且没有一个是微信朋友。所以,我第一次感觉到应该是前面写的一些内容,可能对大家有一些小帮助,才会被大家经常转发和关注。

嗯,也是感觉到这份“厚爱”,我决定再写一篇非常“干货”的文章——我是如何利用当下的AI工具提升工作的,这些工具主要是Midjourney和ChatGPT,涉及的使用场景其实不仅仅是软件、互联网等。

好,下面开始。

Midjourney:描绘你想象中的样子

问题

如果你要创造一款产品,无论是一款专业的软件产品、一个App、一个网站,或者是家装设计、服装设计和工艺品设计,当你有一个好点子的时候,最开始都是很兴奋的。然后过了几天,脑子的画面开始淡化,或者你的“理性”开始对你说会有各种困难,你在一点点地打退堂鼓。再之后,你给合作者描绘你的点子,他们可能是UX设计师、产品经理,或者板房师傅,你发现他们很难理解你的想法,或者他们无法和你共同“看见”你脑子的画面。于是,在各种抱怨与妥协中,最终产品出来了,但和你想象中的相比,多数时候可能只能实现70%的完成度。

答案

最近一段时间我对Midjourney比较痴迷,并做了比较深度的研究,看过上一篇公众号文章的朋友应该知道。所以我就想着在整个产品设计的策划阶段使用Midjourney来组织整个思路,让产品研发团队和市场同事都可以共同“看见”。

下面举一个具体的例子吧。

因为AI热潮的兴起,公司的产品就需要有AI加持。这次在思考产品升级的过程中,一下子出来三个比较明确的产品,都是基于大模型的。第一个产品是农文旅行业大模型,这个不是本文的重点,这里就直接略过了,只提一句这是基于自主训练的7B大模型。这里要举的例子是第二和第三个产品,我可以说说思考的过程。

第二个产品是一个博物馆的产品,在公司内部小范围内已经做了几次讨论,内部几个很有见解的大佬对这个产品都很看好,它在传统的产品上进行升级,并对原有的用户使用场景做了一些改变。为了让团队里面的产品经理、UI设计师和研发人员能清晰明白这是什么产品,也为了让解决方案架构师、销售经理等能快速理解可以提前去摸市场反馈,我用Midjourney做了一些产品图。

其中两幅效果图

01

图1:一个iPad形式的产品展示

02

图2:产品使用场景效果图

这是完全由Midjourney制作的产品效果图和使用场景效果图,非常符合我心里的画面,和同事详细讲解了产品之后,他们也都觉得很贴切,包括人物的眼神都很精确。

针对这个博物馆产品,我在后面还配套了一个小程序产品,以下是其中的一幅效果图,配色和设计很符合客户特点。

03

图3:小程序效果图,重点在于风格,不要在意细节

第三个产品就更有意思了,它也是基于大模型的,并且使用场景的设计上非常巧妙,我不能展示太多,就展示一下最终的外形吧。

04

图4:手办的效果图,人见人爱

我们可以认为这是一种手办的效果图,我用Midjourney一共生成了16个,只展示其中4个吧。

以上这些图,当然是我对Midjourney非常熟练之后,再加上多次调整才制作出来的(花了8美元),但是一旦你上手了,就能让你事半功倍。我相信,如果源头(脑子中的想法)对了,还能高度还原地展示出来,对于产品创造来说是非常重要的。如果我们从源头到成品的各个环节,没办法高度还原,一环环妥协,那么最终就是特斯拉变吉安特了。

ChatGPT:可以增加工作广度

阅读广度

就效果来说,我个人感觉ChatGPT给我带来的工作价值不如Midjourney那么见成效,因为我对ChatGPT的使用往往是在中间环节。比如常见的应用场景是:

  • 归纳:把一篇2000字的文章归纳成100字;
  • 翻译:这是我最常见的用法,包括一些独立开发者分享的浏览器翻译插件(用自己的openai秘钥),让我感觉真的互联网无国界,什么英语、西班牙语、法语、日语,什么文章都能看。而且与传统翻译软件相比,有一个非常大的优势,就是对技术类文章的翻译非常到位;
  • 润色:包括翻译的内容,有时候还是会非常不适合我阅读的,这时候,我会再将翻译成中文的内容再放进去润色一遍,让内容更易于阅读,假设阅读吸收率从52%升到88%;
  • 出题:一篇文章可能我是需要去掌握里面核心点的,但我不想很仔细地去阅读,那我的处理方式是让ChatGPT帮我根据这篇文章出10题选择题,包括正确答案,然后自己一题一题做下来。如果对于不是很有把握和做错的题目,我会再到文章里面去看一下相关内容,其他很有把握的内容,我就不看了。

这几种用法,可以非常快速地让我获取知识,快速地搞懂一些其他领域的知识。

05

图5:ChatGPT帮我们出题目

结对编程

ChatGPT对我来说最好用的还是“结对编程”,就像是我的一个实习生。

今年我自己利用业余时间做了一个工具,是基于Svelte的,一种现代化前端框架,类似于React、Vue。我自己的技术栈一直是数据库、Java、机器学习之类的,上一次大密度写前端还是在2010年之前了,用的是JQuery。这次写Svelte,我没有先去啃书,而是直接搭了Project,然后用ChatGPT帮我写代码——我提问题,它回答。

这期间还用了CSS的框架Tailwindcss,又是一个以前的盲区。但是这次我断断续续地用了两周时间就搭出了这个工具,然后在这次的Midjourney生成产品图的工作上帮了我大忙。

06

图6:编程好帮手,但需要使用者有一些IT技术知识

07

图7:自己在业余时间开发的Midjourney图片生成的小工具

LangChain—让大模型有无限可能

LangChain是一个好东西,它包含了大模型的连接器、Agent(代理)、Memory(状态存储)、Chain(链路)、外部连接插件和一些可以填空的prompt(就是输入给大模型的话)模板等,这些组件组合在一起,可以将我们的一个任务进行拆解,逐步去完成。

举个例子,比如基于LangChain和大模型的驾驶舱,是可以“听话”,然后随意组合呈现的,这里面就需要将任务拆解才能完成。比如我们说:“帮我分析一下6月份的游客消费为什么会比5月份增加这么多?”,假设的分解如下:

  • 首先这句话会被文本转向量(变成几百、上千维的向量数组),然后去匹配有一定相关量的分析组件;
  • 通过相似度算法,找出驾驶舱中有消费相关的各类分析组件(如总消费、人均消费、按类型消费、客流量、天气等23个分析组件);
  • 选择promp模板,将23个分析组件的名称和简述组装进新的prompt:“请将以下分析组件中,选择最能分析消费数据变化的8个:……23个组件的名称和简述。” 注:8个组件基本上凑成一屏;
  • 再通过agent,从数据库获取5月和6月相关数据,装载进这8个组件(比如客流量折线图,可以用蓝色表示5月数据,红色表示6月数据);
  • 最后将这8块数据分析全部展示在同一屏上。

原本的情况是,客流是单独一屏,交通是单独一屏,消费是单独一屏…我们很难把分析一个问题的所有关联数据都集中在一屏来统一查看,而通过LangChain和大模型的结合,我们就可以做到。当然,这里对于前端的要求还是很高的,各个分析组件的尺寸和样式需要灵活可适配。

随着时间推移,大厂在通用大模型方面的优势会越来越大,因为他们有更多资源(GPU服务区)、更多人才和更多数据。对于大多数中小型公司和个人来说,LangChain是真正值得发力的技术。我们的农文旅行业大模型就是基于自训练7B大模型+LangChain,而且最近和国内两个顶级大厂交流下来,他们所谓的行业大模型(注意区分通用大模型和行业大模型)也是这个技术架构。

08

图8:LangChain的一个用法:行业大模型

再补一句就是,对于中小公司和个人来说,要在这波AI上有所收获,我目前看来最有可能的就是好好把握LangChain和Stable Diffusion(你可以理解为是开源版的Midjourney)。

总结

好了,今天就先写到这里吧。欢迎大家多多关注(关注公众号),我会持续输出原创内容,结合自己的思考和实践。






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

公众号:土猛的员外


TorchV AI支持试用!

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



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支持试用!

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