组装 LLaMA3

把前面造的新零件拼成完整的 LLaMA3 解码器,堆叠、加载真实权重,让它说出第一句话。

知识课 · 约 35 分钟 · 更新于 2026-08-14

一层 LLaMA3,就是这几个零件的总装

前面几课造的零件,现在拼起来。LLaMA3 一个解码器层的结构是:

对照早期 Transformer 的解码器层,差异一目了然:

还有一处顺序上的差别:归一化采用 「先归一再进子层」的 Pre-Norm 。在「残差与层归一化」里提过,归一化既可以放在子层 之后 (Post-Norm),也可以放在子层 之前 (Pre-Norm)。LLaMA3 用后者——

把这一层画出来:

输入先过 RMSNorm 再进子层,子层输出在相加处回到主通路。竖直的主通路不经过子层,输入沿它原样直通到深层。

堆叠成完整模型

把解码器层堆 N 层,前后配上嵌入和输出,就是完整模型:

整个模型就是这样一条主线:

词嵌入把 token 变成向量,中间 N 个结构相同的解码器层依次堆叠,末尾归一化后由输出线性层映射回词表。

以 LLaMA3-8B 作工业级参照,看看真实规模长什么样:

作为对照,「BERT 与预训练范式」里提到的 BERT-base 约 1.1 亿参数——LLaMA3-8B 是它的约 70 倍,这就是「大」模型的规模感。

结构能自己搭,权重从哪来

真实的 LLaMA3 在 数万亿 token 上预训练而成,成本极高,个人无法复现。但好消息是:模型的 结构 我们已经能亲手搭出来。

动手:逐层组装

把「RMSNorm 与 SwiGLU」「旋转位置编码 RoPE」「KV 缓存与分组查询注意力」里实现的零件拼成一个解码器层:

全程打印张量形状,确认每一层的输入输出形状一致——这是能反复堆叠的前提。

动手:加载权重,让它开口

LLaMA3-8B 有 80 亿参数,普通环境难以运行。所以这里选一个 规模小、但架构相同 的开源模型——它和 LLaMA3-8B 只是 大小 不同, 结构完全一致 (同样的 RMSNorm、RoPE、SwiGLU、GQA、decoder-only)。真正加载权重、跑推理,直接用 transformers 里同一套架构的成熟实现,而不是把参数手动灌进刚搭的 LlamaModel 骨架;正因为两者结构对得上,官方训练好的权重才装得进去、直接能跑。给它一个前缀,让它自回归生成:

这是第一次见到一个「像样的大模型」真的开口说出连贯的话。

generate 内部是一个循环,前向一次接出一个词,把它接到已有内容的末尾,再作为下一次前向的输入。跑起来是这样:

这里的续写是示意文本,模型实际接出什么,由它装的权重和采样方式决定。

LLaMA3 由 Meta 发布,权重与说明见 llama.com ;各类开源权重可在 Hugging Face 找到。

动手:一个有趣的例子

还有一个流传很广的例子:问它「生命、宇宙以及一切的终极答案」:

42 是模型在预训练语料里记住的 梗 ,出自《银河系漫游指南》。能不能接出它,取决于模型有没有见过这个说法,和推理链路搭得对不对无关。

动手:打开内部看一眼

模型跑起来之后,它内部每一层的注意力权重都可以直接取出来看。

取「从前有一座山,山里有一座庙」这 10 个 token,把某一层、某个头的注意力权重排成方阵:行是当前正在生成的词,列是它回头在看的词。

格子颜色按上方色阶对应注意力权重,每一行是一次 softmax 的输出、行内权重之和为 1,右上角是因果掩码屏蔽的未来位置。这里用的是一组示意权重,用来说明典型的注意力模式,数值不取自某个具体权重的真实推理。

切到不同的层和头会看到,有的头几乎把全部权重给了紧挨着的前一个词,有的头把权重投向「山」「庙」这少数几个实词。每个位置的注意力都有明确的侧重,很少把权重均摊给前文所有词。

小结:一套「公共骨架」

现代主流开源大模型(LLaMA、Qwen、Mistral 等)大多是这套 decoder-only + RMSNorm + RoPE + SwiGLU + GQA 的组合。我们搭的,正是它们的「公共骨架」——理解了它,就理解了今天绝大多数开源大模型的内部构造。

很强,但它只会「接着往下写」

这个模型很强,但它此刻只会做一件事—— 接着你的话往下写 。

从「会续写」到「会对话、听指令」,还差最后一步——对齐。这是「从续写到对话助手」要讲的。