LLM服务公平性
Cohere推出了一种新的推理请求调度解决方案,通过结合速率限制器、性能层级、赤字轮询和优先级选择器,确保多租户LLM平台中不同租户之间的公平性,防止“吵闹邻居”现象,保障每个租户获得公平的计算资源份额。
将大型语言模型作为多租户SaaS平台运行面临一个隐藏的难题:多个组织共享同一组GPU,它们的流量是突发且不均匀的。如果不加管理,一个客户的流量激增可能会变成其他客户的延迟问题。
在这篇博文中,我们将介绍Cohere用于跨租户公平调度推理请求的新解决方案,该方案结合了架构模式和经典调度算法。
问题:吵闹邻居
推理在请求被批量处理时效率最高。满载批次的GPU运行高效且经济,而一次只处理一个请求的GPU大部分时间处于空闲。因此,请求会短暂排队,然后被打包成批次再送到硬件。
问题在于排序。想象一个简单的队列:一个单一的共享队列,仅按优先级和截止日期排序。现在,考虑当一个组织突发发送10,000个请求,而另一个组织只发送5个时会发生什么。使用单一的全局队列,10,000个请求排在前面,而五个表现良好的请求则在后面等待。
这就是经典的“吵闹邻居”问题,多租户LLM平台与其他面临此类流量模式的共享系统没有什么不同。
服务公平性的目标是隔离租户,使租户获得的推理容量份额取决于公平调度,而不是取决于它如何激进地淹没队列。同时,它仍然保留每个租户内部的优先级和截止日期排序,同时保持批处理效率。
解决方案:分层容量管理方法
Cohere通过组合四种不同的机制来公平地管理跨租户的工作负载,每种机制解决问题的不同部分。它们按固定顺序运行:速率限制器控制入口准入,然后三个选择器——性能层级、赤字轮询和优先级——选择下一个出去的请求。
以下是架构和逐步流程:
- 速率限制器
在请求进入调度队列之前,它需要通过准入控制。速率限制限制单个租户在给定时间范围内(如每分钟或每月)可以提交的推理请求的最大数量。
在Cohere,这些限制在端点级别配置,并根据每个模型消耗的资源量而有所不同。例如,重量级生成模型比轻量级嵌入模型具有更严格的限制。
还有一个实时节流检查:如果队列已经积压太多,以至于新请求无法在其延迟目标内得到服务,则请求会提前被拒绝。这可以保护系统免受无法完成的工作的影响,并在负载下保持可预测的延迟。
请求被准入后,会进入下面的选择器链。
- 性能层级(选择器一)
第一个选择决策是层级。计算资源根据服务级别协议(SLA)进行优先级排序:付费较高的层级获得比低层级(或试用层级)更高的处理优先级和更快的队列处理。反过来,后者的客户在容量允许的情况下得到服务。
关键的是,层级决定了谁先走;它本身并不能防止层级内单个大租户的支配。这是接下来两层的目的。
- 赤字轮询(选择器二)
系统的核心是赤字轮询(DRR)算法,它确保在同一层级内公平分配计算资源。
每个租户(“组织”)都有自己的队列。调度器不是要清空最长的队列,而是在租户之间轮流。每个租户获得一个小的预算——一个量子——在轮到自己时可以做的工作。当租户使用其轮次时,其预算会根据刚发送的请求的成本进行扣减。预算用完的租户会被跳过,直到下一轮预算被补充。
DRR的优雅之处在于它既工作守恒又加权。便宜的请求让租户更频繁地出现在轮次中,昂贵的则较少,因此没有租户能独占GPU,但也不浪费任何容量。回到之前的例子:即使组织A排了10,000个请求,而组织B只有5个,组织B仍然在每个周期获得应得的轮次。组织A的突发不再转化为组织B的延迟。
预算的衡量标准
该方案依赖于两个关键变量:
- 量子:每轮授予租户的预算量
- 成本:每个请求消耗的预算量
关键的设计选择在于这些变量以什么单位表示。这决定了在不同推理上下文中如何概念化“公平性”。在Cohere,我们根据端点使用两种成本模型:基于请求的预算和基于令牌的预算。
基于请求的预算
为了简单起见,每个请求的成本设为1,量子是租户每轮可以发送的请求数。因此,公平性纯粹以请求数量来衡量。
这对于生成端点(如聊天和补全)来说不是最优的,因为请求服务成本可能差异很大。一个具有100K令牌提示的请求可能比一个1K令牌提示的请求消耗多几个数量级的资源。对于推理能力模型,总成本不仅取决于输入大小,还取决于请求特定上下文所触发的中间推理、规划和输出生成量。
理想情况下,DRR将使用基于请求令牌归一化服务成本的指数移动平均(EMA)的反馈循环,使预算适应观察到的资源消耗。当端点内的请求在大小和成本上大致相似时,静态预算效果最好。
基于令牌的预算
这里,请求的成本是其令牌数,量子是每轮的令牌预算。现在公平性以实际完成的工作来衡量。这是批量端点(如嵌入和排序器)的自然选择,其中批次的令牌总和(而不是项目数量)驱动GPU成本。发送几个非常大的文档的租户会很快用完预算并更快地让出位置;发送许多小请求的租户每个请求收费很少,更频繁地出现。这样,没有租户能通过提交少量超大型请求来独占GPU。
每个模型对你的请求意味着什么
| 特性 | 基于请求 | 基于令牌 | |------|----------|----------| | 每个请求的成本 | 始终为1,无论大小 | 与其令牌数成比例 | | 量子(每轮预算) | 请求数量 | 令牌配额 | | 大请求 | 与小请求计数相同 | 收费更高,消耗租户更多份额 | | 小请求的租户 | 获得与其他租户相同的轮次数 | 获得更多轮次(每个请求便宜) | | 最适合 | 生成/流式端点 | 嵌入/排序器(批量)端点 | | 公平性衡量 | 服务的请求 | 完成的工作(令牌) |
因此,在基于请求的预算下,你的请求最多等待每个竞争租户固定数量的请求,无论这些请求有多大。这个计数可能是可预测的,但邻居的大请求在每个轮次中仍可能耗费你的GPU时间。
在基于令牌的预算下,大请求“更重”:它更快地消耗其租户的预算,因此该租户更快地让出位置,小请求可以高效地通过。这种模型更忠实地反映了工作的真实成本,并且是对单个租户重流量造成的瓶颈的更强保证。
量子的大小也适应端点的批处理策略:流式端点大约每个租户旋转一个请求以实现紧密交错,而批量端点则授予接近完整批次的预算。因此,一个租户可以在调度器继续之前贡献有意义的部分——在不牺牲公平性下保持批处理效率。
- 优先级(选择器三)
如果公平性是关于决定哪个租户先走,那么优先级选择器决定该租户的哪个请求先走。
一旦赤字轮询选择了某个租户的轮次,调度器就从该租户的队列中取出一个请求——但不是盲目的。每个队列都是按以下顺序排列的系统化队列:
- 优先级:显式更高优先级的请求先被服务。
- 截止日期:在相同优先级中,截止日期最早的请求获胜,因此时间敏感的工作不会过期。
- 到达时间:作为最终决胜条件,较早的请求先走,提供稳定的先进先出行为。
将这种排序保持在每个租户内部,而不是在全局队列中,是让公平性和紧迫性在平台上共存的关键。租户不会因为共享平台而失去其优先级和截止日期保证;它只是将这些保证应用于其自己的公平容量份额。
整合在一起
这四个阶段组合成一个清晰的请求生命周期。速率限制器控制入口准入;层级、公平性和每个租户的紧迫性控制出口选择,每个批次组装时。
单独来看,这些机制——速率限制、层级、轮询调度和优先级队列——对于MLOps和平台工程师来说都很熟悉。它们的新颖价值在于它们如何集成:
- 速率限制保护系统免受过载,并强制每个租户的配额。
- 层级履行商业承诺。
- 赤字轮询保证在同等层级的准入流量中,每个租户获得公平、抗突发的份额。
- 优先级在每个租户的公平份额内保持其自己的紧迫性和截止日期排序。
步骤2-4重复,直到批次满,然后批次被发送到GPU。结果是一个平台,你的体验取决于你的层级和你的公平容量份额——而不是取决于你的邻居那天有多吵。
今天享受更公平、无摩擦的推理
服务公平性现已面向所有通过Cohere SaaS API和第三方市场部署(包括AWS)使用任何Cohere模型的客户启用。
我们以客户需求为中心开发了这一功能。如果您正在使用Cohere模型,并有反馈、观察到的性能问题或改进建议,请通过我们的Discord联系我们的工程团队。