返回 文章 apply CMS 文章

LLM推理端点自动扩缩容:指标选择、窗口调优与冷启动预算

学习如何为LLM推理端点选择自动扩缩容指标、调整扩缩窗口,并预算冷启动时间,以避免过度配置或配置不足。

LLM推理自动扩缩容Together AIGPU利用率
成长分 / 100 77 综合收获、行动、留存与影响

LLM推理端点自动扩缩容:指标选择、窗口调优与冷启动预算
为什么值得读LLM服务扩缩容与传统Web服务不同,GPU利用率等指标可能掩盖真实负载,导致延迟恶化。

文章通过实验对比三种扩缩策略,直观展示不同指标的效果,帮助读者避免常见陷阱。

关键洞察
  1. GPU利用率可能健康但队列积压,因为利用率衡量算术强度而非压力,应优先使用并发驱动指标如inflight_requests。
  2. 冷启动可能需要数分钟,因此扩缩容必须基于领先信号提前行动,而非响应突发流量。
  3. 扩缩窗口不对称:扩容窗口应短(激进),缩容窗口应长(耐心),以避免振荡和重复冷启动。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:12619

摘要

在 Together AI 平台上使用专用模型推理,您可以根据推理引擎实际理解的指标(如进行中的请求、TTFT、GPU 利用率、令牌吞吐量)自动扩展部署。您可以设置副本边界,选择指标和目标,然后调整两个窗口,分别控制扩展的积极程度和缩减的耐心程度。理解并选择正确的指标非常重要,因为它决定了您的部署在峰值流量下的行为,并影响用户看到的延迟。下面我们将介绍如何选择正确的自动扩展指标,并展示一个实验,其中相同的负载在三种不同的自动扩展策略下重放。

过度配置和配置不足都很昂贵

使用专用推理,您按副本分钟付费,这使得容量规划成为两种故障模式之间的平衡:

过度配置——您为 GPU 支付费用,使其利用率仅为 15%,只是为了在峰值流量到来时能够处理。这几乎不可行,尤其是在当前 GPU 受限的环境中。配置不足——一旦流量超过副本能够批处理的能力,您的 p95 会急剧恶化。LLM 服务的退化是非线性的:达到并发限制的副本不会“变慢一点”,而是开始排队,TTFT 可能从 200 毫秒飙升至 15 秒。

“直接自动扩展”是显而易见的答案,对于无状态 Web 服务,这大多有效。但 LLM 服务是另一回事,它打破了经典自动扩展所依赖的两个假设:

CPU 风格的指标掩盖了负载。GPU 可能显示 60% 的利用率,而引擎的请求队列已经积压,利用率衡量的是算术强度,而不是压力。基于错误的信号扩展部署意味着系统将对一个不能描述实际问题的数字做出响应。冷启动可能需要几分钟。新副本必须放置在 GPU 节点上,拉取数十 GB 的权重,将其加载到 VRAM 中,并进行预热。这意味着您无法通过扩展来应对突发流量,因为当流量到达时,扩展已经太晚了。因此,一个好的自动扩展器的工作是提前基于领先信号采取行动。

由于这些细微差别以及每个客户的不同需求,我们的平台为您提供了一系列推理原生指标,并允许您选择部署的扩展方式。本文帮助您做出明智的选择!

工作原理

每个部署都带有自动扩展策略:副本边界、一个或多个带有目标的扩展指标,以及时间窗口。

控制循环如下:观察指标 → 期望副本数(ceil(N × 观察值/目标))→ 时间窗口抑制 → 限制在边界内 → GPU 放置。观察到的负载反馈,循环持续评估,流量分配自动跟随容量。

核心循环是成比例的,这意味着如果您将每个副本的目标设置为 8 个进行中的请求,而观察到 16 个,系统将需要两倍的副本(假设 2 倍副本在最小和最大边界内)。时间窗口可用于添加去抖动效果,使副本数量不会振荡:

