深度解读 📅 2026-10-20 ✍️ MagicNetWorld 编辑部

不跑 GPU 也能做容量规划:BLIS 把排队、批处理与 KV 缓存一起搬进 CPU 模拟器

给一个 LLM 服务选 GPU 数量、并行度和调度策略,传统做法是每种候选都在真机上压测一遍——论文中一组 H100 + Qwen3-14B、1 万请求的评估,单次就要 17 到 42 分钟的 GPU 集群时间。IBM Research 的 BLIS(arXiv:2610.14255,2026-10-09 提交,已被 ACM SIGMETRICS 2027 接收)换了条路:用一个只在 CPU 上跑的确定性离散事件模拟器(仿真运行阶段不用 GPU;延迟系数事先用 15 组真机实验全局拟合一次,此后复用),把准入、路由、调度、prefill/decode 执行、KV 缓存管理和抢占整条流水线都建模进去。结果是:在涵盖 6 个模型、3 种 GPU 的 36 组实验上,BLIS 的端到端延迟预测误差(先逐实验算百分比误差、再取中位数)为 6.7%,仿真运行比真实执行快约 200 倍;在 Llama-2-70B 的四工具对比搜索(420 个候选配置、以平均 TTFT ≤ 300 ms 为 SLO)中,它找到的 4 卡 H100 方案在真机上实测达标,而对比工具里 Vidur 的达标推荐要用 8 卡、AIConfigurator 需 6 卡才达标、LLM-Optimizer 的推荐在负载下严重过载不达标。更实在的是,两条完全在仿真里进化出来的服务策略已经合并进了开源平台 llm-d(截至 2026-10-20 仓库可见)。

LLM 推理容量规划离散事件模拟KV CachevLLMllm-d

先想象一个场景:你要把一个 70B 模型推上线,老板问你「要几张卡」。

这个问题听着简单,实际上是一个联合优化。

GPU 数量、张量并行(TP)度数、每个实例的最大批大小、chunk 大小、准入控制阈值、路由策略——这些旋钮互相拧在一起。

路由策略偏好了缓存局部性,可能把负载挤到少数实例上。

准入阈值只在饱和时才触发,等它触发时队列已经深得能拖垮高优流量。

最可靠的回答方式是真机压测:把候选配置部署到 GPU 集群上,打持续负载,看延迟达标没有。

但论文里给了一个实测数字:在 H100 节点上跑 Qwen3-14B、1 万个请求的一次工作负载评估,要 17 到 42 分钟。

候选配置有几百个,每个都这么试一遍,成本和时间都不可接受。

于是大家转向「先算后验」的预测工具。

IBM Research 在 2026 年 10 月 9 日提交到 arXiv 的这篇论文(编号 2610.14255,已被 ACM SIGMETRICS 2027 接收,作者为 Dipanwita Guhathakurta、Mert Toslali 等 9 人,全部来自 IBM Research)给出了一个相当能打的答案:BLIS(Blackbox Inference Simulator),一个只在 CPU 上跑、确定性、离散事件的 LLM 推理服务模拟器。

它的核心承诺是三句话:

  • 不用 GPU 跑仿真:整个仿真在 CPU 上完成(延迟系数事先用 15 组真机实验全局拟合一次,此后复用);论文的定性说法是「几小时的流量几秒钟回放完」,定量口径是论文表 3 的中位加速比 212 倍(BLIS 单次运行中位 5.7 秒)——两者是同一基准的不同表述;
  • 不用逐配置 profiling:延迟模型全局只拟合一次,新模型、新 GPU、新并行度直接代入公开参数,无需对每个新配置重新做真机标定;
  • 精度可接受:在涵盖 6 个模型、3 种 GPU 的 36 组实验上,BLIS 端到端延迟预测的逐实验百分比误差的中位数为 6.7%。

这篇文章把它的机制拆开讲清楚:它模拟了什么、延迟模型怎么做到「一次拟合、处处可用」、真机验证里它赢在哪、输在哪。

先看懂被模拟的对象:LLM 推理服务的流水线

要理解 BLIS 在模拟什么,先得把被模拟的系统本身讲清楚。

一个生产级 LLM 推理部署分两层:单机引擎层和集群数据平面层。

单机引擎层(以 vLLM 为代表)里,每个请求的一生分两个阶段。

prefill 阶段并行处理整个输入提示词,是计算密集型的。

decode 阶段逐个生成输出 token,每步都要从 GPU 显存里读出累积的全部 KV 缓存,是显存带宽密集型的。

KV 缓存是理解一切的关键:它保存每个已生成 token 的注意力状态,按定长块分配,随序列长度增长。

显存是有限的,所以一个实例能同时服务的请求数被显存死死卡住。

为了提高利用率,现代引擎用连续批处理(continuous batching):一个「步」(step)就是对当前批次做一次前向传播,为批次里每个 decode 请求各产出一个 token。

这里有个反直觉的调度效应——整批共享一次前向传播,所以大 prefill 和一堆 decode 排在同一步时,所有 decode 请求都跟着变慢(直观地说,这步的耗时被批内最贵的操作拖住;至于延迟模型在数学上如何把各项成本组合起来,见下文「延迟模型」一节,二者不矛盾)。

chunked prefill(由 Sarathi-Serve 系统提出,把长 prefill 切成小块与 decode 交错执行)缓解但不能消除这个效应。

当 KV 缓存被占满时,引擎会抢占(preempt)正在运行的请求、释放它们的块。

被抢占的请求之后恢复时,必须重算或重载被逐出的 KV 状态——这是后面「级联」的引信。

集群数据平面层(以 llm-d 为代表)在多个实例前面加准入控制和路由。

准入决定收不收这个请求,路由决定发给哪个实例。

关键在于——这些决策依据的是周期性刷新的实例状态快照(队列深度、KV 利用率、在途请求数),而快照是「过期」的。

等决策生效时,它描述的状态可能已经变了,负载突变时尤其如此。

为什么难算准:三股耦合的动力学

BLIS 论文把「为什么稳态估算器算不准」归为三股互相纠缠的动力学。

