Transformer 是怎么工作的


一、注意力之前:序列建模卡在哪

2017 年之前,文本序列的主流建模方式是循环神经网络。隐藏状态按时间步递推,第 t 步的状态由第 t-1 步的状态和当前输入共同决定:

$$h_t = f(W \cdot x_t + U \cdot h_{t-1})$$

这个递推带来两个硬约束。

一是时间维度无法并行。$h_t$ 必须等 $h_{t-1}$ 算完,长度为 n 的序列在训练时就有 n 个串行步骤。GPU 擅长的矩阵乘法那样的并行计算,在时间维度上完全用不上,只能靠加大 batch、加宽层数来提升吞吐。

二是长距离依赖要走过整条链。第 1 个位置的信息传到第 n 个位置,需要经过 n 次状态更新;反向传播时梯度也沿同样长的路径回传,路径长度是 O(n)。LSTM 的门控把梯度衰减压住了一部分,但链的长度没有改变,几百个 token 之外的依赖仍然容易丢。

注意力最早是作为补丁出现的。Bahdanau 等人在 2015 年让解码器每一步直接读取编码器的所有位置,为每个位置算一个权重再加权求和,长距离依赖的路径长度从 O(n) 降到 O(1)。这项工作解决的是对齐问题,循环结构仍然保留——编码器照旧一步一步读句子。

另一条路线是用卷积替换循环。ConvS2S、ByteNet 这类模型堆叠卷积层来扩大感受野,时间维度可并行,代价是两个相距较远的位置要经过 O(d/k) 层(k 为卷积核宽度)才能交换信息,用空洞卷积则是 O(log d) 层。

衡量这类结构可以用一个简单的指标:任意两个位置之间信息传递的路径长度。循环是 O(n),空洞卷积是 O(log n),全连接自注意力是 O(1)——两个位置直接相乘,不经过任何中间状态。

二、2017 年的那次删除

《Attention Is All You Need》(Vaswani 等,NeurIPS 2017)的立场写在标题里:保留注意力,删掉循环。序列建模全部交给注意力加前馈网络,所有位置同时计算,训练时序列维度上没有任何串行依赖。

任务选的是机器翻译。WMT 2014 英德 450 万句对,源和目标共享约 37000 词的 BPE 词表;英法 3600 万句,32000 词表。

两个配置的差别只在宽度和步数上,层数都是 6 层编码器加 6 层解码器:

配置 base big
d_model / 头数 / 每头维度 512 / 8 / 64 1024 / 16 / 64
前馈维度 2048 4096
训练步数 10 万步(12 小时) 30 万步(3.5 天)
英德 BLEU 27.3 28.4
英法 BLEU 38.1 41.8

训练硬件是 8 块 P100,base 每步 0.4 秒。论文标注 base 约 6500 万参数、big 约 2.13 亿参数——这个规模今天看相当于一个小模型,但它确立的骨架一直用到千亿参数级。

结果上,英德 28.4 BLEU 比当时最好的单模型和集成模型都高出 2 BLEU 以上,英法 41.8 BLEU 是单模型最好成绩。

需要分清的是,注意力机制不是这篇论文发明的,加性注意力比它早两年。真正的分水岭是删除循环:注意力从给循环模型打补丁的辅助模块,变成唯一的信息通路。

三、一个块里的四个部件

现代语言模型的组织方式是同一套块堆叠 L 层,每个块里有两个子层——注意力负责位置之间交换信息,前馈网络负责逐位置加工,两者各自配一条残差连接和一次归一化。块的输入输出形状不变,所以能任意加层。

3.1 分词与词嵌入

文本先被切成子词单元。BPE 从字符起步,反复合并最高频的相邻符号对直到词表达到预设大小;WordPiece 用似然增益做合并决策;SentencePiece 直接在原始字节上操作,不必先做分词。词表规模从 32000 到 150000 不等。

切得细,词表小、序列长;切得粗,词表大、序列短。词表大小直接决定嵌入矩阵的参数量,序列长度则决定注意力那份平方开销——两个方向都有代价。

