想要使用语义搜索处理数据,但又不想花费大量时间在技术细节上?我们引入了 semantic_text
字段类型,帮助你处理所需的基础设施和细节。
语义搜索 是一种利用机器学习模型提高搜索结果相关性的高级技术。与传统的基于关键词的搜索不同,语义搜索专注于理解词语的含义及其使用的上下文。这通过机器学习模型实现,提供了更深层次的文本语义理解。
这些模型生成的向量嵌入是捕捉文本含义的数值表示。这些嵌入与文档数据一起存储,使得向量搜索技术能够考虑词语的含义和上下文,而不仅仅是纯粹的词汇匹配。
要进行语义搜索,你需要以下步骤:
从头开始配置语义搜索可能很复杂,需要设置映射、摄取管道以及针对所选推理模型定制的查询。每一步都有优化的机会,但也需要仔细配置以确保所有组件无缝协作。
semantic_text
简化了这一过程,专注于最重要的部分:推理模型。一旦选择了推理模型,semantic_text
将提供合理的默认设置,使你能专注于搜索,而不必担心如何索引、生成或查询嵌入。
让我们来看一下每个步骤,以及 semantic_text
如何简化这一设置过程。
推理模型将为你的文档和查询生成嵌入。不同的模型在以下方面有所不同:
Elasticsearch 支持内部和外部推理服务:
选择推理模型后,创建推理端点。推理端点标识符将是设置 semantic_text
的唯一配置细节。
PUT _inference/sparse_embedding/my-elser-endpoint
{
"service": "elser",
"service_settings": {
"num_allocations": 1,
"num_threads": 1
}
}
Elasticsearch 需要索引模型生成的嵌入,以便后续高效查询。
在 semantic_text
出现之前,你需要了解用于存储嵌入信息的两种主要字段类型:
sparse_vector
:用于索引稀疏向量嵌入,如 ELSER 生成的嵌入。每个嵌入由标记和权重对组成。每个嵌入生成的标记数量较少。dense_vector
:用于索引包含嵌入信息的数字向量。模型生成固定大小的向量,称为向量维度。使用的字段类型由选择的模型决定。如果使用密集向量,你需要配置字段以包含维度计数、用于计算向量接近度的相似度函数以及存储自定义项如量化或每个元素使用的特定数据类型。
现在,如果使用 semantic_text
,只需指定模型的推理端点标识符即可定义semantic_text 字段映射:
PUT test-index
{
"mappings": {
"properties": {
"infer_field": {
"type": "semantic_text",
"inference_id": "my-elser-endpoint"
}
}
}
}
这样就完成了。不需要定义其他映射选项,也无需了解使用哪种字段类型。
索引准备好存储嵌入后,就可以生成嵌入了。
在 semantic_text
出现之前,要在文档摄取时自动生成嵌入,你需要设置一个摄取管道。
摄取管道用于在文档摄入索引时或摄取过程中明确指定时自动丰富或转换文档。
你需要使用inference 处理器为字段生成嵌入。处理器需要配置:
使用 semantic_text
,你只需将文档添加到索引中。semantic_text 字段会自动使用指定的推理端点计算嵌入。
这意味着不需要创建推理管道来生成嵌入。使用_bulk、index 或 update API 将自动完成这一过程:
PUT test-index/_doc/doc1
{
"infer_field": "These are not the droids you're looking for. He's free to go around"
}
semantic_text
字段的推理请求也会批处理。如果一个_bulk API 请求包含 10 个文档,每个文档包含 2 个 semantic_text
字段,那么该请求将执行一次推理请求,向推理服务发送 20 个文本,而不是分别发送 10 个包含 2 个文本的请求。
选择模型的一个挑战是模型可以生成嵌入的标记数量。模型处理的标记数量是有限的,被称为模型的上下文窗口。
如果需要处理的文本长度超过模型的上下文窗口,你可能会截断文本,只使用其中的一部分生成嵌入。这并不理想,因为你会丢失信息;生成的嵌入将无法捕捉输入文本的完整上下文。
即使有一个长的上下文窗口,长文本意味着大量内容将被简化为一个嵌入,使其成为不准确的表示。
此外,返回长文本对用户理解也是一个挑战,他们需要浏览文本以确定其是否符合他们的需求。使用较小的片段会更好。
另一种选择是使用分块将长文本分割成较小的片段。这些较小的块被添加到每个文档中,以更好地表示完整文本。然后可以使用嵌套查询搜索所有单个片段,并检索包含最佳评分块的文档。
在 semantic_text
出现之前,分块并未开箱即用 - 推理处理器不支持分块。如果需要使用分块,需要在摄入文档之前执行,或者使用脚本处理器在 Elasticsearch 中执行分块。
使用 semantic_text
意味着在索引时将自动执行分块。长文档将被分割成 250 字的部分,每部分有 100 字的重叠,以确保每部分与前一部分共享 100 字。这种重叠确保输入文本中的重要上下文信息不会因硬性断开而丢失。
如果模型和推理服务支持批处理,分块的输入将自动批处理为尽可能少的请求,每个请求都针对推理服务进行优化。生成的块将存储在嵌套对象结构中,以便你可以检查每个块中包含的文本。
现在文档及其嵌入已在 Elasticsearch 中索引,是时候进行一些查询了!
在 semantic_text
出现之前,你需要根据模型生成的嵌入类型(密集或稀疏)使用不同的查询。稀疏向量字段类型需要使用稀疏向量查询,而密集向量字段类型可以使用knn 搜索或knn 查询。
查询过程可以进一步定制以提高性能和相关性。例如,稀疏向量查询可以定义标记修剪以避免考虑不相关的标记。knn 查询可以指定候选者数量和每个分片返回的 top k 结果。
使用 semantic_text
时,你不需要处理这些细节。只需使用一个单一查询类型来搜索文档:
GET test-index/_search
{
"query": {
"semantic": {
"field": "infer_field",
"query": "robots you're searching for"
}
}
}
只需包含字段和查询文本。无需决定使用稀疏向量还是 knn 查询,semantic_text 会为你处理这些细节。
与使用特定的 knn
搜索及其所有配置参数相比:
{
"knn": {
"field": "infer_field",
"k": 10,
"num_candidates": 100,
"query_vector_builder": {
"text_embedding": {
"model_id": "my-dense-vector-embedding-model",
"model_text": "robots you're searching for"
}
}
}
}
要了解 semantic_text
如何工作,你可以创建一个 semantic_text
索引并查看摄取文档时发生的情况。当第一个文档摄取时,推理端点计算嵌入。索引后,你会注意到索引映射的变化:
GET test-index
{
"test-index": {
"mappings": {
"properties": {
"infer_field": {
"type": "semantic_text",
"inference_id": "my-elser-endpoint",
"model_settings": {
"task_type": "sparse_embedding"
}
}
}
}
}
}
现在有了关于模型设置的额外信息。文本嵌入模型还将包括诸如维度数量或模型相似度函数等信息。
你可以检查文档,发现其中已经包含了嵌入结果:
GET test-index/_doc/doc1
{
"_index": "test-sparse",
"_id": "doc1",
"_source": {
"infer_field": {
"text": "these are not the droids you're looking for. He's free to go around",
"inference": {
"inference_id": "my-elser-endpoint",
"model_settings": {
"task_type": "sparse_embedding"
},
"chunks": [
{
"text": "these are not the droids you're looking for. He's free to go around",
"embeddings": {
"##oid": 1.9103845,
"##oids": 1.768872,
"free": 1.693662,
"dr": 1.6103356,
"around": 1.4376559,
"these": 1.1396849
...
}
}
]
}
}
}
}
该字段不仅包含输入文本,还包含一个存储原始文本、模型设置和输入文本被分成的每个块信息的结构。
这个结构包含两个元素:
semantic_text
通过对索引和查询数据做出默认决策来简化语义搜索:
sparse_vector
或 dense_vector
字段类型int8_hnsw
索引类型以利用标量量化。k
和 num_candidates
。这些都是合理的默认设置,允许你快速轻松地开始使用语义搜索。随着时间的推移,你可能希望自定义查询和数据类型,以优化搜索相关性、索引和查询性能以及索引存储。
目前还没有自定义语义查询的选项。如果你想自定义针对 semantic_text
字段的查询,可以使用显式的 knn 和稀疏向量查询执行高级语义文本搜索。
我们计划为 semantic_text
添加检索器支持,并为 semantic_text
字段添加配置选项,使得在查询时不需要这些配置。敬请期待!
如果需要更深入地自定义数据索引,可以使用 sparse_vector
或 dense_vector
字段类型。这些字段类型让你完全控制嵌入的生成、索引和查询方式。
你需要创建一个带有推理处理器的摄取管道来生成嵌入。本教程将指导你完成整个过程。
我们刚刚开始使用 semantic_text
!我们将继续进行许多改进,包括:
semantic_text
即将推出!首先在我们的无服务器环境中提供,然后将在 Elasticsearch 8.15 的所有其他环境中发布。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。