这是全文立论的根基,值得逐个看懂。

第一股是跨请求耦合。

一批请求共享一次前向传播,直观上一步的快慢被批内最贵的操作主导而非平均值(再次说明:这是调度层面的直观效应,延迟模型的数学组合方式见后文)。

连续批处理每步都在改变批的组成,所以单个请求的延迟取决于整个到达流,而不是它自己。

稳态分析假设批次固定或取平均,从根上就丢掉了这个效应。

第二股是 KV 缓存级联。

显存压力通过反馈回路把请求耦合起来:

  • KV 缓存满了;
  • 引擎抢占运行中的请求;
  • 被抢占者重新准入时要重算被逐出的状态;
  • 重算又加重负载、进一步抬高压力。

一个大请求挤进一个接近满的实例,就能级联出一串抢占,拖垮同实例的许多请求。

这个效应对负载是非线性的——低于显存上限时完全不存在,越过后随逐出次数增长。

第三股是过期快照反馈。

集群层面,准入、路由、流控都依据过期快照行动,这又造出反馈。

同一个快照间隔内到达的多个请求,会被负载均衡路由全部发向「看起来最空」的那个实例。

它随即过载、延迟上升,但旧快照还在持续给它引流,直到下一次刷新。

饱和阈值也因为同样的原因滞后触发。

这三股回路互相嵌套,意味着一个部署的行为取决于所有策略的联合配置,而不是任何单一策略。

这正是「闭式估算器」算不准的原因——它们在一个固定工作点上做解析计算,不展开这些事件,自然看不见这些动力学。

术语与符号约定

后面的公式会反复用到这些记号和术语,先在这里一次性约定。

记号 / 术语含义
prefill提示词处理阶段,并行消化全部输入 token,计算受限
decode逐 token 生成阶段,每步读全部 KV 缓存,带宽受限
step(步)对当前批次的一次前向传播
TTFTtime to first token,首 token 延迟
ITL / TPOTtoken 间延迟 / 每输出 token 耗时
E2E端到端请求延迟
KV 缓存每个已生成 token 的注意力状态,按定长块分配
连续批处理每步重组批次,批内请求共享一次前向传播
抢占(preemption)KV 不足时逐出运行中请求、之后重算其状态
TP张量并行度数
SLO服务级目标;本文配置搜索对比实验中用平均 TTFT ≤ 300 ms,其他实验的目标在各自小节另述
PPGPU 峰值算力(FLOP/s)
WW / WnetW_{\text{net}}HBM 带宽 / 卡间互联带宽
Fpf,FdcF^{\text{pf}}, F^{\text{dc}}prefill / decode 阶段的运算量
Mkvpf,MkvdcM^{\text{pf}}_{\text{kv}}, M^{\text{dc}}_{\text{kv}}prefill / decode 阶段的 KV 相关访存字节数
Mw,MtpM_{\text{w}}, M_{\text{tp}}权重字节数 / all-reduce 通信字节数
L,B,nMoEL, B, n_{\text{MoE}}层数 / 批大小 / 交错 MoE 层数(MoE = 混合专家,「交错」指与稠密层交替排布)
β1a…β8\beta_{1a}\dots\beta_{8}全局共享的缩放系数与开销项
α0,α1,α2\alpha_0, \alpha_1, \alpha_2请求生命周期的 CPU/框架开销(摄入、反分词、流式)
si,ss_i, s实例级 / 集群级饱和信号
APE / MAPE绝对百分比误差 / 其均值
MFUModel FLOPs Utilization,峰值算力利用率

BLIS 的第一块基石:确定性离散事件仿真

BLIS 的执行核心是一本标准教科书方法:离散事件仿真(DES)。

模拟器维护一条事件时间线——请求到达、步完成、快照刷新、抢占。

所有事件用一个最小堆按 (时间戳, 优先级, 序号) 排序,逐个弹出处理,仿真时钟直接跳到下一个事件。

一次运行的计算量正比于事件数,而不是被模拟的墙钟时长。

所以「几小时的服务流量在 CPU 上几秒钟就能回放完」——这是论文对设计目标 R4 的定性表述;定量口径见精度一节的表 3 数据(中位加速 212 倍)。

这张图说明了 BLIS 的完整流水线:请求从到达到完成穿过准入、路由、等待队列、组批、步执行五个环节,KV 缓存的分配与抢占形成实例内回路,而周期性刷新的状态快照把实例状态反馈回路由与准入口,构成集群级回路。

flowchart TD
    A[请求到达] --> B{准入控制}
    B -- 放行 --> C[路由:加权打分选实例]
    B -- 丢弃 --> X[请求被 shed]
    C --> D[实例等待队列<br/>FCFS / 优先级 / SJF]
    D --> E[组批:受 max_seqs 与<br/>max_num_batched_tokens 限制]
    E --> F[KV 缓存块分配]
    F -- 显存不足 --> G[抢占运行中请求<br/>释放块]
    G --> D
    F -- 分配成功 --> H[步执行:调用延迟模型<br/>时钟前进 T_step]
    H --> I{还有 token 要生成?}
    I -- 是 --> E
    I -- 否 --> J[请求完成]
    H -. 周期性快照刷新<br/>队列深度/KV 利用率/批大小 .-> B
    H -.-> C

两个设计决定值得单独说。

一是机制与策略分离。

代码分两层:仿真内核提供事件队列、仿真时钟、按子系统隔离的随机数流和统计收集,它对 LLM 服务的细节一无所知。

领域模块(路由器、调度器、KV 缓存管理器、延迟模型、组批逻辑)承载全部推理服务行为。

新增一条策略只需实现一个模块,不动内核——这是后面「策略进化」案例的工程前提。

二是确定性。

事件堆的键是 (时间戳, 优先级, 序号) 三元组,集群级平局按实例下标小的优先。

随机性按子系统分区,互不干扰彼此的事件次序。

效果是:同一个种子产生字节级一致的输出。

这不是洁癖——只有仿真完全确定,它才能充当优化循环里稳定的适应度函数。

两次运行之间唯一的差异,就是你换的那条策略。

