Skip to content

9.5 性能建模与分析

在大模型的研发和部署过程中,"这个模型有多大?训练需要多少显存?推理一张卡能不能放下?"是工程师每天都要面对的问题。回答这些问题不需要实际跑一遍实验——只要掌握几组关键公式,拿出纸笔就能算出相当准确的估计。本节将系统地建立 Decoder-Only Transformer 的性能模型,涵盖参数量、计算量、训练显存和推理显存四个维度,并以 LLaMA-7B 为案例进行完整的手算验证。


9.5.1 浮点运算量(FLOPs)与 6PD 法则

FLOPs 与 FLOPS 的区别。 在深度学习语境中,这两个术语经常被混用,但含义截然不同:

  • FLOPs(Floating-point Operations,注意小写 s):指完成某个计算任务所需的浮点运算总次数,是一个无量纲的计数值。例如"训练 GPT-3 大约需要 3.14×1023 FLOPs"。
  • FLOPS(Floating-point Operations Per Second,大写 S):指硬件每秒能执行的浮点运算次数,是衡量计算速率的指标。例如"H100 的 BF16 理论峰值约为 989 TFLOPS"。

矩阵乘法的 FLOPs。 Transformer 中绝大多数计算量来自矩阵乘法。对于矩阵 ARM×KBRK×N 的乘法 C=AB,输出矩阵 CM×N 个元素,每个元素需要 K 次乘法和 K1 次加法,近似为 2K 次浮点运算。因此:

FLOPs(MatMul)=2MKN

这个公式是所有后续推导的基石。

6PD 法则。 对于拥有 P 个参数的模型,在 D 个 token 上完成一轮训练,总计算量可以用一个极简的经验公式估算:

FLOPstrain6PD

其推导逻辑如下:

  1. 前向传播:模型中的计算以线性层为主,每个线性层本质上是一次矩阵乘法。对于参数量为 P 的模型,每个 token 经过前向传播大约需要 2P 次浮点运算(矩阵乘法中的乘与加)。处理 D 个 token,前向传播总量为 2PD
  2. 反向传播:反向传播需要计算损失对每个参数的梯度,涉及两次矩阵乘法(分别对输入和权重求导),计算量约为前向传播的 2 倍,即 4PD
  3. 总计FLOPstrain=2PD+4PD=6PD

这个公式忽略了 LayerNorm、Softmax、激活函数等非矩阵乘法操作,因为在大模型中它们的计算量相比于大规模矩阵乘法可以忽略不计。

实例:LLaMA-7B 在 1T token 上的训练计算量。P=6.7×109D=1012 代入:

FLOPs=6×6.7×109×1012=4.02×1022

即大约 4×1022 次浮点运算。


9.5.2 模型浮点利用率(MFU)

有了计算量的估算,下一个自然的问题是:我的 GPU 到底跑了多少"有用的"计算?MFU(Model FLOPs Utilization) 正是回答这个问题的指标:

MFU=实际达到的模型有效 FLOPS硬件理论峰值 FLOPS

其中分子的计算方式为:

实际 FLOPS=单步 FLOPs(由模型结构决定)单步墙钟时间(实际测量)

分母则是硬件规格书上标注的理论最大值,取决于芯片型号和所使用的数据精度(BF16、FP8 等)。

MFU 的典型范围。 一般认为 MFU 超过 50% 即为良好。实际训练中,MFU 低于预期通常源于以下瓶颈:

瓶颈类型典型表现
数据加载(I/O)GPU 利用率间歇性降为 0,数据预处理 CPU 占满
通信开销多卡/多节点训练时,AllReduce 等集合通信占比高
Kernel 启动开销batch size 过小或模型过小,GPU 频繁启停
内存带宽受限算子访存密集(如 LayerNorm、Softmax),计算单元空转

优化 MFU 的常见手段包括:增大 batch size 以提高计算密集度、使用 torch.compile 进行算子融合、采用混合精度训练利用 Tensor Core 加速、优化数据加载流水线等。MFU 是大规模训练中最重要的效率指标之一——同样的硬件,MFU 从 30% 提升到 50%,训练时间直接缩短近 40%。


9.5.3 参数量精确公式

掌握参数量公式是进行所有后续显存和计算量估算的前提。以下以标准的 Decoder-Only Transformer(GPT / LLaMA 架构)为对象,逐模块推导。

记号约定: L 为层数,h 为隐藏维度(hidden size),V 为词表大小,a 为注意力头数,dk=h/a 为单头维度。

单层 Transformer Block

每层由自注意力(Self-Attention)模块和前馈网络(FFN)模块组成,各配一个 LayerNorm。

(1)自注意力模块。 包含 Q、K、V 三个投影矩阵和一个输出投影矩阵,每个都是 h×h 的线性层:

PAttn=4h2

注意:多头注意力只是将 h 维度拆分成 adk 维的子空间分别计算,投影矩阵的总参数量与头数无关——WQRh×h 不论拆成几个头,参数量都是 h2

(2)前馈网络模块。 标准设计是两层线性变换 h4hh

PFFN=h×4h+4h×h=8h2

