教程:使用推理 API 进行语义搜索

编辑

教程:使用推理 API 进行语义搜索

编辑

本教程中的说明将向您展示如何使用推理 API 工作流与各种服务一起对您的数据执行语义搜索。

有关在 Elastic Stack 中执行语义搜索的最简单方法,请参阅semantic_text 端到端教程。

以下示例使用

您可以使用任何 Cohere 和 OpenAI 模型,推理 API 都支持它们。有关 HuggingFace 上推荐模型的列表,请参阅支持的模型列表

单击您想要使用的任何小部件下方的服务名称以查看相应的说明。

要求

编辑

需要 Cohere 帐户 才能将推理 API 与 Cohere 服务一起使用。

创建推理端点

编辑

使用 创建推理 API 创建推理端点

resp = client.inference.put(
    task_type="text_embedding",
    inference_id="cohere_embeddings",
    inference_config={
        "service": "cohere",
        "service_settings": {
            "api_key": "<api_key>",
            "model_id": "embed-english-v3.0",
            "embedding_type": "byte"
        }
    },
)
print(resp)
const response = await client.inference.put({
  task_type: "text_embedding",
  inference_id: "cohere_embeddings",
  inference_config: {
    service: "cohere",
    service_settings: {
      api_key: "<api_key>",
      model_id: "embed-english-v3.0",
      embedding_type: "byte",
    },
  },
});
console.log(response);
PUT _inference/text_embedding/cohere_embeddings 
{
    "service": "cohere",
    "service_settings": {
        "api_key": "<api_key>", 
        "model_id": "embed-english-v3.0", 
        "embedding_type": "byte"
    }
}

路径中的任务类型为 text_embedding,而 inference_id(推理端点的唯一标识符)为 cohere_embeddings

您的 Cohere 帐户的 API 密钥。您可以在 Cohere 仪表板的 API 密钥部分 中找到您的 API 密钥。您只需要提供一次 API 密钥。获取推理 API 不会返回您的 API 密钥。

要使用的嵌入模型的名称。您可以在此处找到 Cohere 嵌入模型的列表 此处

使用此模型时,在 dense_vector 字段映射中建议使用的相似性度量为 dot_product。对于 Cohere 模型,嵌入被归一化为单位长度,在这种情况下,dot_productcosine 度量是等价的。

创建索引映射

编辑

必须创建目标索引的映射 - 包含模型根据您的输入文本创建的嵌入的索引。对于大多数模型,目标索引必须包含具有dense_vector字段类型的字段,对于像 elser 服务中稀疏向量模型,则必须具有sparse_vector字段类型,以便对所用模型的输出进行索引。