BLIS 的核心创新:只拟合一次的「物理信息」延迟模型

以往的模拟器(Vidur、LLMServingSim)靠 profiling 拿每步耗时:每个新模型、新 GPU、新并行度都要先跑一次真机标定。

BLIS 的延迟模型则把一步的耗时写成闭式函数。

输入全部来自公开资料:模型的 config.json(隐藏维度、层数、头数、中间维度、专家数、量化精度)和 GPU 的官方数据表(峰值算力、HBM 带宽)。

模型分两层。

第一层是 roofline 基函数:在整个前向传播步的粒度上算闭式界。

计算界把运算量除以峰值吞吐,访存界把搬运字节数除以带宽。

每个基函数的单位都是时间:计算项是「运算量 ÷ 每秒运算量」,访存项是「字节数 ÷ 每秒字节数」。

六个基函数按阶段分组,覆盖一步的主要成本:

Tcomppf=FpfP,Tkvpf=MkvpfW,Tweight=MwWT^{\text{pf}}_{\text{comp}} = \frac{F^{\text{pf}}}{P}, \quad T^{\text{pf}}_{\text{kv}} = \frac{M^{\text{pf}}_{\text{kv}}}{W}, \quad T_{\text{weight}} = \frac{M_{\text{w}}}{W} Tcompdc=FdcP,Tkvdc=MkvdcW,Ttp=MtpWnetT^{\text{dc}}_{\text{comp}} = \frac{F^{\text{dc}}}{P}, \quad T^{\text{dc}}_{\text{kv}} = \frac{M^{\text{dc}}_{\text{kv}}}{W}, \quad T_{\text{tp}} = \frac{M_{\text{tp}}}{W_{\text{net}}}

逐项说:

  • 两个 prefill 项覆盖提示词处理,含 KV 缓存写入;
  • 两个 decode 项覆盖逐 token 生成,读累积上下文是带宽大头;
  • 权重加载 TweightT_{\text{weight}} 每步只发生一次,因为一次前向传播服务整个批次;
  • TtpT_{\text{tp}} 是跨卡 all-reduce 通信。

注意力计算按 FlashAttention(一种 IO 感知的精确注意力实现,按显存访问量记账)的口径记账:新 token 在片上 SRAM 内完成注意力,只有历史上下文贡献 HBM 流量。

量化和 GQA(分组查询注意力,多个查询头共享一组 KV 头)不另起炉灶,通过「每参数字节数」和「KV 头数」两个参数进入同一套式子。

第二层负责弥合「峰值界」与「实测耗时」之间的缺口。

真实 kernel 因访存模式、启动开销、同步、调度而跑不到峰值。

传统做法是给 roofline 乘固定的每阶段利用率因子(MFU),但这个缺口随批组成和负载变化,固定因子跟不上。

BLIS 的做法是从端到端轨迹里把缩放学出来:

Tstep= β1aTcomppf+β1bTkvpf+β2aTcompdc+β2bTkvdc+β3Tweight+β4Ttp+β5L+β6B+β7+β8nMoE\begin{aligned} T_{\text{step}} =\ & \beta_{1a} T^{\text{pf}}_{\text{comp}} + \beta_{1b} T^{\text{pf}}_{\text{kv}} + \beta_{2a} T^{\text{dc}}_{\text{comp}} + \beta_{2b} T^{\text{dc}}_{\text{kv}} \\ & + \beta_{3} T_{\text{weight}} + \beta_{4} T_{\text{tp}} + \beta_{5} L + \beta_{6} B + \beta_{7} + \beta_{8} n_{\text{MoE}} \end{aligned}

系数分三类:

  • 缩放因子 β1a\beta_{1a} 到 β4\beta_{4}:无量纲,吸收峰值与实测的差距,全局只拟合一次;
  • 固定开销 β5\beta_5 到 β8\beta_8:roofline 建模不到的部分——每层成本(kernel 启动与归一化)、每步按批内请求数 BB 计费的 β6\beta_6(调度与掩码构造)、每步常数(同步与采样)、每 MoE 层成本;
  • 请求生命周期开销 α0\alpha_0 到 α2\alpha_2:请求摄入、反分词、逐 token 流式输出——它们发生在请求生命周期上,与 β6\beta_6 的每步批内计费不重复。

因为 LL、BB、nMoEn_{\text{MoE}} 是无量纲计数,β5\beta_5 到 β8\beta_8 自带时间单位——上式每一项贡献的都是时间,量纲自洽。

这套分解自带一个「有没有在学真东西」的检验。

按 roofline,prefill 是计算受限、decode 是访存受限。

所以 prefill 访存项 β1b\beta_{1b} 和 decode 计算项 β2a\beta_{2a} 应该没有权重。

拟合结果确实如此——这两项拟合到了零;在四个 roofline 缩放项(β1a\beta_{1a} 到 β2b\beta_{2b})中,只有 prefill 计算项和 decode 访存项保留了非零权重。

拟合复现了 roofline 预言的 regime,而不是把权重摊到所有项上。

这说明扛预测的是物理先验,不是自由参数在硬凑误差。

而且拟合出的开销量级与物理来源对得上。

在 H100 上:每层几十微秒(β5\beta_5)、每请求几微秒(β6\beta_6)、每步约一百微秒(β7\beta_7)、每个交错 MoE 层几百微秒(β8\beta_8)。

因为基函数只依赖公开参数、系数全局共享,一个从未 profile 过的新模型、新 GPU、新 TP 度数不需要任何标定。

把公开参数代入同一组方程、套用现有系数即可。

一个真正全新的架构类别(比如滑动窗口注意力或 DeepSeek 提出的 MLA——多头潜注意力,压缩每 token 的 KV 表示)只需加一个基函数项并重跑内环拟合,已有系数保持有效。

模型怎么拟合:外环改结构、内环调系数

系数从哪来?

训练数据是 15 组真机实验:H100 上的 vLLM 部署。

覆盖 6 个模型家族:Llama-2-7B、Llama-3.1-70B、Llama-4-Scout-17B-16E、Mistral-Nemo-12B、Qwen2.5-7B、Yi-34B。

