第 10 章 综合案例:七 B、八 K、二十个人
先修:第 1–9 章 · 深度:L2 · 预计阅读:40 分钟
一句话:前面九章是零件,这一章把它们装成一次能交出去的决定。
回到第一天
二十个同事、8K 合同、一张 80GB 卡、一个 7B 模型。首字慢、有人失败、显存拉满。
这次不慌,按顺序走五步。
第一步:算账
权重 13 GiB。一条 8K 请求的缓存 4 GiB。余量留 3 GiB。
72 − 13 − 3 = 56 GiB
56 / 4 = 14 条
二十条请求,十四条能同时跑,六条排队。
第二步:判断先撞哪堵墙
看三个迹象。
显存利用率贴顶、waiting 一直涨,是容量。首字慢但显存有余,是算力或者排队。出字慢、GPU 利用率不高,是带宽。
这个案例里,二十条对十四条,容量和排队同时到。要先解决"装不下",再谈"算得快"。
第三步:四条路,各自牺牲什么
| 方案 | 能到几条 | 牺牲 | 什么时候选 |
|---|---|---|---|
| 加一张卡 | 28 | 钱 | 长期跑、预算批得下来 |
| 权重 INT4 | 3 | 精度、prefill 变慢 | 卡不能加,但能接受质量下降 |
| 换成 8 个 KV 头的模型 | 56 | 换模型、重新验证 | 模型可选、参数差不多 |
| 分页 + 连续批处理 | 14 但浪费少 | 实现复杂度 | 已经在上引擎,且长度不齐 |
注意第二行和第三行不是一回事。量化是同一模型压小,换模型是换一个缓存结构更省的架构。后者收益更大,因为缓存是按头数线性缩的,而权重几乎没变。
还有第五种:降上下文。8K 砍到 2K,一条 1 GiB,能到 28 条。如果业务上可行,这是最便宜的方案。
第四步:定参数
按 14 条定,不要按 20 条定。
同时跑 20 条,前 14 条正常,后 6 条排队到超时。用户看到的是随机失败,比"明确地慢"更糟。
max_num_seqs 设 14。max_num_batched_tokens 按切块需求和 batch 一起定,prefill 块别大到一个请求就能独占一步。
前缀如果重复,打开前缀缓存。二十个人问同一份合同,这一项能省下相当一部分 prefill。
第五步:压测
长度分布按真实情况:两成 8K,八成两百字。到达方式用泊松,持续十分钟,并发从 4 逐步加到 20。
记录五个数:TTFT 的 P50 和 P99、TPOT 的 P50 和 P99、goodput、实测 running batch。
预测是先写好的:加到 14 时吞吐接近线性,超过 14 后 goodput 不再涨,P99 开始陡增。
如果实测不是这样,说明哪一步的假设错了——通常是长度分布,或者缓存命中率。
结论长什么样
一份能交出去的结论,包含四句话。
在 80GB 卡、7B、8K、二十并发的条件下,容量上限是 14 条,超出部分排队。
先撞的是容量,不是算力;换更强的卡不会让排队消失,只会让单条更快。
四条路里,分页加连续批处理能消除浪费但抬不高上限;量化能把上限抬到 3 条的水平但降精度;换 GQA 模型收益最大,代价是重新验证。
建议先压测确认,再决定加卡还是换模型;在此之前不要动 batch 参数。
这本书没讲的部分
训练侧的账完全不同:激活值、优化器状态、梯度同步,瓶颈在通信和显存带宽的配比。
kernel 层的东西只提到"影响什么",没有实现。FlashAttention 这类工作把注意力拆成块,减少显存读写,属于另一层。
多机多卡的拓扑、NCCL、并行策略,是训练 infra 的主战场,推理侧只在张量并行时碰到一点。
这些不在本书范围,但读到这里,你已经有一套可以套用的问法:先算账,再定位墙,然后才谈方案。
经验:结论要带条件
"能扛二十并发"是一句没有信息量的话。
"在 8K 输入、512 输出、TTFT 小于 2 秒的条件下,一张 80GB 卡能扛 14 并发"才是结论。
条件不写全,结论就会在下一次评审会上被一句话推翻。
练习
六道题,先闭卷,再翻 ANSWERS.md。
- 把上文的模型换成 8 个 KV 头的版本,重算 80GB 卡的并发上限。
- 二十条请求全是两百字,账怎么变?
- 为什么"加一张卡"和"换成 GQA 模型"对并发的影响不一样?
- 找错:"按 20 条配参数,反正多了会排队。"
- 写出一份包含四条 SLO 的验收清单。
- 完整跑一次:算账、定参数、压测、写结论,四步都要有数字。
这一章就记一句
同一个案例,五步走完:算账得 14 条,判断先撞容量,四条路各有牺牲,参数按 14 定,压测验证预测。
真只记一句:结论必须带条件,条件不写全,下次评审会就会被推翻。
这本书到这儿结束。接下来是你自己的机器和负载:先用 PROJECTS.md 的 L1 跑通,再用 L2 验证第 3 章的预测。