高效请求排队以优化大语言模型性能
为多个用户并行提供大语言模型(LLM)服务具有挑战性,因为请求会竞争有限的 GPU 资源。为了保持一致的用户体验,组织必须实施复杂的排队和调度策略,以防止单个高流量用户垄断推理引擎。
问题:大流量用户导致的资源阻塞
在标准推理引擎(如 vLLM 或 HuggingFace TGI)中,请求通常由工作线程、队列和调度器处理。由于批量执行 GPU 计算更高效,后端队列使调度器能够将多个请求组合成一个批次。
然而,当“大流量用户”发送大量请求时,他们可能会填满后端队列。这会产生阻塞效应,导致其他用户的后续请求必须等到该大流量用户的所有请求处理完毕后才能继续,无论新请求的紧急程度或数量如何。
解决方案:实现公平调度
为防止资源阻塞,TNG 实现了一个位于用户和推理后端之间的 “LLM-Server”(API 服务器)。LLM-Server 不直接将请求发送到后端,而是为每个用户和模型管理独立的队列。
轮询调度
LLM-Server 使用轮询调度器,而非先进先出(FIFO)方式。这确保了不同用户的请求得到轮流处理,即使某用户仅有单个请求,也能比另一个用户的多个待处理请求更快得到响应。
潜在的调度扩展
除了简单的请求计数外,调度还可以基于多种指标进一步细化:
- 处理时间: 优先处理较短的请求以降低整体等待时间,尽管生成长度难以估计。
- 缓存优化: 按相似性排列请求,以最大化 KV 缓存命中,这是一种被 NVIDIA Dynamo 和 AIBrix 等框架使用的技术。
- 业务成本: 根据操作的财务成本对请求进行优先级排序。
- 优先级层级: 为不同使用场景建立不同的队列。例如,交互式聊天界面获得高优先级以保持响应式 UI,而代码审查或基准测试的批量 API 任务则设为低优先级。
管理后端回压
如果 LLM-Server 立即将所有优先请求发送到后端,则公平调度在 LLM-Server 层面上无效,因为这些请求会在后端的 FIFO 队列中堆积,重新导致阻塞问题。
基于指标的速率调节
由于某些后端(如 vLLM)不支持限制后端队列的最大元素数量,LLM-Server 必须动态调整转发请求的速率。TNG 通过从 vLLM 的 /metrics 端点获取 Prometheus 指标来实现此功能。
通过监控 后端队列长度指标,LLM-Server 仅在队列长度低于特定阈值(例如 3)时转发新请求。这在降低新用户延迟的同时,平衡了低延迟与 GPU 利用率不足之间的权衡。
高级指标反馈回路
此反馈回路可基于实时性能进行进一步优化:
- Token 速度阈值: 如果 每输出 token 时间指标 超过某个限制(例如 150ms),服务器可以停止调度新请求,以保持最低生成速度(例如 >7 token/秒)。
- 特定优先级阈值: 低优先级的批量请求仅在后端队列完全为空时才调度,以确保它们不会增加高优先级用户的延迟。
替代方案:后端侧优先级调度
最新版本的 vLLM 引入了基于优先级的调度,允许为请求标记优先级。高优先级请求可以“跳过”队列,甚至直接进入已处理的批次,可能会将低优先级请求驱回等待队列。
与 LLM-Server 调度的比较
虽然后端侧的优先级调度简化了一些逻辑,但上游 LLM-Server 仍然必不可少,原因如下:
- 兼容性: 后端优先级功能在
vLLM中可用,但在HuggingFace TGI中不可用。 - 速率控制: 后端调度不根据诸如每输出 token 时间等性能指标控制请求提交速率。
- 优先级分配: 需要一个客观的上游实例,根据用户身份或应用类型为请求分配优先级。
排队策略汇总
| 策略 | 实现位置 | 主要收益 | 局限性 |
|---|---|---|---|
| FIFO | 后端 | 实现简单 | 大流量用户阻塞其他用户 |
| 公平调度 | LLM-Server | 防止用户阻塞 | 需要上游服务器 |
| 基于指标的回压 | LLM-Server | 最小化后端延迟 | 需要指标轮询 |
| 优先级调度 | 后端(vLLM) | 高优先级请求即时处理 | 无速率控制;仅限 vLLM |