覆盖三类架构:稠密、GQA、带 FP8 量化的交错 MoE。

TP 度数取 1、2、4。

每组实验记录逐请求的 TTFT、端到端延迟、token 间延迟和吞吐。

刻意之处在于:评估用的模型一个都不在训练集里。

评估模型与同族训练模型参数规模不同——比如用 Llama-2-70B 评估,而训练集里只有 Llama-2-7B。

Mixtral、CodeLlama、Qwen3 三个家族完全不在训练集。

A100 和 L40S 两种 GPU 只在评估中出现。

所以论文报的精度是「分布外泛化」,不是训练域内的插值。

拟合过程是两个嵌套循环。

外环演化模型结构:看上一轮每个实验的残差,识别系统性误差(比如 MoE 被系统性低估),假设一个结构变更(加 MoE 开销项 β8\beta_8、修正某个基函数、拆分一个合并项)。

内环固定结构,搜索使损失最小的系数:

L=RMSE[APE(TTFTi)]+RMSE[APE(E2Ei)]\mathcal{L} = \text{RMSE}\big[\text{APE}(\text{TTFT}_i)\big] + \text{RMSE}\big[\text{APE}(\text{E2E}_i)\big]

其中 APE\text{APE} 是逐实验的绝对百分比误差,RMSE 取在 15 个实验上。

跨实验取 RMSE 是在惩罚方差。

一个在某架构上很准、换个架构就飘的模型,即使平均误差低也会得高损失。

于是系数被压向「在所有训练多样性上都成立」的方向。

内环按搜索空间维度选优化器。

早期用 Optuna 的 TPE(树状 Parzen 估计,一类贝叶斯优化算法)做高维探索(全部系数联合、最多 2000 次试验)。

结构稳定后切 CMA-ES(协方差矩阵自适应进化策略,一类无梯度联合优化算法)做联合精修。

单系数用黄金分割搜索做一维抛光。

后期三者流水线混用:CMA-ES 全局探索、TPE 用先验试验暖启动、黄金分割做最终收敛。

系数始终被约束在物理上有意义的范围内,并从上一外环轮次暖启动。

这张图说明了双环拟合的工作流:外环负责「模型该长什么样」,内环负责「给定结构下系数取多少」,残差分析把两环粘起来,防止内环用扭曲系数掩盖缺失项。

flowchart LR
    subgraph 外环[外环:结构演化]
        A[看上一轮逐实验残差] --> B[识别系统性误差<br/>如 MoE 低估]
        B --> C[假设结构变更<br/>得到新模型形式 f_k]
    end
    subgraph 内环[内环:系数优化]
        D[TPE / CMA-ES / 黄金分割<br/>在物理界内搜索系数]
        E[在 15 组实验上并行跑 BLIS]
        F[算损失 L<br/>RMSE of APE]
        D --> E --> F --> D
    end
    C --> D
    F -- 未收敛 --> A
    F -- 收敛 --> G[输出 f*, α*, β*]

精度实测:中位误差 6.7%,跨 GPU 不重训

先交代口径:本节及后文的实验数字,均为 2026-10-09 提交的论文 v1 所报告;实验的具体执行日期论文未披露。

统计层级也先说清,避免「中位」「平均」打架:每个实验先取该实验全部请求的平均端到端延迟,算出模拟器相对真机的百分比误差(APE);再对全部实验的 APE 取中位数,这就是「中位误差 6.7%」的完整聚合顺序。P90/P99 口径同理,只是把每实验的统计量换成该实验的 P90/P99 延迟。

评估的「地面真值」用 inference-perf 在 vLLM v0.15.1(V1 引擎架构)上采集,覆盖三种 GPU。

作者还量了真机本身的噪声底:同一集群独立重复三次。

结果是:中位端到端延迟的变异系数(CV)在 4–15 rps 的中等到达率下低于 5%,端到端 P90 的 CV 低于 6%。

也就是说,单次真机测量本身就是个稳定参照。

模拟器 6.7% 的中位误差,在量级上已接近这个噪声底(注意:CV 与 MAPE 是不同定义,前者只是测量噪声的尺度参照,不代表模拟器已达到噪声极限)。

精度指标用平均绝对百分比误差:

MAPE=1N∑i=1N∣y^i−yiyi∣×100%\text{MAPE} = \frac{1}{N}\sum_{i=1}^{N}\left|\frac{\hat{y}_i - y_i}{y_i}\right| \times 100\%

其中 y^i\hat{y}_i 是模拟器预测值,yiy_i 是第 ii 个实验的实测值。

36 组实验(涵盖 6 个模型、3 种 GPU、4 类工作负载——是「涵盖」而非全交叉组合,4 类负载只在 H100 的部分模型上出现,A100/L40S 只有基线负载;逐配置清单见论文附录 G)的总账:

  • 端到端延迟:按实验内平均值计算,36 组实验的 MAPE 中位数为 6.7%;按 P90 计算为 7.5%;按 P99 计算为 9.2%;
  • TTFT:均值口径 17.6%、P90 口径 21.3%、P99 口径 29.0%;
  • ITL:均值口径 7.1%(inference-perf 只报平均 ITL,故无尾部分位数)。

注意 TTFT 误差明显大于端到端误差(作者点评:首 token 延迟对调度瞬态更敏感,这类模拟器普遍如此;论文未作此推广)。

横向对比:四家对比工具各自的端到端延迟 MAPE 中位数落在 17% 到 619% 区间——端点分别对应不同工具在其可运行实验集上的成绩,各工具在标定域外会冲到上界;下表「TTFT 误差破万百分比」是 Vidur 在另一指标(TTFT)上的极端值,不与端到端误差混比:

工具延迟模型profiling 粒度能否预测 P90/P99主要短板
LLM-Optimizer(BentoML,本次评估用其估算组件)纯解析不需要不能单请求稳态假设,MoE 上误差约 90%
Vidurprofiling + 随机森林每个 (模型, GPU, TP)能调度器语义停留在 chunked-prefill 之前的 vLLM,TTFT 误差破万百分比
AIConfiguratorprofiling 算子库每种 GPU × 精度不能稳态估计器,算不出排队与批组成演化
LLMServingSim 2.0profiling 内核 + 周期级仿真每个 (模型, GPU, TP)能比真实执行还慢,万级请求跑不动
BLIS解析基函数 + 全局学习系数全局拟合一次能见下文「边界」一节