嵌入矩阵把 token id 映射成 d_model 维向量。输出侧的语言模型头通常复用这个矩阵(权重绑定),省下词表规模的一份参数。输入嵌入之后一般乘一个 $\sqrt{d_{model}}$ 的缩放,让嵌入和位置编码的量级对齐:位置编码的值域在 [-1, 1],嵌入的初始化方差是 $1/d_{model}$,不做缩放时位置信号会盖过词义信号。

3.2 位置编码

自注意力本身没有顺序概念。交换输入序列里两个位置的 token,输出只是跟着交换,注意力分数矩阵完全不变。顺序信息必须显式注入,注入方式分三代。

方案 做法 长度外推
正弦绝对编码 用不同频率的 sin / cos 给每个位置生成固定向量 理论上可外推,实测有限
可学习绝对编码 一张 n_max × d_model 的位置表,随训练更新 不能超过表长
相对位置 / RoPE / ALiBi 把位置信息放进注意力分数:旋转 Q、K,或按距离加一个线性惩罚 配合插值可扩到训练长度的数倍

原论文用的是正弦绝对编码,考虑的是它能让模型外推到比训练更长的序列。后来的做法普遍转向相对位置,原因是绝对位置在长句里泛化不好,而相对位置直接编码”两个位置差多远”,更贴近语言本身的局部性。

RoPE 是今天的默认选择:把每个二维分量按位置角速度旋转,使得两个位置的内积只依赖它们的相对距离。上下文扩展的常见手段——位置插值、NTK 缩放、YaRN——都是在 RoPE 的频率上做文章,把训练时的 4k 视角拉伸到 128k 以上。ALiBi 更简单:不学任何参数,直接在分数上减去一个与距离成正比的惩罚项。两者的共同点是位置信息只进入注意力分数,不进入嵌入本身。

3.3 自注意力

同一个输入 x 经过三个不同的线性变换,得到查询 Q、键 K、值 V。查询表示这个位置要找什么,键表示这个位置能提供什么,值是被取走的内容。

计算分三步走:Q 与 K 转置相乘得到每个位置对之间的分数,按最后一维 softmax 归一化成权重,再用权重对 V 加权求和。

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

除以 $\sqrt{d_{k}}$ 是有原因的。假设 q 与 k 的各维独立同分布、均值 0 方差 1,点积的方差就是 $d_{k}$,标准差是 $\sqrt{d_{k}}$。$d_{k}=64$ 时分数标准差是 8,跨度太大,softmax 会饱和——某个位置拿到接近 1 的权重,其余接近 0,梯度随之消失。除以 $\sqrt{d_{k}}$ 把方差拉回 1,softmax 保持在工作区间内。

多头注意力的做法是把 $d_{model}$ 切成 h 份,每份 $d_{k} = d_{model} / h$,各头独立算一遍再拼接,最后过一个输出投影。多头的计算总量和单头基本相同,换来的是多个独立的表示子空间:同一层里一个头盯紧邻词,另一个头盯句法上呼应的成分,各自的分工不需要人工指定。

解码器里的注意力要加因果掩码,位置 i 只能看见不超过 i 的位置。做法是在 softmax 之前把未来位置的分数置为负无穷,归一化之后这些位置的权重正好是 0。这一步是自回归生成的前提——否则训练时模型可以直接看到答案。

3.4 前馈网络、残差与归一化

前馈层对每个位置独立地过一个两层 MLP:先升维到 $d_{ff}$,过激活函数,再降回 $d_{model}$。原论文的 $d_{ff}$ 是 $d_{model}$ 的 4 倍,中间用 ReLU;现在多换成 GELU 或门控结构(SwiGLU 一线),维度比例相应调整为 8/3 附近。

值得留意的是参数分布:每层注意力是 4 个 $d\times d$ 矩阵($4d^2$),前馈是升维加降维共 $8d^2$。前馈层占了每层参数的三分之二,MoE 替换掉的也正是这部分。

