我算模型参数量从来不查表,就靠一句口诀。今天把它写下来,因为上周刚把它改对了一次。
只算两块
一个 Transformer 层里真正吃参数的就两块:注意力的几个投影矩阵,和 FFN 的三条边。LayerNorm、bias 这些全是零头,千分之一都不到,手算直接扔。
设 d = 隐藏层宽度,把 d² 当成"一块砖"。
注意力:Q 和 O 永远一人一块砖,共 2d²。K 和 V 要看有没有 GQA——完整多头也是一人一块;有分组就按 KV头数/Q头数 打折。记 r = KV头数 ÷ Q头数,那么注意力 = (2 + 2r)·d²。
FFN:现在基本都是 SwiGLU 三条边(gate / up / down)。设中间层 = k·d,就是 3k·d²。
合起来:
一层 ≈ (2 + 2r + 3k) · d²
就这一行。剩下的是乘层数、加词表。
拿真 config 验
Qwen2.5-7B:d=3584,中间层 18944 → k≈5.29;28 个 Q 头 / 4 个 KV 头 → r=1/7。 系数 = 2 + 0.286 + 15.86 = 18.1 d² = 1284 万,一层 2.33 亿,28 层 = 65.3 亿。词表 15.2 万 × 3584 ≈ 5.5 亿,输入输出不共享权重要算两次 → 76 亿。官方口径 7.62B,非嵌入 6.53B,对上了。
Llama-2-13B:d=5120,中间层 13824 → k=2.7,没 GQA 所以 r=1。 系数 = 2 + 2 + 8.1 = 12.1,一层 3.17 亿 × 40 层 = 127 亿,加 embedding 4 亿×2 → 13.0B。也过。
老口诀是怎么翻车的
我以前记的是"一层 16d² 起步",那是按 4d 的 FFN 加完整 QKV 凑出来的经验数。碰到 Qwen 这种把中间层拉到 5d 以上、又把 KV 砍到 1/7 的,能差出快一倍。所以别记数字,记式子——数字会被下一代 config 打脸,式子不会。
一个新花样
前几天翻到一个 config:主干宽 5376、中间层 21504,正好 4 倍一点没打折,但它是整 18d²(配图这块小黑板就是当时的战果)——绝的是它让 K 和 V 共用一份投影。那式子就变成 (2 + r + 3k)·d²,省下的正好是一条 KV 边。这种省法挺有态度:作者显然觉得 K 和 V 的信息高度重复,不如把这条边挪去别处花。
几个账对不上的坑
- embeddings 是否共享(
tie_word_embeddings):不共享就多算一整个词表,几个亿没了。 - MoE:宣传页写的是激活参数,总参数要乘专家数,两者能差十倍。
- 词表:中日韩 tokenizer 词表偏大,embedding 能吃掉总量 10%。
- 多模态:还有视觉塔,我一般先只算语言主干,再单列。
口诀这东西,写下来才知道自己哪一步是蒙的。18d² 这块小黑板就挂这儿,下次再被新 config 打脸,就换一块。