几个切片值得单独看。

跨硬件泛化:系数只在 H100 上拟合,A100 和 L40S 是纯靠数据表参数的外推。

中位端到端 MAPE:H100 上 5.5%,从未标定过的 A100 上 15.7%、L40S 上 13.3%。

跨 GPU 误差上升但仍在可用区间,而且不需要对每个新 GPU 重新标定。

跨工作负载:四类负载的 token 长度分布来自 ServeGen(从生产轨迹再生成请求形状),到达时序来自 Azure LLM 推理轨迹(论文引用:Microsoft Azure, 2024)。

四类负载的输入/输出 token 规模:

  • general:输入约 550、输出约 250;
  • codegen:输入约 570、输出约 250;
  • roleplay:输入约 750、输出约 250(系统提示词更长);
  • reasoning:输入约 1030、输出约 1450,decode 重度,压 KV 缓存也拖长队列排空尾。

前三类负载下 BLIS 中位端到端误差都在 10% 以内。

reasoning 负载上升到 25%——这是 BLIS 在自身评估的工作负载切片中误差最大的 regime,后面专门说。

消融实验回答「学习组件到底贡献了多少」。

同一组基函数改用文献里的固定 MFU 因子、去掉全部开销项,就是纯 roofline 配置,不需要任何训练。

结果它系统性低估延迟:固定 MFU 抓不到随负载变化的 kernel 启动、显存 bank 冲突、通信停顿开销。

差距在 TTFT 上最刺眼(对数坐标):纯 roofline 在多数模型上 MAPE 超过 100%,而 trained-physics 配置显著更低。

开销相对计算占比越高的模型(CodeLlama-34B、Llama-2-70B,prefill 更长更偏访存),差距越大。

速度与精度的取舍上,各家落点很分散。

LLM-Optimizer 单次评估 0.1 秒但误差大;BLIS 占「低误差、中等速度」区;LLMServingSim 的周期级保真代价是运行时间超过真实执行本身;Vidur 在其可运行的稠密配置上中位误差最高。

实战一:420 个配置的四工具对比搜索(目标:平均 TTFT ≤ 300 ms)替 Llama-2-70B 找出 4 卡方案

精度数字只是入场券。

真正的考验是「搜索出来的配置放到真机上达不达标」。

论文用 Llama-2-70B + H100 + 共享前缀的代码生成负载做了一轮四工具配置搜索对比,并把每个工具的 top-2 推荐部署到真机验证。

选 Llama-2-70B 是因为四个工具都原生支持它,搜索空间能对齐。

部署平台用 llm-d,因为它把准入、路由和 vLLM 服务配置通过统一 API 暴露出来。

搜索空间覆盖:

  • 拓扑:TP ∈ {2, 4, 8},副本数由 GPU 预算推出;
  • 批处理:max_num_seqs、max_num_batched_tokens;
  • 调度、路由、准入与抢占策略。

共 420 个配置,8 个并行 worker。

优化目标有三个:吞吐最大、平均 TTFT 最小、GPU 数最少。

约束是平均 TTFT ≤ 300 ms 且 GPU ≤ 8。

这里用平均 TTFT 而非尾部百分位,是因为 AIConfigurator 和 LLM-Optimizer 只能产出均值估计——取四家的最大公约数。

(论文另有一个更大规模的演示:图 1 的多目标搜索扫了 1,100 个候选配置,联合优化吞吐与 TTFT P99;本节四工具对比用的是其中 420 个配置的子集,因为不是所有工具都能预测尾部百分位。两组数字指称不同实验,不要混。)

BLIS 的 420 个配置里,373 个满足 SLO。

Pareto 前沿收敛到两个工作点:TP=4×1(4 卡)和 TP=8×1(8 卡)。

在中等利用率下,拓扑主导一切。

真机验证在 llm-d 部署上进行:恒定 5 rps 到达、5000 个请求、平均输入/输出 566/247 token。

读表前先统一口径:① 「TP=4×1」记法 = 每实例 TP 度 4 × 副本数 1;② 全表是同一指标——平均 TTFT(首 token 之前的排队加 prefill 时间);③ 失败的配置进入严重排队区,数值以秒计,与其余行的毫秒相差三到四个数量级;④ 完成率 = 30 分钟时限内跑完的请求比例(到达只持续 1000 秒,供应充足的部署远在该时限前排空);⑤ 每个工具的 top-2 推荐共 8 行,全部真机部署验证。逐行看:

工具推荐配置GPU 数预测平均 TTFT实测平均 TTFT完成率达标?
BLISTP=4×1, max_seqs=64446 ms96 ms100%✓
BLISTP=4×1, max_seqs=256446 ms112 ms100%✓
VidurTP=4×2, max_seqs=648188 ms74 ms100%✓
VidurTP=4×2, max_seqs=2568190 ms124 ms100%✓
AIConfiguratorTP=2×2, max_seqs=204188 ms732 ms100%✗
AIConfiguratorTP=2×3, max_seqs=206188 ms132 ms100%✓
LLM-OptimizerTP=2×1, max_seqs=42284 ms约 454 s12%✗ 严重过载
LLM-OptimizerTP=4×1, max_seqs=84284 ms约 464 s48%✗ 严重过载

核心结果是一个可行性分离。

BLIS 找到的 4 卡拓扑(TP=4×1)实测 96/112 ms 达标、100% 完成。

Vidur 因为其调度器不建模 chunked prefill,给不出可行的 4 卡配置,只能用 8 卡。

按论文表 2 题注所引时价(报价日期与计费口径论文未标注):4 卡 12.80 美元/小时、8 卡 25.60 美元/小时,Vidur 的达标方案贵整整一倍。

AIConfigurator 的 4 卡推荐(TP=2×2)实测平均 TTFT 732 ms,超标一倍多。

