Elasticsearch:使用 inference API 进行语义搜索
本教程中的说明向您展示了如何将 inference API 工作流与各种服务结合使用来对你的数据执行语义搜索。为了说明问题的方便,我将使用 Cohere 服务来进行详细说明。更多其它服务,请详细参阅链接。
重要:有关在 Elastic Stack 中执行语义搜索的最简单方法,请参阅 semantic_text 端到端教程。
在本次练习中,我们将使用 Cohere 的 embed-english-v3.0 模型。事实上,你可以使用任何 Cohere 和 OpenAI 模型,它们均受 inference API 支持。有关 HuggingFace 上可用的推荐模型列表,请参阅支持的模型列表。 你可以尝试如下的模型:
- Cohere 的 embed-english-v3.0 模型
- HuggingFace 的 all-mpnet-base-v2 模型
- OpenAI 的 text-embedding-ada-002 第二代嵌入模型
- 可通过 Azure AI Studio 或 Azure OpenAI 获得的模型
- Google Vertex AI 的 text-embedding-004 模型
- Mistral 的 mistral-embed 模型
- Amazon Bedrock 的 amazon.titan-embed-text-v1 模型
要求
你需要 Cohere 帐户才能将 inference API 与 Cohere 服务一起使用。
创建推理端点
使用 Create inference API 创建推理端点:
PUT _inference/text_embedding/cohere_embeddings /* 1 */
{
"service": "cohere",
"service_settings": {
"api_key": "<api_key>", /* 2 */
"model_id": "embed-english-v3.0", /* 3 */
"embedding_type": "byte"
}
}
- 任务类型为路径中的 text_embedding,推理端点的唯一标识符 inference_id 为 cohere_embeddings。
- 你的 Cohere 帐户的 API 密钥。你可以在 Cohere 仪表板的 API 密钥部分下找到你的 API 密钥。你只需提供一次 API 密钥。Get inference API 不会返回你的 API 密钥。
- 要使用的嵌入模型的名称。你可以在此处找到 Cohere 嵌入模型的列表。
注意:使用此模型时,建议在密集向量字段映射中使用的相似度度量是点积。对于 Cohere 模型,嵌入被归一化为单位长度,在这种情况下点积和余弦度量是等效的。
从上面的请求上,我们可以看出来有一个限制 requests_per_minute 为 10000。这是因为我使用的是测试账号。
创建索引映射
必须创建目标索引的映射 - 包含模型将根据你的输入文本创建的嵌入的索引。目标索引必须具有一个字段,该字段对于大多数模型具有 dense_vector 字段类型,对于稀疏向量模型具有 sparse_vector 字段类型,就像 elser 服务的情况一样,用于索引所用模型的输出。
PUT cohere-embeddings
{
"mappings": {
"properties": {
"content_embedding": { /* 1 */
"type": "dense_vector", /* 2 */
"dims": 1024, /* 3 */
"element_type": "byte"
},
"content": { /* 4 */
"type": "text"
}
}
}
}
- 包含生成的标记的字段的名称。下一步必须在推理管道配置中引用它。
- 包含标记的字段是 dense_vector 字段。
- 模型的输出维度。在您使用的模型的 Cohere 文档中找到此值。
- 创建密集向量表示的字段的名称。在此示例中,字段的名称为 content。下一步必须在推理管道配置中引用它。
- 字段类型,在此示例中为 text。
使用推理处理器创建摄取管道
使用 inference processor 创建 ingest pipeline,并使用上面创建的模型对管道中摄取的数据进行推理。
PUT _ingest/pipeline/cohere_embeddings
{
"processors": [
{
"inference": {
"model_id": "cohere_embeddings", /* 1 */
"input_output": { /* 2 */
"input_field": "content",
"output_field": "content_embedding"
}
}
}
]
}
- 你使用 Create inference API 创建的推理端点的名称,在该步骤中称为 inference_id。
- 定义推理过程的 input_field 和将包含推理结果的 output_field 的配置对象。
加载数据
在此步骤中,你将加载稍后在推理提取管道中用于从中创建嵌入的数据。
使用 msmarco-passagetest2019-top1000 数据集,它是 MS MARCO Passage Ranking 数据集的子集。它包含 200 个查询,每个查询都附有相关文本段落列表。所有唯一段落及其 ID 都已从该数据集中提取并编译为 tsv 文件。
下载文件并使用机器学习 UI 中的 Data Visualizer 将其上传到你的集群。将名称 id 分配给第一列,将内容分配给第二列。索引名称为 test-data。上传完成后,你可以看到一个名为 test-data 的索引,其中包含 182469 个文档。
具体的步骤可以参考文章 “Elasticsearch:使用 ELSER 进行语义搜索 - sparse_vector”。
通过 inference ingest pipeline 采集数据
通过使用你选择的模型的推理管道重新索引数据,从文本中创建嵌入。此步骤使用重新索引 API 模拟通过管道采集数据。
POST _reindex?wait_for_completion=false
{
"source": {
"index": "test-data",
"size": 50 /* 1 */
},
"dest": {
"index": "cohere-embeddings",
"pipeline": "cohere_embeddings"
}
}
- 重新索引的默认批次大小为 1000。将大小减小到较小的数字可以加快重新索引过程的更新速度,从而使您能够密切跟踪进度并尽早发现错误。
注意:你的 Cohere 账户的速率限制可能会影响重新索引过程的吞吐量。
注意:由于我采用的是测试账号,有速率限制,在上面,我设置 max_docs 为10,也即只针对前 10个 文档进行向量化。你可以根据自己的账号来具体操作。
该调用返回一个任务 ID 来监控进度:
GET _tasks/<task_id>
上面显示我们的10个文档已经完成了向量的生成。我们可以通过如下的命令来进行查看:
如果你不想等到重新索引过程完全完成(对于大型数据集而言,这可能需要数小时),你也可以取消重新索引过程:
POST _tasks/<task_id>/_cancel
语义搜索
使用嵌入丰富数据集后,你可以使用 semantic search 查询数据。对于密集向量模型,将 query_vector_builder 传递给 k-最近邻 (kNN) 向量搜索 API,并提供查询文本和您用于创建嵌入的模型。对于像 ELSER 这样的稀疏向量模型,请使用 sparse_vector 查询,并提供查询文本和您用于创建嵌入的模型。
注意:如果你取消了重新索引过程,则你只会运行查询部分数据,这会影响结果的质量。
GET cohere-embeddings/_search
{
"knn": {
"field": "content_embedding",
"query_vector_builder": {
"text_embedding": {
"model_id": "cohere_embeddings",
"model_text": "Muscles in human body"
}
},
"k": 10,
"num_candidates": 100
},
"_source": [
"id",
"content"
]
}
结果,你将从 cohere-embeddings 索引中收到与查询含义最接近的前 10 个文档,这些文档按与查询的接近程度排序:
"hits": [
{
"_index": "cohere-embeddings",
"_id": "-eFWCY4BECzWLnMZuI78",
"_score": 0.737484,
"_source": {
"id": 1690948,
"content": "Oxygen is supplied to the muscles via red blood cells. Red blood cells carry hemoglobin which oxygen bonds with as the hemoglobin rich blood cells pass through the blood vessels of the lungs.The now oxygen rich blood cells carry that oxygen to the cells that are demanding it, in this case skeletal muscle cells.ther ways in which muscles are supplied with oxygen include: 1 Blood flow from the heart is increased. 2 Blood flow to your muscles in increased. 3 Blood flow from nonessential organs is transported to working muscles."
}
},
{
"_index": "cohere-embeddings",
"_id": "HuFWCY4BECzWLnMZuI_8",
"_score": 0.7176013,
"_source": {
"id": 1692482,
"content": "The thoracic cavity is separated from the abdominal cavity by the diaphragm. This is a broad flat muscle. (muscular) diaphragm The diaphragm is a muscle that separat…e the thoracic from the abdominal cavity. The pelvis is the lowest part of the abdominal cavity and it has no physical separation from it Diaphragm."
}
},
{
"_index": "cohere-embeddings",
"_id": "IOFWCY4BECzWLnMZuI_8",
"_score": 0.7154432,
"_source": {
"id": 1692489,
"content": "Muscular Wall Separating the Abdominal and Thoracic Cavities; Thoracic Cavity of a Fetal Pig; In Mammals the Diaphragm Separates the Abdominal Cavity from the"
}
},
{
"_index": "cohere-embeddings",
"_id": "C-FWCY4BECzWLnMZuI_8",
"_score": 0.695313,
"_source": {
"id": 1691493,
"content": "Burning, aching, tenderness and stiffness are just some descriptors of the discomfort you may feel in the muscles you exercised one to two days ago.For the most part, these sensations you experience after exercise are collectively known as delayed onset muscle soreness.urning, aching, tenderness and stiffness are just some descriptors of the discomfort you may feel in the muscles you exercised one to two days ago."
}
},
(...)
]
更多阅读 :将 Cohere 与 Elasticsearch 结合使用