在 Elasticsearch 中扩展 ML 推理管道:如何避免问题并解决瓶颈

作者:来自 Elastic Iulia Feroli


是时候考虑语义搜索运营了吗?

无论你是一位经验丰富的搜索工程师,希望探索新的人工智能功能,还是一位机器学习专家,希望更多地利用搜索基础设施来增强语义相似性模型 —— 充分利用这些领域的交集可能需要熟悉一些新概念。

虽然 Elasticsearch 提供了一些快速启动指南,比如 ELSER 示例 notebook (或者对于本地的 Elasticsearch, 你可以参考 “Elasticsearch:使用 ELSER 文本扩展进行语义搜索”),但当你希望扩展推理过程时,会引入更多的配置选项。

在本博客中,我们将看看在处理更复杂的工作负载时,可能遇到的潜在瓶颈以及缓解成长烦恼的方法。

在部署大型语言模型到你的环境时,以下是一些需要注意的步骤。

在下载模型之前

机器学习节点大小 在 Elasticsearch 中使用 NLP 模型构建项目的第一步是设置部署模型的正确基础设施。

正确的机器学习节点配置可能是第一个潜在的瓶颈,因此请确保你为预期的结果选择了合适的大小。

推荐的最小大小:

如果关闭了部署自动扩缩,则部署和使用 ELSER 模型的专用机器学习节点的最小大小为 4 GB;对于自然语言处理模型,则为 16 GB。

建议打开自动扩缩,因为它允许你的部署根据需求动态调整资源。

参见文档。

你可能遇到的故障排除场景:

潜在的瓶颈Error 信息解决方案
ML Node is not big enoughApiError(429, 'status_exception', 'Could not start deployment because no ML nodes with sufficient capacity were found')确保为 ML 节点选择合适的大小,并最好启用自动扩展,以便你的部署在遇到额外请求时可以扩展。
Autoscaling limit is not high enoughAutoscaling limits reached. To continue experiencing optimal performance, we recommend increasing your maximum size per zone for the topologies: Machine Learning.还有一些情况,ML 节点足够大,可以下载模型,但如果配置不正确,大吞吐量的推理调用仍然会使系统过载。 增加大小,确保你的分配使用所有可用的 CPU,或使用较小的数据批次来缓解。

模型配置

更大的节点大小也允许在选择模型的分配和线程数量时具有更大的灵活性。

每个线程需要一个 CPU 或 vCPU,所以例如 8 个 CPU 可以让你拥有 1 个分配,每个分配最多 8 个线程,或者最多 8 个分配,每个分配 1 个线程,或者其他排列组合,只要满足以下条件:

umber_of_allocations * threads_per_allocation <= number of available CPUs.

在同一 ML 节点上部署多个模型将共享这些资源,因此你可以通过配置每个模型的最大访问来根据需要分配你的 CPU。

此外,每个模型部署的分配都有一个用于推理请求的有限队列。当对同一部署进行了太多调用并且队列填满时,所有后续请求都将被拒绝。考虑使用专用部署以防止此情况发生。

对于每个部署和用例,你应考虑以下参数:

参数功能
number_of_allocations通过允许并行执行更多推理请求来提高吞吐量。 这反过来又会提高摄取性能。默认为 1; 但你应该更改此设置,以便使用所有可用的 CPU。
threads_per_allocation提高每个推理请求的速度,从而提高搜索速度。默认为 1; 但你应该更改此设置,以便使用所有可用的 CPU。
queue_capacity控制队列中一次允许有多少个推理请求。 当请求数量超过总数时,新请求将被拒绝并返回 429 错误。默认为 1024。最大允许值为 1000000。

此设置的值不得超过每个节点可分配的处理器数量。

请参考有关 ELSER 性能随分配数量增加而提高的基准测试信息作为示例。

在部署模型时

一旦模型已经下载到你的集群中,你可以开始部署它,同时考虑前面讨论的参数。在这个阶段,如果你计划部署同一模型的多个实例,可以考虑使用唯一的 deployment_id。

client.ml.start_trained_model_deployment(
    model_id=".elser_model_2", 
    deployment_id="elser_inference_1",
    number_of_allocations=1, 
    threads_per_allocation=8,
    queue_capacity=7000, 
    timeout="1m", 
    wait_for="starting"
)

在此阶段你可能会遇到一些潜在的瓶颈或错误:

