# OpenAI

# 介绍

OpenAI Cookbook 是一个实用示例和代码片段的集合,供开发人员在实际应用中使用。它演示了如何使用 OpenAI 最新的前沿模型和工具,这些模型和工具处于人工智能研究的前沿。

有关更多信息,请参阅 OpenAI Cookbook 网站 (opens new window)

# 先决条件

要按照本指南进行操作,您需要具备以下条件:

  1. 通过按照 快速入门指南 部署的 MyScale 集群。
  2. 使用 clickhouse-connect 库与 MyScale 进行交互。
  3. 用于查询向量化的 OpenAI API 密钥 (opens new window)

# 安装要求

此笔记本需要 openaiclickhouse-connect 以及其他一些依赖项。使用以下命令安装它们:

!pip install openai clickhouse-connect wget pandas

# 准备您的 OpenAI API 密钥

要使用 OpenAI API,您需要设置一个 API 密钥。如果您还没有一个,可以从 OpenAI (opens new window) 获取。

import openai
# 从 OpenAI 网站获取 API 密钥
openai.api_key = "OPENAI_API_KEY"
# 检查是否已进行身份验证
openai.Engine.list()

# 连接到 MyScale

按照 连接详情 部分从 MyScale 控制台检索集群主机、用户名和密码信息,并使用以下代码创建到集群的连接:

import clickhouse_connect
# 初始化客户端
client = clickhouse_connect.get_client(host='YOUR_CLUSTER_HOST', port=443, username='YOUR_USERNAME', password='YOUR_CLUSTER_PASSWORD')

# 加载数据

我们需要加载由 OpenAI 提供的预计算的维基百科文章向量嵌入数据集。使用 wget 包下载数据集。

import wget
embeddings_url = "https://cdn.openai.com/API/examples/data/vector_database_wikipedia_articles_embedded.zip"
# 文件大小约为 700 MB,所以需要一些时间
wget.download(embeddings_url)

下载完成后,使用 zipfile 包解压文件:

import zipfile
with zipfile.ZipFile("vector_database_wikipedia_articles_embedded.zip", "r") as zip_ref:
    zip_ref.extractall("../data")

现在,我们可以将数据从 vector_database_wikipedia_articles_embedded.csv 加载到 Pandas DataFrame 中:

import pandas as pd
from ast import literal_eval
# 从 csv 读取数据
article_df = pd.read_csv('../data/vector_database_wikipedia_articles_embedded.csv')
article_df = article_df[['id', 'url', 'title', 'text', 'content_vector']]
# 将字符串中的向量读取回列表
article_df["content_vector"] = article_df.content_vector.apply(literal_eval)
article_df.head()

# 索引数据

我们将在 MyScale 中创建一个名为 articles 的 SQL 表,用于存储嵌入数据。该表将包括一个带有余弦距离度量的向量索引,并包含嵌入长度的约束。使用以下代码创建并插入数据到 articles 表中:

# 创建带有向量索引的 articles 表
embedding_len=len(article_df['content_vector'][0]) # 1536
client.command(f"""
CREATE TABLE IF NOT EXISTS default.articles
(
    id UInt64,
    url String,
    title String,
    text String,
    content_vector Array(Float32),
    CONSTRAINT cons_vector_len CHECK length(content_vector) = {embedding_len},
    VECTOR INDEX article_content_index content_vector TYPE HNSWFLAT('metric_type=Cosine')
)
ENGINE = MergeTree ORDER BY id
""")
# 批量将数据插入表中
from tqdm.auto import tqdm
batch_size = 100
total_records = len(article_df)
# 按批次上传数据
data = article_df.to_records(index=False).tolist()
column_names = article_df.columns.tolist()
for i in tqdm(range(0, total_records, batch_size)):
    i_end = min(i + batch_size, total_records)
    client.insert("default.articles", data[i:i_end], column_names=column_names)

在继续搜索之前,我们需要检查向量索引的构建状态,因为它会在后台自动构建。

# 检查插入数据的数量
print(f"articles count: {client.command('SELECT count(*) FROM default.articles')}")
# 检查向量索引的状态,确保向量索引处于 'Built' 状态
get_index_status="SELECT status FROM system.vector_indices WHERE name='article_content_index'"
print(f"index build status: {client.command(get_index_status)}")

# 搜索数据

在 MyScale 中建立索引后,我们可以执行向量搜索以查找相似内容。首先,我们将使用 OpenAI API 为查询生成嵌入。然后,我们将使用 MyScale 执行向量搜索。

import openai
query = "苏格兰历史上著名的战役"
# 从用户查询创建嵌入向量
embed = openai.Embedding.create(
    input=query,
    model="text-embedding-ada-002",
)["data"][0]["embedding"]
# 查询数据库以找到与给定查询最相似的前 K 个内容
top_k = 10
results = client.query(f"""
SELECT id, url, title, distance(content_vector, {embed}) as dist
FROM default.articles
ORDER BY dist
LIMIT {top_k}
""")
# 显示结果
for i, r in enumerate(results.named_results()):
    print(i+1, r['title'])
Last Updated: Thu Mar 14 2024 05:32:10 GMT+0000