残差连接把子层的输出加回输入:x + f(x)。这条恒等通路让梯度可以直达底层,也是深层网络能训起来的原因。可以把贯穿所有层的这条通路看成一条”残差流”,每个子层做的事是读它、算出一个增量、加回去。

归一化是训练稳定性的开关。原论文把 LayerNorm 放在子层之后(Post-LN),后来普遍改成放在子层之前(Pre-LN):Pre-LN 的残差通路完全不被归一化打断,深层模型可以直接用较大的学习率起步。今天的模型还常把 LayerNorm 换成 RMSNorm——去掉减均值那一步,只按均方根缩放,计算更省而效果基本不变。

3.5 三种骨架

同一套块换一下掩码和连接方式,能得到三种不同的模型。

编码器单独用(BERT 一线):注意力不加掩码,每个位置能看见全句,适合分类、抽取、句子表示这类理解型任务。预训练目标是掩码语言模型——随机遮掉 15% 的 token 让模型还原。

解码器单独用(GPT 一线):加因果掩码,每个位置只看左边。训练目标是单一的下一 token 预测。今天绝大多数大模型走这条路,原因有三点:目标函数不需要任何标注,任何任务都能改写成”给一段前缀、让它续写”,生成时已经算过的 K 和 V 可以缓存复用。

编码器配解码器(原版 Transformer、T5):编码器读完整源序列,解码器生成时通过交叉注意力读取编码器的输出——交叉注意力的 Q 来自解码器,K 和 V 来自编码器。机器翻译、语音识别这类”输入一段、输出另一段”的任务仍以这种结构为主。

四、一次前向:形状怎么走

以 batch 为 2、序列长 8、$d_{model}=512$、8 头为例,张量在每一站的形状:

token id                [2, 8]                        整数索引
词嵌入 + 位置编码        [2, 8, 512]

每个块重复以下步骤:
  LayerNorm             [2, 8, 512]
  Q/K/V 投影            [2, 8, 1536] → 切三份 [2, 8, 512]
  拆头                  [2, 8, 8, 64]                  [batch, 头数, 位置, 每头维度]
  分数 Q·Kᵀ             [2, 8, 8, 8]                   位置 × 位置
  掩码 + softmax        [2, 8, 8, 8]                   下三角以外为 0
  对 V 加权求和          [2, 8, 8, 64]
  合并头 + 输出投影      [2, 8, 512]
  残差相加              [2, 8, 512]
  LayerNorm             [2, 8, 512]
  前馈 512 → 2048       [2, 8, 2048]
  前馈 2048 → 512       [2, 8, 512]
  残差相加              [2, 8, 512]

最后一次 LayerNorm       [2, 8, 512]
输出投影到词表           [2, 8, 32000]                每个位置的 logits

整个流程里只有注意力分数矩阵是 n×n 的,其余张量都是 n×d 或 n×d_ff。

训练时整段序列一次算完,序列维度上完全并行,这也是 Transformer 能把 GPU 吃满的原因。

生成时每步只能吐一个 token,把上一步的输出接到输入后面重算,这样做的代价是重复计算。为省掉这份重复,每层已经算过的 K 和 V 会被缓存下来(KV cache)。缓存开销是:

$$M_{\text{KV}} = 2 \times L \times H_{kv} \times d_{head} \times n \times b$$

以 fp16、32 层、32 头、每头 128 维的模型为例,每个 token 约 0.5 MB,4k 上下文就是 2 GB 左右——长上下文推理的显存主要消耗在这里,而且随 batch 和长度线性增长。

计算量的账按乘加运算数估:每层投影部分是 4·n·d²,注意力分数与对 V 的加权求和各是 n²·d、合计 2·n²·d,前馈是 8·n·d²。序列长度远小于 d_model 时前馈占大头;长度超过 d_model 的若干倍之后,平方项压过其他所有项。这就是长上下文贵的根源,属于结构自带的成本,不是实现问题。

结构 任意两位置的路径长度 单层计算量 时间维度可并行
循环网络 O(n) O(n·d²) 否
空洞卷积 O(log n) O(n·d²·k) 是
自注意力 O(1) O(n²·d + n·d²) 是