对于采用 SwiGLU 激活的架构(如 LLaMA),FFN 包含三个投影 gate_proj、up_proj(均为 hdff)和 down_proj(dffh),总参数 3hdff。LLaMA 中 dff=83h(向上取整到 256 的倍数),故 3h×83h=8h2,与标准 FFN 量级一致。

(3)LayerNorm / RMSNorm。 每层有 2 个归一化层。标准 LayerNorm 每个有 2h 个参数(scale γ 和 shift β);RMSNorm 只有 scale,每个 h 个参数。对于 RMSNorm:

PNorm=2h

单层总计:

Player=4h2+8h2+2h=12h2+2h

h 较大时(如 h=4096),2h 相比 12h2 可忽略,因此:

Player12h2

嵌入层与输出层

  • 词嵌入(Token Embedding):查找表 WeRV×h,参数量 Vh
  • 位置编码:若使用 RoPE 等旋转位置编码,不引入可学习参数;若使用可学习位置编码,参数量为 max_seq_len×h
  • 输出投影(LM Head)WoutRh×V,参数量 Vh。若与词嵌入共享权重(weight tying),则不额外计入。

总参数量公式

P12Lh2+Vh

其中第一项是 L 层 Transformer Block 的参数,第二项是嵌入层(若输出层不共享则为 2Vh)。当 h 足够大时,Vh 相比 12Lh2 通常较小,可进一步简化为 P12Lh2


9.5.4 手算案例:LLaMA-7B 参数量验证

LLaMA-7B 的核心配置为:L=32h=4096V=32000,使用 RoPE(无可学习位置编码),输出层不与嵌入共享权重。

逐项计算:

模块公式计算过程参数量
词嵌入V×h32000×40961.31×108
每层注意力4h24×409626.71×107
每层 FFN8h28×409621.34×108
每层 RMSNorm2h2×4096=8192
单层小计12h2+2h2.01×108
32 层合计L×Player32×2.01×1086.44×109
输出投影h×V4096×320001.31×108

总参数量:

P=1.31×108+6.44×109+1.31×1086.7×1096.7B

与官方标注的"7B"基本一致(命名中的 7B 为取整值)。

速算验证: 直接用简化公式 P12Lh2=12×32×40962=6.44×1096.4B,加上嵌入 Vh0.13B,合计约 6.7B,与逐项计算吻合。


9.5.5 训练显存公式推导

训练阶段的显存占用远超推理,因为除了模型参数本身,还需要存储梯度和优化器状态。以当前主流的 Adam + 混合精度训练为基准进行分析。

静态显存:参数 + 梯度 + 优化器

设模型有 Φ 个参数(标量个数)。

(1)模型参数。 混合精度训练中,前向和反向传播使用 FP16/BF16 格式存储参数,每个参数 2 字节:

Mparam=2Φ bytes

(2)梯度。 每个参数对应一个梯度值,与参数同精度(FP16/BF16):

Mgrad=2Φ bytes

(3)优化器状态。 Adam 优化器为每个参数维护两个状态量:

  • 一阶动量 mt(梯度的指数移动平均):FP32 存储,4Φ bytes
  • 二阶动量 vt(梯度平方的指数移动平均):FP32 存储,4Φ bytes
Moptim=8Φ bytes

(4)主参数副本(Master Weights)。 混合精度训练中,优化器更新在 FP32 精度下进行,因此需要维护一份 FP32 的参数副本:

Mmaster=4Φ bytes

静态显存合计:

Mstatic=2Φ+2Φ+8Φ+4Φ=16Φ bytes

即每个参数平均占用 16 字节。如果不保留 master weights(某些实现中梯度也用 FP32),具体数值在 12-20 之间浮动,但 16 bytes/param 是最常用的经验值

动态显存:激活值

前向传播中产生的中间结果(激活值)需要保留到反向传播时用于计算梯度。激活值的显存占用取决于 batch size b、序列长度 s、隐藏维度 h 和层数 L

对于标准 Transformer 的单层,详细分析表明激活值显存约为:

Mact/layer34bsh+5bs2 bytes

其中 34bsh 来自注意力模块和 FFN 模块中需要保存的中间张量(输入、投影结果、dropout 掩码等),5bs2 来自注意力分数矩阵。L 层总计需要乘以 L

在实际工程中,可以使用激活重计算(Activation Checkpointing) 以时间换空间:不保存全部激活值,而是在反向传播时重新计算部分中间结果。这可以将激活显存降低到原来的 1/LL 倍,代价是增加约 30-40% 的计算量。

训练显存经验公式

综合静态和动态部分,训练显存的工程估算公式为:

Mtrain16Φ20Φ bytes+Mactivation

其中 16-20 的范围取决于具体实现(是否保留 master weights、梯度精度等),激活值部分与 bsLh 成正比,粗略可按参数显存的 2-4 倍估算。

手算案例:LLaMA-7B 训练显存。Φ=7×109,按 16 bytes/param 估算静态部分:

Mstatic=16×7×109=1.12×1011 bytes104 GB

