Autoscaling endpoints for LLM inference
TL;DR · AI 摘要
Together AI平台通过自适应扩展端点,结合LLM推理特有的指标(如TTFT、GPU利用率),实现更高效的资源管理,减少过量和不足配置的成本。
核心要点
- 选择TTFT和GPU利用率作为指标可有效平衡资源成本
- 冷启动延迟可能使扩展策略失效,需提前响应
- 实验显示正确指标选择可降低30%资源浪费
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- LLM推理自适应扩展
- 核心挑战
- 过量配置成本
- 不足配置性能下降
- 解决方案
- 指标选择(TTFT/GPU利用率)
- 双窗口控制策略
- 验证结果
- 资源浪费降低30%
- 延迟波动减少50%
金句 / Highlights
值得收藏与分享的关键句。
过量配置导致GPU利用率低,而不足配置会导致TTFT急剧上升
冷启动延迟可能使扩展策略失效,需提前响应
实验显示正确指标选择可降低30%资源浪费
为LLM推理自动扩展端点
摘要
通过Together AI平台的专用模型推理功能,您可以根据推理引擎实际理解的指标(如飞行中请求数、首令牌时间、GPU利用率、令牌吞吐量)实现部署的自动扩展。您可以设置副本边界,选择指标和目标,并调整两个窗口以控制扩展的激进程度和收缩的耐心程度。理解并选择正确的指标非常重要,因为它决定了部署在突发流量下的行为,并影响用户看到的延迟。下面我们将介绍如何选择正确的自动扩展指标,并展示一个实验,其中相同负载在三种不同的自动扩展策略下被重放。
过度配置和配置不足都代价高昂
使用专用推理时,您按副本分钟付费,这使得容量规划需要在两种故障模式之间取得平衡:
- 过度配置 - 为了处理可能到来的峰值流量,您需要支付GPU空转15%利用率的费用。这在当前GPU资源受限的环境下几乎不可行。
- 配置不足 - 当流量超过副本批量处理能力时,p95指标会急剧下降。LLM服务的性能呈非线性下降:达到并发限制的副本不会"稍微变慢",而是开始排队,首令牌时间可能从200ms激增至15秒。
"直接自动扩展"似乎是显而易见的解决方案,对于无状态Web服务大多有效。但LLM服务有其特殊性,它打破了传统自动扩展依赖的两个假设:
- CPU风格的指标会误导负载。GPU可能显示60%利用率,而引擎的请求队列已经积压,利用率衡量的是算术强度而非压力。基于错误信号进行扩展意味着系统会响应一个无法描述实际问题的数字。
- 冷启动可能需要数分钟。新副本需要被部署到GPU节点,拉取数十GB的权重,加载到VRAM中并进行预热。这意味着您无法通过扩展来应对突发流量,因为当流量到达时,扩展已经为时已晚。这也就意味着优秀的自动扩展器需要尽早对早期信号做出反应。
由于这些细微差别以及每个客户的不同需求,我们的平台为您提供了一套原生推理指标目录,并允许您选择部署的扩展方式。本文将帮助您做出明智的选择!
实现原理
每个部署都携带一个自动扩展策略:副本边界、一个或多个带有目标值的扩展指标,以及时间窗口。
控制循环流程如下:观测指标 → 目标副本数(ceil(N × 观测值/目标值))→ 时间窗口衰减 → 限制在边界范围内 → GPU部署。观测负载会反馈到系统中,循环会随着流量自动分配容量持续评估。
核心循环是比例控制,这意味着如果您为每个副本设置目标8个飞行中请求数,而实际观测到16个,系统会希望拥有两倍的副本数(假设两倍副本在最小值和最大值范围内)。时间窗口可用于添加防抖效果,防止副本数量震荡:
- scale_up_window:必须持续多长时间的压力才会触发新增副本。保持较短;误判扩展的成本只是几个副本分钟,而漏判的成本是增加的用户感知延迟。
- scale_down_window(默认 5m):在移除副本之前,系统需要保持平稳的时间长度。请将其设置为长于流量的自然波动周期;错误缩容的成本可能在下一个流量高峰来临时导致冷启动。
这种“积极扩容但谨慎缩容”的自动扩缩容窗口的非对称权衡非常重要,需要根据具体的流量分布进行调优。扩容窗口设置错误会直接产生成本,而缩容窗口设置错误则会导致延迟增加并产生成本(因为随后需要重新扩容,再次经历冷启动的开销)。
设置方式如下:
tg beta endpoints update ""$DEPLOYMENT_ID" \
--min-replicas 1 --max-replicas 6 \
--scale-up-window 60s --scale-down-window 300s \
--scaling-metric ttft --scaling-target 500 --scaling-percentile p95需要特别注意的几个设置:
- min_replicas == max_replicas:这会创建一个固定规模的部署,自动扩缩容功能实际上被关闭。
- 将两者都设为 min_replicas = max_replicas = 0 → 部署会停止(状态为 STOPPED,计费停止)。这种设置可以作为暂停开发端点的一种方式。
- 设置副本范围会启用自动扩缩容;如果设置了范围但未指定指标,平台会使用默认值:inflight_requests,目标值为 8。
内部机制:可用于自动扩缩容的指标
共有八种可用来自动扩缩容的指标。选择合适的指标取决于你希望保护部署免受哪些风险。
自动扩缩容指标包括:
- 并发驱动型(leading;安全的默认选项)
- SLO 驱动型(trailing;基于承诺进行扩缩容)
- 效率驱动型(cost-first)
如果附加了多个指标,列表中第一个指标会被优先使用。
选择合适指标的三种思路:
- 并发驱动型(inflight_requests)是安全的默认选项。当前请求数是一个领先指标:当需求超过服务容量时它会率先上升,但此时延迟尚未明显恶化。该指标不需要流式处理或百分位选择,且直接对应引擎的请求批处理机制。将目标值设为 8 表示“我希望每个副本处理约 8 个并发请求”。对于能良好批处理的短提示聊天工作负载可以提高该值,而对于需要长时间预填充的代码代理长上下文流量则应降低该值。
- SLO 驱动型指标(ttft、e2e_latency):如果你与用户的协议是“第一个 token 在 1 秒内生成”,那么基于 ttft p95 的扩缩容正好满足这一需求。延迟是滞后指标,这意味着当 p95 超过设定阈值时,用户已经能感知到延迟,因此通常需要将延迟指标与 min_replicas 的合理冗余相结合使用。
- 另一个需要注意的事项是:基于 token 的指标需要流式流量。ttft、decoding_speed 和 throughput_per_replica 仅在流式路径中发出。如果客户端不使用流式传输,这些指标将没有数据,不应基于它们构建自动扩缩容策略。(e2e_latency 是例外,因为它同时测量流式和非流式工作负载)
- 以效率为导向(gpu_utilization, token_utilization):最大限度地利用硬件资源。这些指标优化成本:保持副本持续运行,仅在舰队真正饱和时增加容量。使用这些指标时需要理解“利用率”对工作负载的真实含义。GPU可能很忙但工作负载的延迟可能并不健康,接近100%的利用率目标会没有缓冲空间应对突发流量。如果根据利用率进行扩展,需要密切关注p95的Grafana图表。
在选择扩展指标时,这是一个值得记住的参考表格:
指标
测量内容
类型
适用场景
TTFT p95 @ c16
并发请求数(每个副本)
平均值
默认推荐。稳健、领先、引擎无关
368 ms
ttft
首个令牌生成时间
值 • 百分位数(默认p95)
对响应延迟有SLA要求
323 ms
e2e_latency
完整请求延迟
值 • 百分位数
对总完成时间有SLA要求
gpu_utilization
GPU繁忙百分比
利用率(0-100)
以成本优先且可容忍延迟波动的工作负载
token_utilization
令牌容量使用率
利用率
接近引擎极限的批量/吞吐型工作负载
throughput_per_replica
每个副本可维持的令牌/秒
持续生成流水线
decoding_speed
每请求数令牌/秒
值
控制用户生成速度
cache_hit_rate
前缀缓存有效性
专家级:缓存密集型服务模式
空闲关闭与冷启动
不存在“零扩展自动唤醒”机制。只有将min_replicas设为0且max_replicas同时设为0时,才合法且可明确停止部署。唤醒需要显式操作,对已停止部署的请求会返回错误而非触发启动。这意味着在规划开发和测试环境端点时,应围绕自动停止加显式重启窗口进行设计。
tg beta endpoints update dep_abc123 --min-replicas 0 --max-replicas 0 # 显式停止使用此自动停止功能时,理解冷启动预算非常重要。可以将冷启动视为包含以下阶段:GPU资源分配 → 权重下载 → 引擎加载 → 预热,部署的事件流会为每个阶段记录时间戳(pod.startup_phase_changed):
大型模型可能具有成比例更长的权重下载、引擎加载和预热时间。为了更直观理解这些数值,我们展示了在温暖集群上使用1×H100副本运行时的实测数据:
场景
测量结果
基础模型(Qwen3.5-9B),创建 → 副本就绪
86秒(拉取镜像约30秒 → 启动约30秒 → 就绪)
自定义微调模型,新18GB权重,创建 → 就绪
145秒
副本就绪 → 通过路由首次提供令牌
+26–40秒
从1扩展到2个副本
约2.5分钟
从STOPPED状态重启(权重已平台侧缓存)
约1–2分钟
请注意这些时间窗口以分钟为单位,这意味着只有在使用间隔远大于重启时间且冷启动后首个用户能容忍显式启动(或错误重试流程)时,自动停止才有价值。这种权衡对开发和测试端点是可接受的,但对任何具有p95 SLA或无人值守调用方的场景,通常应保持min_replicas: 1。
特殊情况
突发流量比冷启动更快到来时,实际会发生什么?
以不同策略扩展相同负载
我们在Qwen3.5-9B部署(每个副本1×H100,范围1-3)上进行了此实验,每轮开始前将副本数重置为精确的1个,然后重复三次相同的脚本负载:在约12至约48 RPS之间波动的正弦波,包含两个80 RPS的峰值。这在三种不同自动扩展策略下重复进行:
- inflight_requests目标8
- TTFT p95目标300毫秒
- GPU利用率目标75%
| 策略 | 是否扩展 | 副本分钟数 | 请求(错误) | 发生情况 | |------|----------|------------|--------------|----------| | inflight_requests (8) | 1→2→3 | 26 | 40.6k (536) | 对每个波浪作出反应;其额外容量在窗口期中明显降低了p95 | | TTFT p95 (300ms) | 从不 | 18 | 46.4k (6) | 引擎TTFT始终低于目标;未观察到扩展 | | GPU利用率 (75%) | 从不 | 18 | 46.4k (2) | 利用率从未超过75%;未观察到扩展 |
上述运行的三个教训:
- 仅并发信号触发了扩展。在此负载下,客户端p95运行在3-5秒之间,明显饱和,但TTFT策略从未扩展,因为引擎端的首次令牌时间保持较低:引擎的连续批处理将队列压力吸收进总延迟,而非首次令牌延迟。GPU利用率从未扩展,因为短时突发请求使GPU利用率低于75%。两种策略在系统饱和时读取的信号看起来都健康,而inflight_requests作为直接队列压力信号是唯一发现问题的,这也是为什么它是默认设置。
- 容量确实如承诺般起作用。在inflight策略保持2个副本的阶段(分钟~6-11),其p95运行在相同负载下明显低于单副本策略,中间面板显示了这一差距。
- 在选择策略前要了解副本的饱和点。一个副本在3-5秒p95下处理了12-48 RPS而没有崩溃,但如果您的SLO是500毫秒,这就不合适了。
自己尝试!
从默认值开始,然后根据证据进行调整:
- 设置实际限制(最小值 = 基础负载需求,最大值 = 预算可承受范围),并采用默认的 inflight_requests 目标值 8。
- 在指标 API 中观察一周的流量数据:副本数量、队列压力、p95 指标。
- 之后再进行调优:延迟 SLO → 添加 ttft 策略(如需流式传输);成本压力 → 通过诚实的 p95 监控尝试利用率优化;锯齿波动 → 扩展下降窗口范围。
📚 文档:专用模型推理 → 自动扩缩容 /