#十三、参数量估算、复杂度与算力题专项
这一块是很多候选人会忽略、但笔试和强面里都很爱考的部分。因为它最能区分“只会背概念”和“真的有工程/训练直觉”。
#1. 高频笔试题
- 一个 Transformer block 的参数主要来自哪里?
- Self-Attention 的时间复杂度和空间复杂度是什么?
KV cache的显存占用和哪些变量成正比?- 一个模型总参数量可以怎样快速估算?
- 为什么
FFN往往比 attention 占更多参数?
#就地速答
- 问:一个 Transformer block 的参数主要来自哪里?
答:主要来自 attention 的四个线性投影和
FFN两大块,其中FFN因为通常会先扩到4d左右,再压回d,往往是单层参数的大头。 - 问:Self-Attention 的时间复杂度和空间复杂度是什么?
答:长度为
n时,标准 self-attention 的主要计算和中间注意力矩阵都来自 token 两两交互,所以时间复杂度和核心中间空间复杂度通常都按O(n^2)看。 - 问:
KV cache的显存占用和哪些变量成正比?答:粗看与
batch size × sequence length × num_layers × kv_heads × head_dim × dtype_bytes成正比,所以长上下文和高并发会把它迅速推高。 - 问:一个模型总参数量可以怎样快速估算?
答:先抓住 embedding 和每层主干两部分:LLaMA 风格模型单层通常是
O(12d^2),总量近似embedding + layer_num × 12d^2,先看数量级就够用了。 - 问:为什么
FFN往往比 attention 占更多参数?答:因为 attention 主要是几组
d×d投影,而FFN往往要把隐藏维扩到4d左右再压回来,矩阵更大,所以参数和 FLOPs 往往都更重。
#2. 必会估算公式
下面这些不一定要求你严丝合缝,但至少要会数量级估算。
#词嵌入层参数量
- 输入 embedding 参数量大约是:
vocab_size * d_model
- 如果输出头不和 embedding 共享,还要再加一份:
d_model * vocab_size
#标准 attention 投影参数量
对隐藏维度为 d_model 的标准 attention:
Wq:d * dWk:d * dWv:d * dWo:d * d
所以 attention 线性层大约是:
4 * d^2
如果是 GQA / MQA,更精确一点可以写成:
Wq:d * dWk:d * (n_kv_heads * head_dim)Wv:d * (n_kv_heads * head_dim)Wo:d * d
因此 attention 参数量大约是:
2d^2 + 2d^2 * (n_kv_heads / n_heads)
这也是为什么 GQA / MQA 不只影响缓存,也会轻度影响参数量与带宽。
#FFN 参数量
如果是经典两层 FFN,隐藏层维度为 d_ff:
d * d_ff + d_ff * d = 2 * d * d_ff
如果是 SwiGLU / GeGLU 一类门控 FFN,通常会出现三组主矩阵,粗略可记为:
3 * d * d_ff
#LLaMA 类模型常用近似
很多 LLaMA 风格模型里,d_ff 大约取 8/3 * d,再配合 SwiGLU:
- FFN 参数量约为
3 * d * (8/3 d) = 8d^2 - attention 参数量约为
4d^2 - 所以每层粗略约为
12d^2
总参数量粗略可近似为:
embedding + L * 12d^2
这里 L 是层数。
#3. 一个常见手算例子
假设有一个 LLaMA 风格模型:
- 层数
L = 32 - 隐藏维度
d = 4096 - 词表大小
V = 32000
那么:
- embedding 约
32000 * 4096 ≈ 131M - 单层主干参数约
12 * 4096^2 ≈ 201M 32层约6.43B- 加上 embedding、norm、少量其他参数,总量大致就在
6.6B - 6.8B这个量级
所以这就是为什么它会被称为“约 7B 模型”。
#3.1 KV cache 快速估算公式
这是面试里非常高频的快算题。
粗略上,单次推理时 KV cache 占用可以估成:
2 * B * T * L * n_kv_heads * head_dim * dtype_bytes
其中:
2代表K和VB是 batch sizeT是当前缓存长度L是层数n_kv_heads是KV头数head_dim是每头维度dtype_bytes是每个元素的字节数,例如FP16/BF16常按2字节估算
这条式子特别重要,因为它能直接解释三件事:
- 为什么长上下文首先打爆的是缓存,而不是模型参数;
- 为什么
GQA / MQA对 serving 特别重要; - 为什么 batch 一上去,显存经常先炸在缓存而不是权重。
#3.2 MoE 参数量和激活参数量怎么区分
这是另一道非常高频的概念 + 估算混合题。
- 总参数量:所有专家参数都算上,所以很大。
- 激活参数量:每个 token 实际只走 top-k 个专家,所以一次前向真正参与计算的只是一部分。
因此 MoE 的关键不只是“大”,而是:
total params很大;active params per token小得多;- 但系统复杂度、通信和路由复杂度更高。
#3.3 训练显存 vs 推理显存最常见追问
面试官经常会用这组问题排查候选人是否真正有工程感:
- 为什么训练显存通常远大于推理显存?
- 为什么推理长上下文时,显存也可能非常高?
- 参数、梯度、优化器状态、激活值、
KV cache各在什么阶段占主导?
#就地速答
- 问:为什么训练显存通常远大于推理显存?
答:因为训练除了参数,还要保存梯度、优化器状态和大量中间激活;推理虽然没有这些状态,但长上下文时会被
KV cache反向追上。 - 问:为什么推理长上下文时,显存也可能非常高?
答:因为每一层都要缓存历史 token 的
K/V,上下文一长、batch 一大,KV cache就会快速超过权重本身。 - 问:参数、梯度、优化器状态、激活值、
KV cache各在什么阶段占主导?答:训练全参微调时通常是优化器状态和激活值最重,反向阶段梯度也显著;推理阶段没有梯度和优化器状态,主导项通常转成权重和
KV cache。
稳定回答是:
- 训练时除了参数,还要存梯度、优化器状态和中间激活;
- 推理时没有梯度和优化器状态,但长上下文和高并发下
KV cache会非常大; - 所以训练和推理的“显存大头”并不一样。
#4. 高频面试题
- 为什么 7B、13B、70B 之间不是简单线性差别,而是训练成本和服务成本都急剧变化?
- 为什么 attention 的复杂度是
O(n^2),但参数量并不随序列长度增长? - 为什么长上下文主要先打爆的是缓存与带宽,而不只是参数?
- 如果把头数翻倍、层数翻倍、隐藏维度翻倍,哪个对参数量和 FLOPs 影响最大?
MoE为什么总参数量大,但激活参数量未必大?
#就地速答
- 问:为什么 7B、13B、70B 之间不是简单线性差别,而是训练成本和服务成本都急剧变化?
答:因为模型变大不仅增加参数,还会放大显存、带宽、并行通信、部署碎片和高并发服务成本,很多代价是跨过某个规模阈值后突然陡增。
- 问:为什么 attention 的复杂度是
O(n^2),但参数量并不随序列长度增长?答:因为二次增长来自 token 两两交互时生成的计算与中间矩阵,而不是来自模型权重本身;权重矩阵一旦确定,就和序列长度无关。
- 问:为什么长上下文主要先打爆的是缓存与带宽,而不只是参数?
答:因为参数是静态常量,而长上下文会持续放大
KV cache存储和读取次数,系统先被拖垮的往往是显存带宽与缓存管理。 - 问:如果把头数翻倍、层数翻倍、隐藏维度翻倍,哪个对参数量和 FLOPs 影响最大?
答:通常是隐藏维度翻倍最可怕,因为大多数主干矩阵规模近似按
d^2增长;层数和缓存更接近线性放大。 - 问:
MoE为什么总参数量大,但激活参数量未必大?答:因为
MoE总参数把所有专家都算上了,但一次前向里每个 token 通常只走 top-k 少数专家,所以真正参与计算的激活参数只是总量的一小部分。
#5. 复杂度题的易错点
最常见错误有三个:
- 把“参数量”和“计算量”混为一谈;
- 把“训练显存”和“推理显存”混为一谈;
- 只记住
O(n^2),却不知道二次项来自 token 两两交互,而不是参数矩阵本身。
#6. 面试官喜欢怎么追问
- 如果上下文从
4K变32K,参数量会不会变? - 不会。变大的是 attention 计算和缓存压力,不是模型静态参数。
- 为什么
KV cache通常与batch size * seq_len * num_layers * kv_heads * head_dim强相关? - 因为每层每个历史 token 的
K/V都要被缓存下来,供后续 decode 重复使用。