加上激活值后,7B 模型的全量微调通常需要 120-160 GB 显存,对应 2 张 80GB 的 A100 或 H100。这也解释了为什么 LoRA 等参数高效微调方法如此流行——它们大幅减少了需要存储梯度和优化器状态的参数数量。


9.5.6 推理显存公式推导

推理阶段没有梯度和优化器状态,显存占用相比训练大幅降低。但随着序列长度的增长,KV Cache 会成为不容忽视的"内存刺客"。

模型参数

推理时只需加载模型权重,FP16 精度下:

Mparam=2Φ bytes

KV Cache

自回归生成的核心优化是 KV Cache:在生成每个新 token 时,将当前 token 对应的 Key 和 Value 向量缓存起来,避免对历史 token 重复计算。

逐步推导 KV Cache 大小:

  1. 单头、单层、单 token:需要缓存 K 和 V 各一个向量,每个向量维度为 dk=h/a。FP16 下单个向量占 2×dk 字节,K 和 V 合计 4dk 字节。
  2. 所有头a 个头的 K、V 拼接后等价于维度 h 的完整向量。单层、单 token 的 KV Cache 为 4h 字节。
  3. 所有层L 层叠加,单 token 总计 4Lh 字节。
  4. 整个序列:序列长度为 S(含 prompt 和已生成的 token),总计 4LhS 字节。
  5. 考虑 batch:batch size 为 B 时,总计 4LhSB 字节。
MKV=4LhSB bytes(FP16)

更一般地写成 MKV=2LhSB×bytes_per_param,其中 FP16 时 bytes_per_param = 2,FP32 时为 4。

推理总显存

Minfer=2Φ+4LhSB bytes(FP16)

KV Cache 为何是"内存刺客"

KV Cache 的显存占用与序列长度 S 线性增长。当上下文窗口从 2K 扩展到 128K 甚至 1M 时,KV Cache 的增长速度远超参数本身的占用。

手算案例:LLaMA-7B 推理显存。L=32h=4096B=1,FP16 精度。

  • 模型参数2×7×109=14 GB

  • KV Cache(S = 2048)

    4×32×4096×2048×1=1.07×109 bytes1 GB
  • KV Cache(S = 32768,即 32K)

    4×32×4096×32768×1=1.72×1010 bytes16 GB
  • KV Cache(S = 131072,即 128K)

    4×32×4096×131072×1=6.87×1010 bytes64 GB

可以看到:

序列长度参数显存KV Cache总计KV Cache 占比
2K14 GB1 GB15 GB6.7%
32K14 GB16 GB30 GB53%
128K14 GB64 GB78 GB82%

当序列长度达到 128K 时,KV Cache 占据了总显存的 82%,是名副其实的"内存刺客"。这正是 GQA(Grouped-Query Attention)、MQA(Multi-Query Attention)、量化 KV Cache 等技术的驱动力——它们通过减少 K/V 头的数量或降低精度来压缩 KV Cache。


9.5.7 Transformer 拆解建模实践

将上述公式汇总,可以建立一套完整的 Transformer 性能建模方法论:

第一步:确定模型配置。 从模型的 config.json 中读取 L(num_hidden_layers)、h(hidden_size)、V(vocab_size)等关键参数。

第二步:估算参数量。P12Lh2+Vh 快速估算,再逐模块细算验证。

第三步:估算训练成本。

  • 显存:16Φ bytes 起步,加激活值。据此决定需要多少张卡、是否需要模型并行。
  • 计算量:6PD,除以硬件峰值 FLOPS 再除以预期 MFU,得到训练时间。
Ttrain=6PDGPU数×峰值FLOPS×MFU

第四步:估算推理资源。 2Φ+4LhSB bytes,据此选择显卡型号和并行策略。对长序列场景重点评估 KV Cache 占比。

快速参考表:

模型Lh参数量推理显存(FP16)训练显存(粗估)
LLaMA-7B324096~6.7B~14 GB + KV~120 GB
LLaMA-13B405120~13B~26 GB + KV~220 GB
LLaMA-70B808192~65B~130 GB + KV~1.1 TB

9.5.8 本节小结

本节建立了一套围绕 Decoder-Only Transformer 的完整性能建模框架,核心结论可以浓缩为四组公式:

  1. 参数量P12Lh2+Vh,其中单层 12h2(注意力 4h2 + FFN 8h2)。
  2. 训练计算量FLOPs6PD,前向 2PD + 反向 4PD
  3. 训练显存:参数 2Φ + 梯度 2Φ + 优化器 8Φ + master weights 4Φ = 16Φ bytes/param,再加激活值。
  4. 推理显存:参数 2Φ + KV Cache 4LhSB,长序列下 KV Cache 主导显存。

这些公式的价值在于:它们让工程师在项目启动前就能完成资源规划——需要多少卡、训练多长时间、推理能支持多大的 batch 和上下文长度——而不必依赖昂贵的试错。理解这些公式背后的推导过程比记住数字更重要,因为当模型架构发生变化时(例如 MoE、GQA、线性注意力等),只有理解了原理才能灵活地调整估算。