瓶颈解释 / Error 信息解决方案
部署期间超时在不指定 wait_for 参数的情况下,它默认为 started,这意味着只有当模型下载完成并成功部署时,你才会收到响应。然而,这个过程会相当耗时,具体取决于模型大小,而且由于 timeout 参数也默认为仅 30 秒,这通常会导致错误。请改用 wait_for="starting",和/或 增加引发错误之前的等待时间:timeout="3m"
不按顺序运行这些步骤(具体示例请参阅下面的行)在上一步完成运行之前运行命令将导致错误:使用 status = client.ml.get_trained_models(model_id=".elser_model_2", include="definition_status") 检查模型的状态
尝试在模型完全下载之前部署模型Model definition truncated. Unable to deserialize trained model definition [.elser_model_2]你应该仅在 status["trained_model_configs"][0]["complete_define"] == True 时尝试部署模型
尝试对尚未完全部署的模型运行推理404, 'resource_not_found_exception', 'Could not find trained model [.elser_model_2]'

在运行推理之前

一旦模型部署完成,你就可以开始对其进行推理调用。这可以通过 inference API 来完成:

response = client.ml.infer_trained_model(
    model_id=model_id, 
    docs=[{"text_field": query}])

这个推理命令也有一个默认的超时时间为 10 秒,当一次生成少量文档的嵌入时是足够的。

然而,对于大多数实际用例,将会有大量需要处理的文档;例如,在一个大型索引中为每个文档创建嵌入以启用语义搜索功能。

你可以增加超时时间:

response = client.ml.infer_trained_model(model_id=model_id, docs=docs, timeout="5m")

然而,正如前面的部分所提到的,根据分配的数量或发送到同一部署的不同任务的数量,模型也将有一个最大文档队列接受限制。因此,即使设置了较长的超时时间,对于大吞吐量来说,这种方法可能仍然不足够。

另一个选择是为推理过程创建摄入管道。你还可以为不同的管道使用不同的部署:一个用于在摄入新数据时生成嵌入,另一个用于在搜索时运行推理。 管道还允许你通过在 processors 列表中添加元素来设置自定义操作,例如重命名字段或为不同任务使用多个模型。你还可以在后台或按照定期时间表运行较长的任务。

client.ingest.put_pipeline(
    id="elser-2-ingest-pipeline-1",
    description="Ingest pipeline for ELSER with a lot more requests",
    processors=[
        # omitting processors code
    ])

client.reindex(
    source={"index": "raw_data"},
    dest={"index": "data_with_embeddings", "pipeline": "elser-2-ingest-pipeline-1"},
    wait_for_completion=False,
)
瓶颈解决方案
Timeout与前面的步骤类似,冗长的管道过程可能会导致超时。 使用 wait_for_completion = False 参数。
Waiting for pipeline to finish你可以使用从 reindex 函数获得的任务 ID 稍后通过 client.tasks.get(task_id=task_id) 跟踪管道进度。 使用 wait_for_completion 参数时会生成此 ID。

监控和调整

一旦你部署了模型并开始使用推理服务,你可以查看配置的性能。通常,这是确定特定用例的适当参数的最佳方法,并根据需要进行调整,直到达到所需的性能。

举一个简单的例子,如果你部署了一个模型而没有配置上述讨论的任何设置,这些将是分配的默认值:

{
  "threads_per_allocation" : 1, 
  "number_of_allocations" : 1, 
  "queue_capacity" : 1024
}

假设通过推理管道将大量文档发送到该模型后,我们注意到线程分配中的一些警告信号。 endpoint:

GET _nodes/hot_threads

响应:

ml.allocated_processors=16

100.0% [cpu=3.5%, other=96.5%] cpu usage by thread

ML 节点分配有 16 个处理器,但我们仅在模型的一个实例中利用其中 1 个处理器。 此外,在其他而不是与 CPU 相关的任务下报告的高利用率意味着该过程中存在大量等待和冗余,并且我们的文档大部分时间都在排队。

为了优化性能,你应该使用所有可用的内核。

你还可以在训练模型 UI 中或通过以下命令查看更多指标:

GET _ml/trained_models/_stats

在这里你可以看到更多有用的信息,例如 average_inference_time_ms、number_of_pending_requests 或 peak_throughput_per_分钟。

作为说明,这里有两个模型部署在同一个 ML 节点上,在相同的管道和数据上运行推理,但采用不同的分配策略。 你可以看到配置模型的推理时间几乎减半。

Model IDAllocationAverage Inference time
elser_inference_configured3 * 867.80 milliseconds
.elser_model_21 * 1115.58 milliseconds

