别只看吞吐和延迟:LLM 推理中的 Admission Control,才是 Goodput 优化的总开关

发布时间:2026/7/11 2:15:15
别只看吞吐和延迟:LLM 推理中的 Admission Control,才是 Goodput 优化的总开关 很多团队做 LLM Serving 优化时最先盯的是tokens/s、TTFT、P95 latency然后去调batch size、KV Cache、量化、并行策略、Chunked Prefill甚至更换 vLLM、SGLang、TensorRT-LLM。这些工作当然重要但如果系统缺少一层明确的Admission Control准入控制线上服务很容易在高峰期进入一种“GPU 很忙、用户很慢、吞吐看似不低、可交付结果反而下降”的状态。真正决定服务质量的往往不是“还能不能再塞进一个请求”而是“什么请求应该进、什么时候进、以什么代价进”。本文从 AI Infra 和 LLM Serving 的工程视角系统拆解 Admission Control 与 Goodput 的关系为什么只看吞吐会误判系统健康为什么很多优化上线后反而更容易抖动Admission Control 到底在控制什么它与 continuous batching、Chunked Prefill、KV Cache 水位、SLO、队列公平性之间如何耦合以及在线上与面试里该如何把这个主题讲清楚。导读如果把前几篇关于Chunked Prefill、KV Cache、MoE 路由抖动、显存碎片的文章连起来看会发现它们都指向同一个更上层的问题GPU 资源并不是无限的用户请求不是同质的长短请求、交互请求、批处理请求会相互竞争系统不能只考虑“尽量跑满”还要考虑“结果是否值得交付”这正是 Admission Control 发挥作用的位置。很多人以为 Admission Control 只是“队列满了就拒绝”这其实把问题想简单了。在真实 LLM Serving 系统里Admission Control 更像一个资源治理层它决定当前系统还能不能接新请求接进来以后是否会拖垮已有请求哪类请求优先保交互体验长 prompt、长输出、多轮会话是否需要分级处理当前是该追求吞吐还是该保住 goodput如果你做过线上推理服务就会知道系统最危险的时候往往不是 GPU 空闲而是 GPU 过于繁忙但没有产生足够高价值输出的时候。目录先讲清楚什么是 Goodput为什么它比吞吐更重要为什么很多 LLM 服务会陷入“越忙越差”的状态Admission Control 到底在控制什么它为什么不是简单的排队或限流LLM Serving 里最常见的四类资源冲突只看 tokens/s 为什么会误导系统优化Admission Control 的核心输入你到底该看哪些信号常见准入策略一基于队列长度和并发上限常见准入策略二基于 KV Cache / 显存水位常见准入策略三区分 Prefill 与 Decode 的分级准入常见准入策略四按请求画像做分层治理为什么 Admission Control 会和 Continuous Batching 强耦合它和 Chunked Prefill、Prefix Cache、量化是什么关系线上落地时最容易踩的几个坑一套更实用的工程落地框架监控、压测与排障时重点看什么面试里怎么把 Admission Control 讲得像真的做过总结1. 先讲清楚什么是 Goodput为什么它比吞吐更重要很多团队会把下面几个词混着用吞吐单位时间内处理了多少 token、多少请求延迟一次请求完成或首 token 返回用了多久利用率GPU 看起来有多忙Goodput在满足目标体验或 SLO 约束下系统真正交付的有效工作量这里最容易被低估的是 Goodput。1.1 吞吐不等于有效交付假设系统每秒能吐出很多 token但大量请求已经超出用户可接受的等待时间交互式请求被长请求堵住请求虽然没报错但延迟已经超过产品 SLOdecode 速度严重抖动用户体感很差那么这些 token 从工程角度看并不都是“有价值产出”。也就是说Goodput 关注的是“满足目标约束的有效吞吐”而不是裸吞吐。1.2 Goodput 更贴近真实线上目标对一个聊天服务来说用户关心的不是 GPU 是否满载而是能不能尽快看到首 token流式输出是否稳定高峰期是否明显卡住长问题会不会拖垮短问题对平台或业务侧来说关心的是同样的 GPU 预算能稳定支撑多少在线并发P95/P99 是否可控拒绝率是否合理是否能对不同租户、不同模型、不同流量类型做隔离这些目标最终都会落到 Goodput而不是简单的 tokens/s。1.3 一个更工程化的理解可以把 Goodput 理解成在既定 SLO、显存预算、GPU 算力、业务优先级和用户体验约束下系统每单位时间真正交付的“可接受请求量”或“可接受 token 量”。所以Admission Control 的根本目标不是拒绝请求而是保护 Goodput。2. 为什么很多 LLM 服务会陷入“越忙越差”的状态LLM 服务与传统 Web 服务不同它不是“接到请求就简单算一下”。它的资源竞争具有几个很强的系统特征Prefill 和 Decode 的负载形态不同长短请求差异极大KV Cache 占用会持续累积Continuous Batching 会让请求互相影响流式输出让单个请求生命周期变长这会导致一种典型现象低负载时一切指标都很好中等负载时吞吐持续上升再往上压时GPU 利用率更高了但 TTFT、TPOT、P99 延迟、取消率、超时率一起恶化继续压测系统表面还在“工作”但有效交付急剧下降这就是典型的过载区间。2.1 过载不一定表现为崩溃很多工程师一开始会把“系统没挂”当成“还能接流量”。但对 LLM Serving 来说更常见的问题不是直接 500而是用户等到了但等太久流式回复开始得慢回复过程中明显顿挫某些请求长期排队后被取消长请求吞掉了系统公平性这时候系统没有宕机但 Goodput 已经明显下降。2.2 资源过载的后果会被 batching 放大传统请求通常更独立而 LLM 推理为了提高利用率会主动把请求合在一起。合批能提高效率但也意味着一个异常长的 prefill 会影响同一批次中的其他请求显存紧张会影响新旧请求的共存decode 阶段如果被长 prefill 频繁打断用户体感会快速恶化所以越是高并发系统越需要 Admission Control 做“进场秩序维护”。3. Admission Control 到底在控制什么很多人听到 Admission Control第一反应是请求进来判断满不满满了就拒绝这太窄了。在 LLM Serving 场景里Admission Control 至少在控制下面几件事3.1 控制系统进入过载区核心问题不是“还跑不跑得动”而是“再接这个请求之后系统整体质量会不会下降到不可接受”。3.2 控制不同请求之间的相互伤害Admission Control 不是只看总量还要看请求结构短对话请求超长上下文请求长输出请求批处理离线请求高优先级租户请求这些请求对系统的破坏力并不一样。3.3 控制资源分配的形状系统不是只有“算力够不够”的问题还包括KV Cache 水位是否接近危险区Prefill 是否会长时间霸占算力Decode 是否还能维持平滑输出是否要给某类请求预留资源池3.4 控制体验与成本的平衡点Admission Control 的结果不只影响体验也影响成本放太松系统进入抖动区实际有效交付下降放太紧GPU 利用率低成本浪费所以它本质上是在找一个最优工作区间。4. 它为什么不是简单的排队或限流排队、限流、Admission Control 很容易被混为一谈但它们不完全一样。4.1 限流更像外层保护比如每秒最多接收多少请求某租户 QPS 上限是多少某接口突发峰值限制是多少这更偏入口层。4.2 排队更像时间上的缓冲请求先放进等待队列等资源出来再调度。它解决的是“现在不能立刻处理但也许稍后能处理”。4.3 Admission Control 是资源和价值判断Admission Control 要回答的问题更强这个请求是否值得进入系统它什么时候进入最合适它会不会伤害当前更有价值的请求它是否该降级、拆分、转移、延迟或直接拒绝所以它经常结合队列优先级资源预算SLO 约束请求画像模型侧特征它比简单限流和排队更接近“在线资源调度策略”。5. LLM Serving 里最常见的四类资源冲突理解 Admission Control先要理解它在防什么。5.1 Prefill 与 Decode 的冲突Prefill 更偏大块计算Decode 更偏小步迭代和连续响应。如果系统为了拉高吞吐放进太多长 prefill短请求 TTFT 会恶化现有会话的 decode 会被打断交互式体验显著变差5.2 长上下文与高并发的冲突长上下文请求不仅 prefill 重还会迅速抬高 KV Cache 占用。一旦系统让太多长上下文会话同时入场显存水位会快速上升可接入的新请求数下降eviction 或回收压力增加5.3 长输出与公平性的冲突有些请求 prompt 不长但max_new_tokens很大。这类请求会在 decode 阶段长期占据系统资源影响其他短请求完成。5.4 在线交互与离线批处理的冲突如果同一个服务同时承载面向用户的对话流量后台批量生成流量那 Admission Control 不做分层几乎一定会互相污染。6. 只看 tokens/s 为什么会误导系统优化这是一个非常典型的线上误区。6.1 tokens/s 会掩盖坏请求的存在系统可能通过放入更多长输出请求让总 tokens/s 看起来更高。但与此同时用户平均等待变长首 token 变慢短请求完成率下降结果是吞吐好看了Goodput 变差了。6.2 GPU 利用率高不代表系统健康GPU 一直满负荷可能有两种解释资源利用得很充分系统处在良好区间资源已经被低价值工作塞满系统处于过载边缘如果不结合SLO 达成率请求取消率队列等待时间KV Cache 水位各类请求的完成质量单看 GPU Busy 很容易做出错误决策。6.3 只优化 benchmark 容易把线上带偏很多 benchmark 是固定输入长度固定输出长度纯同质请求不考虑真实取消、超时、突发流量这类 benchmark 很适合测底层引擎上限但不等于线上系统最优。Admission Control 正是在“benchmark 最优”和“线上最优”之间补上那层治理逻辑。7. Admission Control 的核心输入你到底该看哪些信号如果只看队列长度策略会非常粗糙。更实用的做法是把 Admission Control 建立在一组组合信号之上。7.1 队列类信号当前等待请求数等待时间分布各优先级队列长度某类请求是否出现堆积7.2 运行时负载信号当前活跃会话数当前 decode token budget当前 prefill token budget每轮调度可用 slot 数7.3 显存与 KV 相关信号KV Cache 使用量可分配 block 数显存碎片程度eviction 频率swap/offload 是否触发7.4 SLO 相关信号TTFT P50/P95/P99TPOT 或 decode token latency请求完成率用户主动取消率超时率7.5 请求画像信号输入长度预估输出长度租户优先级是否交互式请求是否有 cache 命中潜力真正成熟的 Admission Control 往往不是单阈值而是多信号联合判断。8. 常见准入策略一基于队列长度和并发上限这是最容易落地的第一层策略。8.1 做法很直接例如活跃请求数超过阈值不再接受新请求等待队列超过上限直接拒绝或返回稍后重试某优先级队列超长时低优先级请求限流8.2 优点实现简单能快速防止请求无上限堆积对入口保护很有效8.3 问题它没有理解请求之间的异质性。十个短请求和十个超长请求对系统压力完全不同。如果 Admission Control 只看“请求数”会出现两类问题明明还能处理一批短请求却被一刀切拒掉明明系统已经很危险只因为请求数不多还继续放行所以这类策略适合作为第一道防线但远远不够。9. 常见准入策略二基于 KV Cache / 显存水位这类策略更贴近 LLM Serving 的真实瓶颈。9.1 为什么 KV 水位特别关键对于长会话或高并发场景真正把系统推向危险区的往往不是算力而是 KV Cache。因为每个活跃会话都在持续占用 KV上下文越长占用越大长输出也会让会话生命周期更长显存一旦逼近危险区系统会迅速丧失弹性9.2 基于水位做准入判断例如可以设定KV block 使用率低于 70%正常接入70% 到 85%谨慎接入只放行短请求或高优先级请求85% 以上暂停长上下文请求优先保 decode90% 以上进入保护模式只保已有会话和关键流量9.3 这类策略的价值它能避免“系统看起来还有算力但其实已经没有足够显存余量”的误判。9.4 但它也有边界如果只看显存会忽略decode 已经被长 prefill 压住队列等待已经过长某租户独占过多资源所以仍需要与其他信号联合使用。10. 常见准入策略三区分 Prefill 与 Decode 的分级准入这是 LLM Serving 里非常有代表性的工程策略。10.1 为什么要区分Prefill 和 Decode 对用户价值不同Decode 往往对应已开始响应的在线会话打断体验最明显新的长 prefill 虽然重要但优先级未必总高于已有 decode因此很多系统会做优先保 decode谨慎接入长 prefill10.2 典型策略decode 请求默认优先继续执行新进入的长 prefill 需要通过更严格准入门槛当系统进入高水位区时只允许短 prefill 或高优先级 prefill超长 prompt 请求改走 chunked prefill 或延迟入场10.3 它为什么有效因为它保护了流式连续性。很多用户对 TTFT 敏感但对“开始输出后是否持续平滑”同样敏感。如果 decode 经常被打断用户体感会很差。10.4 它的代价如果过度偏向 decode新请求进入速度会变慢长请求可能长期饥饿队列公平性变差所以需要在交互体验和请求公平性之间找平衡。11. 常见准入策略四按请求画像做分层治理这是更接近生产系统的做法。11.1 不同请求应该区别对待可以按这些维度分层交互式 vs 离线批处理短输入 vs 长输入短输出 vs 长输出高优先级租户 vs 普通租户付费流量 vs 内部测试流量11.2 常见治理手段不同队列不同 token budget不同等待上限不同拒绝阈值不同模型实例池11.3 一个典型例子比如把请求分成三类A 类在线短对话严保 TTFT 和流式稳定性B 类普通对话请求量大但优先级中等C 类离线长生成可容忍等待那么 Admission Control 就不应该统一处理而应该A 类优先保B 类在中等负载下正常接入C 类在高峰期被延迟、限流或迁移这类分层对 Goodput 的改善通常比单纯再调一点 kernel 更直接。12. 为什么 Admission Control 会和 Continuous Batching 强耦合很多人把 Continuous Batching 当成单纯的“吞吐优化手段”但从系统角度看它会直接改变准入逻辑。12.1 合批意味着请求相互影响请求一旦共享 batch其中一个长请求会改变这一轮的资源占用batch 结构会影响 decode 调度节奏显存分配也会被整批形态影响所以 Admission Control 不能只看“单请求能不能跑”而要看这个请求加入后batch 会变成什么形状会不会拉坏当前 decode 节奏会不会把显存带入危险区12.2 合批最怕错误的异质混合理论上批越大越高效但真实系统里太长的 prompt 混进在线短对话 batch不一定划算太长的输出请求混进短输出请求会拖慢整体完成节奏Admission Control 的任务之一就是避免“看起来是合批实际上是相互拖累”的组合。13. 它和 Chunked Prefill、Prefix Cache、量化是什么关系这些优化都不是孤立存在的。13.1 和 Chunked Prefill 的关系Chunked Prefill 的作用是把长 prefill 变成可插队、可切分的资源占用形状。它会让 Admission Control 有更多调度空间。但要注意有了 chunking不代表可以无限放长请求chunk 太碎会增加调度开销如果 Admission Control 不配合长请求仍可能挤爆系统13.2 和 Prefix Cache 的关系Prefix Cache 能降低部分 prefill 成本。这意味着有高命中潜力的请求准入代价更低低命中、超长、结构不稳定的请求准入风险更高因此更精细的 Admission Control 会把“是否可能命中缓存”纳入判断。13.3 和量化的关系量化通常会降低权重占用改善吞吐或可部署规模给 KV 或并发留下更多空间但这并不意味着 Admission Control 可以不做。因为量化缓解的是资源压力不是消灭资源竞争。系统进入过载区的边界可能被推远但不会消失。14. 线上落地时最容易踩的几个坑14.1 把拒绝率最小化当成目标很多团队会天然觉得拒绝越少越好但在线服务里合理拒绝往往比错误接入更健康。如果系统接了太多请求最后让大量请求超时、卡顿、取消表面上拒绝率低实则 Goodput 更差。14.2 单阈值策略抖动严重比如显存超过 85% 就拒绝低于 85% 就全放这种策略容易在阈值附近来回震荡。更实用的是滞回区间分级模式平滑窗口统计14.3 只做全局准入不做分类治理结果往往是某类重请求拖垮所有流量高优先级业务没有真正被保护14.4 准入和调度脱节如果 Admission Control 不知道调度器当前状态只在入口层拍脑袋判断策略会很粗糙。成熟系统通常让准入层能看到scheduler backlogactive sequence 数量token budget 使用情况KV block 可用情况14.5 只在压测数据上做阈值线上流量通常更脏输入长度分布更散输出长度更不可控取消率更高租户行为差异更大所以阈值不能只从理想 benchmark 得出。15. 一套更实用的工程落地框架如果让我从 0 到 1 设计一套 LLM Serving 的 Admission Control我会按下面五层来做。15.1 第一层外层流量保护API 网关限流租户级配额基础并发上限作用是防止异常流量把后端瞬间打穿。15.2 第二层请求分类进入服务后先做轻量画像prompt 长度区间max_new_tokens 区间用户/租户优先级在线还是离线先分类再决定进入哪个队列。15.3 第三层运行时资源判断结合当前KV Cache 水位活跃 decode 数prefill backlog预计 token budget最近一段时间的 TTFT / TPOT判断是否允许进入。15.4 第四层准入动作不是只有“过/不过”一个成熟系统里准入动作至少可以有立即接入延迟接入降级接入分块接入转移到低优先级实例池明确拒绝15.5 第五层闭环调参与回灌上线后必须持续回看哪类请求被拒得最多哪类请求造成过载最多拒绝是否真的提升了 Goodput是否存在饥饿或不公平否则 Admission Control 很容易变成一堆静态阈值。16. 监控、压测与排障时重点看什么如果你怀疑系统已经进入“忙但不值”的状态建议重点看下面几组指标。16.1 用户体验指标TTFT P50/P95/P99TPOT 或每 token 解码延迟流式中断/卡顿比例请求取消率请求超时率16.2 系统负载指标活跃 sequence 数prefill 队列长度decode 队列长度每轮调度 token budgetGPU Busy 与 SM 利用率16.3 显存相关指标KV Cache 占用率可用 block 数量eviction 次数swap/offload 次数显存碎片趋势16.4 准入效果指标不同类别请求的接入率延迟接入比例拒绝率被拒后重试成功率分层队列公平性16.5 一个排障判断思路如果你发现tokens/s 没怎么掉但 TTFT、P99、取消率明显恶化优先怀疑Admission Control 过松长 prefill 混入过多decode 连续性被破坏KV 水位过高后仍在盲目接入这类问题不能只靠继续调算子解决。17. 面试里怎么把 Admission Control 讲得像真的做过这是一个非常适合拉开差距的话题因为它天然带工程味。17.1 不要只说“限流和排队”如果只说系统忙了就限流队列满了就拒绝面试官会觉得你停留在通用后端思维。17.2 要主动讲 LLM Serving 的特殊性你应该强调请求异质性强Prefill / Decode 资源形态不同KV Cache 会持续累积Continuous Batching 会放大请求之间的干扰优化目标不是裸吞吐而是 Goodput17.3 一个更像实战的表达模板你可以这样回答我理解 LLM Serving 里的 Admission Control 不是简单限流而是基于运行时资源和请求画像的准入治理。因为大模型请求异质性很强长 prompt、长输出、多轮会话会对系统造成完全不同的压力。如果只看 QPS 或 tokens/s很容易把系统推入过载区看起来 GPU 很忙但 TTFT、P99 和取消率都在恶化。所以我更倾向把 Admission Control 建在多信号之上比如 KV Cache 水位、活跃 decode 数、prefill backlog、请求长度分层和优先级再结合 continuous batching 的调度状态决定是立即接入、延迟、分块还是拒绝。核心目标不是少拒绝而是保护在 SLO 约束下的 goodput。17.4 如果面试官继续追问可以继续展开为什么长 prefill 会伤害 decode 连续性为什么合理拒绝比错误接入更健康为什么显存高水位时系统弹性会迅速变差为什么 batch 更大不一定更好只要能把这些关系说顺基本就不像背概念。18. 总结很多人做 LLM Serving会把精力集中在更快的 kernel更高的 tokens/s更大的 batch更激进的并发这些都对但都不够。因为线上系统不是比谁把 GPU 塞得更满而是比谁能在真实流量、真实约束、真实波动下持续交付更高的 Goodput。从这个角度看Admission Control 的价值非常明确它决定系统是否进入过载区它决定长短请求如何共存它决定交互体验是否能被保住它决定你做的那些底层优化最终能不能转化成真实线上收益一句话总结在 LLM 推理系统里吞吐优化解决的是“能跑多快”而 Admission Control 解决的是“该不该这样跑”。真正稳定的 Goodput必须靠两者一起完成。如果你正在搭建 AI Infra / LLM Serving 系统建议把 Admission Control 从“后面再补”的边角逻辑提升成和 KV Cache、batching、调度器同级的一等公民。因为很多系统的上限不是死在算子不够快而是死在资源治理不够清楚。