resp = client.indices.create(
    index="cohere-embeddings",
    mappings={
        "properties": {
            "content_embedding": {
                "type": "dense_vector",
                "dims": 1024,
                "element_type": "byte"
            },
            "content": {
                "type": "text"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'cohere-embeddings',
  body: {
    mappings: {
      properties: {
        content_embedding: {
          type: 'dense_vector',
          dims: 1024,
          element_type: 'byte'
        },
        content: {
          type: 'text'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "cohere-embeddings",
  mappings: {
    properties: {
      content_embedding: {
        type: "dense_vector",
        dims: 1024,
        element_type: "byte",
      },
      content: {
        type: "text",
      },
    },
  },
});
console.log(response);
PUT cohere-embeddings
{
  "mappings": {
    "properties": {
      "content_embedding": { 
        "type": "dense_vector", 
        "dims": 1024, 
        "element_type": "byte"
      },
      "content": { 
        "type": "text" 
      }
    }
  }
}

包含生成令牌的字段名称。它必须在下一步的推理管道配置中引用。

包含令牌的字段是 dense_vector 字段。

模型的输出维度。在您使用的模型的Cohere 文档中找到此值。

要从中创建密集向量表示的字段名称。在本例中,字段名称为 content。它必须在下一步的推理管道配置中引用。

字段类型,在本例中为文本。

使用推理处理器创建摄取管道

编辑

使用推理处理器创建一个摄取管道,并使用您上面创建的模型对管道中正在摄取的数据进行推理。

resp = client.ingest.put_pipeline(
    id="cohere_embeddings_pipeline",
    processors=[
        {
            "inference": {
                "model_id": "cohere_embeddings",
                "input_output": {
                    "input_field": "content",
                    "output_field": "content_embedding"
                }
            }
        }
    ],
)
print(resp)
const response = await client.ingest.putPipeline({
  id: "cohere_embeddings_pipeline",
  processors: [
    {
      inference: {
        model_id: "cohere_embeddings",
        input_output: {
          input_field: "content",
          output_field: "content_embedding",
        },
      },
    },
  ],
});
console.log(response);
PUT _ingest/pipeline/cohere_embeddings_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "cohere_embeddings", 
        "input_output": { 
          "input_field": "content",
          "output_field": "content_embedding"
        }
      }
    }
  ]
}

您使用创建推理 API创建的推理端点的名称,在该步骤中称为 inference_id

定义推理过程的 input_field 和包含推理结果的 output_field 的配置对象。

加载数据

编辑

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

使用 msmarco-passagetest2019-top1000 数据集,它是 MS MARCO 段落排序数据集的一个子集。它包含 200 个查询,每个查询都附带一个相关文本段落的列表。所有唯一的段落及其 ID 都已从该数据集中提取并编译到一个tsv 文件中。

下载该文件并使用机器学习 UI 中的数据可视化将其上传到您的集群。分析完数据后,单击覆盖设置。在编辑字段名称下,将 id 分配给第一列,将 content 分配给第二列。单击应用,然后单击导入。将索引命名为 test-data,然后单击导入。上传完成后,您将看到一个名为 test-data 的索引,其中包含 182,469 个文档。

通过推理摄取管道摄取数据

编辑

通过使用所选模型的推理管道重新索引数据,从文本中创建嵌入。此步骤使用重新索引 API来模拟通过管道的的数据摄取。

resp = client.reindex(
    wait_for_completion=False,
    source={
        "index": "test-data",
        "size": 50
    },
    dest={
        "index": "cohere-embeddings",
        "pipeline": "cohere_embeddings_pipeline"
    },
)
print(resp)
const response = await client.reindex({
  wait_for_completion: "false",
  source: {
    index: "test-data",
    size: 50,
  },
  dest: {
    index: "cohere-embeddings",
    pipeline: "cohere_embeddings_pipeline",
  },
});
console.log(response);
POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "test-data",
    "size": 50 
  },
  "dest": {
    "index": "cohere-embeddings",
    "pipeline": "cohere_embeddings_pipeline"
  }
}

重新索引的默认批次大小为 1000。将 size 减少到更小的数字可以加快重新索引过程的更新速度,这使您可以密切关注进度并在早期检测到错误。

您 Cohere 账户的速率限制可能会影响重新索引过程的吞吐量。

该调用返回一个任务 ID 以监控进度。

resp = client.tasks.get(
    task_id="<task_id>",
)
print(resp)
const response = await client.tasks.get({
  task_id: "<task_id>",
});
console.log(response);
GET _tasks/<task_id>

重新索引大型数据集可能需要很长时间。您可以只使用数据集的一部分来测试此工作流。为此,请取消重新索引过程,并且仅为已重新索引的子集生成嵌入。以下 API 请求将取消重新索引任务。

resp = client.tasks.cancel(
    task_id="<task_id>",
)
print(resp)
const response = await client.tasks.cancel({
  task_id: "<task_id>",
});
console.log(response);
POST _tasks/<task_id>/_cancel

语义搜索

编辑

在数据集使用嵌入进行丰富后,您可以使用语义搜索来查询数据。对于密集向量模型,请将 query_vector_builder 传递给 k 近邻 (kNN) 向量搜索 API,并提供查询文本和用于创建嵌入的模型。对于像 ELSER 这样的稀疏向量模型,请使用 sparse_vector 查询,并提供查询文本和用于创建嵌入的模型。

如果您取消了重新索引过程,则仅对数据的一部分运行查询,这会影响结果的质量。

resp = client.search(
    index="cohere-embeddings",
    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"
    ],
)
print(resp)
response = client.search(
  index: 'cohere-embeddings',
  body: {
    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'
    ]
  }
)
puts response
const response = await client.search({
  index: "cohere-embeddings",
  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"],
});
console.log(response);
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."
        }
      },
      (...)
    ]

交互式教程

编辑

您还可以使用 Elasticsearch Python 客户端以交互式 Colab Notebook 格式找到教程。