LLM Inference Lab
Q & A

学习过程中问过的原理问题

部署和训练的过程中冒出来的问题,每个答案都尽量对上这台 8 × A800 上测到的真实数字。可以和原理实验台对照着看:实验台负责拨动参数看现象,这一页负责把算式一步步写出来。

decode 每步多久312 TFLOPS批处理与 MoETP4 × PP2宽度相当于几 B从零训练的天花板

1. decode 每一步要多久:理论下限和实测

为什么生成一个 token 要把权重读一遍

模型每一层的核心运算是矩阵乘向量:权重矩阵 W 乘以当前 token 的向量 x。W 存在显存里,计算核心要用它,就得把每个数从显存搬到核心里。生成一个 token 时 x 只有一个,所以每个权重恰好被用一次。结论是:每生成一个 token,所有参与计算的权重都要从显存完整读一遍。

代入 GLM-5.3-Flash 的四个数字

数字取值来历
参与计算的参数18B它是 MoE,总共 320B,路由器每个 token 只挑几个专家,加上注意力部分约 18B,其余 302B 这一步不碰
每个参数的字节数1FP8 权重,8 位就是 1 字节;BF16 是 2 字节
同时分担的卡数4张量并行把每个矩阵切成 4 片,4 张卡同时各读各的
显存带宽2 TB/sA800 的 HBM2e,约每秒 2000 GB
每步要读的总字节 = 18 × 10⁹ 个参数 × 1 字节 = 18 GB
每张卡要读的字节 = 18 GB ÷ 4                = 4.5 GB
每步时间下限     = 4.5 GB ÷ 2000 GB/s       ≈ 2.3 ms

同一步的计算量   = 2 × 18 × 10⁹             = 3.6 × 10¹⁰ 次浮点运算
4 张卡的峰值算力 = 4 × 312 × 10¹²           = 1.25 × 10¹⁵ 次/秒
计算耗时         ≈ 0.03 ms

算只要 0.03 毫秒,搬数据要 2.3 毫秒,差了近 80 倍。计算核心绝大部分时间在等数据,所以 decode 的速度由显存带宽决定,这就是"带宽墙"。

"理论下限"和实测差多少

理论下限的意思是:假设显存带宽被 100% 用满,除了搬权重没有任何别的耗时,最快能多快。它只由硬件规格和模型大小决定,是物理上不可能突破的地板,不是对实际速度的预测。实际耗时可以拆成两部分:

实测每步时间 = 搬权重的时间(公式算的这部分) + 固定开销
模型与部署每卡每步读取理论下限单流实测 TPOT固定开销理论占实测
Qwen3.8-27B,稠密,BF16,2 卡27B × 2 ÷ 2 = 27 GB13.5 ms20.6 ms7.1 ms65%
Qwen3.6-35B-A3B,激活 3B,BF16,2 卡3B × 2 ÷ 2 = 3 GB1.5 ms5.8 ms4.3 ms26%
GLM-5.3-Flash,激活 18B,FP8,TP4 × PP218B × 1 ÷ 4 = 4.5 GB2.3 ms20.1 ms17.8 ms11%

固定开销和模型大小关系不大:每步几千个内核启动、每层一次跨卡 all-reduce、流水线两段之间的交接、采样和调度。Qwen3.8 搬权重要 13.5 ms,固定开销只是配角,所以实测和理论最接近。Qwen3.6 搬权重只要 1.5 ms,固定开销反而成了主角。GLM 在 Ampere 上走的是 Triton 回退内核,稀疏注意力和 FP8 都没有原生硬件支持,固定开销最大。CUDA Graph、内核融合、原生 FP8 硬件要解决的,正是这部分差距。

理论下限还漏掉了 KV cache:每步还要把历史 token 的 K、V 读一遍,上下文越长读得越多。长上下文时它会变成不能忽略的一项,这也是 GLM 用 MLA 把 KV 压小的原因,见实验台第 3 站。

2. A800 的 312 TFLOPS 是怎么算出来的

312 TFLOPS 是单张卡 BF16 的峰值算力,是 NVIDIA 给 A100 标的规格。A800 的计算部分和 A100 完全相同,只把 NVLink 从 600 GB/s 砍到了 400 GB/s。这个数不是测出来的,是从芯片结构直接乘出来的:

108 个 SM × 每个 4 个 Tensor Core × 每周期 256 次乘加 × 每次乘加 2 次运算 × 1.41 × 10⁹ 周期/秒
= 221,184 × 1.41 × 10⁹
≈ 312 × 10¹² 次/秒

