正在加载

文本嵌入和语义搜索

Elastic Stack Serverless

您可以使用这些说明在 Elasticsearch 中部署文本嵌入模型,测试该模型,并将其添加到推断摄取管道。 它使您能够生成文本的向量表示,并对生成的向量执行向量相似性搜索。 该示例中使用的模型可在HuggingFace上公开获得。

该示例使用来自 MS MARCO Passage Ranking Task 的公共数据集。 它由来自 Microsoft Bing 搜索引擎的真实问题以及人工生成的答案组成。 该示例使用此数据集的样本,使用模型来生成文本嵌入,然后在该样本上运行向量搜索。

您可以在 elasticsearch-labs 存储库中使用 Python 客户端找到作为 Jupyter notebook 的此示例

要遵循此页面上的流程,您必须具备

您可以使用Eland 客户端来安装自然语言处理模型。 使用预构建的 Docker 镜像来运行 Eland install model 命令。 使用以下命令拉取最新镜像:

docker pull docker.elastic.co/eland/eland

拉取完成后,您的 Eland Docker 客户端即可使用。

第三方模型参考列表中选择文本嵌入模型。 此示例使用 msmarco-MiniLM-L-12-v3 sentence-transformer 模型。

通过在 Docker 镜像中运行 eland_import_model_hub 命令来安装模型

docker run -it --rm docker.elastic.co/eland/eland \
    eland_import_hub_model \
      --cloud-id $CLOUD_ID \
      -u <username> -p <password> \
      --hub-model-id sentence-transformers/msmarco-MiniLM-L-12-v3 \
      --task-type text_embedding \
      --start

您需要提供管理员用户名和密码,并将 $CLOUD_ID 替换为您的 Cloud 部署 ID。 此 Cloud ID 可以从您的 Cloud 网站上的 Hosted deployments 页面复制。

由于在 Eland 导入命令的末尾使用了 --start 选项,因此 Elasticsearch 部署的模型已准备就绪。 如果您有多个模型并且想要选择要部署的模型,则可以使用 Kibana 中的 Machine Learning > Model Management 用户界面来管理模型的启动和停止。

转到 Machine Learning > Trained Models 页面并同步您训练的模型。 页面顶部会显示一条警告消息,指出 *“需要 ML 作业和训练模型同步”*。 按照链接 *“同步您的作业和训练模型”*。 然后单击 Synchronize。 您也可以等待每小时发生的自动同步,或使用 同步机器学习对象 API

可以在 Machine Learning > Trained Models 下的 Kibana 中评估已部署的模型,方法是为各自的模型选择 Test model 操作。

Test trained model UI

结果是从示例文本转换而来的预测密集向量。

在此步骤中,您加载稍后在摄取管道中使用的数据,以获取嵌入。

数据集 msmarco-passagetest2019-top1000 是 2019 TREC 深度学习轨道的测试阶段中使用的 MS MARCO Passage Ranking 数据集的子集。 它包含 200 个查询,以及每个查询的由简单信息检索 (IR) 系统提取的相关文本段落列表。 从该数据集中,已提取所有具有其 ID 的唯一段落,并将其放入 tsv 文件中,总计 182469 个段落。 在下文中,此文件用作示例数据集。

通过使用数据可视化器上传文件。 将第一列命名为 id,第二列命名为 text。 索引名称为 collection。 上传完成后,您可以看到一个名为 collection 的索引,其中包含 182469 个文档。

Importing the data

使用 推断处理器处理初始数据。 它为每个段落添加一个嵌入。 为此,创建一个文本嵌入摄取管道,然后使用此管道重新索引初始数据。

现在,可以在Stack Management UI中或通过 API 创建一个摄取管道

PUT _ingest/pipeline/text-embeddings
{
  "description": "Text embedding pipeline",
  "processors": [
    {
      "inference": {
        "model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
        "target_field": "text_embedding",
        "field_map": {
          "text": "text_field"
        }
      }
    }
  ],
  "on_failure": [
    {
      "set": {
        "description": "Index document to 'failed-<index>'",
        "field": "_index",
        "value": "failed-{{{_index}}}"
      }
    },
    {
      "set": {
        "description": "Set error message",
        "field": "ingest.failure",
        "value": "{{_ingest.on_failure_message}}"
      }
    }
  ]
}

