#一、基础与 Transformer 架构

#代表笔试题

Transformer block 的标准数据流

面试里讲 Transformer,最好不要从“有 Attention、FFN、LayerNorm”这种模块清单开始,而要讲清楚一个 token 表示在一个 block 里怎样被改写。以 Decoder-only LLM 为例,输入 token 先查 embedding 得到 \(X \in R^{n \times d_{model}}\),叠加或旋转注入位置信息后进入第一个 block。每个 block 通常按这条链路运行:归一化后的 hidden states 进入 Self-Attention,Attention 负责从上下文中聚合信息;聚合结果经过输出投影后和原输入做残差相加;再经过一次归一化进入 FFN/SwiGLU,FFN 做逐 token 的非线性特征变换;最后再残差相加,输出给下一层。最后一层 hidden state 经过最终 Norm 和词表投影,得到下一个 token 的 logits。

Q/K/V、softmax 与 causal mask

Self-Attention 的核心是把同一份输入 \(X\) 线性投影成三组向量:\(Q=XW_Q\)、\(K=XW_K\)、\(V=XW_V\)。Query 表示“当前位置想找什么信息”,Key 表示“每个位置能被什么条件匹配”,Value 表示“一旦被关注,要贡献什么内容”。第 \(i\) 个 token 会用自己的 query 与所有可见 token 的 key 做点积,得到相关性分数,再经过缩放和 softmax 变成权重,最后对 value 做加权求和:\(\mathrm{Attention}(Q,K,V)=\mathrm{softmax}(QK^T/\sqrt{d_k}+M)V\)。Decoder-only 里的 \(M\) 是 causal mask:当前位置只能看自己和过去,不能看未来 token,否则训练时会“偷看答案”,自回归生成就不成立。

为什么要除以 \(\sqrt{d_k}\)

如果 \(q\) 和 \(k\) 的每个维度近似均值为 0、方差为 1,那么点积 \(q \cdot k\) 的方差会随维度 \(d_k\) 线性增长。维度越大,logits 越容易变得很大,softmax 会过早饱和成接近 one-hot,梯度变小,训练不稳定。除以 \(\sqrt{d_k}\) 的作用是把点积分数拉回比较稳定的尺度,让 softmax 既能区分相关性,又不至于在初始化阶段就极端尖锐。

复杂度瓶颈

标准全量 Attention 对长度 \(n\) 的序列要形成 \(n \times n\) 的注意力矩阵,所以时间复杂度和注意力权重显存都是 \(O(n^2)\),Q/K/V 投影本身大约是 \(O(nd_{model}^2)\)。长上下文下真正难的是 \(n^2\) 的注意力计算、训练激活显存,以及推理阶段 KV Cache 随层数、长度、batch 增长。很多长上下文优化,本质是在减少可见 token 数、压缩 KV、改变位置编码外推,或把全局注意力换成局部/稀疏/分块注意力。

#代表面试题

Encoder-only、Decoder-only、Encoder-Decoder 的差异

架构注意力可见性典型任务代表性取舍
Encoder-only双向看完整输入分类、检索、embedding、理解任务理解强,但天然不按从左到右生成长文本
Decoder-onlycausal mask,只看历史续写、聊天、代码生成、工具调用训练目标和生成形式一致,适合统一成 next-token prediction
Encoder-DecoderEncoder 双向理解输入,Decoder 自回归生成并 cross-attention 到 Encoder翻译、摘要、条件生成输入输出分工清楚,但系统更复杂,推理缓存和工程路径不如纯 Decoder 统一

LLM 主流选择 Decoder-only,不是因为它在所有任务上理论最优,而是因为它把预训练、指令微调、对话生成、代码补全、工具调用都统一成“给定前文预测下一个 token”。这种统一让数据构造简单、模型接口简单、推理服务简单,KV Cache 也只需要沿着生成方向追加。代价是:模型不能像 Encoder 那样天然双向编码完整输入,很多理解任务要被改写成 prompt-to-answer;长输入会挤占上下文窗口;生成每个 token 都要串行依赖上一个 token;对于固定输入到固定输出的任务,Encoder-Decoder 有时仍然更参数高效或更容易做条件控制。

为什么不是“Decoder-only 永远更强”

面试里要避免把架构选择讲成流行趋势。Encoder-only 在语义向量、召回、rerank、文本分类中仍然常用,因为这些任务需要稳定地读完整段输入,不一定需要生成。Encoder-Decoder 在机器翻译、语音识别后处理、结构化条件生成中仍有优势,因为 source 和 target 分工明确。Decoder-only 的胜出主要发生在通用生成式 LLM 场景:它牺牲了一部分专用结构偏置,换来了训练目标、产品接口、推理工程和多任务范式的高度统一。