原因是 TP=2 的 prefill 并行度不够,在 5 rps 下饱和。

它的 6 卡推荐(TP=2×3)实测 132 ms 达标——AIConfigurator 的问题不是不可用,而是在 4 卡预算下给不出可行解。

LLM-Optimizer 的两个推荐严重过载:实测平均 TTFT 约 454–464 秒(论文表 2 原始数字为 453,677 ms 与 463,963 ms)。

注意单位是秒——与同表毫秒级的数字相差三到四个数量级(约数千倍),它指称的是「队列无限增长后请求平均要等多久的平均 TTFT」,不是单步变慢,也不是服务进程崩溃(全文未发生进程级故障,失败形态是严重排队、超时限、低完成率)。

机制是:它自己的搜索推荐 max_num_seqs ≤ 8,但该负载在 5 rps 下的稳态并发约 28 个在途请求。

批上限卡死导致队列无界增长,30 分钟时限内只有 12%–48% 的请求跑完。

这个实验真正分离出来的能力,是「在负载下区分可行与不可行配置」,而不是对可行配置的预测精度。

闭式估算器恰恰缺这个能力——它们看不见队列。

实战二:在仿真里「进化」出两条策略,合并进 llm-d

比「选一个已知配置」更进一步的是「进化出一条新策略」。

论文做了两个案例,流程相同:在仿真里迭代、真机验证、合并进 llm-d 上游。

为什么必须在仿真里做?

真机上一次工作负载评估要 17–42 分钟 GPU 时间。

而策略空间(丢弃曲线形状、饱和信号定义、阈值参数)是组合爆炸的。

BLIS 里同样的评估以秒计。

作者用 Nous(论文引用为 AI-native Systems Research 2025 年发布的开源 agentic 框架;注意与 Nous Research 不是同一主体)驱动进化循环:agent 提出候选实现、BLIS 测量效果、agent 根据结果改进下一个候选。

整个循环 10 轮迭代、60 多次仿真运行,墙钟约 75 分钟。

其中 BLIS 只占了 7.5 分钟,其余是 agent 推理与策略集成的时间。

这个工作流对人类专家同样适用,用 AI agent 只是为了把循环跑起来。

案例一:概率准入器(probabilistic admitter)。

要解决的问题:llm-d 默认准入策略在集群饱和信号越限前全收、越限后把可丢弃级(sheddable)请求整体砍掉。

饱和信号定义为逐实例两种归一化利用率的较大者,再对全集群取平均:

si=max⁡(queue_depthimax_queuei, kv_usedikv_totali),s=1N∑i=1Nsis_i = \max\left(\frac{\text{queue\_depth}_i}{\text{max\_queue}_i},\ \frac{\text{kv\_used}_i}{\text{kv\_total}_i}\right), \quad s = \frac{1}{N}\sum_{i=1}^{N} s_i

其中 si∈[0,1]s_i \in [0,1] 是两个归一化利用率的较大者(满队列或满 KV 时趋近 1),ss 为全集群平均。

二元阈值只在队列已深、KV 接近满时才触发。

所以阈值触发前刚被准入的高优请求,要跟排队中的低优流量抢资源,TTFT 被抬高。

进化目标是在效率约束(每丢弃一个请求换来的延迟收益,即延迟降幅与丢弃请求数之比)下,把高优级延迟相对默认策略降至少 30%。

进化早期暴露了一个张力:激进丢弃在中负载下降延迟明显,但低负载下误杀太多。

agent 发现把两个 regime 分开的是丢弃曲线的形状,而不是信号平滑。

最终策略是:高优请求永远准入,可丢弃请求按如下概率丢弃:

pshed(s)=min⁡(300 s5, 1)p_{\text{shed}}(s) = \min\left(300\, s^{5},\ 1\right)

五次方的形状把丢弃集中在该策略的触发区间附近。

具体地:s=0.12s = 0.12 时丢弃概率约 1%(按式实算约 0.75%,论文表述为约 1%),s=0.25s = 0.25 时约 29%,ss 接近 0.32 时全部丢弃。

注意这里的「饱和附近」是相对该策略的触发区间(约 0.3 量级)而言——ss 是归一化利用率、理论上界为 1,但默认策略的阈值触发时集群实际已深度过载,进化出的策略刻意把响应提前到更低区间。

渐变响应替代了二元悬崖。

仿真里(验证用负载与进化用负载不同——论文口径为 blinded validation workloads,即对进化循环不可见的盲测集,避免对特定流量组合过拟合),该策略把高优级 TTFT 降了 17–37%(均值)和 19–44%(P90),端到端延迟降 17–46%。

真机验证:Qwen3-14B、vLLM、4 张 H100、经 llm-d 路由,负载取自 llm-d 官方基准套件。

在 sheddable 占 70% 的代码补全负载(2K 输入 / 128 输出 token)下,高优级 TTFT 降 74%(均值)和 82%(P90),端到端降 50%——论文注明这组数字合并了两档负载水平:82% 出现在近饱和点,低负载下几乎无收益。

代价是丢弃率上升 6.8 个百分点、吞吐下降 14%——被丢弃的请求若不被丢弃,会在过载下经历很长的排队。

在 critical 占 80% 的交互聊天负载(4K 输入 / 1K 输出 token)下几乎无变化(TTFT 约 2%、端到端约 1%),确认没有误伤。

该策略已作为可配置插件合并进 llm-d 路由器的 requestcontrol 目录(截至 2026-10-20 仓库可见),仿真得来的参数直接作为默认值。

案例二:软反射天花板(soft-reflective ceiling)。

它解决互补问题——运维方想保留所有请求,只在饱和上升时节流低优流量、保护高优延迟。

策略给每个优先级带 i∈{0,…,N−1}i \in \{0, \dots, N-1\}(0 为最高优)一个天花板:

ci(s)=1−i⋅sN−1c_i(s) = 1 - \frac{i \cdot s}{N - 1}

0 带永远不受限(对任意 ss 有 c0=1c_0 = 1)。