五、训练:目标、超参数、不稳定点

目标函数是下一 token 的交叉熵。输入是序列去掉最后一位,标签是去掉第一位,每个位置都产生一个损失,整个 batch 的 token 求平均。翻译任务上就是给定源句预测目标句;代码、对话、数学推导在训练阶段没有区别,都被切成同一个 token 序列。

原论文的超参数至今被当作基准参考:Adam 优化器,β1 = 0.9、β2 = 0.98、ε = 1e-9;学习率先线性升到峰值,再按步数的平方根倒数衰减,warmup 4000 步;dropout 0.1,标签平滑 0.1,梯度裁剪 1.0。

warmup 不是可选项。深层注意力的梯度在最初若干步方差很大,学习率直接给峰值容易把参数推进坏区域;论文自己也说这个调度配合 Adam 是收敛稳定的关键之一。

训练不稳定是这套结构的家常事,常见表现是 loss spike——某一步之后损失突然跳高。应对手段基本是三件:跳过坏 batch、回滚到上一个 checkpoint 并调小学习率、以及在结构上做预防(Pre-LN、对 Q 和 K 做归一化、bf16 混合精度配 fp32 主权重、激活重计算换显存)。

数据量上,Chinchilla 的结论是给定算力预算时参数量和训练 token 数应当同比例增长,大约 20 个 token 对应 1 个参数。实际训练普遍用远超这个比例的数据——因为推理成本由参数量决定,训练时多花的一次性成本,能换来一个更小但在线成本更低的模型。

六、九年间的演变

部件 2017 原版 今天主流 更换的原因
位置编码 正弦绝对编码 RoPE / ALiBi 相对位置泛化更好,配合插值可扩上下文
归一化 LayerNorm,放子层之后 RMSNorm,放子层之前 残差通路不被归一化打断,训练更稳更快
激活函数 ReLU GELU / SwiGLU 门控结构在大规模下效果更好
注意力 多头注意力 MQA / GQA / MLA 减少 KV cache 的显存开销
注意力内核 显式构造 n×n 矩阵 FlashAttention IO 感知的分块重算,显存降到 O(n),结果精确等价
前馈层 稠密 4·d_model 稀疏专家(MoE) 总参数增容、激活参数不变
上下文长度 512 128k 以上 位置编码插值 + 长文本数据配比

没变的部分更值得记:块的骨架(注意力 + 前馈 + 残差 + 归一化)、缩放点积注意力本身、下一 token 的预测目标,以及那个 n×n 的分数矩阵——到今天所有稠密前沿模型里都还在。

围绕这张矩阵的平方开销,衍生出两条不同的路线。

一条是近似。稀疏与低秩的做法把参与计算的位置对砍掉一部分:Longformer 用滑窗加少量全局 token,BigBird 用滑窗加随机加全局,Linformer 把键值投影到低维,Performer 用核函数改写注意力,Reformer 用局部敏感哈希做聚类。复杂度能降到接近线性,代价是近似误差,在需要精确检索的任务上会掉点。

另一条是精确但更聪明地算。FlashAttention 不改变数学结果,改为分块计算并把中间矩阵留在片上高速缓存里,避免把 n×n 矩阵写回显存。结果是显存从 O(n²) 降到 O(n),速度还更快。PyTorch 的 scaled_dot_product_attention 默认走的就是这类内核,所以今天写代码时并不会真的构造出那个 n×n 矩阵。

第三条路是换掉注意力。状态空间模型(S4、Mamba 一线)把序列递推重新引入,但让递推可以在训练时并行扫描,推理时保持固定大小的状态。吞吐优势明显,但固定状态在状态跟踪类任务上有表达力上限,这一点有专门的理论分析(ICML 2024)。目前的实用形态是混合层——大部分层用状态空间、少数层保留注意力,纯状态空间替代通用能力还没有出现。

