SLA 分级这件事,在合同和监控面板上看着都挺清楚:金牌客户 P99 800ms,银牌 2s,免费流量尽力而为。等到真出事的时候,问题往往不在 SLA 定义写得好不好,而在于同一个模型实例、同一个调度器、同一条队列里,所有请求其实平等地站着。免费用户的大批量请求在高峰灌进来,金牌用户的 P99 跟着起来,合同条款就变成了一张纸。
这篇写的是推理服务里把分级做成队列隔离时,我在工程上踩过的几个点:隔离的粒度选在哪、配额怎么给才不会被少数大请求吃干净、抢占该不该做、以及监控指标怎么留证据。
先承认一件事:只靠限流不够
最省事的做法是给每个调用方一个 QPS 限流,超了直接 429。它能挡住无限灌流量,但挡不住排队。瓶颈在 GPU 上时,请求延迟由批处理的排队位置和批大小决定,跟你放进来多少 QPS 没有线性关系。给免费档压一半 QPS,它剩下的请求仍然是 30ms 送到调度器,插队成本为零。
所以隔离必须发生在调度队列这一层,而且要在准入之后、拼批之前。到了拼批之后再做区分,同一个 batch 里高优先级请求已经被后进的低优先级请求拖住了:动态拼批本身是一次同步等待,把不同等级的请求混在一个批里,SLA 上限就按最慢的那个请求的 deadline 算。如果按批内最高等级来定 deadline,低等级请求又会享受到它付不起的服务;反过来按最低等级算,SLA 就彻底失效。
隔离粒度:按逻辑队列分,而不是按实例分
常见的选择有两条路。一是每个等级一组实例,物理隔离,简单粗暴,代价是 GPU 利用率朝地板走:金牌实例在午饭时段可能只跑 20% 的负载,而它不能借给银牌用,别人也不能借进来。二是共享实例,在调度器里做多个逻辑队列,再给每个队列分配“并发座位”。我倾向于后者,前提是座位分配带权重和上限。
座位不是简单的一比一,它要按等价单位来算。一个请求消耗的度量值最好用预估输出 token 数乘一个随输入长度递减的系数。单按请求数算,会发现金牌队列里几个长输出请求占满了所有位置;单按 token 算,又会让短请求因为无法达到最小 token 额度而卡在准入。Calnex 在验证推理网络 SLA 时提到的突发请求峰值和链式时延,其实也适用在这里:一个中继调用展开成三四个下游请求时,占的是好几个 IP、在总账上各自占位置。
配额与抢占:钱要花在挡住谁上
分了队列就要定公平分享策略。我比较常用的一条规则是带余量租借:每个等级有自己的保证份额,但不用的份额可以被其他等级“借”走,借来的部分立刻可以回收。这里的关键不是“能借”,是“能在一批之内收回”。如果回收要等落地的长请求自然结束,金牌用户的 P99 在毛刺点上要看见好几十秒的尾部。
能做到批内回收的原因是 KV cache 给了一个便宜的触发时机。正在运行的批只有在逐 token 解码时最短的清除点是每步之后,但你可以整批作废、释放 cache、让被驱逐请求回到队列头部并保留部分已生成结果。代价是首个 token 之前的工作丢了,该写日志写明,不要悄悄吞。
另一个现实做法是引入短暂的软隔离重叠区:在低于 SLO 85% 的情况下按 FIFO 混合排,越接近 SLO 收得越紧,滑到阈值就纯隔离。软重叠会丢掉可租空间里大约中低单数的尾部保证,要先模拟业务分布再开。
监控才是判决证据
SLA 争议不可免,指标要留证据。除了常规的输入输出时长,至少要能按每分钟拉出这几项:每个等级在调度队列里的等待时长分布(不是平均值,平均在长尾语境里就是个笑话),批内不同等级混排的比例,租借份额下发量的占用比例,以及整体 GPU 实际执行时长里各等级的配额占比。
这四项放在一起才说得清某个时刻发生了什么。单看 P99 你只能证明它慢,看不到是“顶级等级没有被隔离”还是“顶级等级自己在处理巨大请求”。我做告警时按队列的等待占比和保底比例做门限,总体 P99 不作单条告警,改为放到面板的对比行。
工程上的落地顺序
要真落,顺序大致定这样比较安全:先定义等级和精确的 SLO,先不发布,只做影子统计指标跑一周到两周;再到限制准入和公平 seat;最后再开抢占。抢占即使关掉,也要让分发器在检测到质量开始滑时能给外部一个可以用的返租缓冲层的应对,比如告诉上游重试到下一可用区,比一上手抢更安全。
要指出的其他限制:同一条传输上把查询流与推理路由请求隔离开时,打流不固定队列只动到通道本身,但路由请求也会走同一个模型请求,这里可以视为未覆盖到;桌面或全机虚拟机上的链传输动作直接改网络不影响 host 端口自身的行为。还有一处是每个排队的延迟,但只有等级相同的请求才会在两两对比时显得是一维,这些只能在工程推演上做结,不要写成功模。
转载请注明出处: 皮哈皮阿
本文的链接地址: https://blog.phpat.com/ai-engineering/646.html
微信或手机浏览器扫一扫,随时随地随心阅读与分享
-
推理成本下降之后:模型路由、KV Cache 与端侧推理
上个月一个团队拿着账单来找我:模型单价降了,费用却涨了三倍。看完调用链就明白了,问题不在单价,在用法。单位 token 便宜,不等于每次任务便宜。
2026/10/10
-
2026 年 AI 应用评测:从单轮打分到多轮轨迹评估
一个 Agent 的评测分数从 72% 涨到 81%,团队很高兴,直到发现它学会了在失败时直接结束任务,把“没做完”算成了“无需回答”。评测设计错了,指标越好看越危险。
2026/10/19
-
长度惩罚参数调优:常见参数名字容易混淆
长度惩罚在主流 API 里并不存在。真正管长度的是 max_tokens 和 stop sequences,frequency、presence、repetition 惩罚管的是用词重复和新词探索。把这些旋钮分开,能避免输出被截断、术语被替换成同义词两类故障。
2026/10/23
-
动态拼批不是开个开关:线上拼批的取舍与门禁
在线服务里的动态拼批和离线批量推理是两码事。窗口时长、KV Cache 水位、批内参数对齐共同决定拼接能否成立。上线前该盯的是 p99 和显存峰值,而不只是吞吐。
2026/10/25
-
推理模型的流式输出:thinking 块怎么流
推理模型的流式输出不只是逐字渲染:思考块、正文、工具调用参数混杂在 SSE 流里,客户端要按字段分流、独立缓冲、支持中途中断。记录接通义千问与智谱过程中的判断和踩坑。
2026/10/24
-
推理服务排队延迟的分层观测:从请求数到Token账本
盯 QPS 和 P99 看不到排队延迟长在哪。把这件事拆成入口→上游准入队列→后端等待→batch 解码四层,用 vLLM 暴露的排队与 KV 缓存指标做层级归因,讨论分层之后仍然看不见的部分与取舍。
6天前
京公网安备11011402053654 
@muffin:链接已更新,分类图像功能...
AI网址导航模版图标库更换指南
作者大大,图标库邀请链接失效了,麻烦更新...
AI网址导航模版图标库更换指南
太好看了,快点更新!
友情链接
@戴墨镜的刘备:哈喽,路过点赞。
vue.js组件之手写签名板vue-signature-simple
太好看了,快点更新!太棒了!👍真的很赞!
vue.js组件之手写签名板vue-signature-simple
你写得非常清晰明了,让我很容易理解你的观...
Emlog插件RSS订阅器发布