使用Weaviate与OpenAI向量化模块进行嵌入搜索
本笔记本适用于以下场景: * 您的数据尚未进行向量化 * 您想要在数据上运行向量搜索 * 您想要使用Weaviate与OpenAI模块(text2vec-openai)为您生成向量嵌入。
本笔记本将带您完成一个简单的流程,设置Weaviate实例,连接到它(使用OpenAI API密钥),配置数据架构,导入数据(这将自动生成您的数据的向量嵌入),并运行语义搜索。
这是客户常见的需求,他们希望在安全环境中存储和搜索我们的嵌入,并支持生产用例,如聊天机器人、主题建模等。
Weaviate是什么
Weaviate是一个开源的向量搜索引擎,它将数据对象与它们的向量一起存储。这允许将向量搜索与结构化过滤相结合。
Weaviate使用KNN算法创建一个向量优化的索引,这使得您的查询运行非常快速。了解更多信息,请点击这里。
Weaviate让您可以使用您喜欢的ML模型,并无缝扩展到数十亿的数据对象。
部署选项
无论您的场景或生产设置如何,Weaviate都有适合您的选项。您可以在以下设置中部署Weaviate: * 自托管 - 您可以在本地使用docker部署Weaviate,或者在任何您想要的服务器上部署。 * SaaS - 您可以使用Weaviate云服务(WCS)来托管您的Weaviate实例。 * 混合SaaS - 您可以在您自己的私有云服务中部署Weaviate。
编程语言
Weaviate提供四种客户端库,允许您从您的应用程序进行通信: * Python * JavaScript * Java * Go
此外,Weaviate 还有一个REST层。基本上,您可以从支持REST请求的任何语言调用Weaviate。
演示流程
演示流程如下: - 先决条件设置:创建一个Weaviate实例并安装所需的库 - 连接:连接到您的Weaviate实例 - 架构配置:配置数据的架构 - 注意:在这里我们可以定义要使用哪个OpenAI嵌入模型 - 注意:在这里我们可以配置要索引哪些属性 - 导入数据:加载演示数据集并将其导入到Weaviate中 - 注意:导入过程将根据架构中的配置自动索引您的数据 - 注意:您不需要显式地对数据进行向量化,Weaviate将与OpenAI通信以代表您执行此操作 - 运行查询:查询 - 注意:您不需要显式地对查询进行向量化,Weaviate将与OpenAI通信以代表您执行此操作
完成本笔记本后,您应该对如何设置和使用向量数据库有一个基本的了解,并可以继续进行更复杂的用例,利用我们的嵌入。
Weaviate中的OpenAI模块
所有Weaviate实例都配备有text2vec-openai模块。
该模块负责在导入(或任何CRUD操作)期间处理向量化以及在运行查询时处理向量化。
无需手动向量化数据
这对您来说是个好消息。使用text2vec-openai,您无需手动向量化您的数据,因为Weaviate会在必要时为您调用OpenAI。
您只需要: 1. 在连接到Weaviate客户端时提供您的OpenAI API密钥 2. 在模式中定义要使用的OpenAI向量化器
先决条件
在开始这个项目之前,我们需要设置以下内容:
- 创建一个
Weaviate
实例 - 安装库
weaviate-client
datasets
apache-beam
- 获取您的OpenAI API密钥
=========================================================== ### 创建 Weaviate 实例
要创建一个 Weaviate 实例,我们有两个选项:
- (推荐路径)Weaviate 云服务 - 在云中托管您的 Weaviate 实例。免费的沙箱应该足够用于这个示例。
- 使用 Docker 在本地安装和运行 Weaviate。
选项 1 - WCS 安装步骤
使用Weaviate 云服务(WCS)创建一个免费的
Weaviate 集群。 1.
创建一个免费帐户并/或登录到WCS 2.
使用以下设置创建一个 Weaviate 集群
: * 沙箱:Sandbox Free
*
Weaviate 版本:使用默认值(最新版) * OIDC 认证:Disabled
3.
您的实例应该在一两分钟内准备就绪 4. 记下
集群 ID
。该链接将带您到您的集群的完整路径(稍后您将需要连接到它)。它应该类似于:https://your-project-name.weaviate.network
选项 2 - 使用 Docker 在本地安装 Weaviate 实例
使用 Docker 在本地安装和运行 Weaviate。 1. 下载
./docker-compose.yml 文件 2.
然后打开您的终端,导航到您的 docker-compose.yml
文件所在的 位置,并使用以下命令启动 Docker:docker-compose up -d
3.
一旦准备就绪,您的实例应该在
http://localhost:8080 上可用
注意:要关闭 Docker 实例,您可以运行:docker-compose down
了解更多
要了解更多关于使用 Docker 和 Weaviate 的信息,请参阅安装文档。
=========================================================== ## 安装所需库
在运行此项目之前,请确保安装以下库:
Weaviate Python客户端
Weaviate Python客户端允许您从Python项目中与Weaviate实例进行通信。
datasets & apache-beam
要加载示例数据,您需要datasets
库及其依赖项apache-beam
。
# 安装适用于Python的Weaviate客户端
!pip install weaviate-client>=3.11.0
# 安装数据集和apache-beam以加载示例数据集
!pip install datasets apache-beam
=========================================================== ## 准备您的OpenAI API密钥
OpenAI API密钥
用于在导入数据时对数据进行向量化,并用于运行查询。
如果您还没有OpenAI API密钥,可以从https://beta.openai.com/account/api-keys获取。
获取到密钥后,请将其添加到您的环境变量中,命名为 OPENAI_API_KEY
。
# 导出 OpenAI API 密钥
!export OPENAI_API_KEY="your key"
# 测试您的 OpenAI API 密钥是否已正确设置为环境变量。
# 注意:如果您在本地运行此笔记本,您需要重新加载终端和笔记本,以使环境变量生效。
import os
# 注意:或者,您也可以像这样设置一个临时的环境变量:
# os.environ["OPENAI_API_KEY"] = 'your-key-goes-here'
if os.getenv("OPENAI_API_KEY") is not None:
print ("OPENAI_API_KEY is ready")
else:
print ("OPENAI_API_KEY environment variable not found")
连接到您的Weaviate实例
在本节中,我们将:
- 测试环境变量
OPENAI_API_KEY
- 确保您已完成#准备您的OpenAI API密钥中的步骤 - 使用您的
OpenAI API密钥
连接到您的Weaviate - 并测试客户端连接
客户端
完成这一步后,client
对象将被用于执行所有与Weaviate相关的操作。
import weaviate
from datasets import load_dataset
import os
# 连接到您的 Weaviate 实例
client = weaviate.Client(
url="https://your-wcs-instance-name.weaviate.network/",
# url="http://localhost:8080/",
auth_client_secret=weaviate.auth.AuthApiKey(api_key="<YOUR-WEAVIATE-API-KEY>"), # 如果您没有为您的 Weaviate 实例使用身份验证(例如,对于本地部署的实例),请注释掉这一行。
additional_headers={
"X-OpenAI-Api-Key": os.getenv("OPENAI_API_KEY")
}
)
# 检查您的实例是否已上线并准备就绪
# 这应该返回 `True`
client.is_ready()
数据模式
在本节中,我们将: 1. 配置数据的模式 2. 选择 OpenAI 模块
这是第二步,也是最后一步,需要进行 OpenAI 特定的配置。 在这一步之后,其余的指令将只涉及 Weaviate,因为 OpenAI 任务将被自动处理。
什么是模式
在 Weaviate 中,您创建 模式 来捕获您将要搜索的每个实体。
模式是您告诉 Weaviate 的方式: * 应该使用什么嵌入模型来将数据向量化 * 您的数据由什么组成(属性名称和类型) * 哪些属性应该被向量化和索引化
在本教程中,我们将使用一个包含以下内容的 Articles
数据集: * title
* content
* url
我们希望将 title
和 content
向量化,但不包括 url
。
为了向量化和查询数据,我们将使用 text-embedding-3-small
。
# 清理架构,以便我们能够重新创建它。
client.schema.delete_all()
client.schema.get()
# 定义Schema对象,对`title`和`content`字段使用`text-embedding-3-small`进行处理,但跳过`url`字段。
article_schema = {
"class": "Article",
"description": "A collection of articles",
"vectorizer": "text2vec-openai",
"moduleConfig": {
"text2vec-openai": {
"model": "ada",
"modelVersion": "002",
"type": "text"
}
},
"properties": [{
"name": "title",
"description": "Title of the article",
"dataType": ["string"]
},
{
"name": "content",
"description": "Contents of the article",
"dataType": ["text"]
},
{
"name": "url",
"description": "URL to the article",
"dataType": ["string"],
"moduleConfig": { "text2vec-openai": { "skip": True } }
}]
}
# 添加文章架构
client.schema.create_class(article_schema)
# 获取架构以确保其正常工作
client.schema.get()
导入数据
在本节中,我们将: 1. 加载Simple Wikipedia数据集 2. 配置Weaviate批量导入(以使导入更有效) 3. 将数据导入Weaviate
注意:
如前所述。我们不需要手动对数据进行向量化。
text2vec-openai 模块会处理这部分。
# ##步骤1 - 加载数据集
from datasets import load_dataset
from typing import List, Iterator
# 我们将使用datasets库来提取Simple Wikipedia数据集以进行嵌入。
dataset = list(load_dataset("wikipedia", "20220301.simple")["train"])
# 在测试阶段,为了演示目的,仅限于2500篇文章。
dataset = dataset[:2_500]
# 为了进行更大规模的演示,限制在25,000篇文章以内
# 数据集 = 数据集[:25_000]
# 对于免费的OpenAI账户,您可以使用50个对象。
# 数据集 = 数据集[:50]
# ##步骤2 - 配置Weaviate批处理功能
# - 初始批次大小为100
# - 根据性能动态增减
# - 如果出现问题,增加超时重试机制
client.batch.configure(
batch_size=10,
dynamic=True,
timeout_retries=3,
# 回调函数=None,
)
# ##步骤3 - 导入数据
print("Importing Articles")
counter=0
with client.batch as batch:
for article in dataset:
if (counter %10 == 0):
print(f"Import {counter} / {len(dataset)} ")
properties = {
"title": article["title"],
"content": article["text"],
"url": article["url"]
}
batch.add_data_object(properties, "Article")
counter = counter+1
print("Importing Articles complete")
# 测试所有数据是否已加载 —— 获取对象数量
result = (
client.query.aggregate("Article")
.with_fields("meta { count }")
.do()
)
print("Object count: ", result["data"]["Aggregate"]["Article"], "\n")
# 通过检查一个对象,测试一篇文章已经生效。
test_article = (
client.query
.get("Article", ["title", "url", "content"])
.with_limit(1)
.do()
)["data"]["Get"]["Article"][0]
print(test_article['title'])
print(test_article['url'])
print(test_article['content'])
搜索数据
与上面类似,我们将向我们的新索引发送一些查询,并根据与现有向量的接近程度返回结果。
def query_weaviate(query, collection_name):
nearText = {
"concepts": [query],
"distance": 0.7,
}
properties = [
"title", "content", "url",
"_additional {certainty distance}"
]
result = (
client.query
.get(collection_name, properties)
.with_near_text(nearText)
.with_limit(10)
.do()
)
# 检查错误
if ("errors" in result):
print ("\033[91mYou probably have run out of OpenAI API calls for the current minute – the limit is set at 60 per minute.")
raise Exception(result["errors"][0]['message'])
return result["data"]["Get"][collection_name]
query_result = query_weaviate("modern art in Europe", "Article")
for i, article in enumerate(query_result):
print(f"{i+1}. { article['title']} (Score: {round(article['_additional']['certainty'],3) })")
query_result = query_weaviate("Famous battles in Scottish history", "Article")
for i, article in enumerate(query_result):
print(f"{i+1}. { article['title']} (Score: {round(article['_additional']['certainty'],3) })")
感谢您的跟进,现在您已经具备了设置自己的向量数据库并使用嵌入来做各种酷炫事情的能力 - 祝您玩得开心!对于更复杂的用例,请继续阅读本存储库中的其他示例。