MoE 是另一个方向的扩张。把每层的前馈网络拆成多个专家,每个 token 只激活其中少数几个:Mixtral 8x7B 每层 8 个专家、每个 token 走 2 个,总参数 47B 而激活 13B;DeepSeek-V3 总参数 671B、每 token 激活 37B,配合 MLA 压缩 KV cache。这条路线用显存和通信换算力,容量上去了,单 token 的计算量没涨。

七、它为什么有效,以及它不擅长什么

从残差流的角度看这套结构,注意力是唯一跨位置通信的通道,前馈层是逐位置的加工——每个位置在被加工前,先通过注意力从其他位置取回信息。层数越深,这种”先取信息再加工”的循环做得越多。

一些具体能力可以定位到很小的电路上。比如两层就能组出归纳头:第一层学”看前一个 token”,第二层按内容匹配,合起来实现的是”找到此前出现过相同前缀的位置,把它后面的内容复制过来”。这是上下文学习的一部分机制,属于可验证的结构,不是比喻。

可解释性的边界也要说清楚。把注意力权重当成解释是不可靠的——有工作专门论证过这点,结论写在标题里:注意力不等于解释。权重只是同一层多个头、后续多层非线性叠加之前的中间量,不能直接读成”模型在看哪里”。用探针和电路分析做的定位更可信,但覆盖面仍然有限。单神经元与概念之间也不是一一对应,叠加现象(superposition)让神经元级别的解读天然模糊。

不擅长的部分可以列得比较具体。长上下文里中间位置的信息最容易被漏掉,这一点在专门的评测里被反复观察到;计数、算术、多步状态跟踪在没有外部工具或草稿纸时容易出错;幻觉不是靠扩大规模能自动解决的问题,模型参数里没有可写的记忆,上下文一关就没了。这些是当前结构的固有短板,而不是训练不充分。

八、实现

下面的实现只有六十来行,包含因果自注意力、Pre-LN 的块、了解位置编码和权重绑定的输出层。它不能做任何有用的事,但把前向和反向都走通了,形状、掩码、损失函数的写法与实际模型一致。

import math
import torch
import torch.nn as nn
import torch.nn.functional as F


class Attention(nn.Module):
    """因果自注意力:Q/K/V 由同一个输入经一次线性变换算出"""
    def __init__(self, d_model, n_head, max_len=512, dropout=0.0):
        super().__init__()
        assert d_model % n_head == 0
        self.n_head, self.d_head = n_head, d_model // n_head
        self.qkv = nn.Linear(d_model, 3 * d_model, bias=False)
        self.proj = nn.Linear(d_model, d_model, bias=False)
        self.drop = nn.Dropout(dropout)
        # 下三角矩阵:位置 i 只能看见位置 <= i
        self.register_buffer("mask", torch.tril(torch.ones(max_len, max_len, dtype=torch.bool)))

    def forward(self, x):
        B, T, C = x.shape
        q, k, v = self.qkv(x).split(C, dim=2)                     # 各 [B, T, C]
        q, k, v = (t.view(B, T, self.n_head, self.d_head).transpose(1, 2)
                   for t in (q, k, v))                            # [B, n_head, T, d_head]
        att = q @ k.transpose(-2, -1) / math.sqrt(self.d_head)    # [B, n_head, T, T]
        att = att.masked_fill(~self.mask[:T, :T], float("-inf"))
        att = self.drop(F.softmax(att, dim=-1))
        y = (att @ v).transpose(1, 2).reshape(B, T, C)            # 合并头
        return self.proj(y)


class Block(nn.Module):
    """Pre-LN:归一化放在子层之前,残差通路上不加任何东西"""
    def __init__(self, d_model, n_head, d_ff, max_len=512, dropout=0.0):
        super().__init__()
        self.ln1, self.attn = nn.LayerNorm(d_model), Attention(d_model, n_head, max_len, dropout)
        self.ln2 = nn.LayerNorm(d_model)
        self.ffn = nn.Sequential(
            nn.Linear(d_model, d_ff, bias=False), nn.GELU(),
            nn.Linear(d_ff, d_model, bias=False), nn.Dropout(dropout),
        )

    def forward(self, x):
        x = x + self.attn(self.ln1(x))          # 跨位置交换信息
        return x + self.ffn(self.ln2(x))        # 逐位置加工


