Architecture / Foundation Models

Transformer 模型架构:残差流、注意力块与自回归生成

把 token 表示沿 residual stream 逐层更新:注意力负责跨位置通信,FFN 负责逐 token 非线性变换。

Mechanism Lab

动画:一个 Transformer block 如何更新 residual stream

动画展示 token 表示进入位置编码与 LayerNorm,经多头注意力跨位置通信,再通过残差、FFN 和输出头变成下一步预测分布。

Step 1 / 5

Embed

token embedding 与位置编码相加,形成第一条 residual stream。

H_0=E+P

Animation Control

Reduced-motion users receive the same step states without continuous motion.

01 / 直觉

核心直觉

Transformer 不是单个注意力公式,而是一套可堆叠的表示更新规则:embedding、位置编码、LayerNorm、multi-head attention、残差、FFN 和输出头共同工作。

残差连接让每层学习增量更新,而不是重写整个表示;LayerNorm 稳定每个 token 的尺度,使深层堆叠更容易训练。

自注意力在序列内做全局通信,FFN 在每个 token 上独立做非线性通道变换,二者交替形成深层语义表示。

encoder、decoder 和 decoder-only LLM 的差异主要来自 mask 和训练目标:全可见理解、因果生成或 encoder-decoder 条件生成。

02 / 数学

从一个 Transformer block 推导整层更新

01 / 输入表示

token id 先查 embedding,再加上位置编码。没有位置信息时,自注意力对 token 顺序近似置换等变,难以区分同词不同位置。

H_0 = E[token] + P[position]

02 / Pre-norm 注意力

现代深层 Transformer 常用 pre-norm:先规范化,再做 multi-head attention。这样梯度可以更稳定地沿残差路径传播。

U_l = H_l + MHA(LN(H_l))

03 / 多头通信

每个 head 学习一个 Q/K/V 空间;并行 heads 的输出拼接后经 W_O 混合,形成跨 token 通信项。

MHA(X)=Concat(head_h)W_O

04 / FFN 通道变换

FFN 对每个 token 独立应用同一组两层 MLP,通常先把维度扩张到 d_ff,再用 GELU/ReLU 非线性压回 d_model。

FFN(x)=W_2 phi(W_1 x + b_1)+b_2

05 / 第二条残差

FFN 输出也作为增量加回 residual stream。一个 block 的输出是注意力通信和 token-wise 非线性处理后的表示。

H_{l+1}=U_l + FFN(LN(U_l))

06 / 输出分布

语言模型把最后一层隐藏向量投影到词表,softmax 得到下一个 token 概率;训练时最大化真实 token 的对数似然。

p(x_{t+1}|x_{<=t})=softmax(h_t W_vocab)

03 / 代码

NumPy 演示:一个 pre-norm Transformer block

这个例子不是训练大模型,而是用小矩阵把 block 的数据流显式跑一遍:位置编码、MHA、残差、FFN 和 logits。

import numpy as np

def layer_norm(x, eps=1e-5):
    mean = x.mean(axis=-1, keepdims=True)
    var = ((x - mean) ** 2).mean(axis=-1, keepdims=True)
    return (x - mean) / np.sqrt(var + eps)

def softmax(a, axis=-1):
    a = a - np.max(a, axis=axis, keepdims=True)
    exp = np.exp(a)
    return exp / exp.sum(axis=axis, keepdims=True)

def mha(x, weights, n_heads=2, mask=None):
    n, d_model = x.shape
    d_head = d_model // n_heads
    Q = x @ weights["Wq"]
    K = x @ weights["Wk"]
    V = x @ weights["Wv"]

    Q = Q.reshape(n, n_heads, d_head).transpose(1, 0, 2)
    K = K.reshape(n, n_heads, d_head).transpose(1, 0, 2)
    V = V.reshape(n, n_heads, d_head).transpose(1, 0, 2)

    scores = Q @ K.transpose(0, 2, 1) / np.sqrt(d_head)
    if mask is not None:
        scores = np.where(mask[None, :, :], scores, -1e9)
    attn = softmax(scores, axis=-1)
    context = attn @ V
    context = context.transpose(1, 0, 2).reshape(n, d_model)
    return context @ weights["Wo"], attn

def ffn(x, weights):
    hidden = np.maximum(0, x @ weights["W1"] + weights["b1"])
    return hidden @ weights["W2"] + weights["b2"]

rng = np.random.default_rng(11)
n, d_model, d_ff, vocab = 5, 8, 24, 32
tokens = rng.integers(0, vocab, size=n)

embedding = rng.normal(size=(vocab, d_model)) / np.sqrt(d_model)
position = rng.normal(size=(n, d_model)) / np.sqrt(d_model)
H = embedding[tokens] + position

weights = {
    "Wq": rng.normal(size=(d_model, d_model)) / np.sqrt(d_model),
    "Wk": rng.normal(size=(d_model, d_model)) / np.sqrt(d_model),
    "Wv": rng.normal(size=(d_model, d_model)) / np.sqrt(d_model),
    "Wo": rng.normal(size=(d_model, d_model)) / np.sqrt(d_model),
    "W1": rng.normal(size=(d_model, d_ff)) / np.sqrt(d_model),
    "b1": np.zeros(d_ff),
    "W2": rng.normal(size=(d_ff, d_model)) / np.sqrt(d_ff),
    "b2": np.zeros(d_model),
    "W_vocab": rng.normal(size=(d_model, vocab)) / np.sqrt(d_model),
}

causal_mask = np.tril(np.ones((n, n), dtype=bool))
A, attention_weights = mha(layer_norm(H), weights, n_heads=2, mask=causal_mask)
U = H + A
H_next = U + ffn(layer_norm(U), weights)
logits = H_next[-1] @ weights["W_vocab"]
probs = softmax(logits)

print("hidden shape:", H_next.shape)
print("attention shape:", attention_weights.shape)
print("top next-token ids:", probs.argsort()[-5:][::-1])

04 / 案例

案例:研究文本和回归表格如何通过 Transformer 建模

  • 在 StatsPAI 场景中,一段研究问题、数据字典、回归表、脚注和审稿意见会被切成 token。每个 token 先进入 embedding 与位置编码,形成初始 residual stream。
  • 注意力层让“treatment effect”关注表格列名、估计量、标准误、样本限制和识别设计段落;FFN 层则对每个 token 的局部表示做非线性重编码。
  • 多层堆叠后,模型可以在生成解释时同时调用前文定义、表格结构和方法段上下文,但这只是表示能力,不等于已经验证了因果识别。
  • 在 Agent 系统里,Transformer 适合读写研究材料;真正的可靠工作流还要把输出接到工具调用、代码复跑、数据 provenance 和人工审阅节点。

05 / 风险

常见误区

只记住“Transformer = Attention”,忽略残差流、LayerNorm、FFN、位置编码和训练目标共同决定模型行为。
在 decoder-only 生成任务中漏掉 causal mask,会让训练或评估偷看未来 token。
把模型生成的流畅解释当作识别证明;Transformer 学到的是表示和条件分布,不自动提供因果有效性。
忽略长上下文成本:标准自注意力是 O(n^2),长论文、长日志和高频数据需要 chunking、retrieval 或稀疏策略。
在小数据任务中过度微调大模型,导致记忆训练样本、格式漂移或工具调用不稳定。
把所有层输出都当作同等可解释;单个 head 或单层激活的可视化只能作为诊断线索,不能单独作为结论。

参考资料