Skip to content
Neo's Blog
Go back

从 Transformer 到 Mamba:LLM 的底层原理与下一代架构

如果你用过 ChatGPT、Claude 或者 DeepSeek,可能会产生一个错觉:它们背后藏着某种截然不同的”黑科技”。毕竟,有的更擅长推理,有的更擅长中文,有的能处理百万字长文。

但如果你把它们的”内脏”翻出来看——它们几乎长着完全一样的架构。GPT-4、Claude 3.5、DeepSeek V3、LLaMA 3,底层都是同一个东西:Transformer 的 Decoder-Only 自回归模型

这不是巧合,而是过去八年 AI 领域最重要的技术收敛。但故事并没有到此为止。Transformer 有一个致命的软肋——O(n²) 的计算复杂度——而新一代架构正在试图推翻它。

这篇文章会带你走完整个故事:Transformer 是怎么工作的 → 为什么 LLM 只能逐字生成 → 业界如何绕过这个限制 → 以及 Mamba 为什么可能成为”后 Transformer 时代”的主角。

RNN 的原罪:为什么 Transformer 是革命

在 Transformer 之前,处理序列数据(文本、语音、时间序列)的主角是 RNN 和它的改进型 LSTM。RNN 的工作方式很”人类”——一个字一个字地读,每一步更新一个隐藏状态,把”记忆”压缩进一个固定大小的向量里。

但这种方式有三个致命问题:

第一,无法并行。 h₂ 依赖 h₁,h₃ 依赖 h₂,你必须算完第 1 步才能算第 2 步。GPU 上有几千个核心,但 RNN 一次只能用一个。

第二,长距离遗忘。 句子开头的信息要经过几十步的传递才能到达末尾,梯度在反向传播途中要么消失要么爆炸。LSTM 用门控机制缓解了这个问题,但没有根治。

第三,信息瓶颈。 无论句子多长,所有上下文都被压缩进一个固定长度的向量。句子一长,这个向量就装不下了。

2017 年,Vaswani 等人在论文 “Attention Is All You Need” 中提出了一个大胆的想法:把 RNN 的循环结构完全扔掉,只用”注意力”来建模序列中元素之间的关系。

这个想法的核心突破是:任意两个位置之间的距离从 O(n) 降到了 O(1)。无论句子多长,第一个词和最后一个词之间直接有一条注意力路径,不需要经过中间节点的层层传递。

Self-Attention:Transformer 的心脏

理解 Transformer 的关键,是理解 Self-Attention 机制。用一个类比来建立直觉:

你在读这句话:“猫坐在垫子上,因为它饿了。”

理解”它”的时候,你的注意力自动指向了”猫”,而不是”垫子”。

注意力机制就是让模型学会这种”关注相关信息”的能力。

具体怎么做到的呢?每个 token 被映射成三个向量:

  • Query(查询):我在找什么?
  • Key(键):我提供什么信息?
  • Value(值):我的实际内容是什么?

当模型处理”它”这个词时,用”它”的 Query 和所有词的 Key 做点积,得到注意力权重——权重越大表示越相关。然后用这些权重对所有词的 Value 做加权求和,得到输出。

用公式表示:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V

其中 √dₖ 是缩放因子,防止点积过大导致 softmax 梯度消失。

但一个注意力头学到的关系有限。Transformer 使用多头注意力(Multi-Head Attention),让不同的头关注不同的语义关系:

  • 头 1 学会代词指代消解(“它” → “猫”)
  • 头 2 学会语义相关(“饿” → “吃”)
  • 头 3 学会位置邻近(“垫子” → “上”)
  • 头 4 学会句法依存(主语 → 谓语)

多个头的结果拼接起来,模型就获得了多维度的理解。

还有一个细节:纯注意力不感知顺序——“猫吃鱼”和”鱼吃猫”对注意力来说只是同一组词的不同排列。解决方案是给每个位置加一个位置编码向量,告诉模型这个词在第几个位置。现代 LLM 普遍使用 RoPE(旋转位置编码),可以外推到训练时未见过的更长序列。

