作者:来自 Elastic Daniel Rubinstein
Elasticsearch 开放推理 API 现已支持可配置的分块,以便在文档摄取时处理语义文本字段。
Elasticsearch 推理 API 允许用户利用各种提供商的机器学习模型执行推理操作。其中一个常见用例是在索引中支持用于语义搜索的语义文本字段。随着文档数据量的增加,对整个数据创建嵌入可能会导致结果不够准确。此外,一些推理模型对可处理的输入大小有限制。因此,推理 API 采用了一种称为分块(chunking)的处理方式,将摄取到索引的大型文档拆分为较小且更易管理的子部分,即 "块"(chunks)。然后对每个块单独运行推理操作,并将推理结果存储在索引中。
在本篇博客中,我们将介绍分块策略,解析 Elasticsearch 如何进行文本分块,并讲解如何为推理端点配置分块设置。
更多阅读:Elasticsearch:为推理端点配置分块设置
可配置的分块设置是什么?
从 8.16 版本开始,用户可以从两种分块策略中进行选择,每种策略都具备可配置的属性。
基于单词的分块策略
用户可配置的参数:
- (必需)max_chunk_size:单个块的最大单词数。
- (必需)overlap :相邻块之间的重叠单词数。
注意:此值不能超过max_chunk_size
的一半。
基于单词的分块策略会根据 max_chunk_size
限制,将输入数据拆分成多个块,每个块最多包含指定数量的单词。此策略会尽可能填充一个块达到最大大小后再创建下一个块,除非已处理完整个输入数据。从第二个块开始,每个新块都会包含一部分来自前一个块的单词,其数量由 overlap
参数决定。
这种重叠的目的在于提高推理精度,防止关键上下文因分块而被切断,从而影响推理结果。
基于句子的分块策略
用户可配置的参数:
- (必需)max_chunk_size:单个块的最大单词数。
- (必需)sentence_overlap :相邻块之间的重叠句子数。
注意:此值只能设置为 0 或 1。
基于句子的分块策略会按照完整句子拆分输入数据。每个块仅包含完整的句子,除非某个句子超过 max_chunk_size
,此时它会被拆分到多个块中 。从第二个块开始,每个新块都会包含一部分来自前一个块的句子,其数量由 sentence_overlap
参数决定。
注意:
- 如果在 8.16 之后创建推理端点时未提供分块设置 ,默认使用基于句子的策略,
max_chunk_size
为 250,sentence_overlap
为 1。 - 对于 8.16 之前创建的推理端点 ,默认使用基于单词的策略,
max_chunk_size
为 250,overlap
为 1。
如何选择分块策略?
没有通用的最佳分块策略,最适合的策略取决于要处理的文档、使用的模型以及计算资源的限制 。建议对部分数据集进行测试,尝试不同的分块策略、块大小和重叠参数,并观察它们对数据摄取时间、搜索延迟、查询结果相关性的影响。例如,可以对不同的块重叠和长度进行参数扫描,并测量其对性能的影响。
以下是一些选择分块策略时的基本原则:
选择分块策略
- 基于句子的分块策略 能有效减少上下文信息的丢失,但由于它优先保持句子的完整性,因此可能会生成更多块,增加存储和计算成本。
- 基于单词的分块策略 可以优化块的填充效率,通常生成更少的块,提高数据摄取和搜索的效率。
选择合适的块大小
- 选择块大小时,应尽量减少将有价值的上下文信息拆分到不同的块中,同时保持块内部的主题一致性。
- 通常,接近模型最大支持序列长度的块大小效果更好,但较长的块可能包含多个主题,降低检索的精准度。
选择合适的块重叠
- 较大的重叠值 (最多可达块长度的一半)有助于提高检索质量,因为它减少了上下文信息的丢失。
- 但重叠越大,生成的块数量也会增加 ,导致存储和计算成本上升。因此,选择合适的重叠值需要在检索质量和计算资源之间权衡。
Elasticsearch 如何对文本进行分块?
Elasticsearch 使用 ICU4J 库 来检测单词和句子的边界。
单词边界识别
- 并不仅 依赖空格字符 来划分单词,而是遵循一系列规则来确定单词边界。
- 对于不使用空格 的语言(如中文、日文 ),Elasticsearch 使用词典查找方法来识别单词边界。
句子边界识别
- 并不仅 依赖句号(".")等标点符号来确定句子边界,而是遵循更复杂的句子划分规则。
- 这可以确保不同语言的句子边界都能被准确识别,即使句子结构和断句方式不同。
额外的上下文信息
- 在某些情况下,简单的分块策略 可能无法保留长距离的上下文信息。
- 如果计算资源允许,可以为块添加额外的生成式上下文,以增强理解和检索质量。
- 具体方法和讨论请参考**这个讨论**。
如何为推理端点配置分块设置?
前置要求
在配置分块设置之前,请确保满足以下条件:
- 持有有效的企业许可证(enterprise license)。
- 对于连接到第三方集成的推理端点 ,需设置必要的访问权限(如创建账户、获取 API 密钥等)。
在本指南中,我们将使用 Elastic 的 ELSER 模型 来配置推理端点的分块设置,因此唯一的要求是拥有有效的企业许可证 。如果要为第三方集成 创建推理端点,请参考 create inference endpoint API 文档获取相关信息。
步骤 1:在推理端点创建时配置分块设置
json
`
1. client.inference.put(
2. task_type="sparse_embedding",
3. inference_id="my_elser_endpoint",
4. body={
5. "service": "elasticsearch",
6. "service_settings": {
7. "num_allocations": 1,
8. "num_threads": 1,
9. "model_id": ".elser_model_2"
10. },
11. "chunking_settings": {
12. "strategy": "sentence",
13. "max_chunk_size": 25,
14. "sentence_overlap": 1
15. }
16. }
17. )
`AI写代码
步骤 2:将推理端点链接到索引中的 semantic text 字段
lua
`
1. client.indices.create(
2. index="my_index",
3. mappings={
4. "properties": {
5. "infer_field": {
6. "type": "semantic_text",
7. "inference_id": "my_elser_endpoint"
8. }
9. }
10. }
11. )
`AI写代码
步骤 3:将文档摄取到索引
使用 Index Document API 将文档摄取到索引:
dart
`
1. client.index(index="my_index", document={
2. "infer_field": "This is some sample document data. The data is being used to demonstrate the configurable chunking settings feature. The configured chunking settings will determine how this text is broken down into chunks to help increase inference accuracy."
3. })
`AI写代码
生成的块及其相应的推理结果可以在索引中的文档下的 _inference_fields
元字段的 chunks
键中找到。要查看存储的块,可以使用搜索 API 查找索引中的所有文档:
arduino
`
1. client.search(index="my_index", body = {
2. 'size' : 100,
3. 'query': {
4. 'match_all' : {}
5. },
6. 'fields': [ '_inference_fields' ]
7. })
`AI写代码
在响应中可以看到这些块。在 8.18 之前,块是作为完整的文本值存储的。从 8.18 开始,块作为字符偏移值的列表存储:
arduino
`
1. ...
2. 'chunks': {
3. 'infer_field': [
4. {'start_offset': 0, 'end_offset': 117, 'embeddings':[...]},
5. {'start_offset': 34, 'end_offset': 198, 'embeddings':[...]},
6. {'start_offset': 120, 'end_offset': 242, 'embeddings':[...]}
7. ]
8. }
9. ...
`AI写代码
立即开始使用可配置的分块功能!
有关如何使用此功能的更多信息,请查看配置分块的文档。尝试此笔记本,以开始使用可配置的分块设置:配置推理端点的分块设置。
Elasticsearch 与行业领先的生成 AI 工具和提供商有原生集成。查看我们的网络研讨会,了解如何超越 RAG 基础,或构建生产就绪的应用程序 Elastic 向量数据库。
为了构建最适合你用例的搜索解决方案,现在开始免费云试用,或立即在本地机器上尝试 Elastic。
原文:Configurable chunking settings for inference API endpoints - Elasticsearch Labs