结论

这既是一件好事,也可能是一件困难的事情,有多种灵活和模块化的方法来构建适合你的项目的推理架构。 为每个用例构建最佳方法也不仅仅是选择正确的配置或基础设施设置。 你可以详细了解模型的检索优化甚至数据处理决策(例如分块策略)如何影响性能。

Elasticsearch 汇集了令人惊叹的开箱即用功能,并提供自定义选项和指导,帮助你构建最佳的语义搜索解决方案。

准备好将 RAG 构建到你的应用程序中了吗? 想要尝试使用向量数据库的不同 LLMs?
在 Github 上查看我们的 LangChain、Cohere 等示例 notebooks,并参加即将开始的 Elasticsearch 工程师培训!

原文: Scaling ML Inference Pipelines in Elasticsearch: How to avoid issues and troubleshoot bottlenecks — Elastic Search Labs

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python统计分析——用sklearn进行回归

参考资料&#xff1a;python统计分析【托马斯】 scikit-learn提供了简单而有效的数据挖掘和数据分析工具&#xff0c;包括监督和无监督学习。它提供了如下工具&#xff1a; 分类&#xff1a;辨别出新的观测值应该属于哪一组类别。 回归&#xff1a;对一个新的例子预测一个连续值…

Rust腐蚀服务器常用参数设定详解

Rust腐蚀服务器常用参数设定详解 大家好我是艾西&#xff0c;一个做服务器租用的网络架构师上期我们分享了rust腐蚀服务器的windows系统搭建方式&#xff0c;其中启动服务器bat参数因为涉及的东西比较多所以想通过这篇文章给大家做一下详细的分享。 &#xff08;注本文中xxxx…

基于 FPGA 的 DE1-SoC 功率估算器

Introduction 功耗是当今许多技术都要考虑的重要因素。例如&#xff0c;手机生产商总是谈论他们在电源管理方面的改进&#xff0c;以及如何延长电池的使用寿命。功能与功耗之间的平衡是许多人都在研究的有趣课题。然而&#xff0c;当我们做实验时&#xff0c;我们很少会考虑我…

【Godot4.2】CanvasItem绘图函数全解析 - 8.绘制点索引

概述 在示意图绘制过程中或者测试过程中&#xff0c;可能需要标记点的索引。 最常见的形式就是用一个圆圈作为背景&#xff0c;用阿拉伯数字作为索引。 实现的重点是动态计算背景圆的半径。原理是&#xff0c;获取字符串的矩形&#xff0c;取对角线长度的一半作为外接圆的半…

【JavaScript | RegExp】正则表达式

本文原创于CSDN秋说&#xff0c;未经授权&#xff0c;不得转载。 文章目录 定义特殊字符元字符字符表格汇总特殊结构标记优先级实例匹配常见的 HTTP 或 HTTPS URL匹配路径匹配URL的各个部分全局搜索邮箱正则表达式日期匹配正则表达式特殊字段匹配正则表达式匹配邮箱正则表达式用…

在Windows中用命令行编译C项目

在Windows中可以用命令行编译C项目 官方指导文档&#xff1a; 演练&#xff1a;在命令行上编译 C 程序 | Microsoft Learn 在官方文档中可以看到&#xff0c;可以只安装VS的命令行工具集&#xff0c;如下图所示

MySQL8.0.36-社区版:错误日志(2)

mysql有个错误日志&#xff0c;是专门记录错误信息的&#xff0c;这个功能默认是开启的 一般都是在/var/log/mysqld.log 日志中存放 1.错误日志的位置 首先我们使用命令去查看一下&#xff0c;这个错误日志文件究竟在哪 进入到mysql中&#xff0c;使用命令 show variables…

009、Python+fastapi,第一个后台管理项目走向第9步:ubutun 20.04下安装vscode+git环境配置

一、说明 git是一定要配置的&#xff0c;由于是白嫖的无影云电脑&#xff0c;东西得保存在网上&#xff0c;就继续白嫖gitee吧&#xff0c;显然国内github是不太合适的了 二、安装git 直接安装sudo apt install -y git git --version git version 2.25.1 三、配置git 在git上…

使用阿里云试用Elasticsearch学习:使用内置模型 lang_ident_model_1 创建管道并使用

文档&#xff1a;https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-deploy-model.html 部署刚刚下载好的内置模型 部署内存不够用 还得花钱&#xff0c;拉几把倒吧。就用自带的吧。 测试模型 POST _ml/trained_models/lang_ident_model_1/_infer {"doc…

