适用读者:要做容量规划、SLO 设计,或解释"为什么平均负载够、用户还是等很久"的人。
前置:S23-J09、J10(KV 与全模型资源)。
覆盖旧文:A-4336 §3.1–§3.3(持续到达的负载 + 多轮与 Agent + 多模态与实时交互,219 点)→ 219 点。
扩展点:E-S23-026(三个时间指标与 p95 口径)、E-S23-027(状态占用 = byte·s:等待也是容量问题)、E-S23-028(前缀复用省重算、不省注意力)、E-S23-029(多模态的三段数据量:文件 / EC / KV)。
上一篇:S23-J10 · 条件计算、网络形状与模型矩阵
下一篇:S23-J12 · 训练负载、RL 与预算。
1. 一句话结论
"平均负载够不够"是个假问题。 真正决定体验的是三件事:请求到达的时间分布、阶段组成(长输入 vs 长输出),以及等待期间占着的状态。三者任何一个失衡,都会在平均值看起来健康时把 p95 打穿。
出处:AI Infra 教材 §3.1–§3.3(
id 4336)。
一次请求 = 1 次 prefill + (G−1) 次 decode
负载 = 到达时间 × 输入长度 × 输出长度 的联合分布
2. 三个时间指标(E-S23-026)
在时间线上标三个事件:请求到达 t_a、首个 token 返回 t_1、最后一个 token 返回 t_G:
TTFT = t_1 − t_a (多久开始回应)
T_request = t_G − t_a (整件事做完要多久)
T_token = (t_G − t_1)/(G−1) (G>1,输出节奏)
| 指标 | 包含什么 | 少算了什么 |
|---|---|---|
| TTFT | 排队 + 输入准备 + prefill + 首 token 回传 | 后续生成 |
| T_request | 全程 | — |
| T_token | 生成阶段的平均间隔 | 首响应、排队 |
判据:缩短某一段,只会改变包含这段的指标。 减少排队会改善 TTFT,但不会让已经开始生成后的 token 间隔变短。
2.1 reasoning 模型多一个观察点
思考 token 在"用户看到答案"之前就产生了:内部生成、用户可见输出、任务完成是三个不同的时间点。用 TTFT 衡量 reasoning 模型,会把"思考耗时"藏进"首响应"里——所以原文建议另记"首个有用输出"。
2.2 p95 怎么算(最近秩法)
把 n 个观测从小到大排序,取第 ⌈0.95n⌉ 个
4 条请求 → p95 = 最大值(第 4 个)
480 条 → p95 = 第 456 个
判据:只看平均值会掩盖慢请求。 分别对"完成、排队、首响应"排序,才能看出长等待发生在哪一段。
3. 等待也是容量问题(E-S23-027)
状态驻留得越久,同样容量能同时服务的任务越少。原文用"面积"来度量:
A_M = ∫ M(t) dt (单位 byte·s)
1 GiB 状态占用 10 秒 = 10 GiB·s
稳定到达(λ 个/秒、每任务 M₀ 字节、平均等待 τ 秒)时,仅等待任务的平均占用约:
λ · M₀ · τ
判据:工具调用、人工审核、排队等待,都是"状态挂着不干活"的时间,按 byte·s 计费。 这一段不写在延迟里,却写在容量账单里。
4. 到达分布决定积压(例题 3-1)
场景:decode 由两张 RTX PRO 6000 Blackwell 承担,两分钟内共 480 条请求(平均 4 条/秒),两类:
| 类型 | 输入 | 输出 |
|---|---|---|
| 长输入类 | 8,192 | 256 |
| 长输出类 | 1,024 | 2,048 |
三种时间窗(总量相同):
| 时间窗 | 新输入 token/s | 后续 decode 步/s |
|---|---|---|
| 均匀混合(1:1) | 18,432 | 4,604 |
| 时段变化·前一分钟(9:1) | 29,900.8 | 1,736.8 |
| 时段变化·后一分钟(1:9) | 6,963.2 | 7,471.2 |
结论:总量相同,阶段需求完全不同。 前一分钟的输入量是均匀混合的 1.6 倍,后一分钟的 decode 步数是 1.6 倍——pipeline 的瓶颈在两个时段之间来回切换。
判据:负载描述必须保留到达时间 × 输入长度 × 输出长度的联合分布,只记总量会丢掉"什么时候需要什么资源"。
5. 多轮与 Agent:前缀复用(E-S23-028)
第 i 轮:输入长度 I_i,可复用前缀 K_i
本次需处理:P_i = I_i − K_i 已有上下文:S_i = K_i
原文算例(4 轮代码修复任务):
| 项 | 数值 |
|---|---|
| 四轮累计输入 | 5,297 token |
| 命中缓存 | 4,480 token |
| 未命中(真正重算) | 817 token |
| 每轮全量重算的 prefill | 76.196 TFLOPs |
| 复用前缀后 | 11.976 TFLOPs |
但缓存没有把旧上下文从后续计算里删掉:P 变小让投影/FFN 只处理新增 token,注意力仍要让新查询访问完整前缀。
5.1 改动位置决定能复用多少
| 编辑方式 | 可复用前缀 |
|---|---|
| 末尾追加 100 token | 全部原有前缀 + 100 行新输入 |
| 改动 2,000 个 token 中的第 501 个 | 只剩前 500 个(其后的表示全部失效) |
判据:缓存收益不取决于"改了多少字",而取决于"改在哪里"。 这也是上下文工程(追加 vs 摘要替换)会直接影响成本的系统原因。
5.2 增加生成计算是否值得
c = 每次尝试平均成本,p = 成功率,同策略重复尝试的期望次数 1/p:
每个成功任务的期望成本 ≈ c / p
三种加法:延长思考(增串行时间与状态)、多份回答再选(增计算与验证)、按难度分配(要决定何时停止)。
判据:判断标准是"每个成功任务成本",不是"单次调用成本"。 便宜但经常失败的配置,总账可能更贵。
6. 多模态:三段数据量(E-S23-029)
一次视觉问答的基本依赖:E(视觉编码)→ P(语言 prefill)→ D(decode)。图片大小影响 E 的工作量,编码后的视觉 token 数影响 P 的工作量。
6.1 视觉 token 数
n_v = H_img · W_img / (p_patch² · r²)
p_patch = 单个 patch 边长;r = 每边合并的 patch 数
Qwen3-VL-4B 实例:640×640 图片、16×16 patch → 1,600 个 patch;2×2 合并 → 400 个视觉 token;特征宽度 2,560。
| 阶段 | 数据量 |
|---|---|
| 原始压缩文件 | 0.8 MB |
| 视觉编码输出(单份) | 400×2560×2 = 2,048,000 B ≈ 1.95 MiB |
| 完整 EC(四份拼接,DeepStack) | [400,10240] = 8,192,000 B = 7.8125 MiB |
| 进入语言模型后的 KV(144 KiB/token) | 56.25 MiB |
判据:同一张图在三个阶段有三个数量级不同的数据量。 说"多模态很贵"必须指明是哪一段:编码、EC 传输,还是 KV 驻留。
6.2 编码缓存 vs 语言 KV
| 缓存 | 存什么 | 生命周期 | 本例大小 |
|---|---|---|---|
| EC(encoder cache) | 视觉编码器输出 | 同一张图可跨请求复用 | 7.8125 MiB |
| KV | 语言主干每层 K/V | 随请求存活 | 56.25 MiB |
视觉编码的矩阵运算量约 1.310 TFLOPs(本配置),图片解码与缩放发生在编码之前。
7. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
| 三指标相互独立 | 各阶段可分别计时 | 端到端流式(语音)需再加播放与缓冲 |
| p95 用最近秩法 | 观测数足够 | 观测太少 → p95 等于最大值 |
| 前缀复用省 76→12 TFLOPs | 缓存命中且前缀不变 | 改到早期位置 → 命中率骤降 |
| 视觉 token 数按 patch 公式 | 固定 patch 与合并倍数 | 动态分辨率 → 按实际切分算 |
8. 常见误区
| 误区 | 纠正 |
|---|---|
| "平均 QPS 够就没问题" | 阶段组成与到达时间会让瓶颈来回切换 |
| 用 TTFT 评价 reasoning 模型 | 思考 token 藏在首响应里,要另记"首个有用输出" |
| 认为缓存命中就不用读旧上下文 | 注意力仍要访问完整前缀(只是不重算投影/FFN) |
| 改上下文只算"改了多少字" | 改的位置决定后缀是否全部失效 |
| 多模态只算一次编码成本 | EC 与 KV 是两笔不同的账 |
9. 自测
- 480 条请求,p95 取第几个?4 条请求呢?
- 1 GiB 状态挂 10 秒、λ=2 条/秒、τ=5 秒时,等待占用约多少?
- 四轮任务每轮全量重算 76.196 TFLOPs,命中 4,480/5,297 token 后降到 11.976——省下的是哪部分计算?没省的是哪部分?
- 640×640 图、16 patch、2×2 合并,视觉 token 多少?完整 EC 多大?
答案
- 第 456 个;4 条取最大值(第 4 个)。
λ·M₀·τ = 2×1 GiB×5 = 10 GiB(稳态平均占用)。- 省下投影与 FFN 的重复计算;没省注意力对完整前缀的访问与 KV 读取。
- 400 个视觉 token;
[400,10240]×2 B = 7.8125 MiB。
10. 下一篇
S23-J12 · 训练负载、RL 与预算 —— 从推理转到训练:一次训练步要算多少、状态怎么分片、checkpoint 与故障恢复的代价,以及把"完成期限"倒推成硬件配置。