1.41 GHz 就是在这台机器上用 nvidia-smi 查到的最高 SM 频率。用同样的方法验证 FP32 规格:普通计算核心 6912 个,每周期各做 1 次乘加,6912 × 2 × 1.41 × 10⁹ ≈ 19.5 TFLOPS,正好是官方标称值。312 是它的 16 倍,这就是 Tensor Core 的价值。

精度峰值走哪种电路
FP3219.5 TFLOPS普通核心
TF32156 TFLOPSTensor Core
FP16 / BF16312 TFLOPSTensor Core
INT8624 TOPSTensor Core
FP8不支持Ampere 没有这个模式,FP8 权重只能先解成 16 位再算

峰值的前提是做大块稠密矩阵乘、Tensor Core 满载。实际能用掉的比例叫 MFU:这台机器上训练 d32 时 MFU 是 65%,相当于每张卡持续 200 TFLOPS 左右。作为对比,H100 的 BF16 峰值是 989 TFLOPS,并且有原生 FP8。

3. 批处理为什么能共享权重,MoE 为什么是例外

权重就是模型本身。训练结束后这几百亿个数就固定了,不管谁来问、问什么,走的都是同一套矩阵。不同请求之间不一样的只有三样:输入的 token、每层算出来的中间向量、各自的 KV cache。

单条请求:y = W · x       x 是这条请求当前 token 的向量
16 条请求:Y = W · X       X 的 16 列分别是 16 条请求各自的向量

W 的每个数只从显存搬一次,到了计算核心后分别和 16 个不同的向量相乘。搬运量几乎不变,计算量变成 16 倍,而计算本来就闲着,所以总时间几乎不变。这就是并发越高总吞吐越高的原因。

MoE 是例外。稠密模型里所有 token 用的都是全部权重;MoE 里每个 token 只挑几个专家,16 个 token 挑的专家各不相同,合起来要读的专家比单个 token 多得多。并发越高,一步里被激活的专家越多,要搬的权重越多。实测正好体现了这一点:

模型并发 1 的 TPOT并发 32 的 TPOT变慢倍数
Qwen3.8-27B,稠密20.6 ms28.6 ms1.4 倍
Qwen3.6-35B-A3B,MoE5.8 ms17.1 ms2.9 倍
GLM-5.3-Flash,MoE20.1 ms49.0 ms2.4 倍

数据来自评测报告的压测矩阵。

4. TP4 × PP2 是什么意思

TP 和 PP 是把一个模型切到多张卡上的两种切法,后面的数字是切成几份。

            第 1 段:第 1 到 24 层              第 2 段:第 25 到 45 层
          ┌────────────────────────┐        ┌────────────────────────┐
 token →  │ GPU0  GPU1  GPU2  GPU3 │  ───→  │ GPU4  GPU5  GPU6  GPU7 │ → 下一个 token
          │ 每层矩阵切 4 片,       │ 只传一  │ 每层矩阵切 4 片,       │
          │ 4 卡同时算,每层合一次  │ 个向量  │ 4 卡同时算,每层合一次  │
          └────────────────────────┘        └────────────────────────┘
                    TP4                                TP4

306 GB 的权重就这样分到了 8 张卡上,每张约 38 GB,和启动日志里的数字一致。

张量并行 TP流水线并行 PP
怎么切每一层的矩阵切开层的先后顺序切开
卡之间怎么配合同时算同一层一段算完交给下一段
通信每层都要合并一次,很频繁,靠 NVLink只在段与段之间传一次
缺点卡越多通信越碎,收益递减一个 token 在第一段时第二段空等,叫气泡

GLM 没有用 TP8 也没有用 PP8,而是各取一半:A800 的 NVLink 被砍到 400 GB/s,TP 只切到 4 来控制通信开销;PP 只分 2 段来控制气泡。两个 Qwen 模型小,只用了 TP2。

PP 不会让单个 token 变快。 一个 token 要依次经过两段:第一段的 4 张卡各读约 2.25 GB,然后第二段的 4 张卡各读约 2.25 GB。两段先后发生,时间相加,效果等同于 4 张卡各读 4.5 GB,所以第 1 节的算式按 4 张卡算。PP 增加的是能放下的模型大小,不是单个 token 的速度。实验台第 4 站有这个布局的 3D 动画。

5. "层数 × 宽度"里的宽度是什么

