Elasticsearch:使用 semantic_text 简化语义搜索

news2024/11/15 19:37:41

作者:来自 Elastic Carlos Delgado, Mike Pellegrini

semantic_text - 你知道,用于语义搜索!

你是否想开始使用语义搜索来搜索数据,但专注于模型和结果而不是技术细节?我们引入了 semantic_text 字段类型,它将处理你所需的细节和基础架构。

语义搜索(semantic search)是一种复杂的技术,旨在通过利用机器学习模型来增强搜索结果的相关性。与传统的基于关键字的搜索不同,语义搜索专注于理解单词的含义及其使用的上下文。这是通过应用机器学习模型来实现的,这些模型可以提供对文本的更深入的语义理解。

这些模型生成向量嵌入(vector embeddings),它们是捕获文本含义的数字表示。这些嵌入与你的文档数据一起存储,从而启用考虑单词含义和上下文而不是纯词汇匹配的向量搜索技术。

你需要添加什么来添加语义搜索?

要执行语义搜索,你需要执行以下步骤:

  • 选择一个推理模型来创建嵌入,用于索引文档和执行查询。
  • 创建索引映射以存储推理结果,以便之后可以有效地搜索它们。
  • 设置索引,以便为添加到索引中的新文档计算推理结果。
  • 自动处理长文本文档,以便搜索准确并覆盖整个文档。
  • 查询数据以检索结果。

从头开始配置语义搜索可能很复杂。它需要设置映射、提取管道和针对你选择的推理模型量身定制的查询。每个步骤都提供了微调和优化的机会,但也需要仔细配置以确保所有组件无缝协作。

虽然这提供了很大程度的控制,但它使使用语义搜索成为一个详细而深思熟虑的过程,要求你配置彼此相关并与推理模型相关的单独部分。

semantic_text 通过专注于重要的事情来简化此过程:推理模型。一旦你选择了推理模型,semantic_text 将通过提供合理的默认值让你轻松开始使用语义搜索,这样你就可以专注于搜索,而不是如何索引、生成或查询嵌入。

让我们看一下每个步骤,以及 semantic_text 如何简化此设置。

选择一个推理模型

推理模型将为你的文档和查询生成嵌入。不同的模型在以下方面有不同的权衡:

  • 结果的准确性和相关性
  • 可扩展性和性能
  • 语言和多语言支持
  • 成本

Elasticsearch 支持内部和外部推理服务:

  • 内部服务部署在 Elasticsearch 集群中。你可以使用已包含的模型(如 ELSER 和 E5),也可以使用 eland 将外部模型导入集群。
  • 外部服务由模型提供商部署。Elasticsearch 支持以下内容:
    • Cohere
    • Hugging Face
    • Mistral
    • OpenAI
    • Azure AI Studio
    • Azure OpenAI
    • Google AI Studio

选择推理模式后,为其创建推理端点。推理端点标识符将是你设置 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 processor 为你的字段生成嵌入。处理器需要使用以下内容进行配置:

  • 从中生成嵌入的文本字段
  • 将添加生成的嵌入的输出字段
  • 根据模型类型,针对文本嵌入或稀疏嵌入的特定推理配置

使用 semantic_text,你只需将文档添加到索引中。semantic_text 字段将使用指定的推理端点自动计算嵌入。

这意味着无需创建推理管道来生成嵌入。使用批量、索引或更新 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 之前,你需要根据模型生成的嵌入类型(密集或稀疏)使用不同的查询。查询 sparse_vector 字段类型需要 sparse vector query,而搜索 density_vector 字段类型则可以使用 knn search 或  knn query。

查询过程可以进一步定制,以提高性能和相关性。例如,稀疏向量查询可以定义标记修剪(token pruning),以避免考虑不相关的标记。Knn 查询可以指定要考虑的候选数以及要从每个分片返回的前 k 个结果。

使用 semantic_text 时,你无需处理这些细节。你可以使用 single query type 来搜索文档:

GET test-index/_search
{
  "query": {
    "semantic": {
      "field": "inference_field",
      "query": "robots you're searching for"
    }
  }
}

只需包含字段和查询文本。无需在稀疏向量和 knn 查询之间做出选择,语义文本会为你完成此操作。

将其与使用具有所有配置参数的特定 knn 搜索进行比较:

{
  "knn": {
    "field": "inference-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

              …
            }
          }
        ]
      }
    }
  }
}

