将 textembedding-gecko@003 用于矢量嵌入

1. 简介

上次更新时间: 2024-04-08

文本嵌入

文本嵌入是指将文本数据转换为数值表示形式的过程。这些数值表示法(通常是向量)可捕获文本中字词的语义含义和关系。您可以这样理解:

文本就像一种复杂的语言,充满了细微差别和歧义。

文本嵌入会将这种语言转换为计算机可以理解和操作的更简单的数学格式。

文本嵌入的优势

  • 实现高效处理:与原始文本相比,计算机处理数值表示形式的速度要快得多。这对于搜索引擎、推荐系统和机器翻译等任务至关重要。
  • 捕获语义含义:嵌入不仅仅是字词的字面含义,还可以捕获字词之间的上下文和关系,从而实现更细致的分析。
  • 提高机器学习性能:文本嵌入可用作机器学习模型中的特征,从而在情感分析、文本分类和主题建模等任务中实现更好的性能。

文本嵌入的应用场景

文本嵌入通过将文本转换为数值表示形式,在自然语言处理 (NLP) 中解锁了各种应用。以下是一些主要应用场景:

1. 搜索引擎和信息检索

借助文本嵌入,搜索引擎可以理解查询背后的语义含义,并将其与相关文档进行匹配,即使文档中没有确切的关键字也是如此。

通过比较搜索查询的嵌入与文档嵌入,搜索引擎可以识别涵盖类似主题或概念的文档。

**2. 推荐系统

推荐系统使用文本嵌入来分析用户行为以及通过评价、评分或浏览记录表达的偏好。

然后,系统可以通过比较用户互动过的产品、文章或其他内容的嵌入来推荐类似内容。

3. 抄袭检测

通过比较两段文本的嵌入,可以发现其语义结构中的显著相似之处,从而帮助识别潜在的抄袭行为。

以上仅是一些示例,随着文本嵌入技术的不断发展,其应用场景也在不断扩大。随着计算机通过嵌入更好地理解语言,我们可以期待未来出现更多创新应用。

textembedding-gecko@003

Textembedding-gecko@003 是 Google Cloud Platform (GCP) 通过 Vertex AI 及其 AI 工具和服务套件提供的预训练文本嵌入模型的特定版本。

构建内容

在此 Codelab 中,您将构建一个 Python 脚本。此脚本将执行以下操作:

  • 使用 Vertex API 调用 textembedding-gecko@003,并将文本转换为文本嵌入(向量)。
  • 创建由文本及其向量组成的模拟数据库
  • 通过比较向量对模拟向量数据库执行查询,并获取最可能的响应。

学习内容

  • 如何在 GCP 中使用文本嵌入
  • 如何调用 textembedding-gecko@003
  • 如何在 Workbench 中运行此脚本
  • 如何使用 Vertex AI - Workbench 执行脚本

所需条件

  • 较新版本的 Chrome
  • 了解 Python
  • Google Cloud 项目
  • 访问 Vertex AI - Workbench

2. 准备工作

创建 Vertex AI Workbench 实例

  1. 在 Google Cloud 控制台的“项目选择器”页面上,选择或创建 Google Cloud 项目。
  1. 转到项目选择器
  2. 确保您的 Google Cloud 项目已启用结算功能。
  3. 启用 Notebooks API。

您可以使用 Google Cloud 控制台、gcloud CLI 或 Terraform 创建 Vertex AI Workbench 实例。在本教程中,我们将使用 Google Cloud 控制台创建实例。如需详细了解其他方法,请点击此处

  1. 在 Google Cloud 控制台中,前往“实例”页面,该页面可在 Vertex AI 菜单的“笔记本”部分中访问,然后点击“Workbench”。 56c087d619c464dd.png
  2. 前往“实例”。
  3. 点击“新建”。 381ff9b895e77641.png
  4. 在“创建实例”对话框的“详细信息”部分中,为新实例提供以下信息:

名称:为新实例提供名称。名称必须以字母开头,后面最多可跟 62 个小写字母、数字或连字符 (-),但不能以连字符结尾。

区域和可用区:为新实例选择区域和可用区。为获得最佳网络性能,请选择与您的地理位置最近的区域。

无需安装 GPU

在“网络”部分中,提供以下信息:

网络:调整网络选项,以在当前项目或宿主项目中使用共享 VPC 网络(如果已配置)。如果您在宿主项目中使用共享 VPC,则还必须在服务项目中向 Notebooks Service Agent 授予 Compute Network User 角色 (roles/compute.networkUser)。

在“网络”字段中:选择所需的网络。您可以选择 VPC 网络,只要该网络启用了专用 Google 访问通道或者可以访问互联网即可

在“子网”字段中: 选择所需的子网。您可以选择默认子网。

在“实例属性”中,您可以保留默认属性,即 e2-standard-4。

