发挥向量数据库的力量:用个性化信息影响语言模型
利用个性化信息影响语言模型的向量数据库的力量
使用向量数据库增强您的语言模型!使用您自己的数据个性化提示,以塑造这些强大模型的行为,为它们提供上下文。集成个人信息,实现定制化的语言生成体验。
在本文中,我们将学习两种新技术:向量数据库和大型语言模型如何共同工作。这种组合目前正在引起技术行业的重大变革。
它经常用于整合您自己的文档或企业知识数据库,这些语言模型尚未经过训练。其目的是确保在生成模型响应时考虑到此类信息。它是关于让您的语言模型访问您的有用信息,以使其输出更好、更相关或两者兼有。
这就是我们将要探索的用例。以下是我们将要执行的步骤:
- 使用ChromaDB创建向量数据库。
- 在数据库中存储信息。
- 通过查询检索信息。
- 使用此信息生成扩展提示。
- 从Hugging Face加载模型。
- 将提示传递给模型。
- 模型将考虑提供的信息提供响应。
通过遵循这些步骤,我们可以使用ChromaDB轻松地将个人信息添加到语言模型的决策过程中。
- 从ChatGPT到Pi,我要告诉你为什么!
- 准备好迎接AI的声音革命:2023年是生成式声音波的年份
- 一项新的人工智能研究提出了一种多模态的思维链推理语言模型,其在ScienceQA上的表现超过了GPT-3.5 16%(从75.17%提升至91.68%)
这样,我们可以获得高度定制和上下文相关的响应。
让我们深入了解每个步骤,并发掘这种方法的全部潜力!
但在深入研究之前,让我们简要介绍一下向量数据库的工作原理。
向量数据库如何工作?
首先,这些数据库存储向量,正如它们的名称所示。我们需要将我们拥有的文本转化为可以存储在这些工具中的信息。换句话说,我们需要将文本转化为向量。
有各种方法可用,但总的来说,它们都会将一系列文本(可以是单词、音节或短语)转化为向量。
我们得到的向量是多维的,自然地,我们可以计算一个向量与另一个向量之间的差异,或者搜索与特定向量更接近的向量。
有了这些信息,我们可以大致了解它的工作原理。
- 我们将文本转换为向量并存储它们。
- 我们将要搜索的文本转换为向量并与之进行比较。
- 它选择最接近的向量。
- 然后将这些向量转换回文本并返回。
让我们忘记文本搜索!重点是向量比较。
正如您可能已经猜到的那样,将文本转换为向量的过程对于存储的文本和要搜索的文本应该是相同的。否则,比较将毫无意义。
向量数据库变得越来越重要,不仅适用于我们这样搜索相关新闻的情况,还适用于任何推荐系统。
确实,向量本质上是数值表示,不一定来源于文本。我们可以将电影转换为向量,并存储它们以及它们的元数据,然后搜索最相似的电影。我们甚至可以识别出允许我们基于用户观看习惯推荐电影的模式。等一下……难道Netflix也在为他们的推荐系统使用它们吗?我们来打个赌怎么样?
我们将使用什么技术?
至于数据库,我选择了ChromaDB。它是最新出现并迅速获得人气的数据库之一。您将看到它的使用非常简单!我们不需要担心太多,因为ChromaDB会为我们处理大部分工作。它是一个开源解决方案,可以与LangChain无缝集成,在未来的文章中,我们将使用LangChain构建越来越复杂的解决方案。
我们将从Hugging Face获得模型。具体来说,我使用了dolly-v2–3b。这是Dolly Models系列中最小的版本。我建议尽可能使用较小的模型版本。
个人而言,每当有机会时,我喜欢尝试不同的模型,而Hugging Face提供了大量可供选择的模型。
如果您想尝试其他模型,可以在Hugging Face上搜索,并确保其经过文本生成训练。
让我们开始项目吧!
您可以在Kaggle上的一个笔记本中找到代码,在那里您可以分支、运行和进行实验。它还在GitHub上的一个存储库中提供,我在那里存储了所有大型语言模型课程的笔记本以及相应的文章。
使用矢量数据库优化LLM的提示
使用多个数据源的Kaggle笔记本来探索和运行机器学习代码
www.kaggle.com
GitHub – peremartra/Large-Language-Model-Notebooks-Course
通过在GitHub上创建一个帐户来为peremartra/Large-Language-Model-Notebooks-Course开发做贡献。
github.com
如果您有兴趣跟进完整的课程,最好订阅GitHub存储库。这样,您将收到有关新课程或对现有课程的修改的通知。
让我们导入必要的库。
要开始,我们需要安装一些Python包:
- sentence-transformers:这个库用于将句子转换为固定长度的向量,即嵌入。
- transformers:这个包提供了各种库和实用程序,便于使用变换器模型。即使我们可能不直接使用它,但不安装它将导致在使用模型时出现错误消息。
- chromadb:我们的矢量数据库。它易于使用、开源且快速。它可能是存储嵌入的最广泛使用的矢量数据库。
您可以使用以下命令安装这些包:
!pip install sentence-transformers!pip install xformers!pip install chromadb
以下两个库可能对您来说已经很熟悉:Numpy和Pandas。它们是数据科学中最常用的两个Python库。
Numpy是一个用于数值计算的库,它使数学计算变得容易。
Pandas则是数据操作和分析的首选库。
import numpy as np import pandas as pd
加载数据集。
我已经准备好了与Kaggle上的三个不同数据集一起使用的笔记本。所有数据集都包含新闻文章,但格式不同。其中两个只包含文章摘要,而第三个包含完整的文章内容。
主题标记的新闻数据集
包含8个主题(平衡)的108774篇新闻文章
www.kaggle.com
BBC新闻
自动更新的数据集- BBC新闻RSS订阅
www.kaggle.com
MIT AI新闻发布至2023年
由MIT在其网站上发布的所有与人工智能相关的新闻。
www.kaggle.com
将笔记本与三个不同的数据集一起工作的唯一原因是为了方便实验,看到解决方案对不同输入的反应。随意尝试任意多个数据集。关键是观察和理解解决方案在不同数据源下的行为和性能。
由于在Kaggle或Colab等平台上的资源有限,我设置了加载新闻文章数量的限制。此限制由变量MAX_NEWS定义。
包含新闻文章的字段名称已分配给变量DOCUMENT,而可能被视为元数据或类别的内容存储在变量TOPIC中。通过这种方式,我们将笔记本的其余部分与所选择使用的特定数据集隔离开来。
您只需取消要使用的数据集的注释标记。
news = pd.read_csv('/kaggle/input/topic-labeled-news-dataset/labelled_newscatcher_dataset.csv', sep=';')MAX_NEWS = 1000DOCUMENT="title"TOPIC="topic"#news = pd.read_csv('/kaggle/input/bbc-news/bbc_news.csv')#MAX_NEWS = 1000#DOCUMENT="description"#TOPIC="title"#news = pd.read_csv('/kaggle/input/mit-ai-news-published-till-2023/articles.csv')#MAX_NEWS = 100#DOCUMENT="Article Body"#TOPIC="Article Header"#由于这只是一个课程,我们只选择了新闻的一小部分。subset_news = news.head(MAX_NEWS)
导入并配置向量数据库。
首先,我们将导入ChromaDB,然后是其来自config模块的Settings类。该类允许我们修改ChromaDB系统的配置并自定义其行为。
import chromadbfrom chromadb.config import Settings
现在,我们已经导入了库,我们可以通过调用导入的Settings类来创建一个settings对象。
settings对象将使用两个参数创建。
- chroma_db_impl:我们将指示要使用的数据库实现和我们将存储数据的格式。我不会详细介绍所有各种选择,但我会解释我选择的背后动机: – 对于实现,我们选择了“duckdb”。它在大部分操作中主要在内存中运行,性能很好,并且与SQL完全兼容。 – 至于数据格式,我们将使用“parquet”。这是表格数据的最佳选择。Parquet提供很好的压缩比,并为查询和处理数据提供高性能。
- persist_directory:此参数包含我们要保存信息的路径。如果我们不指定它,数据库将是内存中的,并且不是持久的。然而,纯粹在内存中工作可能会在云端或Kaggle等协作环境中引发问题,因为它可能会尝试创建临时文件。
settings_chroma = Settings(chroma_db_impl="duckdb+parquet", persist_directory='./input')chroma_client = chromadb.Client(settings_chroma)
在ChromaDB中处理数据。
ChromaDB中的数据组织成集合。每个集合必须具有唯一的名称,因此,如果我们尝试使用现有名称创建集合,它将抛出错误。
为了实现这一点,我们将检查集合是否存在于ChromaDB集合列表中。如果存在,则在创建之前删除它。重要的是要注意,此方法适用于测试和实验中的笔记本。在生产环境中应采用不同的策略。
或者,我们可以创建三个单独的集合,每个数据集一个。我将在这里提出这个想法,以便您可以修改笔记本并根据自己的喜好进行调整。
collection_name = "news_collection"if len(chroma_client.list_collections()) > 0 and collection_name in [chroma_client.list_collections()[0].name]: chroma_client.delete_collection(name=collection_name)collection = chroma_client.create_collection(name=collection_name)
创建集合后,我们可以通过调用`add`函数并为每个记录提供文档、元数据和唯一标识符来向ChromaDB数据库添加数据。
文档可以是任意长度,并且将包括我们文档的全部内容。根据我们想要存储的文档长度,我们可以考虑将它们拆分为较小的部分,如页面或章节。我们应该记住,数据库返回的信息将用于创建我们提示的上下文,并且这些提示在长度上有限制。因此,在设计系统时,考虑文档长度和提示长度限制之间的权衡是很重要的。
在这个例子中,我们将使用整个文档信息来创建提示。然而,在更高级的项目中,我们可以使用另一个模型来生成返回信息的摘要。这使我们能够创建一个包含更少内容但更相关的提示。当我们深入了解LangChain的工作原理时,我们将进一步探索这种方法。
元数据本身不在向量搜索中使用。元数据用于存储可以在后处理中用于细化结果的类别或其他信息。
至于唯一标识符,我们可以使用Python轻松生成它。可以简单地从0到MAX_RANGE生成数字。
collection.add( documents=subset_news[DOCUMENT].tolist(), metadatas=[{TOPIC: topic} for topic in subset_news[TOPIC].tolist()], ids=[f"id{x}" for x in range(MAX_NEWS)],)
一旦我们将信息存储在ChromaDB中,我们就可以执行查询并检索与所需主题或搜索查询匹配的文档。
正如前面提到的,结果是基于搜索词与文档内容之间的相似性返回的。
重要的是要注意,搜索过程中不使用元数据。比较仅基于文档内容进行。
results = collection.query(query_texts=["laptop"], n_results=10 )print(results)
在`n_results`参数中,我们指定希望返回的最大文档数。
让我们看看响应:
{‘ids’: [[‘id173’, ‘id829’, ‘id117’, ‘id535’, ‘id141’, ‘id218’, ‘id390’, ‘id273’, ‘id56’, ‘id900’]], ‘embeddings’: None, ‘documents’: [[‘传奇的东芝公司正式停止制造笔记本电脑’, ‘今天你不能负担得起的3款游戏笔记本电脑优惠’, ‘联想和惠普控制全球一半的笔记本电脑市场份额’, ‘华硕ROG Zephyrus G14游戏笔记本电脑在印度发布’, ‘Acer Swift 3搭载10代Intel Ice Lake处理器、2K屏幕等,以64999印度卢比(865美元)的价格在印度上市’, ‘苹果的下一款MacBook可能是公司历史上最便宜的’, ‘华为台式电脑的特点被揭示’, ‘Redmi将于8月14日推出首款游戏笔记本电脑:以下是所有细节’, ‘东芝在35年后关闭了笔记本电脑业务’, ‘这是迄今为止最便宜的Windows PC,它甚至有一个多余的SSD插槽’]], ‘metadatas’: [[{‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}, {‘topic’: ‘科技’}]], ‘distances’: [[0.8593593835830688, 1.02944016456604, 1.0793330669403076, 1.093000888824463, 1.1329681873321533, 1.2130440473556519, 1.2143317461013794, 1.216413974761963, 1.2220635414123535, 1.2754170894622803]]}
正如我们所见,它返回了10篇新闻文章。它们都很短,但与笔记本电脑相关。有趣的是,并不是所有的文章都包含“笔记本电脑”这个词。这是如何可能的呢?
想象一下向量在一个多维空间中表示,其中每个向量表示该空间中的一个点。向量之间的相似性是通过测量这些点之间的距离来确定的。让我们想象一个二维空间,并以返回的短语之一作为例子来表示该空间中的词语。
“印度推出了售价64999卢比(865美元)的Acer Swift 3,配备第10代英特尔Ice Lake CPU、2K屏幕等。”
图表可能看起来类似于这个图像,我们可以看到与“笔记本”相关的词汇密集地聚集在一起。通过计算它们之间的距离,我们可以检索包含这些词汇的句子或文档。
现在,我们已经有了数据和对搜索工作原理的基本理解,可以开始使用模型进行工作了。
从Hugging Face加载模型并创建提示。
现在是时候开始使用Transformers开源库中的工具了。由Hugging Face维护的这个非常受欢迎的库提供了对大量模型的访问。
让我们导入以下工具:
- AutoTokenizer:这个工具用于对文本进行标记化,与Hugging Face库中许多预训练模型兼容。
- AutoModelForCasualLM:提供了一个用于文本生成任务的模型接口,例如基于GPT的模型。在我们的小项目中,我们使用的是模型databricks/dolly-v2–3b。
- Pipeline:这允许我们创建一个组合不同任务的流水线。
我选择的模型是dolly-v2–3b,它是Dolly系列中最小的模型。即使如此,它仍然有30亿个参数。对于我们的小实验来说,这个模型已经足够了,并且根据我进行的测试,它在这种情况下似乎表现更好,而不是GPT-2。
然而,我鼓励你自己尝试不同的模型。我唯一的建议是从你选择的系列中选择最小的模型开始。
from transformers import AutoTokenizer, AutoModelForCausalLM, pipelinemodel_id = "databricks/dolly-v2-3b"tokenizer = AutoTokenizer.from_pretrained(model_id)lm_model = AutoModelForCausalLM.from_pretrained(model_id)
在这些代码行之后,我们现在将标记器存储在变量`tokenizer`中,将模型存储在变量`lm_model`中。我们将使用这些变量来创建流水线。
在调用流水线时,我们需要指定响应大小,我将限制为256个标记。
我们还为`device_map`字段提供了值“auto”。这表示模型本身将决定在文本生成时是使用CPU还是GPU。
pipe = pipeline( "text-generation", model=lm_model, tokenizer=tokenizer, max_new_tokens=256, device_map="auto",)
创建提示。
为了创建提示,我们将使用之前在数据库上执行的查询的结果。在我们的例子中,它返回了与单词“笔记本”相关的10篇文章。
提示由两部分组成:
1. 上下文:这是我们将提供给模型考虑的除已知信息之外的信息。在我们的例子中,它将是从数据库查询结果中获得的结果。
2. 用户的问题:这是用户可以输入他们具体的问题或查询的部分。
构建提示就像将所需的文本链接在一起,以得到所需的提示一样简单。
question = "我可以买东芝的笔记本电脑吗?"context = " ".join([f"#{str(i)}" for i in results["documents"][0]])#context = context[0:5120]prompt_template = f"相关上下文:{context}\n\n 用户的问题:{question}"prompt_template
让我们看一下提示的样子:
“相关上下文:#The Legendary Toshiba is Officially Done With Making Laptops #3 gaming laptop deals you can’t afford to miss today #Lenovo and HP control half of the global laptop market #Asus ROG Zephyrus G14 gaming laptop announced in India #Acer Swift 3 featuring a 10th-generation Intel Ice Lake CPU, 2K screen, and more launched in India for INR 64999 (US$865) #Apple’s Next MacBook Could Be the Cheapest in Company’s History #Features of Huawei’s Desktop Computer Revealed #Redmi to launch its first gaming laptop on August 14: Here are all the details #Toshiba shuts the lid on laptops after 35 years #This is the cheapest Windows PC by a mile and it even has a spare SSD slot\n\n 用户的问题:我可以买东芝的笔记本电脑吗?”
正如您所见,一切都非常简单明了!没有秘密。我们只需告诉模型:“考虑我提供的这个上下文,接着是一个换行符,用户的问题是这个。”
从这里开始,模型接管并完成解释提示并生成正确回答的所有工作。
让我们获取回答。我们只需要调用之前创建的pipeline,并将其传递给最近创建的提示。
lm_response = pipe(prompt_template)print(lm_response[0]["generated_text"])
让我们看看模型的回答:
相关背景:#传奇东芝正式停止生产笔记本电脑#今天您无法负担得起的3款游戏笔记本电脑优惠#联想和惠普占据全球笔记本电脑市场的一半#华硕ROG Zephyrus G14游戏笔记本在印度发布#Acer Swift 3配备第10代英特尔Ice Lake CPU、2K屏幕等,在印度以64999印度卢比(865美元)的价格上市#苹果下一款MacBook可能是公司历史上最便宜的一款#华为桌面电脑的功能被揭示#Redmi将于8月14日发布其首款游戏笔记本电脑:以下是所有细节#东芝在35年后关闭笔记本电脑业务#这是迄今为止最便宜的Windows PC,甚至还有一个备用的SSD插槽
用户的问题:我可以买东芝笔记本电脑吗?答案:不可以,东芝已决定停止生产笔记本电脑。
太棒了!模型考虑了我们提供的上下文,并正确构造了用户的回答,不仅利用了其预训练知识,还利用了我们在提示中传递的信息。
结论,下一步。
我想您已经意识到一切都比起初看起来要简单得多。
我们使用了一个向量数据库来存储我们自己的信息,我们用它构建了一个大型语言模型的提示。
模型返回了正确的回答,考虑到我们提供的上下文。您可以想象,这种工作方式打开了无限的可能性,并完美地补充了大型语言模型的微调。
如果您想在笔记本中进行尝试,请记住它在Kaggle和GitHub上都可以找到。
以下是一些想法:
1. 使用笔记本准备的所有数据集,如果可能的话,尝试并入一个新的数据集。
2. 探索Hugging Face上的不同模型并比较结果。
3. 修改提示创建过程。
请随意尝试、迭代和探索不同的可能性。这将帮助您更深入地了解向量数据库、大型语言模型及其在自然语言处理任务中的应用。
我经常写关于深度学习和机器学习的文章。考虑关注我在VoAGI上获取新文章的更新。当然,欢迎您通过LinkedIn与我联系。