该字段不仅包含输入文本,还包含一个结构,用于存储原始文本、模型设置以及输入文本被划分成的每个块的信息。

此结构由一个具有两个元素的对象组成:

  • text:包含原始输入文本
  • inference:推理端点添加的推理信息,包括:
    • 推理端点的 inference_id
    • 包含模型属性的 model_settings
    • chunks:嵌套对象,包含从输入文本创建的每个块的元素。每个块包含:
      • 块的 text
      • 块文本的计算 embeddings

自定义语义文本

semantic_text 通过对数据进行索引和查询做出默认决策来简化语义搜索:

  • 根据推理模型类型使用 sparse_vector 或 density_vector 字段类型
  • 根据推理结果自动定义维度数和相似度
  • 对密集向量字段类型使用 int8_hnsw 索引类型来利用标量量化 。
  • 使用查询默认值。sparse_vector 查询不应用任何标记修剪,knn 查询也不设置自定义 k 和 num_candidates。

这些都是合理的默认值,可让你快速轻松地开始使用语义搜索。随着时间的推移,你可能希望自定义查询和数据类型以优化搜索相关性、索引和查询性能以及索引存储。

查询自定义

目前还没有针对语义查询的自定义选项。如果你想针对 semantic_text 字段自定义查询,可以使用显式 knn 和稀疏向量查询执行高级 semantic_text 搜索。

我们计划添加对 semantic_text 的 retrievers 支持,并向 semantic_text 字段添加配置选项,以便在查询时不需要它们。敬请期待!

数据类型自定义

如果你需要对数据索引进行更深入的自定义,则可以使用 sparse_vector 或 density_vector 字段类型。这些字段类型让你可以完全控制嵌入的生成、索引和查询方式。

你需要创建一个带有推理处理器的摄取管道来生成嵌入。本教程将引导你完成整个过程。

下一步是什么?

我们刚刚开始使用 semantic_text!我们将继续致力于许多增强功能,包括:

  • 更好的推理错误处理
  • 自定义分块策略
  • 默认隐藏 _source 中的嵌入,以避免使搜索响应混乱
  • 内部命中支持,用于检索查询的相关信息块
  • 过滤和 retrievers 支持
  • Kibana 支持

试试吧!

使用此笔记本[准备好后添加链接]探索语义文本,快速了解语义文本的工作原理。

如果你已经拥有 Elasticsearch 集群,则可以在本教程中查看使用语义文本测试语义搜索的完整示例。

我们很乐意听听你使用语义文本的经验!请在论坛中告诉我们你的想法,或在 GitHub 存储库中打开问题。让我们一起让语义搜索更容易!

准备好自己尝试一下了吗?开始免费试用。
Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序!

原文:Semantic search simplified with semantic_text — Elastic Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1861100.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python-爬虫 下载天涯论坛帖子

为了爬取的高效性,实现的过程中我利用了python的threading模块,下面是threads.py模块,定义了下载解析页面的线程,下载图片的线程以及线程池 import threading import urllib2 import Queue import re thread_lock threading.RL…

上电相位确定性:使用多芯片同步

将多个数字信号处理 (DSP) 块、宽带数模转换器 (DAC) 和宽带模数转换器 (ADC) 集成到单个单片芯片中,现在可以卸载耗电的 FPGA 资源,以允许更小的占地面积、更低的功耗、增加通道数的平台,能够以比以前更高的速率进行采样。伴随这一新功能而来…

【大数据开发语言Scala的入门教程】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

井盖位移传感器:给井盖装上“大脑”

你是否曾经在深夜回家时,因为路上一个不起眼的井盖而心惊胆战?或者因为某个井盖缺失,导致车辆受损、行人受伤?这些看似微小的问题,其实都隐藏着巨大的安全隐患。 旭华智能针对这一问题,研制了井盖位移传感器…

多种驱鸟设备,在电力安全中各显神通

多种驱鸟设备,在电力安全中各显神通 鸟类对电力的危险是一个不容忽视的问题,尤其是在电力设施密集的区域。随着人类对自然环境的不断开发和利用,鸟类与电力设施之间的接触也日益频繁,由此引发的安全隐患和事故也屡见不鲜。 具体…

【详细教程】如何使用YOLOv10进行图片与视频的目标检测

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

基于SaaS平台的iHRM管理系统测试学习