class TinyGPT(nn.Module):
    def __init__(self, vocab, d_model=128, n_head=4, n_layer=4, d_ff=None,
                 max_len=512, dropout=0.0):
        super().__init__()
        d_ff = d_ff or 4 * d_model
        self.tok_emb = nn.Embedding(vocab, d_model)
        self.pos_emb = nn.Embedding(max_len, d_model)             # 可学习绝对位置
        self.blocks = nn.Sequential(*[Block(d_model, n_head, d_ff, max_len, dropout)
                                      for _ in range(n_layer)])
        self.ln_f = nn.LayerNorm(d_model)
        self.lm_head = nn.Linear(d_model, vocab, bias=False)
        self.lm_head.weight = self.tok_emb.weight                 # 权重绑定
        self.apply(self._init)

    def _init(self, m):
        if isinstance(m, (nn.Linear, nn.Embedding)):
            nn.init.normal_(m.weight, std=0.02)

    def forward(self, idx):
        B, T = idx.shape
        pos = torch.arange(T, device=idx.device)
        x = self.tok_emb(idx) + self.pos_emb(pos)
        return self.lm_head(self.ln_f(self.blocks(x)))           # [B, T, vocab]


# 过拟合一小段固定文本:损失能压到接近 0,说明前向和反向都通了
torch.manual_seed(0)
text = "注意力让每个位置直接看到其它所有位置。" * 8
chars = sorted(set(text))
stoi = &#123;c: i for i, c in enumerate(chars)&#125;
data = torch.tensor([[stoi[c] for c in text]])

model = TinyGPT(vocab=len(chars), d_model=96, n_head=4, n_layer=3, max_len=len(text))
print("参数量", sum(p.numel() for p in model.parameters()))

opt = torch.optim.AdamW(model.parameters(), lr=3e-3)
for step in range(301):
    logits = model(data[:, :-1])                                 # 输入去掉最后一位
    loss = F.cross_entropy(logits.reshape(-1, logits.size(-1)),
                           data[:, 1:].reshape(-1))              # 标签去掉第一位
    opt.zero_grad()
    loss.backward()
    opt.step()
    if step % 60 == 0:
        print(f"step &#123;step:>3&#125;  loss &#123;loss.item():.3f&#125;")

本机跑出来的输出:

参数量 349344
step   0  loss 2.930
step  60  loss 0.009
step 120  loss 0.004
step 180  loss 0.003
step 240  loss 0.002
step 300  loss 0.001

这段代码省掉的东西,恰好是实际训练里最麻烦的部分:dropout 与权重衰减的具体配置、按层数缩放的初始化(残差分支输出按 √(2L) 缩放)、学习率调度、梯度裁剪、KV cache、混合精度与激活重计算。模型的规模也远小于真实场景——这里 3 层 96 维,实际模型是几十层、几千维。

参数量可以套一个粗略的公式核对:

$$P_{\text{layer}} = 4d^2 + 8d^2 = 12d^2$$

拆开看:
  注意力   Q、K、V、输出投影四个 d×d 矩阵        4·d²
  前馈层   升维 d×4d 与降维 4d×d                8·d²
再加词嵌入与输出层 2·V·d(权重绑定时只算一份)

核对:Llama 2 7B 的配置是 32 层、d_model = 4096、词表 32000
  12 × 32 × 4096²      ≈ 64.4 亿
  2 × 32000 × 4096     ≈ 2.6 亿
  合计                 ≈ 67 亿,与公开的 6.74B 对得上

九、常见误解

“参数量都花在注意力上。” 每层注意力是 4·d²,前馈是 8·d²,前馈占了三分之二。MoE 时代这个比例更偏——被拆成多个专家的正是前馈层,注意力部分保持不变。

“注意力权重能说明模型在想什么。” 权重只是多层非线性之前的中间量,用它做解释已被专门论证过不可靠。要定位具体行为,电路分析和探针比读权重更有信息量。

