停止排队推理请求

发布: (2026年3月3日 GMT+8 06:21)
5 分钟阅读
原文: Dev.to

Source: Dev.to

问题概述

大多数推理后端在突发负载下会退化。
这不仅限于大语言模型(LLM),任何受限的计算系统都会出现:

  • 单个 GPU
  • 本地模型运行器
  • CPU 受限的工作者
  • 紧凑规模的推理集群

当需求激增时,大多数系统会采取以下两种做法之一:

  1. 接受所有请求,让请求在内部累积。
  2. 在入口处限流。

这两种方式都掩盖了真正的问题。

  • 队列不断增长。
  • 延迟拉长。
  • 重试加剧压力。
  • 内存使用变得不可预测。
  • 过载变得不透明。

你不会立刻看到失败,只会看到缓慢的衰退。

缺失的边界

限流执行治理 是有区别的。

  • 限流 控制请求到达的速度。
  • 执行治理 控制允许运行的请求数量。

这两者并不相同。你可以限流,却仍然构建一个无限的内部队列。如果不对并发执行施加硬性上限,后端本身就会成为队列,而在突发负载下的队列是隐蔽的负债。

另一种思路:显式 Yield

与其缓冲过载,不如将其转化为显式响应。当容量已满时:

  • 不排队。
  • 不阻塞。
  • 不悄悄延迟。

返回:

status = yield
retry_hint_ms = 

系统保持有界,客户端自行决定何时重试,过载变得显式而非隐藏。

具体示例

下面是一个简单的测试:

  • max_inflight = 1
  • 20 个并发客户端
  • 后端执行时间 = 10 秒

观察到的状态转变:

t=44  inflight=1  executed_total=1  yielded_total=19
t=79  inflight=0  executed_total=1  yielded_total=19

解释

  • 同时进行的请求数从未超过 1。
  • 只有一个请求被执行。
  • 其余十九个请求立即被 yield。
  • 队列没有增长。

系统没有退化,保持了有界性。

为什么这对推理系统重要

推理工作负载本身是突发的;提示词并不是平滑曲线到达,而是成簇出现:

  • 用户刷新风暴
  • 重试循环
  • 并发 UI 事件
  • 负载均衡器重新分配
  • 自动伸缩延迟

如果你的后端悄悄缓冲这些突发,你将会在后期承受尾部延迟和内存压力。对执行进行有界限制并在超载时返回 yield,将隐式的不稳定性换成显式的回压——这几乎总是值得的权衡。

这不是

不是

  • 调度器
  • 策略引擎
  • 公平性系统
  • 网关
  • 仪表盘
  • 分布式运行时

它是一个狭义原语:硬并发上限 + 显式 yield。仅此而已。

一个小工具,故意保持简约

我围绕这个思路实现了一个小型入口治理器。它:

  • 接收以换行分隔的 JSON 帧(TCP)
  • 验证上传完整性
  • 强制 max_inflight
  • 当饱和时立即返回 yield
  • 暴露最小指标(inflightexecuted_totalyielded_total

检查提示词、不对模型进行 introspection、也不计数 token 或应用策略。它仅仅治理执行槽——别无他物。

为什么不直接用 Nginx?

因为限流并不是执行治理。你可以限制每秒请求数,却仍然允许后端接受无限数量的并发提交。有限并发和显式 yield 是不同的原语;它们可以共存,但解决的问题不同。

核心思想

停止把过载当作需要缓冲的东西。把它当作需要暴露的东西。如果容量已满,就直接说明。返回 yield。保持有界。

参考实现

https://github.com/newssourcecrawler/heptamini

0 浏览
Back to Blog

相关文章

阅读更多 »

当工作成为心理健康风险时

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...