这些段落位于名为 text 的字段中。 field_map 将文本映射到模型期望的 text_field 字段。 on_failure 处理程序设置为将故障索引到不同的索引中。

在通过管道摄取数据之前,创建目标索引的映射,特别是对于摄取处理器存储嵌入的 text_embedding.predicted_value 字段。 dense_vector 字段必须配置为与模型生成的文本嵌入具有相同的维度数 (dims)。 该值可以在模型配置中的 embedding_size 选项中找到,该选项位于 Kibana 中的 Trained Models 页面下或 Get trained models API 调用的响应正文中。 msmarco-MiniLM-L-12-v3 模型具有 384 的 embedding_size,因此 dims 设置为 384。

PUT collection-with-embeddings
{
  "mappings": {
    "properties": {
      "text_embedding.predicted_value": {
        "type": "dense_vector",
        "dims": 384
      },
      "text": {
        "type": "text"
      }
    }
  }
}

通过推断管道将数据重新索引到 collection-with-embeddings 索引来创建文本嵌入。 推断摄取处理器将嵌入向量插入到每个文档中。

POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "collection",
    "size": 50
  },
  "dest": {
    "index": "collection-with-embeddings",
    "pipeline": "text-embeddings"
  }
}
  1. 重新索引的默认批处理大小为 1000。 将 size 减小为较小的数字可以更快地更新重新索引过程,这使您能够密切关注进度并及早发现错误。

API 调用返回一个任务 ID,可用于监视进度

GET _tasks/<task_id>

您还可以打开模型状态 UI 以跟踪进度。

Model status UI

重新索引完成后,新索引中的文档将包含推断结果 – 向量嵌入。

在数据集已通过向量嵌入丰富后,您可以使用语义搜索来查询数据。 将 query_vector_builder 传递给 k-最近邻 (kNN) 向量搜索 API,并提供查询文本和您用于创建向量嵌入的模型。 此示例搜索“牙买加的天气如何?”

GET collection-with-embeddings/_search
{
  "knn": {
    "field": "text_embedding.predicted_value",
    "query_vector_builder": {
      "text_embedding": {
        "model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
        "model_text": "How is the weather in Jamaica?"
      }
    },
    "k": 10,
    "num_candidates": 100
  },
  "_source": [
    "id",
    "text"
  ]
}

结果,您将收到与查询含义最接近的前 10 个文档,这些文档来自按其与查询的接近程度排序的 collection-with-embedings 索引

"hits" : [
      {
        "_index" : "collection-with-embeddings",
        "_id" : "47TPtn8BjSkJO8zzKq_o",
        "_score" : 0.94591534,
        "_source" : {
          "id" : 434125,
          "text" : "The climate in Jamaica is tropical and humid with warm to hot temperatures all year round. The average temperature in Jamaica is between 80 and 90 degrees Fahrenheit. Jamaican nights are considerably cooler than the days, and the mountain areas are cooler than the lower land throughout the year. Continue Reading."
        }
      },
      {
        "_index" : "collection-with-embeddings",
        "_id" : "3LTPtn8BjSkJO8zzKJO1",
        "_score" : 0.94536424,
        "_source" : {
          "id" : 4498474,
          "text" : "The climate in Jamaica is tropical and humid with warm to hot temperatures all year round. The average temperature in Jamaica is between 80 and 90 degrees Fahrenheit. Jamaican nights are considerably cooler than the days, and the mountain areas are cooler than the lower land throughout the year"
        }
      },
      {
        "_index" : "collection-with-embeddings",
        "_id" : "KrXPtn8BjSkJO8zzPbDW",
        "_score" :  0.9432083,
        "_source" : {
          "id" : 190804,
          "text" : "Quick Answer. The climate in Jamaica is tropical and humid with warm to hot temperatures all year round. The average temperature in Jamaica is between 80 and 90 degrees Fahrenheit. Jamaican nights are considerably cooler than the days, and the mountain areas are cooler than the lower land throughout the year. Continue Reading"
        }
      },
      (...)
]

如果您想快速验证结果,请按照这篇博文快速验证部分的步骤进行操作。

© . All rights reserved.