MySQL-触发器:触发器概述、触发器的创建、查看删除触发器、 触发器的优缺点

触发器 触发器1. 触发器概述2. 触发器的创建2.1 创建触发器语法2.2 代码举例 3. 查看、删除触发器3.1 查看触发器3.2 删除触发器 4. 触发器的优缺点4.1 优点4.2 缺点4.3 注意点 注&#xff1a;此为笔者学习尚硅谷-宋红康MySQL的笔记&#xff0c;其中包含个人的笔记和理解&#…

HarmonyOS实战开发-横竖屏切换

介绍 本实例展示如何使用媒体查询&#xff0c;通过ohos.mediaquery 接口完成在不同设备上显示不同的界面效果。 效果预览 使用说明 1.在竖屏设备上&#xff0c;首页展示新闻列表&#xff0c;点击新闻进入详情界面。 2.在横屏设备上&#xff0c;首页左侧展示新闻列表&#x…

RT-Thread内核简介

1、RT-Thread 内核介绍 RT-Thread 内核架构图,内核处于硬件层之上,内 核部分包括内核库、实时内核实现 内核库是为了保证内核能够独立运行的一套小型的类似 C 库的函数实现子集。这部分根据编译器的不 同自带 C 库的情况也会有些不同,当使用 GNU GCC 编译器时,会携带…

STM32外设配置以及一些小bug总结

USART RX的DMA配置 这里以UART串口1为例&#xff0c;首先点ADD添加RX和TX配置DMA&#xff0c;然后模式一般会选择是normal&#xff0c;这个模式是当DMA的计数器减到0的时候就不做任何动作了&#xff0c;还有一种循环模式&#xff0c;是计数器减到0之后&#xff0c;计数器自动重…

【GD32】MQ-3酒精检测传感器

2.31 MQ-3酒精检测传感器 MQ-3气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(Sn0)。当传感器所处环境中存在酒精蒸气时&#xff0c;传感器的电导率随空气中酒精蒸气浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。…

嵌入式STM32F407CET6移植OpenHarmony系统方法

第一:【实验目的】 1、STM32F407CET6开发版移植鸿蒙系统的方式 第二:【实验原理】 涉及到原理图添加原理图--普通STM32F407原理图第三:【实验步骤】 一、下载LiteOs源码,复制到到虚拟机中并解压 https://gitee.com/LiteOS/LiteOS

政安晨:【Keras机器学习实践要点】(二十九)—— 半监督图像分类使用具有SimCLR对比性预训练的方法

目录 介绍 半监督学习 对比学习 设置 超参数设置 数据集 图像增强 编码器结构 有监督基线模型 用于对比预训练的自我监督模型 对预训练编码器进行有监督微调 与基准线的比较 进一步改进 架构 超参数 相关工作 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x…

Guava里一些比较常用的工具

随着java版本的更新提供了越来越多的语法和工具来简化日常开发&#xff0c;但是我们一般用的比较早的版本所以体验不到。这时就用到了guava这个包。guava提供了很多方便的工具方法&#xff0c;solar框架就依赖了guava的16.0.1版本&#xff0c;这里稍微介绍下。 一、集合工具类…

20240413,类和对象

对象&#xff1a;一切都可为对象&#xff0c;类&#xff1a;相同特性的对象&#xff1b;面向对象特性&#xff1a;封装&#xff0c;继承&#xff0c;多态 一&#xff0c;封装 CLASS 类名 { 访问权限 &#xff1a;属性/行为 } 实例化&#xff1a;通过一个类&#xff0c;创建一…

0101tomcat部署war访问mysql失败-容器间通信-docker项目部署

文章目录 一、简介二、部署1、mysql数据迁移2、docker部署redis3、docker部署tomcat并运行war包 三、报错四、解决1 分析2 解决 结语 一、简介 最近参与开发一个项目&#xff0c;其中一部分系统需要迁移。从阿里云迁移到实体服务器&#xff0c;使用docker部署。系统使用Java语…

11 Php学习:函数

PHP 内建函数Array 函数 PHP Array 函数是 PHP 核心的组成部分。无需安装即可使用这些函数。 创建 PHP 函数 当您需要在 PHP 中封装一段可重复使用的代码块时&#xff0c;可以使用函数。下面详细解释如何创建 PHP 函数并举例说明。 创建 PHP 函数的语法 PHP 函数的基…