目录 1、登录模块 2、员工管理模块 3、Postmannewman软件的安装,学习 1、Postman的使用 2、Postman断言 1、断言状态码(重要) 2、断言包含某个字符串(contains string) 3、断言等于某个字符串(equal string) …

【多通道卷积终结篇,通俗易懂,清晰必读】

作为常识, 1、卷积层 输出特征图通道数 卷积核个数 与输入特征图通道数无关, 2、多卷积核处理多通道特征图的机制过程如下: 本文的参考资料为知乎:一文读懂Faster RCNN。 对于多通道图像多卷积核做卷积,计算方式如…

中兴光猫破解telnet配置命令汇总

中兴光猫telnet配置命令汇总 | LogDicthttps://www.logdict.com/archives/zhong-xing-guang-mao-telnetpei-zhi-ming-ling-hui-zong

Pikachu靶场--SSRF

参考借鉴:pikachu靶场练习——SSRF详解_pikachu ssrf-CSDN博客 SSRF(curl) 先了解一下curl curl是一个非常实用的、用来与服务器之间传输数据的工具;支持的协议包括 (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, PO…

【技术指南】稳压器(电压调节器):原理、类型及其实际用用案例

电压调节器(稳压器)是一种电子器件或电路,用于控制电路中的电压水平,以确保在电源电压波动或负载变化时,输出电压能够保持在设定的稳定水平。它们通常用于各种电子设备和电源系统中,以提供稳定的电压供应。…

AMEYA360代理品牌江苏润石:RS8661/2/4系列高压精密低噪声运算放大器

继RS8651/2/4系列高压精密低噪声运算放大器成功推向市场,润石科技再次成功量产RS8661/2/4系列高压精密低噪声运算放大器。 RS8661/2/4系列产品将工作电压提升到最高36V(18V)、失调电压进一步优化到5μV、在工业现场数据采集、各种仪器仪表测量设备\分析设备上有着广…

QT中的样式表.qss文件

一、前言 qt中样式表的改变有几种方法,第一种就是直接在ui界面对应的组件右键修改样式表,还有一种就是直接在程序里面修改样式表,我知道的还有一种就是qss文件,这个文件就是将在程序中写的修改样式表的语句写道qss文件中&#xff…

ROS CDK魔法书:点亮博客上云新技能(Python篇)

引言 在数字世界的浩瀚海洋中,信息与数据如同戏剧中的主角,舞动着无形的旋律,构建起信息时代的交响乐。而在这其中,作为一位技术领域的探索者,你的使命便是挥舞着编码的魔杖,创造和守护着这些宝贵的数字灵…

游戏AI的创造思路-技术基础-深度学习(1)

他来了,他来啦,后面歌词忘了~~~~~ 开谈深度学习,填上一点小坑,可又再次开掘大洞 -.-b 目录 1. 定义 2. 深度学习的发展历史和典型事件 3. 深度学习常用算法 3.1. 卷积神经网络(CNN) 3.1.1. 算法形成过…

前端必会--浏览器的工作原理与实践

进程与线程 线程 线程分为单线程和多线程 线程是不能单独存在的,它是由进程来启动和管理的。 进程 一个进程就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的…

OpenAI扩大版图,收购Mac协作应用巨擘Multi

Multi,这款专为macOS用户打造的多人协作应用,凭借其卓越的低延迟实时协作功能,如共享光标、绘图和键盘控制,在业界享有盛誉。如今,OpenAI宣布成功收购Multi,以进一步扩大其技术生态。Multi公司将停止运营&a…

ppt忘记保存怎么恢复?

朋友们大家好,我是热爱分享电脑知识的资源伙伴~接下来,别忘了点赞、收藏并关注资源伙伴!如果你在使用PowerPoint时忘记保存演示文稿,突然关闭程序或电脑出现故障,不用太担心。 PowerPoint和大多数现代Office应用程序都…

将本地项目托管到Github或码云中

最按照打开页面的步骤,一步步生成公钥就: 按照提示完成三次回车,即可生成 ssh key 到C:\Users\登录用户名.ssh下找到文件d_rsa.pub ,打开就可以获取到public key 将id_rsa.pub文件中的内容全部复制到设置/SSH页面中: 单…

PWN练习---Stack_1

pwn123 题源:ctfshow–pwn123 知识点:逻辑漏洞引发的数组越界,导致任意地址写,覆盖返回地址。 主要源码 查看ida存在后面函数,可以劫持ctfshow函数的返回值到backdoor获得shell。 查看case 1代码发现并未对数组赋值的…