当饱和度越过某带的天花板,该带的派发被限速到每 ⌈s/(1−s)⌉\lceil s / (1 - s) \rceil 个调度节拍一次。

边界行为:s∈[0,1)s \in [0,1),ss 越接近 1 限速间隔越长(s=0.5s=0.5 时每 1 拍、s=0.8s=0.8 时每 4 拍);「节拍」指实例调度循环的一次 tick;优先级带数量 NN 由部署的分级数决定。

仿真里(三类负载、接近容量上限),该策略把高优级 TTFT 降 34–94%(均值)、端到端降 32–68%。

真机验证:2 张 H100;论文给出该部署每实例可持续吞吐约 17 req/s 的口径(取延迟-负载曲线的拐点,未按负载类型分别给出——三类负载各自的到达率区间不同:代码生成 4–24 rps、交互聊天 5–40 rps、reasoning 0.2–1.2 rps,过载与否按各负载自身区间理解,不能拿 17 req/s 套 reasoning),critical/sheddable 为 80/20。

结论是收益强烈依赖 regime:

  • 接近拐点的负载下,端到端 P50 降 32–48%(相对无策略基线);
  • 饱和以下是无操作或轻微节流延迟(聊天 +5–6%,0.2 rps 的 reasoning +31%);
  • 重度过载(1.2 rps 的 reasoning)下用 TTFT 换 TPOT(+88% / −32%),端到端反而升 30%。

换句话说,它保护的是「接近拐点」这个最有价值的区间,而不是全天候免费午餐。

该策略同样已合并进 llm-d 路由器的 flowcontrol 目录(截至 2026-10-20 仓库可见)。

两条案例的共同点值得记住:仿真与真机用的是不同负载(刻意盲测),迁移的不是绝对延迟数字,而是相对优劣——仿真选出的这两条策略,在真机验证的若干负载上均优于默认基线。

对策略搜索来说,关键是仿真排序与真机排序一致;本轮两条策略在各自验证负载上做到了这一点(论文同时注明:这是相对策略改进的初步证据,多实例下的绝对预测误差留待未来工作)。

边界与未解问题

论文对失效模式的坦白程度值得加分,主要四条。

第一,reasoning 负载是最难的 regime,中位端到端 MAPE 25%。

机制是:每步的微小计时差异在约 1450 次 decode 迭代上复利式累积。

长 decode 序列占着 KV 缓存、重塑批次准入节奏,模拟的调度次序逐渐漂离真实。

第二,all-reduce 竞争被低估。

解析带宽模型假设每次传输独占全部带宽,并发批次争用 NVLink 时失真。

稠密模型 Llama-3.1-8B 的端到端 MAPE 从 TP=1 的 2.5% 升到 TP=2 的 15.5%。

但这个效应不是随 TP 单调的:Mixtral-8x7B 上提高并行度反而降误差。

Mixtral-8x22B(TP=8,all-reduce、专家分发、显存占用误差叠加)在 general 负载下达 12.5%,对比 Mixtral-8x7B 的 6.0%。

拓扑(同 NVLink 域、同机架、跨机架)与延迟抖动则完全没有建模。

专家并行的 all-to-all 分发也是空白,得作为独立项加入。

第三,覆盖面缺口。

不建模的有:LoRA 多适配器服务、prefill/decode 分离部署(跨池 KV 传输)、投机采样(draft-and-verify 打破「一步一 token」假设)。

KV 缓存压缩会改变 decode 访存项的标度。

状态空间模型与 RWKV(一种线性注意力式的循环架构)用循环状态替代 KV 缓存、MLA 改变每 token 缓存形状,当前的 decode 项都覆盖不了。

非 NVIDIA 加速器(AMD、TPU)完全未测,开销系数大概率要按厂商重拟合。

第四,深饱和区的固有限制。

延迟模型标定在「有载但未深度饱和」区间。

重度过载下,到达或服务时间的微小扰动产生不成比例的排队效应,任何确定性模拟器都无法精确预测。

好在配置搜索与策略进化寻找的恰恰是避开饱和的工作点。

在这个用途上,这个限制是「有界的」。

另有一个工程性提醒:BLIS 镜像的是特定版本 vLLM 与 llm-d 的调度语义(精度实验的 ground truth 用 vLLM v0.15.1;配置搜索的真机验证部署用 v0.22.1)。

目标系统演进时模型要跟着更新。

模块化接口让各组件可以独立更新,但「平台漂移」是长期维护成本,不是一次性工作。

快速上手(按官方文档站 Quick Start 整理,2026-10-20 打开核对;本文未实跑)

BLIS 是开源的:Go 实现、Apache-2.0 协议、仓库 inference-sim/inference-sim(论文对应 v0.9.2 标签,仓库 2025-06-10 创建)。

模型参数经模型目录(blis-catalog,收录各模型的 config.json)与延迟核注册表(blis-registry)读入。

下面命令来自官方文档站当前 Quick Start 页(2026-10-20 逐字核对;前置条件:本机有 Go 工具链与 git,首次运行需联网拉取模型目录与延迟核测试数据;要复现论文口径可固定到 v0.9.2 标签):

git clone https://github.com/inference-sim/inference-sim.git
cd inference-sim
go build -o blis main.go
git clone --branch 0.2.1 --depth 1 https://github.com/inference-sim/blis-catalog.git
git clone --branch v0.1.1 --depth 1 https://github.com/inference-sim/blis-registry.git
export BLIS_CATALOG=$PWD/blis-catalog   # 或每次 run/replay 时传 --catalog
./blis run --scenario llama-3.1-70b-instruct-h200-fp8-vllm-tp4.yaml \
  --scenarios $(go env GOMODCACHE)/github.com/inference-sim/blis-latency-kernel@v0.1.0/testdata/aisimulate \
  --registry $PWD/blis-registry \
  --rate 10 --num-requests 100

工作负载可以用预设类型(chatbot、contentgen、summarization、multidoc),也可以用 YAML 自定义到达过程(Poisson / Gamma / Weibull / 恒定)与 SLO 分级(critical / standard / sheddable 等)。

