#模块一:基础与 Transformer 架构知识点
#知识地图:先把 Transformer 当成一条数据流
模块一的核心不是背十二个问题,而是能把一句话从输入 token 一直讲到下一个 token 的预测。标准 Decoder-only LLM 的主线可以压成:tokens -> embedding -> position signal -> N 个 Transformer block -> final norm -> lm head -> logits。每个 block 里通常是两段计算:先用 self-attention 做跨位置的信息交换,再用 FFN/MLP 对每个位置独立做非线性变换;两段外面都有 residual 和 norm 来稳定深层训练。
面试时要主动区分三类架构。Encoder-only 像 BERT,更擅长把整段输入编码成双向表示,适合分类、匹配、抽取等理解任务;Encoder-Decoder 像 T5/BART,encoder 双向读输入,decoder 自回归生成输出,适合翻译、摘要这类条件生成;Decoder-only 像 GPT 系列,只用因果自注意力预测下一个 token,把预训练、指令跟随、多轮对话和工具调用都统一到“给定前缀继续生成”的接口里。今天的大模型偏向 Decoder-only,不是因为它在所有任务上天然最优,而是因为统一目标、数据构造、扩展训练和在线生成链路更简单。
#核心机制:Q/K/V、缩放与 mask
Self-Attention 可以理解成“每个位置根据当前问题,从整段上下文里动态取证”。输入隐藏状态 X 会通过三组线性投影得到 Q、K、V:Q 表示当前位置想找什么信息,K 表示每个位置能被什么查询匹配,V 表示一旦被选中,真正贡献给输出的内容。公式是:
QK^T 得到的是 token 两两之间的相关性分数;softmax 把分数变成权重;最后乘以 V,得到每个位置聚合后的上下文表示。这里最容易误解的是:attention 权重不是最终语义本身,它只是“从哪些位置取多少信息”的路由;真正的表达还要经过输出投影、多层堆叠和 MLP 加工。
为什么要除以 sqrt(d_k)?如果 q 和 k 的每一维方差大致为 1,那么内积 q · k 会累加 d_k 个随机项,方差随 d_k 增大。维度越大,分数越容易变成很大的正数或负数,softmax 就会过早接近 one-hot,梯度集中在少数位置,训练变得不稳定。除以 sqrt(d_k) 的作用是把分数尺度拉回可控范围,让 softmax 还处在有梯度、有区分度的区域;这不是经验玄学,而是数值尺度控制。
M 是 mask。Padding mask 用来屏蔽补齐出来的空 token,避免模型把 padding 当成真实内容;causal mask 用来屏蔽当前位置之后的未来 token,保证第 t 个位置只能看 1..t 的前缀。没有 causal mask,自回归训练会偷看答案,loss 会虚假变低,推理时却无法复现训练条件。Decoder-only 的“只能往左看”就是 causal mask 实现的。
#从单头到多头:表达能力与推理成本
单头 attention 只能在一个投影空间里计算相似度。Multi-Head Attention 会把隐藏维度切成多个 head,每个 head 有自己的 Q/K/V 投影,在不同子空间里学习不同关系:有的头可能偏局部搭配,有的头偏长程指代,有的头偏格式边界。多个 head 的输出拼接后再过 output projection,模型就能把多种证据模式合成一个隐藏状态。多头不是“复制多份同样的 attention”,而是把一个大表示分解成多个可并行的关系通道。
工程上又要区分 MHA、MQA、GQA。MHA 中 query heads 和 key/value heads 一样多,表达充分,但 KV cache 最大;MQA 让所有 query heads 共享一组 K/V,推理缓存和带宽压力显著下降,但质量可能受损;GQA 把多个 query heads 分成若干组,每组共享一组 K/V,是质量和成本之间的折中。面试里不要只说“GQA 更省显存”,要说清楚省的是解码阶段每层缓存的 K/V 头数,以及读取 KV cache 的 HBM 带宽。
#工程取舍:Decoder-only、Norm 位置与长上下文瓶颈
Decoder-only 的优势是统一。预训练时做 next-token prediction,SFT 时把 prompt 和 answer 拼成序列,RLHF/DPO 时也围绕生成结果优化,线上 serving 则天然逐 token decode。这个统一接口让数据、训练、推理和产品形态都更顺。但代价也明确:生成必须串行,不能一次并行产出所有 token;条件输入没有 encoder 那样独立、双向、结构化地编码;对部分强条件生成或理解任务,Encoder-Decoder 或 Encoder-only 仍可能更自然。
Pre-Norm 和 Post-Norm 关注的是 LayerNorm 放在残差分支的哪里。Post-Norm 常写成 x_{l+1}=LN(x_l+F(x_l)),早期 Transformer 使用这种形式,输出分布规整,但深层时梯度要穿过更多 norm 和子层,训练更脆弱。Pre-Norm 常写成 x_{l+1}=x_l+F(LN(x_l)),残差主干更像一条直接的梯度通路,因此更适合很深的大模型训练。它的代价是层输出的规整性弱一些,常需要 final norm、合适初始化和学习率策略配合。
长上下文瓶颈来自两部分。训练或 prefill 阶段,标准 attention 要构造或隐式计算 n x n 的 token 交互,时间和中间激活随序列长度近似二次增长;decode 阶段虽然每步只处理新 token,但要读取历史所有层的 KV cache,成本随上下文长度、层数、KV head 数线性增长,并且经常受 HBM 带宽限制。常见优化路线各自解决不同问题:FlashAttention 改善 attention 的内存访问和中间矩阵落盘;GQA/MQA 减少 KV cache;稀疏/滑窗 attention 降低可见范围;线性 attention、SSM 试图改掉二次复杂度;RAG 则从系统层减少需要塞进窗口的无关文本。
#常见误区:面试里最容易被追着打的点
- 把 attention 当成解释性结论。 权重高只能说明该层该头在当前计算中取了更多信息,不等于人类语义上的“模型原因”。
- 只背复杂度 O(n²)。 更完整的回答要区分训练 attention map、prefill 计算、decode 的 KV cache 读取和并发服务的显存占用。
- 把参数量和上下文长度绑定。 序列变长通常不直接增加 Transformer 参数量,增加的是计算、激活、cache 和位置泛化压力。
- 认为 Decoder-only 全面替代所有架构。 它是大规模生成模型的主流工程选择,不代表 Encoder-only 在检索、分类、embedding,或 Encoder-Decoder 在某些条件生成任务上失去价值。
- 混淆 causal mask 和 padding mask。 前者防止看未来,后者防止看空位;二者可以同时存在,解决的问题完全不同。
- 把 MHA/MQA/GQA 说成只影响参数量。 真正的线上价值多体现在 KV cache 大小、带宽、吞吐和长上下文并发容量。
#复盘清单:能讲到这些才算过关
复盘时按五条线检查。第一,能不能从 token embedding 一路讲到 logits,并说明 attention、MLP、residual、norm 各自负责什么。第二,能不能写出 scaled dot-product attention 公式,并解释 Q/K/V、sqrt(d_k) 和 mask 的直觉。第三,能不能说清 Encoder-only、Encoder-Decoder、Decoder-only 的任务适配,而不是只背模型名。第四,能不能把 MHA、MQA、GQA 的差异落到 KV head 数、cache 和质量取舍。第五,能不能把长上下文瓶颈拆成复杂度、显存、带宽、位置外推和噪声干扰,而不是笼统说“上下文长会变慢”。
#面试追问链路:从基础题走向工程判断
一条常见追问链是:先让你手写 attention 公式,然后问为什么缩放,再问 mask 放在 softmax 前还是后,接着追问训练和推理复杂度是否一样,最后转到 FlashAttention 或 KV cache。另一条链是:先问 Decoder-only 为什么流行,再问它相对 Encoder-Decoder 的代价,然后让你解释长文本摘要、RAG 问答或 embedding 检索为什么未必都该用同一种架构。高级追问通常不满足于概念定义,而是看你能否把结构选择、数值稳定性和 serving 成本连起来。
如果需要用一句话向外行解释 attention,可以说:模型生成每个词时,不是机械地平均看前文,而是先判断当前最需要哪些上下文线索,再按相关性把这些线索混合进当前表示。技术面试再补一句:这个“判断相关性”的过程就是 Q 和 K 的匹配,真正被混合的是 V,为了防止偷看未来还要加 causal mask。