宽度是每个 token 在模型内部用多少个数来表示,也叫隐藏维度,代码里叫 n_embd。d12 里每个 token 是一个 768 维的向量,d24 是 1536 维,d32 是 2048 维。这个向量从第一层一路传到最后一层,长度始终不变,每一层都读它、改它,再传给下一层。层数是 token 要经过多少道加工,宽度是每道加工时手里的信息有多少维。

宽度决定了几乎所有参数的大小。每层里,注意力的 Q、K、V、输出四个投影矩阵各是宽度 × 宽度;MLP 先把向量放大到 4 倍宽再压回来,两个矩阵相当于 8 个宽度 × 宽度:

每层参数     ≈ 12 × 宽度²
全部矩阵参数 ≈ 12 × 层数 × 宽度²
模型层数宽度公式算出训练日志里的矩阵参数
d121276884,934,65684,935,088
d24241536679,477,248679,478,976
d323220481,610,612,7361,610,615,808

词嵌入表也一样,是词表大小 × 宽度:32768 × 768 = 25,165,824,正好是 d12 日志里的 wte。注意力头数是宽度 ÷ 128,所以 d12、d24、d32 分别有 6、12、16 个头。

参数随宽度的平方增长:层数相同时宽度翻倍,参数变成 4 倍。d32 是 32 层 × 2048,矩阵参数 16 亿;Llama-2-7B 也是 32 层,宽度 4096,参数约 65 亿。nanochat 不单独设宽度,固定取层数的 64 倍,这就是它"只用层数一个旋钮"的原因。

6. d12、d24、d32 相当于几 B 的模型

模型层数 × 宽度总参数其中查找表参与矩阵乘的参数形状最接近
d1212 × 7680.29B0.15B0.11BGPT-2 small,0.12B
d2424 × 15361.38B0.60B0.73BGPT-2 large,0.77B
d3232 × 20482.82B1.07B1.68BGPT-2 XL,1.56B

nanochat 在注意力里加了一种叫 value embedding 的结构:每个 token 额外查一张表,把结果加到注意力的 V 上。查表只占显存、几乎不花计算,却被算进总参数,占了三分之一到一半。scaling law 的惯例只数参与矩阵乘的参数,训练耗时和推理速度也跟着这个数走,按这个算三个模型是 0.1B、0.7B、1.7B。

按能力折算,可以用评测数据包里自带的四个 GPT-2 的 CORE 分数作参照:

模型CORE折算
GPT-2 small,0.12B0.114
d120.145约 0.2B 的 GPT-2,在 small 和 medium 之间
GPT-2 medium,0.36B0.185
GPT-2 large,0.77B0.215
d240.249约 1.4B,基本等于 GPT-2 XL
GPT-2 XL,1.56B0.257
d320.346超过最大的 GPT-2;沿 GPT-2 家族的趋势粗略外推,约 7B

d24 只用一半的计算参数就追平了 GPT-2 XL,靠的是更新的架构、优化器和更好的训练数据。

这个换算只在和 2019 年的 GPT-2 比时成立。和现在同样大小的模型比不了:Llama-3.2-1B 训练了 9 万亿 token,Qwen3-1.7B 训练了 36 万亿,d32 只训练了 134 亿,少了将近三个数量级。参数量说明模型有多大、跑起来有多贵,能力主要取决于训练数据量。

7. 这 8 张卡从零训练的天花板

账的基础是实测:8 张卡在 MFU 63% 左右时,持续算力约 1.5 PFLOP/s,一天约 1.3 × 10²⁰ 次浮点运算。训练的计算量约等于 6 × 参数量 × 训练 token 数。

规模参数训练 token计算量8 卡耗时CORE
d24,已完成14 亿58 亿2.8 × 10¹⁹5.1 小时0.249 实测
d32,已完成28 亿134 亿1.4 × 10²⁰约 1 天,实际 4 卡跑了 49 小时0.346 实测
d40,估算约 50 亿约 260 亿5.2 × 10²⁰约 4 天按 d24 到 d32 的实际涨幅外推,约 0.40
满负荷一个月3.9 × 10²¹30 天
Llama-3.2-1B,202412 亿9 万亿约 5 × 10²²约 1.1 年
Qwen3-1.7B,202517 亿36 万亿约 3.7 × 10²³约 7.5 年

两个结论。从零训练,这台机器的合理上限是 2020 到 2022 年间几十亿参数基础模型的水平,d32 已经到了"值得做"的边界,d40 是极限尝试。要得到真正能用的现代模型,正确的路径是在现成开源模型上做后训练:LoRA、SFT、偏好优化、强化学习,几张卡几小时就够。训练实录最后一节列了这些手段。