尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

大模型应用开发--6--Transformer架构介绍

大模型应用开发--6--Transformer架构介绍 Transformer 架构详解2017 年 Google 论文Attention Is All You Need提出是 GPT、BERT 等大模型的基石。目录1. 核心概念2. Token文本的最小单位3. 整体架构4. 词嵌入 位置编码5. 自注意力机制Self-Attention6. 多头注意力Multi-Head Attention7. 前馈网络 残差连接 层归一化8. 掩码机制Masking9. 交叉注意力Cross-Attention10. 自回归生成过程11. 输出层Logits → Softmax → 选词12. 训练 vs 推理13. Transformer 家族14. 面试高频问题速答15. 总结1. 核心概念一句话概括Transformer 是一种不依赖循环RNN完全靠**注意力机制Attention**来理解上下文关系的深度学习架构。与 RNN 的对比对比项RNN/LSTMTransformer处理方式逐词阅读顺序处理所有词同时处理并行计算长距离依赖信息会衰减注意力直接连接任意位置无衰减训练速度慢无法并行快GPU 友好可并行可扩展性堆层效果有限参数越多能力越强Scaling Law2. Token文本的最小单位Token ≠ 词Token ≠ 词 ID概念本质例子文本原始字符串unbelievableToken切分后的最小单元字符串[un, ##believ, ##able]Token IDToken 在词表中的编号整数[489, 23871, 3450]为什么要用子词Subword级别方案词表大小问题词级别50万词表太大罕见词无法覆盖字符级别~100序列太长语义信息弱子词级别3万~10万平衡词表大小和序列长度 ✅主流分词算法算法使用模型原理BPEGPT 系列从字符开始反复合并最高频的相邻对WordPieceBERT类似 BPE但合并标准是最大化语言模型似然SentencePieceT5/LLaMA不依赖空格直接把整句话当字节流处理在 Transformer 中的流程我爱NLP → 分词器: [我, 爱, N, LP] ← Token字符串 → 查词表: [5, 12, 308, 456] ← Token ID整数 → 查嵌入表: [[0.2,0.5,...], ...] ← 嵌入向量 → 送入 Transformer3. 整体架构Transformer 由Encoder编码器和Decoder解码器两大部分组成原始论文中各堆叠 6 层每层结构相同但参数不同。3.1 完整架构图输入: 我爱NLP 输出: I love NLP │ ▲ ▼ │ ┌────────────────┐ ┌────────────────┐ │ 词嵌入 │ │ 线性层Softmax │ │ (Input Embedding)│ │ (输出层,不属于 │ └───────┬────────┘ │ 6层之内) │ │ └────────▲───────┘ ▼ │ ┌────────────────┐ │ │ 位置编码 │ │ │ (Positional │ │ │ Encoding) │ │ └───────┬────────┘ │ │ │ ▼ 相加(⊕) │ ┌──────────┐ │ │ X (5×4) │ Encoder最终输出 H (5×4) │ └────┬─────┘ 传给Decoder每一层的 │ │ Cross-Attention的 K 和 V │ ▼ (6层都用同一个H) │ ┌──────────────────────────────┐ ┌───────────▼─────────────────── │ Encoder Layer 1 │ │ Decoder Layer 1 │ │ ┌────────────────────────┐ │ │ ┌────────────────────────┐ │ │ │ ① 多头自注意力(无掩码) │ │ │ │ ① 掩码多头自注意力 │ │ │ │ 残差 LayerNorm │ │ │ │ 残差 LayerNorm │ │ │ ├────────────────────────┤ │ │ ├────────────────────────┤ │ │ │ ② 前馈网络 FFN │ │ │ │ ② 交叉注意力 │ │ │ │ 残差 LayerNorm │ │ │ │ Q←Decoder K,V←Encoder│ │ │ └────────────────────────┘ │ │ │ 残差 LayerNorm │ │ │ │ │ ├────────────────────────┤ │ │ (2个子层) │ │ │ ③ 前馈网络 FFN │ │ │ │ │ │ 残差 LayerNorm │ │ │ │ │ └────────────────────────┘ │ │ │ │ │ │ │ │ (3个子层) │ └──────────────┬───────────────┘ └──────────────▲───────────────┘ │ │ ┌──────┴──────┐ ┌──────┴──────┐ │ │ │ │ ▼ │ │ │ ┌──────────────────────┐ ┌──────┴──────────────┐ │ Encoder Layer 2~5 │ │ Decoder Layer 2~5 │ │ (结构同Layer 1) │ │ (结构同Layer 1) │ │ 每层参数不同 │ │ 每层参数不同 │ └──────────┬───────────┘ └──────▲──────────────┘ │ │ ▼ │ ┌──────────────────────┐ ┌──────┴──────────────┐ │ Encoder Layer 6 │ │ Decoder Layer 6 │ │ (结构同Layer 1) │ │ (结构同Layer 1) │ └──────────┬───────────┘ └──────▲──────────────┘ │ │ └─────────────────────────────────────┘Encoder最终输出 H (5×4) 传给Decoder每一层的Cross-Attention的 K 和 V (6层都用同一个H)在Input Embedding[词嵌入]前还有一步数据预处理: 分词[使用tokenizer分词获取token] 和 查词表[从词表中查找token id]。数据预处理不属于transformer架构中的所以transformer架构图从Input Embedding开始Input Embedding根据token id从嵌入表中查看相应token的向量。3.2 Encoder 每层结构2个子层Encoder Layer: ① 多头自注意力无掩码 残差 LayerNorm ② 前馈网络 FFN 残差 LayerNorm数据流我爱NLP → 分词 嵌入 位置编码 → X (5×4) → Layer 1: 自注意力 → FFN → 输出 → Layer 2: 自注意力 → FFN → 输出 → ... → Layer 6: 自注意力 → FFN → 最终输出 H (5×4) H 源语言的上下文表示传给 Decoder 每一层的 Cross-Attention3.3 Decoder 每层结构3个子层Decoder Layer: ① 掩码自注意力Masked Self-Attention 残差 LayerNorm ② 交叉注意力Cross-Attention 残差 LayerNorm ③ 前馈网络 FFN 残差 LayerNorm 输出层不属于6层之内: 线性层 Softmax → 选词三个子层各自的作用子层Q/K/V 来源作用① 掩码自注意力Q,K,V 都来自 Decoder 输入理解已生成词之间的关系掩码防止看到未来② 交叉注意力Q 来自 DecoderK,V 来自 Encoder从源语言中提取相关信息翻译的依据③ FFN上一步的输出非线性变换增强表达能力3.4 Encoder vs Decoder 对比对比项Encoder 每层Decoder 每层自注意力✅无掩码✅有掩码交叉注意力❌✅前馈网络 FFN✅✅子层数2 个3 个计算量较小较大多两次注意力3.5 关键设计要点Encoder 只跑一次输入源语言后6层处理完输出 H结果固定不变Decoder 循环跑每生成一个词跑一次自回归逐词生成6层共用同一个 HDecoder 每一层的 Cross-Attention 都直接从 Encoder 的同一个输出 H 取 K/V不是层间传递输出层在6层之外线性层 Softmax 是独立的输出头不属于 Decoder 的任何一层4. 词嵌入 位置编码4.1 词嵌入每个 Token ID 查嵌入表得到一个 d_model 维向量原始论文 d_model512。4.2 为什么需要位置编码Transformer 同时处理所有词没有顺序概念。我打你和你打我如果没有位置编码模型看到的是完全相同的向量集合。所以需要给每个位置一个独特的指纹。4.3 位置编码公式PE(pos, 2i) sin(pos / 10000^(2i/d_model)) PE(pos, 2i1) cos(pos / 10000^(2i/d_model))pos 词在句子中的位置1, 2, 3, …i 维度对的索引0, 1, 2, …d_model 嵌入维度总数4.4 为什么需要两个公式sin cossin 和 cos 配对 单位圆上的一个点 (x, y) 唯一确定一个角度状态。单独用 sin 会有歧义sin(30°) sin(150°) 0.5加上 cos 就能区分cos(30°) 0.866 ≠ cos(150°) -0.866。4.5 多频率的意义不同维度对使用不同频率就像时钟的秒针、分针、时针维度对0 (i0): 频率 1/10000^(0/d) ← 高频秒针区分相邻位置 维度对1 (i1): 频率 1/10000^(2/d) ← 中频分针 ... 维度对N (iN): 频率 1/10000^(2N/d) ← 低频时针区分远距离位置高频能精确区分相邻位置但周期短远距离会重复低频无法区分相邻位置但周期长能区分远距离位置组合近看靠高频远看靠低频4.6 相对位置的表达sin((posk)·ω) sin(pos·ω)·cos(k·ω) cos(pos·ω)·sin(k·ω) cos((posk)·ω) cos(pos·ω)·cos(k·ω) - sin(pos·ω)·sin(k·ω) → 偏移量 k 对应一个固定的旋转矩阵不依赖绝对位置 pos → 位置3→5 和 位置100→102 的变换完全相同 → 模型能学到相隔k个位置的一致语义关系4.7 计算示例d_model45个位置维度对0: ω₀ 1/10000^(0/4) 1.0 维度对1: ω₁ 1/10000^(2/4) 0.01 sin(ω₀) cos(ω₀) sin(ω₁) cos(ω₁) pos 1 [ 0.84, 0.54, 0.01, 1.00 ] pos 2 [ 0.91, -0.42, 0.02, 1.00 ] pos 3 [ 0.14, -0.99, 0.03, 1.00 ] pos 4 [ -0.76, -0.65, 0.04, 1.00 ] pos 5 [ -0.96, 0.28, 0.05, 1.00 ] 前两列高频变化剧烈 → 区分相邻位置 后两列低频变化缓慢 → 区分远距离位置4.8 最终输入 词嵌入 位置编码最终输入 Embedding(token_id) PE(pos)5. 自注意力机制Self-Attention5.1 三个角色角色含义类比Query (Q)“我在找什么信息”图书馆搜索的关键词Key (K)“我能提供什么信息”每本书的标签/标题Value (V)“我的实际内容是什么”书的正文内容5.2 计算步骤① 生成 Q, K, V: X × W_Q → Q, X × W_K → K, X × W_V → V 三个权重矩阵 W_Q, W_K, W_V 各不相同训练学习 ② 计算注意力分数: Score Q × Kᵀ / √d_k 除以 √d_k 防止分数过大 ③ Softmax 归一化: 把分数变成概率分布0~1和为1 ④ 加权求和 V: Output Attention权重 × V5.3 为什么除以 √d_k当 d_k 较大时Q·K 的点积值会很大导致 softmax 梯度变得很小进入饱和区。除以 √d_k 把分数缩回到合理范围保证梯度稳定。5.4 Softmax 归一化softmax(x_i) e^(x_i) / Σ(e^(x_j))为什么需要 Softmax 而不是直接用原始分数原因说明变成权重分数可负、无界Softmax 后全为正数和为1天然是权重尺度稳定不归一化时序列越长输出越大Softmax 后无论多长都稳定放大差异e^x 指数放大让强信号更突出差异大时赢家通吃5.5 加权求和 V 的含义每个词不再只代表自己而是变成了我 我关注的那些词的信息的融合体。自然的输出 24%×V(自然) 22%×V(语言) 21%×V(我) 18%×V(处理) 16%×V(爱) 自然语言处理这个整体概念的上下文表示 → 同一个词在不同句子中因为上下文不同会得到不同的输出向量 → 模型因此能理解多义词、指代关系、长距离依赖5.6 为什么用 V 而不是原始输入 XX 词嵌入 位置编码 → 我是谁我在哪原始身份 V X × W_V线性变换 → 我能提供什么信息投影后的内容 类比: X 一个人的身份证, V 这个人的专业技能5.7 计算示例我的注意力分数: [0.25, 0.33, 0.66, 0.42, 0.03] e^x: [1.28, 1.39, 1.93, 1.52, 1.03] Sum7.16 softmax: [0.18, 0.19, 0.27, 0.21, 0.14] ← 自然权重最高 加权求和: Out(我) 0.18×V(我) 0.19×V(爱) 0.27×V(自然) 0.21×V(语言) 0.14×V(处理)6. 多头注意力Multi-Head Attention核心思想一个注意力头只关注一种关系。多个头可以关注不同维度的关系Head 1: 关注语法关系主谓宾 Head 2: 关注语义关系同义/反义 Head 3: 关注指代关系他指代谁 ... Head 8: 关注长距离依赖 → 拼接所有头的结果 → 线性变换 → 最终输出计算流程① 把 d_model 维向量分成 h 个头每个头 d_k d_model / h 维 ② 每个头独立计算 Q·Kᵀ/√d_k → softmax → 加权V ③ 拼接所有头的输出: Concat(head₁, head₂, ..., headₕ) → (seq_len × d_model) ④ 乘以输出权重矩阵 W_O → 最终输出7. 前馈网络 残差连接 层归一化7.1 前馈网络FFNFFN(x) max(0, x × W₁ b₁) × W₂ b₂ 第一层: d_model → 4×d_model扩展4倍 ReLU 激活 第二层: 4×d_model → d_model压缩回来 → 对每个位置独立做非线性变换模型能学到复杂的特征变换增强表达能力7.2 残差连接输出 LayerNorm(x SubLayer(x)) → 把输入直接加回来保证原始信息不丢失 → 解决深层网络梯度消失问题 → 注意力/FFN 只是额外添加上下文7.3 层归一化LayerNorm层归一化的含义残差连接后训练模型时不同位置的向量数值范围差异很大有的均值 1.15有的均值 0.12直接传入下一层会导致训练不稳定。LayerNorm 把每个位置的向量独立地归一化到均值≈0、方差≈1的统一尺度让所有位置在同一数值范围内被下一层处理从而稳定训练、加速收敛推理时维持数值稳定性和训练时一致的归一化操作对每一行每个词的向量独立计算① 均值: μ (x₁ x₂ ... x_d) / d ② 方差: σ² Σ(x_i - μ)² / d ③ 归一化: x̂_i (x_i - μ) / √(σ² ε) ④ 缩放偏移: y_i γ × x̂_i β γ, β 是可学习参数计算示例我的向量 [1.28, 1.18, 0.09, 2.05]μ (1.28 1.18 0.09 2.05) / 4 1.15 σ² [(0.13)² (0.03)² (-1.06)² (0.90)²] / 4 0.488 σ √0.488 0.699 归一化: [(1.28-1.15)/0.699, (1.18-1.15)/0.699, (0.09-1.15)/0.699, (2.05-1.15)/0.699] [0.19, 0.04, -1.52, 1.29] → 均值≈0方差≈1所有行统一到相同尺度归一化前后对比归一化前数值范围不统一: 我: [1.28, 1.18, 0.09, 2.05] → 均值1.15范围 [0.09, 2.05] 爱: [1.92, -0.75, 0.55, 1.34] → 均值0.77范围 [-0.75, 1.92] 处理:[-0.61,-1.13, 0.38, 1.83] → 均值0.12范围 [-1.13, 1.83] → 每行数值范围差异大下一层处理时不稳定 归一化后统一到相同尺度: 我: [0.19, 0.04, -1.52, 1.29] → 均值≈0方差≈1 爱: [1.15, -1.51, -0.21, 0.57] → 均值≈0方差≈1 处理:[0.27, -0.89, 0.51, 0.11] → 均值≈0方差≈1 → 所有行统一尺度训练稳定为什么用 LayerNorm 而不是 BatchNorm对比BatchNormLayerNorm归一化方向对同一维度跨样本归一化列方向对同一样本的所有维度归一化行方向适用场景CNN图像Transformer/RNNbatch size 依赖依赖变化时不稳定不依赖每个样本独立计算γ 和 β 的作用归一化后所有维度被强制拉到均值0、方差1但并非每个维度都需要相同的分布。γ缩放和 β偏移让模型自己决定每个维度的最佳数值分布初始 γ1, β0训练中学习调整。8. 掩码机制Masking8.1 为什么需要掩码训练时: Decoder 一次性处理整个目标序列love 能看到 NLP 推理时: 逐词生成生成 love 时 NLP 还不存在 → 如果训练时不加掩码love 会依赖 NLP 的信息 → 推理时没有 NLP模型就懵了 → 必须用掩码强制切断未来信息8.2 掩码矩阵输入: [START, I, love, NLP, END] 掩码矩阵 M (5×5): START I love NLP END START [ 0, -∞, -∞, -∞, -∞ ] I [ 0, 0, -∞, -∞, -∞ ] love [ 0, 0, 0, -∞, -∞ ] NLP [ 0, 0, 0, 0, -∞ ] END [ 0, 0, 0, 0, 0 ] 0 允许看不遮挡 -∞ 遮挡不允许看未来的词 规律: 下三角矩阵当前位置只能看自己和之前的位置8.3 掩码如何参与计算第1步: 算注意力分数 Q·Kᵀ/√d_k START I love I [ 0.48, 0.82, 0.65] 第2步: 加掩码未来位置变 -∞ START I love I [ 0.48, 0.82, -∞ ] 第3步: Softmax-∞ → 0未来词权重为0 START I love I [ 0.42, 0.58, 0.00] 第4步: 加权求和 V未来词的 V 贡献为0 Out(I) 0.42×V(START) 0.58×V(I) 0.00×V(love)8.4 推理时掩码的作用推理时虽然没有未来词掩码仍然必须加目的是保持和训练时一致。不加掩码: START 会看到 I 和 love → 它的表示和训练时不一致 → 预测出错 加掩码: 每个位置只看该看的 → 和训练时一致 → 预测正确 本质: 掩码 训练和推理之间的一致性保证8.5 只有一个START时的掩码序列长度1掩码矩阵 M (1×1) [0] → 没有未来词可遮掩码不起作用 → 注意力权重 [1.0]100%关注自己 → 输出 V 本身9. 交叉注意力Cross-Attention9.1 Q/K/V 来源Q 来自 Decoder 当前输出: 我需要什么信息 K 来自 Encoder 最终输出 H: 源文本各词的标签 V 来自 Encoder 最终输出 H: 源文本各词的内容9.2 一个 Encoder 输出如何变成 K 和 VEncoder 输出只有一个矩阵 H (5×4) K H × W_K^cross ← 乘以一个权重矩阵提取可被匹配的标签 V H × W_V^cross ← 乘以另一个权重矩阵提取可被提取的内容 类比: 同一份档案用关键词提取器得到标签(K)用内容提取器得到详情(V)9.3 6层的 K/V 都来自同一个 Encoder 输出✅ 正确理解: Layer 1~6 的 Cross-Attention 中K 和 V 每层都直接来自 Encoder 的同一个输出 H 不同的是每层有自己的 W_K 和 W_V从同一个 H 中提取不同维度的信息 ❌ 错误理解: Layer 2 的 K,V 来自 Layer 1不是9.4 计算示例Decoder的Q: [0.45, 0.30, 1.35, 0.50] Encoder的K (5×4): 我[0.72,0.48,0.15,1.20], 爱[1.55,-0.35,0.62,0.88], ... 注意力分数: Score(START, 我) Q·K(我)/2 0.635 Score(START, 爱) Q·K(爱)/2 0.935 Score(START, 自然) Q·K(自然)/2 1.012 ← 最高 Score(START, 语言) Q·K(语言)/2 0.346 Score(START, 处理) Q·K(处理)/2 0.498 softmax → [0.184, 0.249, 0.269, 0.138, 0.161] → START 最关注 自然(0.269) 和 爱(0.249)9.5 三种注意力对比注意力类型Q 来源K 来源V 来源Encoder 自注意力Encoder 输入 XEncoder 输入 XEncoder 输入 XDecoder 掩码自注意力Decoder 输入 YDecoder 输入 YDecoder 输入 Y交叉注意力Decoder 输出Encoder 输出 HEncoder 输出 H10. 自回归生成过程10.1 核心机制把上一步的输出当作下一步的输入 自己生成的结果 → 回头喂给自己 → 生成下一个结果 → 再喂回去 → ... 就像接龙: 看到 START → 接 I 看到 START I → 接 love 看到 START I love → 接 NLP 看到 START I love NLP → 接 END停止10.2 完整流程“我爱NLP” → “I love NLP”Encoder只跑1次: 我爱NLP → H (5×4) Decoder循环跑: 步骤1: 输入 [START] → 预测 I 步骤2: 输入 [START, I] → 预测 love 步骤3: 输入 [START, I, love] → 预测 NLP 步骤4: 输入 [START, I, love, NLP] → 预测 END → 停止 最终输出: I love NLP10.3 每步输入的变化时间步 Decoder输入 Encoder参考 预测输出 ─────────────────────────────────────────────────────────── 1 [START] 我爱NLP → I 2 [START, I] 我爱NLP → love 3 [START, I, love] 我爱NLP → NLP 4 [START, I, love, NLP] 我爱NLP → END 每次都把上一步的输出加到输入末尾10.4 为什么每步只取最后一个位置的输出输入: [START, I, love] Decoder 输出3个向量: 位置0 (START) → 向量A ← 预测I时用的现在不需要了 位置1 (I) → 向量B ← 预测love时用的现在不需要了 位置2 (love) → 向量C ← 用这个预测下一个词 NLP → 每次只需要最后一个位置的输出 → 因为它包含了看完所有已生成词后下一个词应该是什么的信息10.5 停止条件模型预测出END标记 → 停止如果一直不输出END设置最大长度强制停止11. 输出层Logits → Softmax → 选词11.1 线性层Decoder 6层最终输出: [1.85, 0.32, 0.15, 0.92] (4维) │ ▼ 乘以权重矩阵 W (4×10000[嵌入表有10000各token])W 是训练学习的 │ Logits (1×10000): [8.5, 2.1, 1.8, 0.3, -0.5, ...] I love the NLP END ... → 每个词的分数 Decoder输出向量 和 该词权重向量的点积 → 点积越大说明 Decoder 输出和该词越匹配Logits 的维度训练 vs 推理训练时: n×10000每个位置都有 logits并行预测所有词 推理时: n×10000但只用最后一个位置的 logits 预测下一个词11.2 Softmax → 概率分布P(I) e^8.5 / Σ 99.67% ← 最高 P(love) e^2.1 / Σ 0.17% P(the) e^1.8 / Σ 0.12% ...11.3 选词策略策略方式适用场景Greedy贪心选概率最高的简单快速翻译任务Beam Search束搜索保留 top-k 条路径综合选最优翻译任务常用Top-k / Top-p Sampling从 top-k 中随机采样ChatGPT 等生成任务增加多样性12. 训练 vs 推理12.1 核心区别对比项训练推理Decoder 输入完整目标序列一次性输入逐词输入自回归计算方式并行计算所有位置串行逐词生成掩码作用防止看到未来词模拟自回归保持和训练一致输出所有位置的 logits 都用只用最后一个位置的 logitsEncoder每次重新算只算一次结果固定速度快并行慢串行越长越慢12.2 训练时的 Teacher Forcing训练时不用模型自己生成的词作为输入而是用真实答案Ground Truth: 输入: [START, I, love, NLP] 目标: [I, love, NLP, END] 位置1: START → 预测 I 和目标 I 比较算 loss 位置2: I → 预测 love 和目标 love 比较算 loss ... 好处: 不依赖前一步的预测结果避免错误累积训练效率高12.3 推理效率优化KV Cache朴素推理的问题步骤1: 输入 [START] → Decoder 处理 1 个词 → 预测 I 步骤2: 输入 [START, I] → Decoder 处理 2 个词 → 预测 love 步骤3: 输入 [START, I, love] → Decoder 处理 3 个词 → 预测 NLP 步骤4: 输入 [START, I, love, NLP] → Decoder 处理 4 个词 → 预测 END 问题: 步骤2 重新计算了 START 的 K,V步骤3 又重新计算了 START, I 的 K,V... 大量重复计算序列越长浪费越严重KV Cache 的核心思想缓存已计算过的 K, V每步只计算新词的 K, V: 步骤1: 输入 [START] → 计算 K₁,V₁ → 存入缓存 → 缓存: K[K₁], V[V₁] → 用完整 K,V 做 attention → 预测 I 步骤2: 输入 [I]只输入新词 → 计算 K₂,V₂ → 追加到缓存 → 缓存: K[K₁,K₂], V[V₁,V₂] → 用缓存中完整的 K,V 做 attention → 预测 love 步骤3: 输入 [love]只输入新词 → 计算 K₃,V₃ → 追加到缓存 → 缓存: K[K₁,K₂,K₃], V[V₁,V₂,V₃] → 用缓存中完整的 K,V 做 attention → 预测 NLP → 每步只处理 1 个新词不重复计算之前的词朴素推理 vs KV Cache 对比对比项朴素推理KV Cache每步输入完整序列n 个词只输入新词1 个词每步计算量O(n)O(1)只算新词的 K,V重复计算大量重复无重复额外开销无需要存储 K,V 缓存显存换速度总计算量n 步O(n²)O(n)输出层也只算最后一个位置Decoder 6层最终输出: n × d_model 矩阵 线性层: 输出 × W → n × vocab_size 的 logits 朴素做法: 计算所有 n 行的 logits → 只用最后一行做 softmax 优化做法: 只取最后一行 → 只计算 1 × d_model × W → 1 × vocab_size → 和 KV Cache 配合每步只处理 1 个词从输入到输出全程无浪费13. Transformer 家族模型类型特点适用任务BERT仅 Encoder双向理解分类、问答、NERGPT 系列仅 Decoder自回归生成对话、写作、代码生成T5 / BARTEncoder Decoder通用 seq2seq翻译、摘要ViTEncoder 变体图像分 patch 当词图像分类14. 面试高频问题速答Q1: Transformer 为什么比 RNN 好并行计算所有位置同时处理、长距离依赖无衰减、可扩展性强参数越多能力越强。Q2: 自注意力的 Q/K/V 分别是什么QQuery “我在找什么信息”KKey “我能提供什么信息”VValue “我的实际内容”。通过 Q·Kᵀ 算关联度softmax 归一化后加权求和 V得到上下文感知的表示。Q3: 为什么除以 √d_k防止点积值过大导致 softmax 进入饱和区梯度消失。√d_k 是点积方差的标准化因子。Q4: 位置编码为什么用 sin/cos三个原因①有界值在 [-1,1]②每个位置有唯一编码sincos 配对确定单位圆上的点③能表达相对位置偏移 k 对应固定旋转矩阵不依赖绝对位置。多频率设计让高频区分近距离、低频区分远距离。Q5: Decoder 的掩码是什么为什么需要上三角矩阵把未来位置的注意力分数设为 -∞softmax 后变成 0。训练时防止偷看未来词推理时保持和训练一致。本质是训练和推理之间的一致性保证。Q6: 交叉注意力的 K/V 从哪来来自 Encoder 的最终输出 H。H 乘以 W_K 得到 K乘以 W_V 得到 V。6 层 Decoder 的每一层都直接从同一个 H 取 K/V不是层间传递但每层的 W_K/W_V 不同提取不同维度的信息。Q7: Decoder 是怎么逐词生成的自回归把上一步的输出加到输入末尾作为下一步的输入。每次只用最后一个位置的输出预测下一个词。遇到END停止。Q8: 训练和推理有什么区别训练时并行处理完整序列Teacher Forcing所有位置的 logits 都用推理时串行逐词生成只用最后一个位置的 logits。训练快并行推理慢串行。Q9: LayerNorm 和 BatchNorm 的区别BatchNorm 对同一维度跨样本归一化列方向依赖 batch sizeLayerNorm 对同一样本的所有维度归一化行方向不依赖 batch size。Transformer 用 LayerNorm 因为序列长度可变且 batch size 不稳定。Q10: 多头注意力为什么有用不同的头可以关注不同维度的关系语法、语义、指代、长距离依赖等拼接后得到更丰富的表示。Q11: Logits 是什么线性层输出的每个词的原始分数未归一化。Decoder 输出 d_model 维向量乘以权重矩阵 W (d_model × vocab_size) 得到 vocab_size 维的 logits每个维度对应词表中一个词的得分。Q12: Transformer 的参数量主要在哪注意力层的 Q/K/V 权重矩阵、FFN 的两层全连接占参数量最大因为扩展 4 倍、嵌入矩阵vocab_size × d_model。层越深、d_model 越大、词表越大参数越多。附关键数字对照参数教学示例GPT-2 SmallGPT-3d_model476812,288注意力头数11296层数61296词表大小~10050,25750,257参数量~几千1.17亿1,750亿核心机制完全一样只是规模不同。这就是 Scaling Law 的魅力——同一架构参数越多能力越强。15 总结- 数据预处理用户输入的文本 - 分词: Tokenizer 将原始文本切分为子词级别的 Token如 unbelievable → un, ##believ, ##able - 查词表: 根据 Token 字符串在词表中查找对应的整数编号Token ID如 我,爱 → 5, 12 - 编码器 - Input Embedding用 Token ID 查嵌入表把整数 ID 映射为 d_model 维稠密向量让模型能在连续空间中处理文本 - 位置编码 - 位置编码意义Transformer 并行处理所有词没有顺序概念位置编码给每个位置一个独特的指纹让模型区分我打你和你打我 - 6层 - 多头自注意力 - 计算QKV - Q: 输入 X 乘以权重矩阵 W_Q表示我在找什么信息 - K: 输入 X 乘以权重矩阵 W_K表示我能提供什么信息 - V: 输入 X 乘以权重矩阵 W_V表示我的实际内容是什么 - 计算 softmax(QK^T/√d_k)V - QK^T的意义计算每个词的 Query 和所有词的 Key 的点积得到词与词之间的关联度分数矩阵点积越大说明两个词越相关 - /√d_k的意义当 d_k 较大时点积值会很大导致 softmax 进入饱和区梯度消失除以 √d_k 把分数缩回合理范围保持梯度稳定 - softmax的意义QK^T 算出的注意力分数有三个问题——可正可负负数无法作为权重、无上界某个词分数特别大时会完全压制其他词、 总和不确定序列越长总分越大导致加权求和后的输出幅度不稳定。Softmax 通过 e^x 指数运算一次性解决这三个问题 所有值变成正数、归一化到和为1无论序列多长输出幅度都稳定、指数放大差异让强信号更突出从而得到一组公平、可 比较的注意力权重 - softmax()V的意义用归一化后的注意力权重对 V 加权求和让每个词的输出变成自己 关注的那些词的信息的融合体实现上下文感知 - 残差连接层归一化 - 残差连接的操作把子层输入直接加到子层输出上即 Output x SubLayer(x) - 残差连接意义保证原始信息不丢失解决深层网络梯度消失问题让注意力/FFN 只是额外添加上下文 - 层归一化操作对每个词的向量独立计算均值和方差归一化到均值≈0、方差≈1再用 γ 缩放、β 偏移 - 层归一化意义统一各位置向量的数值范围稳定训练、加速收敛推理时维持和训练一致的计算流程 - 前馈网络 - 操作两层全连接先 d_model→4×d_model 扩展经 ReLU 激活再 4×d_model→d_model 压缩回来 - 意义对每个位置独立做非线性变换没有 ReLU 多层线性变换会坍缩成一层模型丧失非线性表达能力。自注意力本质是加权求和线性操作 只能决定看哪些词无法改变特征本身的表达。FFN 通过 ReLU 引入非线性让模型能学到如果特征A强且特征B弱则激活特征C这类 复杂的条件逻辑。如果全程都是线性变换无论堆多少层都等价于一层 y Wx b只能画直线、切平面无法拟合语言中大量的非线性 规律如多义词在不同上下文含义不同、语法规则的条件触发等。一句话注意力负责信息路由FFN 的非线性负责特征加工缺一不可 - 残差连接层归一化 - 数据预处理已经生成的文本 - 分词: Tokenizer 将已生成的文本切分为 Token与编码器使用同一个分词器 - 查词表: 查找每个 Token 对应的 Token ID与编码器共用同一个词表 - 解码器 - Output Embedding用 Token ID 查嵌入表得到向量与编码器的 Input Embedding 共用同一张嵌入表 - 位置编码 - 6层 - 掩码多头自注意力 - 操作和普通自注意力一样算 QK^T/√d_k但加上三角掩码矩阵把未来位置的分数设为 -∞softmax 后权重变 0 - 意义防止当前位置偷看未来的词保证训练时的计算方式和推理时逐词生成一致 - 残差连接层归一化 - 交叉多头自注意力 - KV 来自于编码器输出 H×W_K、H×W_VQ 来自于解码器掩码多头自注意力的输出×W_Q - 残差连接层归一化 - 前馈网络 - 残差连接层归一化 - Linear - 操作Decoder 6层最终输出 × 权重矩阵 W (d_model × vocab_size) 得到 logits每个维度对应词表中一个词的得分 实际工程中的做法 - 训练时 不用 KV Cache 所有位置并行计算本来就需要所有位置的 logits 算 loss 线性层 n×vocab_size 全算没有浪费 - 推理时 用 KV Cache 每次只输入1个新词 Decoder 6层只处理1个位置 线性层只算1行 → 几乎零浪费 - 意义把 Decoder 的抽象向量映射到词表空间给每个词打一个匹配分数充当抽象向量→选词的桥梁 - Softmax将 logits 转成概率分布0~1、和为1分数越高的词概率越大 - 选词策略 - temperature控制概率分布的陡峭程度值越低分布越尖锐更确定值越高分布越平坦更随机 - top_k只从概率最高的 k 个词中采样直接截断低概率词k 越小越保守 - top_p从概率最高的词开始累加直到累计概率达到 p如 0.9为止只在这个范围内采样比 top_k 更灵活
返回列表