d47bdc2d7f516c46.png

  1. 点击“创建”。

Vertex AI Workbench 会创建实例并自动启动该实例。当实例可供使用时,Vertex AI Workbench 会激活一个“打开 JupyterLab”链接。点击此链接。

创建 Python 3 笔记本

  1. 在 Jupyterlab 中,从启动器中的“笔记本”部分,点击带有 Python 徽标且显示“Python3”的图标。 e16bb118cd28256f.png
  2. 系统会创建一个名为“Untitled”且扩展名为 ipynb 的 Jupyter 笔记本。 da9bd34cf307156c.png
  3. 您可以使用左侧的文件浏览器部分重命名该笔记本,也可以保留原样。

现在,我们可以开始将代码放入笔记本中了。

3. 导入必需的库

创建实例并打开 Jupyterlab 后,我们需要为 Codelab 安装所有必需的库。

我们需要:

  1. numpy
  2. pandas
  3. 来自 vertexai.language_models 的 TextEmbeddingInput、TextEmbeddingModel

将以下代码复制并粘贴到单元格中:

from vertexai.language_models import TextEmbeddingInput, TextEmbeddingModel

import numpy as np
import pandas as pd

此时的代码如下所示:

6852d323eedcac93.png

4. 创建模拟向量数据库

为了测试我们的代码,我们将创建一个由文本及其各自的向量组成的数据库,这些向量是使用 gecko@003 文本嵌入模型转换而来的。

我们的目标是让用户搜索文本,将其转换为向量,在我们的数据库中搜索该向量,并返回最接近的结果。

我们的向量数据库将包含 3 条记录,我们将按如下方式创建它:

将以下代码复制并粘贴到新单元格中。

DOCUMENT1 = {
    "title": "Operating the Climate Control System",
    "content": "Your Googlecar has a climate control system that allows you to adjust the temperature and airflow in the car. To operate the climate control system, use the buttons and knobs located on the center console.  Temperature: The temperature knob controls the temperature inside the car. Turn the knob clockwise to increase the temperature or counterclockwise to decrease the temperature. Airflow: The airflow knob controls the amount of airflow inside the car. Turn the knob clockwise to increase the airflow or counterclockwise to decrease the airflow. Fan speed: The fan speed knob controls the speed of the fan. Turn the knob clockwise to increase the fan speed or counterclockwise to decrease the fan speed. Mode: The mode button allows you to select the desired mode. The available modes are: Auto: The car will automatically adjust the temperature and airflow to maintain a comfortable level. Cool: The car will blow cool air into the car. Heat: The car will blow warm air into the car. Defrost: The car will blow warm air onto the windshield to defrost it."}

DOCUMENT2 = {
    "title": "Touchscreen",
    "content": "Your Googlecar has a large touchscreen display that provides access to a variety of features, including navigation, entertainment, and climate control. To use the touchscreen display, simply touch the desired icon.  For example, you can touch the \"Navigation\" icon to get directions to your destination or touch the \"Music\" icon to play your favorite songs."}

DOCUMENT3 = {
    "title": "Shifting Gears",
    "content": "Your Googlecar has an automatic transmission. To shift gears, simply move the shift lever to the desired position.  Park: This position is used when you are parked. The wheels are locked and the car cannot move. Reverse: This position is used to back up. Neutral: This position is used when you are stopped at a light or in traffic. The car is not in gear and will not move unless you press the gas pedal. Drive: This position is used to drive forward. Low: This position is used for driving in snow or other slippery conditions."}

documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]

df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db

此时的代码如下所示:

26baa3b876c0605d.png

分析代码

在变量 DOCUMENT1、DOCUMENT2 和 DOCUMENT3 中,我们存储了一个字典,该字典将模拟包含标题和内容的文档。这些“文档”引用了 Google 制造的汽车的模拟手册。

在下一行中,我们从这 3 个文档(字典)创建一个列表。

documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]

最后,我们利用 pandas 从该列表中创建一个数据帧,该数据帧将称为 df_initial_db。

df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db

5. 创建文本嵌入

现在,我们将使用 gecko@003 模型为模拟文档数据库中的每条记录获取文本嵌入。

将以下代码复制并粘贴到新单元格中:

def embed_fn(df_input):
    list_embedded_values = []
    for index, row in df_input.iterrows():        
        model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
        embeddings = model.get_embeddings([(row['Text'])])        
        list_embedded_values.append(embeddings[0].values)
    df_input['Embedded text'] = list_embedded_values
    return df_input        
                                           
df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db      

此时的代码如下所示:

4c4af091c7a82861.png

分析代码

我们定义了一个名为 embed_fn 的函数,该函数将接收一个 pandas 数据帧作为输入,该数据帧包含要执行嵌入的文本。然后,该函数会返回编码为向量的文本。