策略全部可用单个 YAML 文件(—policy-config)配置:路由(round-robin / least-loaded / 加权打分等)、调度(fcfs / priority-fcfs / sjf 等)、抢占(fcfs / priority)、准入(always-admit / token-bucket / tier-shed 等,tier-shed 与本文案例一的准入问题直接相关)。

输出侧有逐请求、逐实例、集群级三档指标,含 TTFT/ITL/E2E 分布、KV 缓存诊断、SLO 达成率和 Jain 公平指数。

用它做自己容量规划的最小闭环(据文档与论文流程整理):

  • 输入:目标模型的 config.json、目标 GPU 的公开规格、负载描述(到达过程 + 输入/输出长度分布)、SLO 目标;
  • 输出:逐配置的 TTFT/ITL/E2E 分布与吞吐、Pareto 前沿、SLO 达成率;
  • 必须真机复验的部分:最终入围的 top 候选(尤其接近饱和区的工作点)、论文明确不覆盖的技术(PD 分离、投机采样、LoRA、非 NVIDIA 硬件)。

对工程读者的三点启示

第一,「先模拟、后上卡」这条路线在本次评估里出现了误差可接受的工具。

6.7% 的中位端到端误差,配上约 200 倍于真实执行的速度(论文表 3 中位 212 倍),意味着「几百个配置 × 多种负载」的穷举,成本从「大量 GPU 压测」降为「CPU 上分钟级跑完」(账单对比是示意,不是可复用预算)。

第二,选工具时先问「它建不建模排队」。

这次对比里最惨烈的失败(LLM-Optimizer 估算组件给出的配置实测平均 TTFT 约 454–464 秒)不是延迟模型不准,而是其估算组件不建模队列。

稳态估算器在其假设内可以很准,但只要问题涉及「负载下的可行性」,排队就是主角。

反过来,如果你只需要一个孤立请求的稳态延迟估计,BLIS 反而是杀鸡用牛刀。

第三,「仿真里进化策略、真机只做验证」这条工作流在本次案例中跑通了闭环。

两条策略(概率准入器、软反射天花板)从仿真迭代到合并进 llm-d 上游,真机验证确认仿真选出的策略在验证负载上优于基线。

对运维团队来说,这意味着策略搜索所需的大部分 GPU 压测被省掉了——但模型维护(平台漂移)与入围候选的真机复验仍然必要。

小结

BLIS 的回答可以压缩成一句话。

把「一次前向传播步要多久」交给一个只拟合一次的物理信息延迟模型,把「负载下系统怎么演化」交给一个确定性的离散事件仿真内核。

前者让泛化不需要逐配置 profiling,后者让排队、抢占、过期快照这些耦合动力学无处遁形。

它的数字经得起拆:

  • 36 组实验,逐实验端到端延迟误差的 MAPE 中位数 6.7%,P90/P99 口径分别为 7.5% / 9.2%;
  • 跨未标定 GPU(A100 / L40S)误差 13–16%;
  • 420 配置搜索里找出实测达标的 4 卡方案(对比工具中 Vidur 的达标推荐要 8 卡、AIConfigurator 需 6 卡、LLM-Optimizer 的推荐严重过载不达标);
  • 两条仿真进化的策略合并进 llm-d,真机兑现收益(高优 TTFT P90 最高降 82%——近饱和点口径、合并两档负载;拐点附近端到端 P50 降 32–48%)。

它的边界同样清楚:reasoning 负载 25% 误差、NVLink 竞争低估、不建模 PD 分离 / 投机采样 / LoRA、只覆盖 NVIDIA。

知道一个工具在哪失效,和知道它在哪有效,是同一篇论文给出的两类信息。

📋 来源与核验记录

本文为一手论文精读,全部关键数字均在写作时回原文核对(arXiv HTML 全文,2026-10-20 核验);代码仓库事实(语言、协议、创建时间、star 数)经 GitHub API 于 2026-10-20 现查。本文无独立实跑 BLIS 的内容;「约 200 倍加速」「6.7% 中位误差」等均为论文自报口径。本文基于公开资料整理,AI 辅助生成,MagicNetWorld 尚未对 BLIS 做独立实测。

  1. 论文(一手):Simulate Before You Scale: High-Fidelity LLM Inference Planning Without GPUs(BLIS),arXiv:2610.14255,2026-10-09 提交,ACM SIGMETRICS 2027 接收,IBM Research(Dipanwita Guhathakurta、Mert Toslali 等 9 人)。https://arxiv.org/abs/2610.14255 (全文 HTML:https://arxiv.org/html/2610.14255v1 ,本轮已逐节精读)
  2. 代码(一手):inference-sim/inference-sim(BLIS 官方实现,Go,Apache-2.0,2025-06-10 创建,论文对应 v0.9.2 标签)。https://github.com/inference-sim/inference-sim 与 https://github.com/inference-sim/inference-sim/releases/tag/v0.9.2 (本轮已打开,HTTP 200)
  3. 官方文档(一手):BLIS 文档站(快速上手、策略与工作负载 DSL 说明)。https://inference-sim.github.io/inference-sim/latest (本轮已打开,HTTP 200)
  4. 部署平台(一手):llm-d/llm-d(分布式 LLM 服务开源平台,策略合并的上游)。https://github.com/llm-d/llm-d (本轮经 GitHub API 核验)
  5. 策略落地证据(一手):llm-d 路由器中的两个插件目录——概率准入器 https://github.com/llm-d/llm-d-router/tree/main/pkg/epp/framework/plugins/requestcontrol/admitter/probabilisticadmitter 与软反射天花板 https://github.com/llm-d/llm-d-router/tree/main/pkg/epp/framework/plugins/flowcontrol/usagelimits/softreflectiveceiling (本轮均已打开,HTTP 200;即论文脚注 2、3 所给路径)

本文自行推导说明:文中「秒级与毫秒级相差三到四个数量级(约数千倍)」的换算为基于论文表 2 原始数字(453,677 ms / 463,963 ms)的直接算术;「4 卡 12.80 对 8 卡 25.60 美元/小时、相差一倍」直接出自论文表 2 题注(报价日期论文未标注)。除此之外无自行推导的数字。