把这些组件组装起来,就是 Transformer 的一层:

graph TD
    IN["输入: 词序列"] --> EMB["词嵌入 + 位置编码"]
    EMB --> MH["Multi-Head Self-Attention<br/>所有词互相看,算关联度"]
    MH --> ADD1["残差连接 + LayerNorm"]
    ADD1 --> FFN["前馈网络 FFN<br/>两层全连接 + 激活函数"]
    FFN --> ADD2["残差连接 + LayerNorm"]
    ADD2 --> OUT["输出到下一层"]
    OUT --> NEXT["...... 堆叠 N 层 ......"]
    NEXT --> FINAL["最终输出"]

残差连接让梯度能直接回传,使训练几百层的深层网络成为可能。

三种范式,一种胜出

原始 Transformer 是 Encoder-Decoder 结构,设计用于翻译任务。但后来根据任务需求,演化出三种范式:

Encoder-OnlyDecoder-OnlyEncoder-Decoder
注意力类型双向(看全句)Masked(只看左边)Encoder 双向 + Decoder masked
训练目标完形填空(MLM)预测下一个词序列到序列
代表模型BERTGPT、LLaMA、Claude、DeepSeekT5、BART

为什么 Decoder-Only 胜出了?因为语言模型的定义就是”给定前面的词,预测下一个词”——天然就是一个”不能看未来”的任务,和 Decoder 的 Masked Attention 完美契合。

更重要的是 GPT-3 之后的一个重要发现:当模型足够大、数据足够多时,Decoder-Only 模型在生成过程中自然涌现出了理解能力。因为要准确预测下一个词,必须理解上文。一个架构同时搞定理解和生成——这就是为什么 GPT-4、Claude、LLaMA 全是 Decoder-Only。

Masked Attention:不能”偷看”未来

Decoder-Only 的核心机制是 Masked Attention。用一个例子说明:

生成”我喜欢吃苹果”时,每个词的注意力范围:

        我    喜    欢    吃    苹    果
    我  ✓    ✗    ✗    ✗    ✗    ✗
    喜  ✓    ✓    ✗    ✗    ✗    ✗
    欢  ✓    ✓    ✓    ✗    ✗    ✗
    吃  ✓    ✓    ✓    ✓    ✗    ✗
    苹  ✓    ✓    ✓    ✓    ✓    ✗
    果  ✓    ✓    ✓    ✓    ✓    ✓

上三角全部 mask 掉(设为 -∞),确保模型无法”偷看”未来的 token。每个位置只能看到它左边(包括自身)的 token。

这就是**自回归(Autoregressive)**的含义——用自己的输出作为输入,一步步往后生成。每一步都是:把当前所有 token 喂进去 → 算出下一个 token 的概率分布 → 采样一个 token → 拼回输入,重复直到遇到结束符。

用时序图表示这个生成过程:

sequenceDiagram
    participant U as 用户输入
    participant M as 模型
    participant O as 输出

    U->>M: "今天天气很好,适合出去"
    M->>M: 计算 → 下一个 token 概率分布
    M->>O: "散"
    M->>M: 把"散"拼回输入,重新计算
    M->>O: "步"
    M->>M: 把"步"拼回输入,重新计算
    M->>O: "。"
    M->>M: 遇到 EOS 结束符

这就是为什么 LLM 回复是一个字一个字”蹦”出来的——它本质上就是在做一连串的”完形填空”。

为什么不能一次预测多个 token?

你可能会问:为什么不能让模型一次预测多个 token,并行生成?答案藏在条件概率链里:

P(w1,w2,...,wT)=P(w1)P(w2w1)P(w3w1,w2)P(wTw1:T1)P(w_1, w_2, ..., w_T) = P(w_1) \cdot P(w_2|w_1) \cdot P(w_3|w_1,w_2) \cdots P(w_T|w_{1:T-1})

