附录 A 公式、速查与路线
一张表放完所有公式
| 要算的 | 公式 | 单位注意 |
|---|---|---|
| 权重 | 参数量 × 每参数字节 | FP16 是 2,INT8 是 1,INT4 是 0.5 |
| 一条请求的缓存 | 2 × L × H_kv × d_head × T × bytes | 不含 batch |
| 并发上限 | ⌊(可用显存 − 权重 − 余量) / 单条缓存⌋ | 三个数先统一成 GiB |
| decode 每步读取 | 权重 + B × 单条缓存 | 权重只读一次 |
| 每步耗时 | 读取字节 ÷ 显存带宽 | 理想值,实际更高 |
| 算术强度 | 运算量 ÷ 读取字节 | 与硬件平衡点比 |
| 硬件平衡点 | 峰值算力 ÷ 显存带宽 | A100 约 153 FLOP/字节 |
| TPOT | (端到端 − TTFT) ÷ (输出数 − 1) | 首字不算 |
| goodput | 达标请求数 ÷ 总时间 | 超时的不算 |
| 每 token 成本 | GPU 小时 × 单价 ÷ 有效 token | 口径要一起报 |
十秒钟判断
拿到一个新场景,按这个顺序问。
显存够不够:权重 + 单条缓存 × 并发,超了就是容量问题。
一条请求的 prefill 要多久:运算量除以算力。超过首字容忍度,就是算力问题。
decode 每步读多少:权重加全部缓存,除以带宽。算出来接近你的 TPOT 目标,就是带宽问题。
三个都没超,但用户还在等:看队列,是调度问题。
符号表
| 符号 | 意思 | 常见取值 |
|---|---|---|
| L | Transformer 层数 | 7B 约 32,70B 约 80 |
| H_kv | KV 头数 | MHA 等于 Q 头数,GQA 常见 8 |
| d_head | 每头维度 | 128 |
| T | 输入加已生成的 token 数 | 8K = 8192 |
| B | 并发或 batch | 1 到几十 |
五个数的一句话定义
TTFT:等多久才看见第一个字。
TPOT:之后每个字多快。
P99:最慢的那一 percent 有多慢。
goodput:达标的产能有多少。
每 token 成本:产出一个有效 token 花多少钱。
术语去哪查
全书术语在 GLOSSARY.md,按首次出现的章节排。最容易混的四组:
prefill 与 decode,是同一模型的两段,不是两个模型。
KV cache 与权重,一个随并发涨,一个固定。
吞吐与 goodput,一个算所有产出,一个只算达标的。
分页与前缀缓存,前者解决分配,后者解决重复。
动手做什么
PROJECTS.md 有四级任务,从"能跑"到"能讲"。
L1 用 llama.cpp 起一个模型,跑通流式。L2 改并发参数,验证第 3 章的预测。L3 给定场景写一份选型结论。L4 在自己的真实负载上复现一次完整的五步。
做完 L1 和 L2,这本书的公式才算你的。
还要往哪走
训练侧:激活值、优化器状态、梯度同步、并行策略。瓶颈结构和推理完全不同。
kernel 层:FlashAttention、算子融合、自定义 CUDA。知道它们改变什么就够,实现是另一门手艺。
多机:拓扑、NCCL、张量并行与流水线并行。单卡算不过来的模型,最终都要走到这里。
前沿方向:投机解码、MoE 路由、Agent 场景的沙箱与工具调用。
这本书的边界
所有数字都是纸面手算,没有在你的硬件上实测。
引擎的具体行为和默认参数随版本变化,书里标了 B 级的地方,用之前按当期文档核一遍。
不写价格。成本结构写了,具体单价每天在变。
不写训练。这本书只到推理侧为止,训练是另一套账。
怎么继续迭代这本书
每章末尾的练习和 WORKBOOK.md 是同一套题。做题时把卡住的地方写进 FEEDBACK.md,下一轮改书就从那里开始。
改完记得跑:python tools/build.py 生成页面,python tools/check.py 过文风闸门。
两个都过了,这一版才算交付。