向量嵌入

了解如何将文本转换为数字,从而解锁搜索等用例。

新的嵌入模型source

text-embedding-3-smalltext-embedding-3-large,我们最新、性能最高的嵌入模型现已推出,具有更低的成本、更高的多语言性能以及控制整体大小的新参数。

什么是嵌入?

OpenAI 的文本嵌入测量文本字符串的相关性。嵌入通常用于:source

  • 搜索(其中结果按与查询字符串的相关性排名)
  • 聚类(其中文本字符串按相似性分组)
  • 推荐(推荐包含相关文本字符串的项目)
  • 异常检测(识别出相关性不大的异常值)
  • 多样性测量(分析相似性分布)
  • 分类(其中文本字符串按其最相似的标签进行分类)

嵌入是浮点数的向量(列表)。两个向量之间的距离衡量它们的相关性。小距离表示高相关性,大距离表示低相关性。source

请访问我们的定价页面,了解 Embeddings 定价。请求根据输入中的令牌数量计费。source

如何获取嵌入

要获取嵌入,请将您的文本字符串与嵌入模型名称(例如text-embedding-3-small).响应将包含一个嵌入(浮点数列表),您可以提取该嵌入(浮点数列表),并将其保存在矢量数据库中,并用于许多不同的用例:source

示例:获取嵌入
1
2
3
4
5
6
7
curl https://api.openai.com/v1/embeddings \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "input": "Your text string goes here",
    "model": "text-embedding-3-small"
  }'

响应将包含嵌入向量以及一些其他元数据。source

嵌入响应示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "index": 0,
      "embedding": [
        -0.006929283495992422,
        -0.005336422007530928,
        ... (omitted for spacing)
        -4.547132266452536e-05,
        -0.024047505110502243
      ],
    }
  ],
  "model": "text-embedding-3-small",
  "usage": {
    "prompt_tokens": 5,
    "total_tokens": 5
  }
}

默认情况下,嵌入向量的长度将为 1536text-embedding-3-small或 3072 表示text-embedding-3-large.您可以通过传入 dimensions 参数来减小嵌入的维度,而不会使嵌入丢失其概念表示属性。我们将在 embedding use case 部分更详细地介绍嵌入维度。source

嵌入模型

OpenAI 提供了两个强大的第三代嵌入模型(用-3在模型 ID 中)。有关更多详细信息,您可以阅读 embedding v3 公告博客文章source

使用量按输入令牌定价,以下是每美元文本页数的定价示例(假设每页 ~800 个令牌):source

MODEL~ 每美元页数MTEB 评估性能最大输入
文本嵌入 3 小62,50062.3%8191
text-embedding-3-large (文本嵌入 3 大)9,61564.6%8191
文本嵌入 ADA 00212,50061.0%8191

使用案例

在这里,我们展示了一些具有代表性的使用案例。对于以下示例,我们将使用 Amazon fine-food reviews 数据集source

获取嵌入

该数据集包含截至 2012 年 10 月的 Amazon 用户留下的总共 568454 条食品评论。我们将使用 1,000 条最新评论的子集进行说明。评论是英文的,往往是正面的或负面的。每条评论都有一个 ProductId、UserId、Score、评论标题 (Summary) 和评论正文 (Text)。例如:source

产品 ID用户 ID得分总结文本
B001E4KFG0A3SGXH7AUHU8GW5优质狗粮我已经买了好几个 Vitality 罐装......
B00813GRG4A1D87F6ZCVE5NK1与宣传的不符产品到达时贴有 Jumbo Salted Peanut 的标签...

我们会将评论摘要和评论文本合并为一个组合文本。该模型将对此组合文本进行编码并输出单个向量嵌入。source

Get_embeddings_from_dataset.ipynbsource

1
2
3
4
5
6
7
8
9
from openai import OpenAI
client = OpenAI()

def get_embedding(text, model="text-embedding-3-small"):
   text = text.replace("\n", " ")
   return client.embeddings.create(input = [text], model=model).data[0].embedding

df['ada_embedding'] = df.combined.apply(lambda x: get_embedding(x, model='text-embedding-3-small'))
df.to_csv('output/embedded_1k_reviews.csv', index=False)

要从保存的文件中加载数据,您可以运行以下命令:source

1
2
3
4
import pandas as pd

df = pd.read_csv('output/embedded_1k_reviews.csv')
df['ada_embedding'] = df.ada_embedding.apply(eval).apply(np.array)

常见问题

在嵌入字符串之前,如何判断字符串有多少个标记?

在 Python 中,您可以使用 OpenAI 的分词器将字符串拆分为令牌tiktoken.source

示例代码:source

1
2
3
4
5
6
7
8
9
import tiktoken

def num_tokens_from_string(string: str, encoding_name: str) -> int:
    """Returns the number of tokens in a text string."""
    encoding = tiktoken.get_encoding(encoding_name)
    num_tokens = len(encoding.encode(string))
    return num_tokens

num_tokens_from_string("tiktoken is great!", "cl100k_base")

对于像text-embedding-3-small,请使用cl100k_base编码。source

更多详细信息和示例代码请参阅 OpenAI 说明书指南如何使用 tiktoken 对令牌进行计数source

如何快速检索 K 个最近的嵌入向量?

为了快速搜索多个向量,我们建议使用向量数据库。您可以在 GitHub 上的说明书中找到使用矢量数据库和 OpenAI API 的示例。source

我应该使用哪个距离函数?

我们建议使用余弦相似性。距离函数的选择通常并不重要。source

OpenAI 嵌入被归一化为长度 1,这意味着:source

  • 仅使用点积即可计算余弦相似度的速度稍快一些
  • 余弦相似度和欧几里得距离将导致相同的排名

我可以在线共享我的嵌入吗?

是的,客户拥有我们模型的输入和输出,包括嵌入。您有责任确保您输入到我们的 API 的内容不违反任何适用法律或我们的使用条款source

V3 嵌入模型是否了解最近的事件?

不,该text-embedding-3-largetext-embedding-3-small模型缺乏对 2021 年 9 月之后发生的事件的了解。这通常不像文本生成模型那样大,但在某些边缘情况下,它会降低性能。source