如何部署文本嵌入模型并将其用于语义搜索
编辑如何部署文本嵌入模型并将其用于语义搜索
编辑您可以使用这些说明在 Elasticsearch 中部署文本嵌入模型,测试该模型,并将其添加到推理摄取管道中。它使您能够生成文本的向量表示,并对生成的向量执行向量相似性搜索。示例中使用的模型在 HuggingFace 上公开可用。
该示例使用来自 MS MARCO Passage Ranking Task 的公共数据集。它由来自 Microsoft Bing 搜索引擎的真实问题以及人为生成的答案组成。该示例使用此数据集的样本,使用模型生成文本嵌入,然后对其运行向量搜索。
您可以在 elasticsearch-labs
存储库中找到此示例的 Jupyter 笔记本,其中使用了 Python 客户端。
要求
编辑要按照此页面上的流程进行操作,您必须具备以下条件:
部署文本嵌入模型
编辑您可以使用 Eland 客户端 安装自然语言处理模型。使用预构建的 Docker 镜像来运行 Eland 安装模型命令。使用以下命令拉取最新镜像:
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 网站上的部署页面复制。
由于在 Eland 导入命令的末尾使用了 --start
选项,因此 Elasticsearch 会部署该模型以供使用。如果您有多个模型并想选择要部署的模型,则可以使用 Kibana 中的 机器学习 > 模型管理 用户界面来管理模型的启动和停止。
转到 机器学习 > 训练模型 页面并同步您的训练模型。页面顶部会显示一条警告消息,指出 “需要机器学习作业和训练模型同步”。单击链接以 “同步您的作业和训练模型。” 然后单击 同步。您也可以等待每小时自动同步,或使用 同步机器学习对象 API。
测试文本嵌入模型
编辑可以在 Kibana 中的 机器学习 > 训练模型 下评估已部署的模型,方法是为相应的模型选择 测试模型 操作。
通过使用 _infer API 测试模型
您还可以使用 _infer API 评估您的模型。在以下请求中,text_field
是模型期望找到输入的字段名称,如模型配置中所定义。默认情况下,如果模型是通过 Eland 上传的,则输入字段为 text_field
。
POST /_ml/trained_models/sentence-transformers__msmarco-minilm-l-12-v3/_infer { "docs": { "text_field": "How is the weather in Jamaica?" } }
API 返回类似于以下内容的响应
{ "inference_results": [ { "predicted_value": [ 0.39521875977516174, -0.3263707458972931, 0.26809820532798767, 0.30127981305122375, 0.502890408039093, ... ] } ] }
结果是从示例文本转换而来的预测密集向量。
加载数据
编辑在此步骤中,您将加载稍后在摄取管道中使用的,以获取嵌入的数据。
数据集 msmarco-passagetest2019-top1000
是 2019 TREC 深度学习 Track 测试阶段中使用的 MS MARCO Passage Ranking 数据集的子集。它包含 200 个查询,以及每个查询由简单信息检索 (IR) 系统提取的相关文本段落列表。从该数据集中,已提取所有唯一的段落及其 ID,并放入tsv 文件中,总共 182469 个段落。在下文中,此文件用作示例数据集。
使用数据可视化工具上传该文件。将第一列命名为 id
,第二列命名为 text
。索引名称为 collection
。上传完成后,您可以看到一个名为 collection
的索引,其中包含 182469 个文档。
将文本嵌入模型添加到推理摄取管道
编辑使用推理处理器处理初始数据。它为每个段落添加一个嵌入。为此,创建一个文本嵌入摄取管道,然后使用此管道重新索引初始数据。
现在,在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 的“训练模型”页面下找到,也可以在获取训练模型 API 调用的响应正文中找到。msmarco-MiniLM-L-12-v3 模型的 embedding_size 为 384,因此 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" } }
API 调用返回一个任务 ID,可用于监视进度
GET _tasks/<task_id>
您还可以打开模型统计 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" ] }
因此,您会收到来自 collection-with-embedings
索引的、在含义上与查询最接近的前 10 个文档,这些文档按与查询的接近程度排序
"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" } }, (...) ]
如果您想快速验证结果,请按照此博客文章的 快速验证 部分的步骤进行操作。