#这一块真正考什么

MHA、MQA、GQA 的工程权衡

形式Q 头数K/V 头数主要收益主要代价
MHA多个多个,通常与 Q 一一对应表达力强,不同头可学习不同关系KV Cache 大,长上下文推理成本高
MQA多个共享一组 K/V显著降低 KV Cache 和访存压力K/V 表达容量下降,效果可能损失
GQA多个按组共享 K/V在效果和推理成本之间折中比 MQA 贵,比 MHA 表达略受限

MHA 的直觉是让不同注意力头在不同子空间里看不同关系,例如局部依赖、长程指代、格式边界或代码缩进。MQA/GQA 不是改变 Attention 的基本公式,而是减少 K/V 的头数,从而减少推理时每层需要缓存和读取的 K/V 张量。对于大模型 serving,很多时候瓶颈不是算不动矩阵乘,而是 KV Cache 占显存、访存带宽和并发 batch 被拉低,所以 GQA 成为常见折中。

Pre-Norm、Post-Norm 与训练稳定性

Post-Norm 是早期 Transformer 的形式:子层输出先残差相加,再做 LayerNorm,即 Norm(x + Sublayer(x))。它的输出分布整洁,但深层网络中梯度要穿过很多 Norm,训练容易不稳定。Pre-Norm 把 Norm 放到子层前:x + Sublayer(Norm(x))。这样残差路径更像一条干净的恒等高速路,梯度更容易从深层传回浅层,所以现代 LLM 更常用 Pre-Norm 或其变体。代价是层输出未必每次都被强制归一化,通常会在最后再加 final norm。

FFN、SwiGLU 与 RMSNorm

Attention 负责跨 token 聚合信息,FFN 负责对每个 token 的表示做非线性变换。经典 FFN 是两层 MLP:先把维度从 \(d_{model}\) 扩到更大的中间维度,再用激活函数压回原维度。SwiGLU 把中间层拆成“内容分支”和“门控分支”,形式可理解为 W_down(SiLU(xW_gate) * xW_up),让模型用门控决定哪些特征通过,通常比普通 GELU FFN 更有效。RMSNorm 则只按均方根缩放,不减均值;它比 LayerNorm 更简单、计算更省,在大模型中常与 Pre-Norm、SwiGLU 搭配出现。

#作答抓手

常见误区

  • 把 Attention 说成“找最重要的词”。更准确地说,它是对可见 token 的 value 做加权聚合,权重来自 query-key 相似度。
  • 把 causal mask 说成“只在推理时需要”。训练 next-token prediction 时同样必须 mask 未来 token。
  • 把多头理解成简单投票。多头是在多个低维子空间并行建模关系,最后 concat 或合并后再投影。
  • 把 FFN 当成可有可无。没有 FFN,模型主要只是线性投影和加权平均,表达非线性特征组合的能力会弱很多。
  • 把 Pre-Norm/Post-Norm 只当代码顺序差异。它真正影响深层梯度路径、训练稳定性和是否需要额外 warmup/初始化技巧。

面试回答模板

回答架构题时,可以固定成这条链:输入 token -> embedding/位置 -> QKV 投影 -> causal self-attention 聚合上下文 -> 输出投影和残差 -> Norm -> FFN/SwiGLU 做逐 token 非线性变换 -> 残差 -> 多层堆叠 -> vocab projection 得到 logits。如果面试官追问复杂度,就补充 \(O(n^2)\) attention 和 KV Cache;如果追问架构选择,就从任务形式、训练目标、推理缓存和工程统一性解释 Decoder-only;如果追问大模型细节,就展开 GQA、Pre-Norm、RMSNorm、SwiGLU 这些稳定性和效率改造。

追问链路

  1. 先问公式:Q/K/V 怎么来,softmax 之前为什么缩放,mask 加在哪里。
  2. 再问数据流:一个 block 内 Attention、残差、Norm、FFN 的顺序是什么,Pre-Norm 和 Post-Norm 有什么训练差异。
  3. 再问复杂度:训练时 \(n^2\) 注意力矩阵贵在哪里,推理时 KV Cache 为什么会成为显存和带宽瓶颈。
  4. 再问架构:Encoder-only、Decoder-only、Encoder-Decoder 分别适合什么任务,为什么通用 LLM 偏向 Decoder-only。
  5. 最后问工程取舍:MHA/MQA/GQA 怎么影响效果、显存、吞吐和长上下文 serving。