def embed_fn(df_input):
    list_embedded_values = []
    for index, row in df_input.iterrows():        
        model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
        embeddings = model.get_embeddings([(row['Text'])])        
        list_embedded_values.append(embeddings[0].values)
    df_input['Embedded text'] = list_embedded_values
    return df_input             

在名为 list_embedded_values 的列表中,我们将存储并附加每行的编码文本。

使用 pandas 中的 iterrows 方法,我们可以迭代数据帧中的每一行,从列“Text”(其中包含模拟数据库中的手册信息)获取值。

为了使用 gecko@003 模型发送常规文本并返回其向量,我们初始化了变量 model,在该变量中,我们通过调用 TextEmbeddingModel.from_pretrained 函数来设置要使用的模型。

model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])                     

然后,在变量 embeddings 中,我们捕获通过 model.get_embeddings 函数发送的文本的向量。

在该函数末尾,我们在数据帧中创建一个名为“Embedded text”的新列,其中将包含基于 gecko@003 模型创建的向量列表。

df_input['Embedded text'] = list_embedded_values
return df_input             

最后,在变量 df_embedded_values_db 中,我们捕获包含模拟数据库中的原始数据以及包含每行向量列表的新列的 DataFrame。

df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db      

6. 向向量数据库提问

现在,我们的数据库包含文本及其向量,我们可以继续提问并查询数据库以找到答案。

为此,请将以下代码复制并粘贴到新单元格中:

question='How do you shift gears in the Google car?'
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(question)])        
text_to_search=embeddings[0].values
len(text_to_search)

结果应如下所示:

6b7cf9b08e3b4573.png

分析代码

与上一步中的函数类似,我们首先使用要向数据库提出的问题初始化 question 变量。

question='How do you shift gears in the Google car?'

然后,在 model 变量中,我们通过 TextEmbeddingModel.from_pretrained 函数设置要使用的模型,在本例中为 gecko@003 模型。

model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")

在 embeddings 变量中,我们调用 model.get_embeddings 函数并传递要转换为向量的文本,在本例中,我们传递要提出的问题。

embeddings = model.get_embeddings([(question)])        

最后,text_to_search 变量保存从问题转换而来的向量列表。

我们打印向量的长度,仅供参考。

text_to_search=embeddings[0].values
len(text_to_search)

7. 比较向量

现在,我们的模拟数据库中有一个向量列表,并且有一个问题已转换为向量。也就是说,我们现在可以将问题的向量与数据库中的所有向量进行比较,以找出哪个向量最接近,从而更准确地回答我们的问题。

为此,我们将测量问题向量与数据库中每个向量之间的距离。有多种技术可以测量向量之间的距离,对于此特定 Codelab,我们将使用欧几里得距离或 L2 范数。

73ea8635c4570bea.png

在 Python 中,我们可以利用 numpy 函数来实现此目的。

将以下代码复制并粘贴到新单元格中:

list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1
for position, embedded_value in enumerate(list_embedded_text_from_db):
    distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
    print(distance)
    if distance<shortest_distance:
        shortest_distance=distance
        shortest_position=position
        
print(f'The shortest distance is {shortest_distance} and the position of that value is {shortest_position}')

结果应如下所示:

b70563b50ea86668.png

分析代码

我们首先将保存嵌入文本或数据库向量的列转换为列表,并将其存储在 list_embedded_text_from_db 中。

我们还将 shortest_distance 变量初始化为 1,以便不断更新它,直到找到实际的最短距离。

list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1

然后,使用 for 循环,我们迭代并获取问题向量与数据库中每个向量之间的距离。

使用 numpy linalg.norm 函数,我们计算了它们的距离。

如果计算出的距离小于 shortest_distance 变量中的距离,则计算出的距离将设置为此变量

然后,我们捕获最短距离以及在列表中找到该距离的位置。在 shortest_distance 和 shortest_position 变量中。

for position, embedded_value in enumerate(list_embedded_text_from_db):
    distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
    print(distance)
    if distance<shortest_distance:
        shortest_distance=distance
        shortest_position=position

8. 结果

了解向量列表中保存问题与数据库之间最短距离的向量的位置后,我们可以打印结果。

将以下代码复制并粘贴到新单元格中:

print("Your question was:\n "+question+ " \nAnd our answer is:\n "+
      df_embedded_values_db.at[shortest_position, 'Title']+": "+
      df_embedded_values_db.at[shortest_position, 'Text'])

执行后,您将看到如下内容:

7a0e429171a19afe.png

9. 恭喜

恭喜,您已成功在实际应用场景中使用 textembedding-gecko@003 模型构建了您的第一个应用!

您学习了文本嵌入的基础知识,以及如何在 GCP Workbench 上使用 gecko003 模型。

现在,您已了解将知识应用于更多应用场景所需的关键步骤。

后续操作

查看下列 Codelab…

参考文档