第 N+1 个 token 的概率分布依赖于第 N 个 token 是什么。你还没确定第 N 个,就没法确定第 N+1 个。就像多米诺骨牌——你不推倒第一块,后面的倒向哪里是不确定的。

如果强行并行预测:token N 有 50,000 种可能(词表大小),对每一种 N 的可能,token N+1 又有 50,000 种可能——组合起来就是 25 亿种组合,输出空间爆炸到无法训练。

这里有一个容易混淆的点:训练时可以”并行”,推理时必须串行。

graph TD
    subgraph "训练时(可以并行)"
        T1["已知: 'Hello World'"] --> T2["一次性预测所有位置"]
        T2 --> T3["与真实标签对比算 loss"]
    end
    
    subgraph "推理时(必须串行)"
        I1["输入: '你好世界'"] --> I2["预测: 'Hello'"]
        I2 --> I3["输入: '你好世界 Hello'"]
        I3 --> I4["预测: 'World'"]
        I4 --> I5["输入: '你好世界 Hello World'"]
        I5 --> I6["预测: EOS"]
    end

训练时用”teacher forcing”——因为 ground truth 已知,所有位置的标签都有了,可以一次性算 loss。但推理时没有 ground truth,只能用自己的输出当输入,一步一步来。

不过,业界发明了一个巧妙的绕过方式:Speculative Decoding(推测解码)

Speculative Decoding:用并行做草稿,用串行做裁决

Speculative Decoding 的思路很优雅——小模型快速生成草稿,大模型一次性验证:

sequenceDiagram
    participant S as 小模型(草稿)
    participant L as 大模型(验证)

    S->>L: 快速生成 5 个候选 token: "散 步 去 公 园"
    L->>L: 一次性并行验证这 5 个位置
    Note over L: "散"✓  "步"✓  "去"✓  "公"✗ → 应该是"逛"
    L->>L: 接受前 4 个,拒绝第 5 个,补上"逛"
    Note over L: 一次前进了 4 个 token

具体流程:

  1. 先用小模型快速生成 5 个候选 token(草稿)
  2. 再用大模型一次性并行验证这 5 个位置
  3. 大模型接受前面正确的 token,拒绝第一个错误的,然后补上正确的

这个方法的神奇之处在于:它的输出分布与直接用大模型自回归采样完全一致。不是近似,是数学等价的。推理速度可以提升 2-3 倍。

本质上,Speculative Decoding 是”用并行做草稿,用串行做裁决”的混合策略——并没有彻底抛弃自回归,而是在自回归的框架内找到了并行的空间。

Transformer 的软肋:O(n²) 的代价

回到 Transformer 本身。Self-Attention 虽然优雅,但有一个根本性的问题:计算复杂度是 O(n²)

序列长度翻倍,计算量翻四倍。100K tokens 的上下文窗口,注意力矩阵就是一个 100K × 100K 的怪物。这就是为什么长文本推理又慢又贵——GPU 显存被注意力矩阵吃满了。

过去几年,业界用各种工程手段缓解这个问题:KV Cache 缓存已计算的 K/V 向量、Flash Attention 优化内存访问、GQA/MQA 减少 K/V 头数量。但这些都是”优化”,没有改变 O(n²) 的本质。

有没有一种架构,天然就是 O(n) 复杂度

状态空间模型(SSM):递推压缩的哲学

答案是有的。**状态空间模型(State Space Model, SSM)**借鉴了控制理论中的状态空间方程,把序列建模转化为一个递推过程:

h_t = A · h_{t-1} + B · x_t    (状态更新)
y_t = C · h_t                  (输出计算)

直觉对比很清晰:

graph LR
    subgraph "Transformer(全局注意力)"
        T1["每个词和所有词算关联"] --> T2["O(n²) 复杂度"]
    end
    
    subgraph "SSM(递推压缩)"
        S1["x₁ → 状态 h₁"] --> S2["x₂ + h₁ → 状态 h₂"]
        S2 --> S3["x₃ + h₂ → 状态 h₃"]
        S3 --> S4["状态 h 是固定大小的压缩表示"]
    end
  • Transformer 像一个人读文章时反复回看前面的所有内容——完美,但昂贵。
  • SSM 像一个人读文章时只在脑子里维护一个”摘要状态”,读到新内容就更新摘要——高效,但有损。