“长上下文等于能记住。” 上下文窗口说的是输入可以有多长,能不能用好是另一回事。检索类评测里,处在中间位置的信息普遍掉得最厉害,把关键内容放开头或结尾,效果往往比放中间好。

“Transformer 一定是二次复杂度。” 稠密精确注意力确实是,但滑窗、低秩、核近似、状态空间都能绕开这一项。绕开的代价是近似误差或表达力上限,所以到今天,主流仍然选择精确注意力加 IO 层的优化。

“换成状态空间模型就能替掉注意力。” 固定大小的状态在状态跟踪类任务上有被证明的上限,当前的实用形态是混合层,不是全面替换。

参考

  • 1706.03762 — Attention Is All You Need — NeurIPS 2017(CCF-A)
  • 1409.3215 — Sequence to Sequence Learning with Neural Networks — NeurIPS 2014(CCF-A)
  • 1409.0473 — Neural Machine Translation by Jointly Learning to Align and Translate(加性注意力)— ICLR 2015
  • 1508.04025 — Effective Approaches to Attention-based Neural Machine Translation — EMNLP 2015
  • 1810.04805 — BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding — NAACL 2019
  • 2005.14165 — Language Models are Few-Shot Learners(GPT-3)— NeurIPS 2020(CCF-A)
  • 1910.10683 — Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer(T5)— JMLR 2020(CCF-A)
  • 2307.09288 — Llama 2: Open Foundation and Fine-Tuned Chat Models — 技术报告 2023
  • 1607.06450 — Layer Normalization — 预印本 2016
  • 1910.07467 — Root Mean Square Layer Normalization(RMSNorm)— NeurIPS 2019(CCF-A)
  • 2002.05202 — GLU Variants Improve Transformer — 预印本 2020
  • 2104.09864 — RoFormer: Enhanced Transformer with Rotary Position Embedding(RoPE)— arXiv 2021,期刊版 Neurocomputing
  • 2108.12409 — Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation(ALiBi)— ICLR 2022
  • 2305.13245 — GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints — EMNLP 2023
  • 2001.04451 — Reformer: The Efficient Transformer — ICLR 2020
  • 2009.14794 — Rethinking Attention with Performers — ICLR 2021
  • 2007.14062 — BigBird: Transformers for Longer Sequences — NeurIPS 2020(CCF-A)
  • 2004.05150 — Longformer: The Long-Document Transformer — 预印本 2020
  • 2006.04768 — Linformer: Self-Attention with Linear Complexity — 预印本 2020
  • 2205.14135 — FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness — NeurIPS 2022(CCF-A)
  • 2312.00752 — Mamba: Linear-Time Sequence Modeling with Selective State Spaces — 预印本 2023
  • 2404.08819 — The Illusion of State in State-Space Models — ICML 2024(CCF-A)
  • 2203.15556 — Training Compute-Optimal Large Language Models(Chinchilla)— NeurIPS 2022(CCF-A)
  • 2101.03961 — Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity — JMLR 2022(CCF-A)
  • 2401.04088 — Mixtral of Experts — 预印本 2024
  • 2412.19437 — DeepSeek-V3 Technical Report — 技术报告 2024
  • 2307.03172 — Lost in the Middle: How Language Models Use Long Contexts — TACL
  • 1902.10186 — Attention is not Explanation — NAACL 2019
  • 2209.10652 — Toy Models of Superposition — 预印本 2022

文章作者: Halensea
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Halensea !
 本篇
Transformer 是怎么工作的 Transformer 是怎么工作的
2017 年那篇论文真正拿掉的不是注意力,而是循环——把序列上不可并行的依赖换成一次矩阵乘法,让序列上任意两个位置直接相乘,此后所有主干模型都长在这个骨架上
2026-10-15
下一篇 
多模态模型 多模态模型
文本是主模态,其它模态都要先被翻译成它——多模态的全部工程问题都从这句话长出来。文本是一种高效的压缩格式,但不是世界的全部格式
2026-10-14
  目录