MiniMind 的一层由六个决定构成
一句话总结
MiniMind-3 是与 Qwen3 骨架相同的解码器。一层(block)是 Pre-Norm RMSNorm → 注意力(GQA、RoPE、QK-norm)→ 残差 → RMSNorm → SwiGLU FFN → 残差,嵌入和输出层共享权重。这个模块会把这套配置缩小(768 维、8 层缩到 128 维、4 层),做出约 100 万参数的模型,并用数字确认每个决定到底起了什么作用。
为什么需要它
最初的 Transformer(2017)里,相当一部分决定后来都改了。训练不稳定(层之后的 LayerNorm),推理时占内存太多(每个头各一份 K、V),长度也难以扩展(相加的位置嵌入)。如今的公开模型大多采用同样的办法,而 MiniMind 用几百行 Python 把这些办法展示了出来。注意力本身的手算,已经在 Transformer 课程里做过了,所以这里要看的是 MiniMind 的真实代码 是如何实现这些办法的,以及对应的数字。
工作原理
这是 MiniMindConfig 的默认值及其含义。
| 设置 | MiniMind-3 | 本课程 | 含义 |
|---|---|---|---|
| hidden_size | 768 | 128 | 表示一个令牌的向量长度 |
| num_hidden_layers | 8 | 4 | 层数 |
| num_attention_heads / num_key_value_heads | 8 / 4 | 4 / 2 | Q 头 / K·V 头(GQA) |
| vocab_size | 6,400 | 1,024 | 词表 |
| intermediate_size | ceil(768·π/64)·64 = 2,432 | 448 | FFN 的中间宽度 |
| rope_theta | 1e6 | 1e6 | RoPE 旋转周期的底数 |
RMSNorm。LayerNorm 先减去平均值,再除以标准差。RMSNorm 的论文认为,不做减去平均值的重新中心化也可以,只用均方根(RMS)去除。MiniMind 的代码也只是对 x * rsqrt(mean(x²) + eps) 乘以权重。所以输出的 RMS 会回到 1,但平均值不会变成 0。由于是在层 之前 做归一化的 Pre-Norm,残差通路不经过归一化,直接贯通,层再深,梯度也能顺畅地流动。
GQA。Q 头有 4 个,K·V 头有 2 个。k_proj 的输出是 2 × head_dim,是 Q 的一半,计算时用 repeat_kv 把 K·V 各复制两份,凑成与 Q 头数相同。推理时留在缓存里的是复制前的 K·V,所以 每个令牌的 KV 缓存只有一半。GQA 论文发现,把 K·V 头减到 1 个的 MQA 会损失质量,而取两者之间的值,质量接近 MHA,速度接近 MQA。
RoPE 和 QK-norm。不是把位置加到向量上,而是把 q 和 k 按位置 旋转。两个向量各自转到自己的位置之后再做内积,结果里只剩下两个位置的 差——(3, 7) 和 (103, 107) 的内积相同。MiniMind 在旋转之前,还会用 RMSNorm 再分别对 q 和 k 归一化一次(q_norm、k_norm)。这是 Qwen3 使用的方式,用来防止注意力分数变得过大。
SwiGLU。FFN 是 down(silu(gate(x)) * up(x))。带门控的 GLU 系列有三个矩阵,所以 MiniMind 把中间宽度设为 hidden 的约 π 倍(向上取整到 64 的倍数)。GLU 变体的论文发现,这种带门控的 FFN 质量优于 ReLU、GELU 的 FFN。
嵌入共享。由于 tie_word_embeddings=True,lm_head.weight 就是 embed_tokens.weight。这是在小模型里把词表份额减半的装置。
MoE 变体。如果 use_moe=True,FFN 就变成 4 个专家,每个令牌只用 1 个。这就是 MiniMind-3-MoE 被写成“198M-A64M”的原因——参数增加到三倍多,而一个令牌用到的计算量与稠密模型几乎相同。
在现场相遇的样子
应该能凭模型卡里的一份配置文件(config.json),算出参数量、KV 缓存大小和服务所需的内存。“KV 头 8、head_dim 128、32 层”,每个令牌占多少 KB 立刻就能算出来,而这个数字决定了并发用户数。反过来,如果按公式数出的参数与模型不符,就是漏掉了共享权重或归一化权重。在开始训练之前,看损失是否接近 ln(词表),也是常见的确认方法——如果初始化坏了,从第一步起就能发现。
MiniMind 的 README 在小模型里宽度和深度如何分配这个问题上引用了 MobileLLM 论文——同样的参数量,窄而深的通常比浅而宽的更好,但维度降到 512 以下之后,表示瓶颈就会变得明显。这门课程的 128 维,比那个界限低得多。这是为了在两个 CPU 上几分钟内训练完而特意选的大小,其代价会在最后一个模块里量出来。
下一项实验要做什么
用小配置创建 MiniMind 模型,分别用公式和模型数出参数。依次确认 GQA 的投影大小和每个令牌的 KV 缓存、RMSNorm 的输出、RoPE 的相对位置性质、训练前的损失,以及换成 MoE 时的总参数和激活参数。