SSM 的状态 h 是固定大小的压缩表示,不随序列长度增长。这意味着:

对比TransformerSSM
训练复杂度O(n²)O(n)
推理内存需 KV Cache,随序列增长固定内存,与序列长度无关
长距离依赖完美(全局注意力)有损(状态压缩)
训练模式并行(所有位置同时算)并行卷积形式
推理模式逐 token 读取 KV Cache逐 token 递推,无需 KV Cache

SSM 可以看作 LSTM 的理论推广——LSTM 是 SSM 的一种特例。但 SSM 通过更灵活的参数化获得了更强的表达能力。

Mamba:给 SSM 装上”选择性”开关

原始 SSM(如 S4)有一个致命问题:对所有输入一视同仁。读到重要信息和无关信息时,状态的更新方式完全一样。

2023 年,Stanford 团队提出的 Mamba 解决了这个问题。核心创新是选择性机制——让参数 B 不再是固定矩阵,而是输入依赖的:

原始 SSM:h_t = A · h_{t-1} + B · x_t     (B 是固定的)
Mamba:   h_t = A · h_{t-1} + B(x_t) · x_t  (B 随输入变化)

效果是:模型可以学会——遇到重要信息时保留进状态,遇到无关信息时丢弃。类似 LSTM 的门控,但是可学习的、更灵活的。

Mamba 在保持 O(n) 复杂度的同时,在语言建模任务上首次匹配甚至超越同规模 Transformer。

对比TransformerMamba
训练复杂度O(n²)O(n)
推理内存需 KV Cache,随序列增长固定内存
长距离精确召回精确访问任意位置选择性保留,可能丢失
生态成熟快速发展中

Mamba 的局限也很明显:有损压缩。状态大小固定,远距离信息可能丢失。在需要精确回忆长文档中某个细节的任务上,Transformer 仍然有优势。而且 Mamba 在 100B+ 参数规模的表达力尚未充分验证。

从 S4 到 Mamba 的演进路线:

模型特点局限
S4(2022)第一个成功的长序列 SSM对所有输入一视同仁,无法选择性遗忘
Mamba(2023)引入选择性机制有损压缩,长距离精确召回仍不如 Transformer

回头看:收敛与分化

回到开头的问题:为什么 GPT-4、Claude、DeepSeek 底层架构如出一辙?

因为 Transformer 的 Decoder-Only 自回归范式,是过去八年验证过的”最优解”——它在表达力、可扩展性、工程成熟度之间找到了最好的平衡点。所有厂商都走上了同一条路,差异不在架构,而在数据配比、对齐策略和工程优化。

但故事并没有结束。Transformer 的 O(n²) 复杂度是一个根本性的约束,而 SSM/Mamba 提供了一个优雅的替代方向。

短期(1-2 年),混合架构可能是最务实的选择——80% 的层用高效的 SSM,20% 的层用精确 Attention(如 Jamba 的做法)。

中期(3-5 年),如果 SSM 在 100B+ 规模上证明自己能匹配 Transformer 的表达力,替代可能真正发生。

长期,架构只是故事的一部分。数据质量、训练方法、对齐策略的重要性不亚于架构创新。Mamba 很优雅,但 GPT-4 的数据飞轮和 RLHF 积累不是换个架构就能追上的。

技术的演进从来不是线性的替代,而是层层的叠加。Transformer 不会消失——它会是新一代架构的参照系,正如今天我们在讨论 Mamba 时,仍然需要用 Transformer 作为基准。


💡 延伸阅读:如果你对 Transformer 推理优化的工程细节感兴趣,可以看看 KV Cache:Transformer 推理的「记忆体」——它详细拆解了如何用 PagedAttention 和 RadixAttention 管理 GPU 显存。