: 在添加副本之前压力必须持续多久。保持较短;误扩容的成本只是几个副本分钟,而漏扩容的成本则是用户可见延迟增加。scale_up_window

(默认scale_down_window

5m):在移除副本之前,事情必须保持平静多久。保持比流量的自然节奏更长;误缩容的成本可能是在下一个高峰到来时发生冷启动。

这种不对称的权衡——激进的扩容和耐心的缩容自动缩放窗口——非常重要,需要根据你的特定流量分布进行直观理解。扩容窗口的错误花费金钱,而缩容窗口的错误则花费延迟金钱(因为你会想要立即扩容回去,在回去的路上支付冷启动成本)。

设置它只需一个 PATCH:

需要记住的几个设置:

min_replicas == max_replicas

:这导致固定大小的部署,自动缩放实际上关闭。- 将两者设置为

min_replicas = max_replicas = 0

→ 部署停止(状态STOPPED

,计费停止)。这可以用作暂停开发端点的方式。 - 给出一个范围则开启缩放;如果你设置了边界但没有指标,平台应用默认值:

.inflight_requests

目标为 8

底层原理:用于自动缩放的指标

有八个指标可用于自动缩放。选择正确的指标取决于你试图保护部署免受什么影响。

自动缩放指标包括并发驱动(领先;安全默认)、SLO驱动(滞后;基于承诺缩放)、效率驱动(成本优先)。如果你附加多个指标,则使用列表中的第一个。

有三种思考选择正确指标的方式:

并发驱动(在途请求计数是inflight_requests

)是安全默认。领先指标:当需求超过服务时上升,但在延迟明显恶化之前。此指标不需要流式或百分位数选择,它直接映射到引擎如何批处理请求。此指标的目标为 8 表示“我希望每个副本处理大约八个并发请求”。你可以为批处理良好的短提示聊天工作负载提高它,并为需要更长预填充时间的编码代理长上下文流量降低它。SLO驱动指标(如果你与用户的合同是“一秒内首令牌”,则基于ttft

e2e_latency

缩放):ttft

p95 正好针对这一点。延迟是滞后信号,这意味着当 p95 超过设定阈值时,用户已经能注意到,所以你应该通常将延迟指标与min_replicas

中的诚实余量配对。- 另一点要记住的是,每令牌指标需要流式流量。

ttft

decoding_speed

throughput_per_replica

仅在流式路径上发出。如果你的客户端不流式,这些指标没有数据,你不应该基于它们构建自动缩放策略。(e2e_latency

是一个例外,因为它针对流式和非流式工作负载进行测量)。效率驱动型(这些指标优化成本:保持副本忙碌,仅在集群真正饱和时增加容量。使用这些指标时,你需要理解“已利用”对你的工作负载真正意味着什么。GPU 可能很忙,但工作负载的延迟并不健康,接近 100% 的利用率目标没有为突发流量留出余量。如果你根据利用率进行扩展,应密切关注 p95 Grafana 图表。gpu_utilization

,token_utilization

):最大限度地利用硬件。

在选择扩展指标时,这张表值得牢记:

空闲关闭和冷启动

没有自动唤醒的缩容到零。 min_replicas: 0

仅与 max_replicas: 0

一起使用才是合法的,这是一种显式停止部署的方式。唤醒需要显式操作,对已停止部署的请求会返回错误,而不是触发启动。这意味着你应该围绕自动停止和显式重启窗口来规划开发环境和预发布环境端点。

使用此自动停止功能时,冷启动预算很重要。你可以将冷启动视为包含以下阶段:GPU 放置 → 权重下载 → 引擎加载 → 预热,部署的事件源会为每个阶段打上时间戳(pod.startup_phase_changed):

较大的模型可能具有成比例的更长的权重下载、引擎加载和预热时间。为了更好地了解这些数字,我们在热集群上的 1×H100 副本上展示了多次运行的结果:

请注意,这些时间窗口以分钟为单位,这意味着自动停止仅在两次使用之间的间隔相对于重启时间较长,并且空闲期后的第一个用户愿意容忍显式启动(或错误后重试流程)时才值得。这种权衡对于开发环境和预发布环境端点是可以接受的,但对于任何具有 p95 SLO 或无人值守调用者的场景,通常应保持 min_replicas: 1

边缘情况

流量尖峰比冷启动更快。实际会发生什么?

请求会在现有副本上排队(inflight_requests

和引擎队列深度会增加),延迟会恶化,TTFT 首先增加,随后在新副本启动期间出现错误/超时风险。这意味着如果你的流量在 90 秒内激增 10 倍,而冷启动需要 4 分钟,唯一的防御措施是 min_replicas

余量或更高目标的策略,以保持备用容量。这更多是容量规划问题,而不是调优问题,最好在发布日之前解决。

我的自动扩缩器会与滚动更新冲突吗?

不会。在滚动更新进行期间,平台会固定两个部署的自动扩缩边界;否则,滚动更新的副本数可能会在步骤中途被缩容决策撤销。滚动更新完成或中止时,你配置的边界会自动恢复。

扩展如何与流量拆分交互?

这处理得很顺畅,因为流量拆分权重是按就绪副本计算的(容量 = 权重 × 就绪副本数),自动扩展的部署会自动吸收成比例的更多流量,无需更改路由。自动扩展和路由基于相同的容量视图。

为什么我的副本数看起来像锯齿波?

这是缩容窗口短于流量自然节奏的典型症状。突发流量 + 1 分钟缩容窗口 = 在每个低谷缩容,在每个高峰冷启动。要解决这个问题,你应该加宽 scale_down_window

直到锯齿波变平。这允许你牺牲几个副本分钟来消除重复的冷启动。

使用不同策略对相同负载进行自动扩缩容

我们在一个 Qwen3.5-9B 部署(每个副本 1×H100,边界 1–3)上运行了这个实验,每轮之前重置为恰好 1 个副本,然后重放相同的脚本化负载三次:一个在约 12 到约 48 RPS 之间的正弦波,带有两个 80 rps 的尖峰。这在三种不同的自动扩缩容策略下重复进行:

inflight_requests

目标 8ttft

p95 目标 300 毫秒gpu_utilization

目标 75%

从上述运行中得出三个教训:

只有并发信号触发了。在此负载下,客户端 p95 运行在 3–5,明显饱和,但 ttft

策略从未扩展,因为引擎端的首令牌时间保持较低:引擎的连续批处理将队列压力吸收到延迟中,而不是首令牌延迟。而 gpu_utilization

从未扩展,因为短促的突发请求使 GPU 低于其 75% 的阈值。两种策略都在读取看起来健康的信号,而系统已经饱和。inflight_requests

,直接的队列压力信号,是唯一看到问题的信号,这就是为什么它是默认策略。容量恰好如承诺的那样有帮助。在 inflight 策略保持 2 个副本的时间段(约 6–11 分钟),其 p95 在相同负载下明显低于单副本策略,中间面板显示了差距。在选择策略之前,了解你的副本的饱和点。一个副本在 3–5 秒 p95 下服务 12–48 rps 而没有崩溃,但如果你有 500 毫秒的 SLO,这将不可行。

自己试试!

从默认值开始,然后根据证据进行调整:

  • 设置真实的边界( min

= 你的基础负载所需,max

= 你的预算能承受的),并采用默认的inflight_requests

目标 8。 - 在

metrics API中观察一周的流量:副本数、队列压力、p95。 - 然后才进行调整:延迟 SLO → 添加

ttft

策略(如果你流式传输);成本压力 → 尝试使用利用率并诚实监控 p95;锯齿波 → 加宽缩容窗口。

📚 文档: 专用模型推理自动扩缩容