ai-interview
FUNDAMENTALS · 八股

AI 八股速查手册

2026 年 AI 岗面试高频理论题精选。每题给要点 + 关键公式 + 加分回答三段式,按主题从 Transformer 基础一直串到推理加速、分布式、RAG/Agent。

一句话:八股 ≠ 背答案。面试官通常会追问 2–3 层("为什么不这样"/"极端情况会怎样"/"你自己遇到过吗"),能讲清楚"为什么这样设计"比把公式背出来重要得多。每道题的加分回答部分,基本就是第二层追问的标准姿势。
目录
  1. Transformer & Attention
  2. 训练与优化
  3. Post-training & 对齐
  4. 推理加速
  5. 分布式训练
  6. RAG · Agent · 多模态

1. Transformer & Attention

1.1 Self-Attention 的 Q/K/V 为什么要分三个矩阵?可以只用一个吗?

如果把 Q、K、V 合并成同一个线性投影,会有什么问题?

要点:

  • Q/K/V 在注意力计算里扮演三种不同角色:Q 是"我想找什么",K 是"我提供什么匹配线索",V 是"我真正要被带走的信息"。
  • 如果三者共用一组权重(Q = K = V = XW),那 QK^T = XW W^T X^T 会变成一个对称矩阵,token i 对 j 的注意力 = j 对 i 的注意力,丧失了方向性。
  • 共用参数还会让模型没法把"匹配用的特征"和"被传递的内容"解耦——很多时候它们确实不是同一个子空间。
attn(Q, K, V) = softmax(QK^T / sqrt(d_k)) V
Q = X W_Q,  K = X W_K,  V = X W_V

加分回答:可以点名 ALBERT / Linformer 等工作里尝试过 K=V 共享投影,在小模型上影响不大,但大模型里实测会掉点;另外 MQA/GQA 是在"多头之间"共享 K/V,不是把 Q/K/V 合一,要分清楚这两件事。

1.2 为什么 attention 要除以 sqrt(d_k)?不除会怎么样?

写出完整推导:为什么是 sqrt(d_k) 而不是 d_k 或 log(d_k)?

要点:

  • 假设 Q、K 的每一维都是均值 0 方差 1 的独立随机变量,那 q · k = Σ q_i k_i 是 d_k 个独立项的和,方差为 d_k,标准差为 sqrt(d_k)。
  • d_k 一大(比如 128),点积绝对值会很大,送进 softmax 后会饱和到 one-hot,梯度几乎为 0——训练卡住。
  • 除以 sqrt(d_k) 是把方差拉回 1,让 softmax 工作在"温和"区间。
Var(q · k) = Var(Σ q_i k_i) = d_k · Var(q_i)·Var(k_i) = d_k
=> 标准差 = sqrt(d_k)
缩放后: (q · k) / sqrt(d_k)  ~  均值 0, 方差 1

加分回答:其实除什么数只是归一化常数的选择,关键是"让方差不随 d_k 增长"。有些工作(如 μP / Tensor Programs)把这个缩放因子改成 1/d_k,配合不同的初始化能让超参在宽度上可迁移,这是更现代的视角。

1.3 Multi-Head Attention 为什么多头比单头好?头数是不是越多越好?

h 个头维度 d/h 拼起来,参数量和单头 d 维几乎一样,为什么效果不同?

要点:

  • 单个 softmax 注意力只能在一个相似度空间里找一种对齐关系。多头相当于在 h 个低维子空间里独立做 attention,再拼接,可以同时捕捉"句法关系/指代/位置偏移"等多种模式。
  • 参数量总数差不多,但表达能力不同——单头 d×d 的投影是 rank-d 的一次对齐;h 头是 h 次 rank-(d/h) 的对齐叠加,灵活性更高。
  • 头数越多不一定越好:d_head 太小(比如 <32)每个头能编码的信息就很稀,且 FlashAttention 对 d_head 有对齐要求。工程上一般取 d_head ∈ {64, 128}。
head_i = attn(Q W_Q^i, K W_K^i, V W_V^i)
MHA    = Concat(head_1, ..., head_h) W_O
典型: d_model = 4096, h = 32, d_head = 128

加分回答:Are Sixteen Heads Really Better than One 这篇发现推理时很多头是冗余的、可以剪掉而不掉点——这就引出了 MQA/GQA 的动机:推理时其实不需要那么多独立的 K/V。另一方面 μP/maximal-update 下头数变化有更可预测的缩放。

1.4 FlashAttention 做了什么?为什么省显存?IO-aware 具体指什么?

FlashAttention 并没有改变 attention 的数学形式,它的加速来自哪里?

要点:

  • 标准 attention 的瓶颈是 QK^T 这个 N×N 矩阵要读/写 HBM(显存),访存 O(N²),比算 O(N²·d) 还慢——这是 memory-bound。
  • FlashAttention 用 tiling:把 Q/K/V 按块加载到 SRAM(片上高速缓存),在 SRAM 内完成 softmax 和与 V 的乘法,只把最终输出块写回 HBM。中间的 N×N 矩阵从来不落盘。
  • softmax 要归一化,没法简单分块 — FA 用 online softmax(增量维护 max 和 sum)把 softmax 拆成可流式计算。
  • 显存从 O(N²) 降到 O(N),速度也因为访存省了 2–4x。这就是"IO-aware"的含义:不改算法,只改访存模式。
online softmax:
  m_new = max(m_old, m_block)
  l_new = exp(m_old - m_new) * l_old + exp(m_block - m_new) * l_block
  O_new = (l_old * exp(m_old - m_new) * O_old + exp(m_block - m_new) * PV_block) / l_new

加分回答:可以顺着讲 FA-2 做了 warp 级调度优化、FA-3 用上 Hopper 的 async copy 和 FP8。另外反向传播时 FA 需要重算 attention(而不是存下来),这是典型的 time-memory tradeoff——算力便宜访存贵,所以划算。

1.5 MHA / MQA / GQA 的区别与取舍,GQA 的分组数怎么选?

为什么大模型普遍从 MHA 转到 GQA?极端情况 MQA 不是更省显存吗?

要点:

  • MHA:h 个 Q 头,h 个 K 头,h 个 V 头,KV cache 大小 ∝ h。
  • MQA:h 个 Q 头,只有 1 个 K 头和 1 个 V 头——所有 Q 头共享同一组 KV。显存最省,但表达能力大幅下降,训练稳定性差。
  • GQA:h 个 Q 头分成 g 组,每组共享一对 KV。KV cache 是 MHA 的 g/h。g=1 退化为 MQA,g=h 退化为 MHA。
  • 分组数:Llama 系列常见 h=32, g=8(省 4x KV),Llama 3 70B 是 h=64, g=8(省 8x)。一般 g 选到让单个 KV 头能被 TP 切的整数份就够。
KV cache 大小 (per token) = 2 · n_layers · g · d_head · dtype_bytes
MHA  g=h=32  : 32·128·2 = 8192 bytes/layer/token (bf16)
GQA  g=8     :  8·128·2 = 2048 bytes/layer/token
MQA  g=1     :  1·128·2 =  256 bytes/layer/token

加分回答:MQA 推理快但"训练不收敛或 quality drop"是很实际的问题——原 MQA 论文提到要从 MHA checkpoint 做 uptraining 恢复。GQA 是甜点:几乎不掉点 + 显著省 KV cache。现在再进一步有 MLA(DeepSeek 用的)用低秩压缩 KV,压得比 GQA 还狠。

1.6 KV Cache 的作用、显存占用公式、优化手段

为什么 decode 阶段显存占用会随序列变长?怎么估算 KV cache 大小?

要点:

  • 自回归解码时,第 t 步生成只需要算新 token 的 Q,但要和过去所有 token 的 K/V 算 attention。如果不缓存,每步都要重算前面的 K/V,O(N²) 退化成 O(N³)。
  • KV cache 就是把每一层每个 token 的 K、V 存下来,下一步直接读。这样 decode 每步是 O(N)。
  • 代价是显存:长上下文 + 大 batch 时,KV cache 经常比模型本身还大。
KV cache 总大小
  = 2 · batch · seq_len · n_layers · n_kv_heads · d_head · bytes

例 Llama-3-70B, bf16, GQA g=8, seq=8192, batch=1:
  = 2 · 1 · 8192 · 80 · 8 · 128 · 2
  ≈ 2.5 GB  (仅单 batch, 单序列)

加分回答:优化手段:① GQA/MQA/MLA 减 head;② PagedAttention(vLLM)按页管理,避免碎片化;③ 量化 KV cache(int8 / fp8 / int4);④ sliding window / StreamingLLM 丢弃远端;⑤ prefix caching 跨 request 复用公共前缀;⑥ CacheBlend / CacheGen 做 KV 压缩和跨 request 复用。长上下文的系统瓶颈本质就是 KV 太大。

1.7 位置编码:绝对 / 相对 / RoPE / ALiBi 的差别

RoPE 为什么现在一统江湖?和 ALiBi 对比长度外推能力如何?

要点:

  • 绝对位置编码(Sinusoidal / learned):加到 embedding 上,超出训练长度就失效。
  • 相对位置编码(T5-style bias):attention 里加一个和相对距离有关的 bias,外推好一点但表达力有限。
  • RoPE:把 Q、K 在每两维上旋转一个和绝对位置相关的角度,q_m · k_n 自然变成只依赖 m−n 的函数。拥有"相对位置"的优点,形式简洁,兼容 FlashAttention。
  • ALiBi:给 attention logits 加一个 -m · |i-j| 的线性惩罚,训练轻,远距离快速衰减,外推能力强,但近距离精度略差。
RoPE:
  q_m ⊙ [cos(mθ), sin(mθ)]  -> 旋转 mθ
  k_n ⊙ [cos(nθ), sin(nθ)]  -> 旋转 nθ
  q_m · k_n = f(q, k, m-n)   // 仅依赖相对位置

外推技巧: NTK-aware scaling, YaRN, PI (position interpolation)

加分回答:RoPE 的 base θ=10000 在长上下文会产生"高频位过拟合到训练长度"的问题。YaRN 本质是对低频维度做拉伸、对高频维度保留,再配合少量长文本 fine-tune 就能从 4k 扩到 128k。最新的 DeepSeek/Qwen 基本都走这条路。

2. 训练与优化

2.1 Adam / AdamW / Lion / Muon 的区别,为什么 LLM 训练倾向 AdamW?

AdamW 相比 Adam 改了什么?Lion 和 Muon 各有什么卖点?

要点:

  • Adam:一阶动量 m + 二阶动量 v,自适应学习率。weight decay 写在梯度里(等价 L2 正则)。
  • AdamW:把 weight decay 从梯度里拿出来,单独乘以 lr 作用在参数上 — 这才是"真正的 weight decay"。对大模型影响很大。
  • Lion:只用 sign(m) 更新,显存省一半(不存 v),在某些任务上和 AdamW 打平。但对 lr 敏感。
  • Muon:对矩阵参数用 Newton-Schulz 迭代近似正交化后的动量方向更新,类似隐式二阶法。对 attention/MLP 权重效果好,嵌入层和 LayerNorm 仍用 AdamW。
Adam:      θ ← θ - lr · (m̂ / (sqrt(v̂) + ε)  + wd · θ)   // wd 混在梯度里
AdamW:     θ ← θ - lr · (m̂ / (sqrt(v̂) + ε)) - lr · wd · θ  // wd 解耦
Lion:      θ ← θ - lr · sign(β1 · m + (1-β1) · g) - lr · wd · θ
Muon:      θ ← θ - lr · NewtonSchulz(M)        // M 为动量矩阵

加分回答:LLM 用 AdamW 主因:① 解耦 wd 对 generalization 重要;② 二阶动量自适应 lr 对不同层的梯度尺度差异鲁棒。显存代价:每参数要存 (param, grad, m, v) 共 4x,fp32 优化器状态是 16 bytes/param。Muon 是 2024 年出来后被 Kimi K2 实锤在 1T 规模稳定收敛且更省算力的路径,正在替代一部分 AdamW。

2.2 学习率调度:warmup + cosine / linear decay / WSD 对比

WSD(warmup-stable-decay)相比 cosine 的优势是什么?

要点:

  • Warmup:开始时梯度统计量(尤其 Adam 的 v)还没稳定,直接用大 lr 容易炸。Warmup 0→peak 线性增 1–5% steps。
  • Cosine decay:从 peak 缓慢降到 0 或 0.1·peak。平滑,经典,但总步数必须事先知道。
  • Linear decay:简单线性下降,效果一般略差于 cosine,但对 step 数不敏感。
  • WSD:warmup → 长期恒定 lr → 最后 10–20% steps 快速 decay。好处:中间任何一个 checkpoint 都可以"随时拉 decay tail"得到可用模型,不用事先决定训多少 token;更适合持续预训练。
cosine:  lr_t = lr_min + 0.5·(lr_peak - lr_min)·(1 + cos(π·t/T))
WSD:     warmup -> const lr_peak -> 末段 sqrt/linear decay to lr_min

加分回答:MiniCPM、Llama 3、DeepSeek 都验证过 WSD 的可扩展性——你可以一边训一边决定"就现在收尾"。Cosine 的本质缺陷是它把 LR schedule 和训练预算耦合了,不符合现代"训到算力/数据耗尽"的范式。

2.3 梯度累积、梯度裁剪、混合精度各解决什么问题?

fp16 和 bf16 的差别?fp8 训练要注意什么?

要点:

  • 梯度累积:显存不够装大 batch 时,分 k 步各自 forward/backward,累加梯度再 step,等效 batch=k·micro_batch。
  • 梯度裁剪:全局 L2 norm 超阈值(常用 1.0)就等比缩放,防止 loss spike 时梯度爆。
  • fp16:5 bits exponent,动态范围小(~6e-5 到 65504),容易 overflow — 必须用 loss scaling。
  • bf16:8 bits exponent(和 fp32 相同),动态范围大,精度略差但训练更稳定,不需要 loss scaling。现在是 LLM 默认。
  • fp8:E4M3(forward)+ E5M2(backward),动态范围极小,需要 per-tensor 或 per-block scaling 跟踪;主要用在 matmul,accumulator 仍是 fp32。
梯度累积:  effective_bs = micro_bs · accum_steps · dp_size
裁剪:      g ← g · min(1, clip_norm / ||g||_2)
loss scale (fp16): scale_up 后 backward, unscale 再 step, 溢出就回退 scale

加分回答:fp8 训练(Hopper/Blackwell)的关键是 DeepSeek-V3 那种 block-wise scaling 做到稳定。实操中先用 bf16 warmup 几百步再切 fp8,或部分层保留 bf16(embedding、output head、LayerNorm 一般都不 fp8)。另外梯度累积会放大 BatchNorm 统计的偏差,但 LLM 用 LayerNorm/RMSNorm 所以不成问题。

2.4 为什么大模型普遍用 RMSNorm?SwiGLU 相对 ReLU/GELU 的优势?

RMSNorm 省了什么?SwiGLU 为什么效果好但参数多?

要点:

  • LayerNorm:减均值再除标准差,有可学习 γ 和 β。
  • RMSNorm:只除以 RMS,不减均值,只保留 γ。省一次均值计算 + 一个参数(β),效果基本不变甚至更好。"减均值"这一步被发现对 transformer 并不必要。
  • ReLU:死神经元问题。GELU:平滑近似 ReLU,性能更好。SwiGLUSwiGLU(x) = Swish(xW) ⊙ (xV),带 gating 机制,表达力更强,但 FFN 多一个矩阵 V,参数量 1.5x。为了参数量对齐,Llama 把 FFN 的 hidden dim 从 4d 改到 8d/3 ≈ 2.67d。
LayerNorm: y = γ · (x - μ) / sqrt(σ² + ε) + β
RMSNorm:   y = γ · x / sqrt(mean(x²) + ε)

SwiGLU FFN:  FFN(x) = (Swish(x W1) ⊙ (x V1)) W2
            dim: d -> d_ff -> d   (d_ff ≈ 8d/3)

加分回答:RMSNorm 省的那点算力不是关键——关键是"均值减法在 transformer 里是多余的"这个发现被 Llama 带火了。SwiGLU 的 gating 本质类似于 LSTM 的 input gate,让 FFN 能学到"对某些特征开/关"的动态选择。Noam Shazeer 原文标题就叫《GLU Variants Improve Transformer》。

2.5 损失突然 spike 怎么定位?

训练 loss 跑了几千步突然冲高,你怎么排查?

要点:

  • 第一步看 grad norm:spike 前一般会有 grad norm 先爆,如果 clip 得住还能回,clip 不住就炸了。
  • 看数据:最近几个 batch 是不是有脏数据(超长重复 / 全 padding / 编码错乱)。可以把 spike 前的 batch dump 出来人看。
  • 看 lr 和 warmup:是否刚进入 peak lr、是否 accum 没正确缩放。
  • 看数值精度:fp16 溢出?某个 logit 炸了导致 softmax nan?attention 的 score 有没有超过 fp16 上限。
  • 看模型内部:某一层的激活值 max/min、attention entropy 是不是异常。Qwen/Llama 训练日志都会打 per-layer grad norm。
  • 兜底:回滚到 spike 前 checkpoint,skip 若干 batch 重试,或降 lr 10%。
常见诱因清单:
  - 数据: 异常长序列 / 全重复 token / unicode 错乱 / tokenizer bug
  - 精度: fp16 overflow / attention softmax 饱和 / LN 分母为 0
  - 优化器: β2 太高导致 v 估计迟钝 / lr 过大
  - 并行: grad 同步错位 / PP 边界状态没对齐

加分回答:大模型训练里 spike 几乎是必然事件(PaLM、OPT、Llama 都在 blog 里承认了)。工业界做法是自动检测 + 回退 + skip batch,不是靠人盯。另外 z-loss(让 logsumexp 趋近 0)和 QK-norm 是两个防 spike 的常见 trick,最新的模型基本都带上了。

3. Post-training & 对齐

3.1 SFT / RLHF / DPO / GRPO 的核心区别

什么场景选哪个?各自的数据成本?

要点:

  • SFT:监督微调,loss = -log p(y|x) on (prompt, good-response)。便宜、稳定,是所有对齐的起点,但只学到"怎么说",学不到"别说什么"。
  • RLHF (PPO):先训 reward model(从 pairwise preference 学),再用 PPO 最大化 reward − β·KL(ref)。效果天花板高,但工程复杂:要同时装 policy / ref / reward / critic 四个模型,不稳定。
  • DPO:直接从 (chosen, rejected) pair 优化,不需要显式 reward model 和 on-policy 采样。简单稳定,但对 preference 数据质量敏感,表达能力略弱于 PPO。
  • GRPO(DeepSeek-R1 用的):对每个 prompt 采 G 个 response,用组内相对排名代替 critic。省掉 value head,适合 reasoning 这种"结果好判断对错"的任务。
方法数据稳定性天花板典型场景
SFT(x, y) demo冷启动、格式对齐
PPO-RLHFpreference pair + on-policy通用 chat 对齐
DPOpreference pair (offline)中高轻量对齐、小团队
GRPO可验证 reward数学/代码 reasoning

加分回答:2024 下半年开始业内共识是"SFT + DPO 做通用对齐,GRPO 做 reasoning 增强"。PPO 在 reasoning 上并没有消失,Anthropic/OpenAI 据信都还在用复杂的 online RL。DPO 的一个已知问题是"likelihood displacement"——chosen 的概率也会降,可以配合 SFT loss 混合或用 IPO/KTO 缓解。

3.2 RLHF 里 PPO 为什么需要 reference model?KL 惩罚项防什么?

如果没有 reference model 和 KL,模型会怎么坏掉?

要点:

  • Reward model 是从有限 preference 数据学来的,有限样本 + 高维空间 ⇒ 存在很多"奖励高但质量差"的对抗样本(reward hacking 的前身)。
  • 如果只最大化 reward,policy 会迅速偏离正常语言分布,跑到这些对抗样本里,输出退化成模式化/重复/胡言乱语。
  • KL(policy || ref) 把 policy 锚定在 SFT 模型附近,限制它"走得别太远",只在 ref 允许的邻域里找高 reward 点。
PPO 目标:  max E[ r(x, y) - β · KL(π(·|x) || π_ref(·|x)) ]
等价形式: max E[ r(x, y) ] s.t. KL(π || π_ref) ≤ ε

加分回答:β 是个敏感超参:太小就 mode-collapse 到高 reward 垃圾;太大就训练没进展。通常 β ∈ [0.01, 0.1]。更现代的做法是 adaptive KL(InstructGPT 里的 approach),或者干脆用 DPO 的闭式解——DPO 的推导恰恰证明了"PPO + KL 约束 + BT reward model"有闭式最优,对应的就是 DPO 的 loss。

3.3 DPO 的 loss 推导

写出 DPO loss 的推导过程,为什么 reward 模型"消失"了?

要点:

  • 起点:RLHF 目标在 KL 约束下有闭式最优:π*(y|x) ∝ π_ref(y|x) · exp(r(x,y)/β)
  • 反过来可以把 reward 表达为 r(x,y) = β · log(π*(y|x)/π_ref(y|x)) + β·log Z(x)
  • 把这个 r 代入 Bradley-Terry preference 模型 P(y_w ≻ y_l) = σ(r(x,y_w) - r(x,y_l)),Z(x) 在减法里消掉。
  • 于是学 reward + PPO 两步合成了一个分类 loss:直接在 policy 上最大化 chosen 比 rejected 的 log-odds。
DPO loss:
  L = -E[ log σ( β·log(π(y_w|x)/π_ref(y_w|x))
              - β·log(π(y_l|x)/π_ref(y_l|x)) ) ]

直觉: 让模型对 chosen 的 log ratio 大于 rejected, margin 由 β 控制

加分回答:DPO 的关键洞察是"reward model 和 policy 本质是同一个东西的两种参数化"。但这个等价性假设 preference 数据符合 BT 模型、且数据覆盖了 π 的支撑集。实际上 π 训着训着会走到 offline 数据没覆盖的区域,导致 likelihood displacement——这就是 iterative DPO / online DPO / IPO 等变体要解决的问题。

3.4 Reward hacking 是什么?怎么缓解?

举一个具体的 reward hacking 例子,以及你会怎么防?

要点:

  • Reward hacking:policy 找到 reward model 里的"漏洞"——得分很高但实际效果差。经典例子:长度 bias(长回答得分高于短回答)、客套话堆砌、refuse 成 "As an AI language model..."、在 code 任务里输出测试会 pass 但逻辑错误。
  • 本质原因:reward 是 proxy,不是 ground truth。Goodhart's Law:当 measure 变成 target,它就不再是好 measure。

缓解手段:

  • KL 约束:限制偏离 ref 的程度(前面说过)。
  • Reward model ensemble:多个 RM 求最小值或一致性过滤。
  • 长度归一化:reward 减去长度 bias 的线性项。
  • 迭代更新 RM:用当前 policy 产生的新样本再标注,更新 RM。
  • 可验证 reward:数学题对答案、代码跑单测、形式化证明——尽量用 ground truth 替换 learned RM。
  • Early stopping:RL 训到一定步数就停,过训必 hack。

加分回答:现在主流 reasoning 模型(R1/o1)为什么能 scale 上去?很大原因是用了可验证 reward(数学答案/代码 pass)代替 learned RM,从根上避免 hacking。这也是为什么这波 RL 是在"结果可验证"的任务上先爆发。推理之外的 creative writing 等任务还在 RM-based,hack 风险仍在。

3.5 推理模型(o1/R1)是怎么训出来的?RL 用 outcome reward 为什么也能学 CoT?

只给最终答案对错的 reward,模型怎么学会长链思考?

要点:

  • 典型 pipeline:base → SFT(含 CoT demo)→ RL(outcome reward 的 GRPO/PPO)→ 蒸馏 / 再 SFT。DeepSeek-R1 的惊艳之处是"R1-Zero"直接从 base 跳过 SFT 做 RL 也能涨。
  • outcome reward 能学到 CoT 的直觉:长思考是"达到正确答案"这个事件的必要手段,RL 通过 credit assignment 把最终 reward 分摊到中间 token 的概率上。
  • 训练中会出现"涌现"现象:response 长度持续增加、模型开始自我反思("wait... let me reconsider")、出现长程规划。这些都是 outcome reward 隐式鼓励的副产品,不需要显式教。
GRPO 简化:
  对 prompt x 采 G 个 response y_1..y_G
  r_i = verifier(y_i)              // 0/1 或 [0,1]
  A_i = (r_i - mean(r)) / std(r)   // 组内优势
  loss = -E[ min(ρ_i · A_i, clip(ρ_i, 1±ε) · A_i) ]
         + β · KL(π || π_ref)
  ρ_i = π(y_i|x) / π_old(y_i|x)

加分回答:R1 带火了一个核心观察:足够强的 base model + 可验证 reward + 足够算力 ⇒ 涌现 reasoning。但这依赖 base model 的 CoT 能力种子已经存在——7B 以下模型直接跑 RL 涨得就有限。另外 process reward model(PRM)和 outcome reward model(ORM)的对比:ORM 简单但 credit assignment 粗;PRM 更细但标数据贵、容易被 hack。业界目前倾向 ORM 打底 + PRM 精调。

4. 推理加速

4.1 Continuous batching 和 PagedAttention 原理

Static batching 为什么效率低?PagedAttention 借鉴了操作系统的什么思想?

要点:

  • Static batching:把 batch 里所有 request 填齐到最长 seq,一起 forward。问题:不同请求生成长度差异大,短的早就该结束但要等长的,GPU 大量空转。
  • Continuous batching(iteration-level scheduling):每生成一个 token 就重新组 batch,结束的 request 立刻出队,新 request 立刻入队。GPU 利用率大幅提升(2–10x 吞吐)。
  • PagedAttention:KV cache 按固定大小的 block(页,常用 16 tokens)组织,逻辑连续的 cache 可以物理不连续,通过页表映射。好处:① 完全消除内部碎片;② 共享前缀(beam search / parallel sampling / prefix cache)天然支持 copy-on-write;③ 显存利用率接近 100%。
传统 cache:  每 request 预留 max_seq 的连续显存 -> 浪费巨大
PagedAttention:
  block_size = 16
  每 request 维护一个 block_table: [b0, b17, b42, ...]
  attention kernel 通过 block_table 间接寻址

加分回答:PagedAttention 就是把 OS 的虚拟内存搬到了 KV cache 上——vLLM 原论文标题《Efficient Memory Management for LLM Serving with PagedAttention》。后继 SGLang 的 RadixAttention 更进一步,用基数树组织所有前缀,跨 request 自动复用公共 prefix,对 agent/rag 场景收益极大。

4.2 Speculative decoding 的数学期望

为什么 speculative decoding 不改变输出分布?期望加速是多少?

要点:

  • Draft 模型(小而快)一次 autoregressive 生成 γ 个草稿 token。Target 模型(大)一次 forward 对这 γ+1 个位置并行打分(因为有 KV cache,成本约等于一次 decode)。
  • 逐位接受/拒绝:用 p_target(x)/p_draft(x) 的比值做 rejection sampling,第一次拒绝的位置从 max(0, p_target - p_draft) 重采样。
  • 数学上可证明:最终输出分布严格等于 target 模型自己解码的分布。所以是 exact 加速,不是近似。
  • 期望接受数 α 取决于 draft 和 target 的一致性:E[接受数] = (1-α^(γ+1))/(1-α),加速比 ≈ 这个数除以一次 target forward 的时间(比 draft 的 γ 次贵很多所以划算)。
接受概率: min(1, p_target(x) / p_draft(x))
若拒绝: 从 p'(x) ∝ max(0, p_target(x) - p_draft(x)) 重采样
期望生成 token 数: (1 - α^(γ+1)) / (1 - α),  α = 平均接受率
典型 α = 0.6~0.8, γ = 4~7 -> 2~3x 加速

加分回答:变体很多:Medusa(多头并行猜 k 个位置)、EAGLE(用 target 自己的 feature 做 draft,α 提到 0.85+)、Lookahead decoding(不需要 draft model)。工程上要注意:speculative 对 batch size 友好度差——batch 越大,target 一次 forward 已经很贵,draft 的相对收益就小了。所以它在低并发、低延迟场景(单用户聊天)价值最大。

4.3 量化:GPTQ / AWQ / SmoothQuant / FP8 差异

权重量化和激活量化分别解决什么?int8 权重对 perplexity 影响多大?

要点:

  • GPTQ:权重 int4,基于 OBS/OBQ 思想,逐层解近似最优量化(考虑 Hessian,用少量校准数据),weight-only。
  • AWQ:activation-aware,发现少数 channel 的 activation 很大(outlier),保护这些对应的 weight channel 不被过度量化(用 per-channel scale 预处理),weight-only。工程上比 GPTQ 更鲁棒、更快。
  • SmoothQuant:W8A8,把 activation 的 outlier "搬"到 weight 上(Y = (X/s) · (s·W)),让 activation 变得平滑好量化。
  • FP8:硬件原生(Hopper+),E4M3/E5M2,per-tensor 或 block scaling。推理 matmul 用 FP8,accumulate 仍 fp32。
  • Int8 权重对 perplexity 影响一般 < 0.5%,int4(GPTQ/AWQ)影响 ~1–3%,int3 开始明显掉点。小模型(<7B)对量化更敏感。
方法WA解决问题主要成本
GPTQint4fp16权重压缩 → 显存/带宽离线校准较慢
AWQint4fp16权重压缩,更稳per-channel scale
SmoothQuantint8int8W+A 同时量化需找 α 平衡
FP8fp8fp8硬件原生, 训练也能用需 Hopper+

加分回答:Decode 阶段是 memory-bound(每步从 HBM 读全部权重算几 tokens 的 logits),所以 weight-only 量化直接给你 4x 带宽 = ~3–4x 加速。Prefill 是 compute-bound,激活量化(SmoothQuant/FP8)才有收益。所以"聊天场景"优先 AWQ int4,"长 prompt 批量"场景才上 FP8/SmoothQuant。

4.4 MoE 推理瓶颈在哪?EP/TP/DP 怎么选?

为什么 MoE 省训练算力但推理反而难?

要点:

  • MoE 的卖点是"参数量大但每 token 激活少"——训练时 activated params 决定算力。但推理时所有 expert 的权重都得存在某张卡的显存里(不然路由到了就没法算),所以显存成本按总参数算。
  • 瓶颈一:显存。DeepSeek-V3 总参 671B,激活 37B,推理你仍要给 671B 的权重留地方。
  • 瓶颈二:all-to-all 通信。Expert parallelism 下 token 要路由到不同卡的 expert,每层两次 all-to-all(dispatch + combine),网络延迟主导。
  • 瓶颈三:负载不均。Router 输出的 top-k 分布常常不均,少数 expert 被挤爆,其他闲。要靠 aux loss 或 DeepSeek 的 auxiliary-loss-free balancing 解决。

并行选型:

  • TP(Tensor Parallel):切 FFN 和 attention 的矩阵维度,通信 all-reduce。适合单机多卡(NVLink)。
  • EP(Expert Parallel):不同 expert 放不同卡,通信 all-to-all。适合 expert 数多(≥ 64)的场景。
  • DP(Data Parallel):batch 维度切,每卡一份完整模型。只在模型放得下时才用。
  • 实战:MoE 推理通常 TP 放 attention + EP 放 FFN,再叠 DP 扩吞吐。

加分回答:DeepSeek-V3 推理的 prefill/decode 分离 + 大 EP size(64–320)就是针对 MoE 特性做的:prefill 阶段 compute-bound、适合大 TP;decode 阶段 memory-bound、路由稀疏、适合大 EP 让每卡只装几个 expert。另一个新的思路是 shared expert + routed expert 混合(DeepSeek-MoE),shared expert 是每个 token 都走的稠密部分,缓解 routing 偏差。

4.5 Prefill vs Decode 的 roofline 分析

同一个模型同样参数,prefill 和 decode 的算力/带宽利用率为什么差这么多?

要点:

  • Prefill:一次处理整个 prompt 的 N 个 token,矩阵乘是 (N, d) × (d, d),arithmetic intensity ≈ N。N 大(> 百量级)就 compute-bound,GPU 算力打满。
  • Decode:每步只算 1 个新 token,矩阵乘是 (1, d) × (d, d),arithmetic intensity ≈ 1。永远 memory-bound,瓶颈是 HBM 带宽把权重从 HBM 搬到 SM。
  • Roofline:perf = min(peak_flops, intensity · peak_bandwidth)。A100 FLOP/B 比 ≈ 220,所以 intensity < 220 就 memory-bound;decode 永远在左半区。
Prefill:  N=2048, d=4096
  compute: O(N · d²) = 3.4e10  FLOPs
  memory : O(N·d + d²) ≈ 1.7e7 bytes
  intensity ≈ 2000  -> compute-bound

Decode:   N=1,    d=4096
  compute: O(d²)  ≈ 1.7e7
  memory : O(d²)  ≈ 3.4e7
  intensity ≈ 0.5 -> memory-bound

加分回答:这个分析直接导出了现代 LLM serving 的两大设计:① 大 batch decode——把很多 request 的 decode 拼起来提升 intensity;② prefill/decode 分离部署(DistServe、Splitwise、Mooncake)——两个阶段用不同硬件配置,prefill 堆算力/decode 堆带宽,TTFT 和 TPOT 解耦优化。

5. 分布式训练

5.1 DP / TP / PP / EP / SP 分别切什么?

画一下它们的切分维度和通信模式。

要点:

  • DP (Data Parallel):每卡一份完整模型,切 batch。通信:backward 末尾 all-reduce 梯度,通信量 ≈ param_size。
  • TP (Tensor Parallel):切单层的权重矩阵(column-wise 或 row-wise)。通信:每层 forward/backward 各一次 all-reduce(或 all-gather + reduce-scatter)。通信频繁,必须 NVLink 内。
  • PP (Pipeline Parallel):按层切模型,不同 stage 在不同卡。通信:相邻 stage 之间点对点传激活/梯度,通信量小但要处理 bubble。需要 micro-batch 和 1F1B 调度。
  • EP (Expert Parallel):MoE 专用,不同 expert 放不同卡。通信:每层两次 all-to-all。
  • SP (Sequence Parallel):切序列维度。两种含义:① Megatron SP 切 LN/dropout 的序列维,省激活显存;② 长上下文 SP / Ring Attention,把 attention 的 seq 维分片,用 ring 传递 K/V。
并行切什么通信单次通信量
DPbatchall-reduce gradO(param)
TP矩阵维度每层 all-reduceO(batch·seq·d) × 层数
PP点对点 activationO(batch·seq·d) × 段数
EPexpertall-to-allO(batch·seq·d) × 2层
SP (Megatron)LN/dropout 的 seq配合 TP 的 allgather/RSO(batch·seq·d)

加分回答:通信量公式里要盯紧哪些项随 N(卡数)变化。TP 的 all-reduce 是 2·(N-1)/N · M(ring 实现),M 是 tensor 大小。随 N 增大每卡分到的通信量增加缓慢,但延迟线性。所以 TP 很少超过 8(单机)。PP 的 bubble 比例 ≈ (PP-1)/(micro_batch),所以 PP 越大需要 micro-batch 越多才划算。

5.2 ZeRO-1/2/3 各省了什么?和 FSDP 是什么关系?

ZeRO-3 和 TP 有什么区别?为什么 FSDP 被认为是 ZeRO-3 的"官方"实现?

要点:

  • 优化器状态(Adam 的 m、v、主 fp32 权重)是最大头:每参数 12 bytes,比参数本身(fp16/bf16 2 bytes)大 6 倍。
  • ZeRO-1:切优化器状态。每卡只存 1/N 的 optimizer states,step 时 all-gather 合并。
  • ZeRO-2:再切梯度。backward 完直接 reduce-scatter 到各自负责的分片。
  • ZeRO-3:再切权重。每卡只存 1/N 权重,forward 前 all-gather 这一层的权重用完即丢。通信量比 DP 多一倍(多了 forward 的 all-gather),但显存省到 1/N。
  • FSDP(PyTorch 原生)本质就是 ZeRO-3 的实现,API 更好用。现在事实标准。
  • TP 的区别:TP 是把"单次矩阵乘"本身切开并行算(纵向切模型),ZeRO-3 是"每张卡有完整 micro-batch 但只持有部分权重、临时凑齐"(横向 DP + 权重 shard)。ZeRO-3 通信是每层 all-gather,TP 是 all-reduce;ZeRO-3 比 TP 通信量稍大但不受拓扑限制、可以跨机。
显存 per GPU (N=8 DP, 模型 7B, bf16 weight + Adam fp32):
  baseline DP:   7B·2 (w) + 7B·2 (grad) + 7B·12 (opt) = 112 GB
  ZeRO-1:        7B·2 + 7B·2 + 7B·12/8 = 38.5 GB
  ZeRO-2:        7B·2 + 7B·2/8 + 7B·12/8 = 26.25 GB
  ZeRO-3:        7B·(2+2+12)/8 = 14 GB

加分回答:ZeRO-3/FSDP + TP + PP 可以组合:3D 并行里 DP 维度用 FSDP,TP 在机内,PP 跨机但每段内再 FSDP。Llama 3 405B 训练用 FSDP + TP=8 + PP=16 + CP(context parallel)。HSDP 是 FSDP 的进化版:在 DP group 内 shard,group 间 replicate,减少跨机 all-gather。

5.3 3D Parallel 配置 (TP, PP, DP) 怎么定?

1024 卡训 70B 模型,你的初始配置是什么?

要点:

  • 先定 TP:TP 通信密集必须在 NVLink 内,上限 = 单机卡数(A100/H100 通常 8)。模型不能被 TP=8 切完就再加 PP。
  • 再定 PP:PP 段数 ≈ 模型层数的约数,让每段层数差不多。PP 越大 bubble 越多,但每段显存越小。70B 典型 PP=4 或 8。
  • DP = 总卡数 / (TP·PP),配合 ZeRO/FSDP 补显存。
  • micro-batch 要足够大让 PP bubble 比例可接受:bubble_frac ≈ (PP-1)/(PP-1 + num_micro_batches)。
  • 验证:单 GPU 显存是否放得下 (权重分片 + 激活 + 优化器)。不够就加 gradient checkpointing 或 ZeRO-3。
例: 1024 × H100, 70B, seq=8192
  TP = 8         (机内, 80 层 / 8 不分段内也行)
  PP = 4         (80 层分 4 段, 每段 20 层)
  DP = 32        (1024 / 8 / 4)
  micro_batch = 1, num_micro_batches ≥ 16 抑 bubble
  DP 内开 FSDP/ZeRO-3 存优化器

加分回答:长上下文要再加 CP (Context Parallel / Ring Attention),切 seq 维,通信 ring all-gather K/V。Llama 3 128k context 训练就用了 CP=8。另外要考察计算通信比:如果 TP 通信占 forward 30%+ 就过头了,TP=4 配合 DP 更好。做 4D/5D 并行时先写一个 cost model 算期望 MFU(典型目标 40–50%)再下手。

5.4 All-Reduce vs All-Gather + Reduce-Scatter

为什么说 all-reduce = reduce-scatter + all-gather?通信量差别在哪?

要点:

  • Ring all-reduce 的经典实现就是两阶段:先 reduce-scatter(每卡得到一部分的完整 sum),再 all-gather(每卡凑齐全局 sum)。
  • 单卡通信量(ring):all-reduce 是 2·(N-1)/N · M,reduce-scatter 是 (N-1)/N · M,all-gather 也是 (N-1)/N · M
  • ZeRO-3/FSDP 不需要"完整的 sum 在每张卡上"——梯度每卡只负责自己那一片,所以用 reduce-scatter 即可,省掉 all-reduce 的后半段 all-gather。forward 时用 all-gather 拿权重。总通信量和 DP+all-reduce 相比多了 forward 一次 all-gather。
ring all-reduce:   each GPU sends/recvs 2(N-1)/N · M bytes
= reduce-scatter:  (N-1)/N · M  +  all-gather: (N-1)/N · M

ZeRO-3/FSDP 单 step 通信:
  forward  all-gather weight:   (N-1)/N · M
  backward all-gather weight:   (N-1)/N · M   // 重算
  backward reduce-scatter grad: (N-1)/N · M
  total ≈ 3 · (N-1)/N · M   (DP baseline ≈ 2·(N-1)/N · M)

加分回答:ZeRO-3 通信量比 DP 多 50%,但换来 N 倍显存节省,工程上非常划算——尤其权重远大于激活的大模型。另外 NCCL 的 ring 只是一种拓扑,现代实现(tree、double binary tree)对延迟更友好。跨机 all-reduce 受限于 IB 带宽(H100 NVLink 900GB/s vs IB 400Gbps ≈ 50 GB/s),这就是为什么 TP 不能跨机。

5.5 Recompute / Activation Checkpointing 的 time-memory tradeoff

哪些层适合 recompute?selective checkpointing 是什么?

要点:

  • Backward 需要 forward 时的激活,默认全存下来会吃掉几十 GB。Recompute = forward 时不存激活,backward 时再跑一遍 forward 算出来。
  • 代价:额外约 1/3 的 forward 算力(反向本来就是 2x forward,加 recompute 变成 3x forward + backward ≈ 1 forward 的 30% 多开销)。
  • 全量 checkpoint:每个 transformer block 都 recompute。简单,显存省最多,算力代价明显。
  • Selective checkpoint(Megatron 推荐):只 recompute 便宜的算子(如 attention softmax、dropout),把贵的矩阵乘输出存下来。显存省 ~70%,算力代价 < 5%。这是现代标配。
每层激活显存 ≈ batch · seq · d · (hidden_mult)
  full attn+ffn: ~ batch · seq · d · 34  (Megatron 估算)
  selective   : ~ batch · seq · d · 10
  full ckpt   : ~ batch · seq · d · 2    (只存输入)

加分回答:更激进有 CPU offload checkpointing(激活甩到 CPU),以及 selective offload(只 offload 最贵几层)。另外 FlashAttention 本身就自带 recompute——attention matrix 不存,backward 重算,属于"免费 checkpointing"。所以开了 FA 后 selective checkpoint 的目标变成了 FFN 的中间激活。

6. RAG · Agent · 多模态

6.1 RAG 的 hit@k 和 end-to-end 指标怎么设计?

只看 retriever 的 recall 够吗?评测 pipeline 怎么拆分?

要点:

  • RAG 有两个阶段,要分别和联合评测:
  • Retriever 层:给 query 标出"相关文档集合",计算 Recall@k / nDCG@k / MRR。k 通常取 {1, 5, 10, 20}。hit@k 特指"top-k 里至少一个相关"的二值指标。
  • Generator 层:给 ground truth 上下文时的回答质量,用 exact-match / F1 / LLM-as-judge。这是隔离评测。
  • End-to-end:retriever 的真实 top-k 喂给 generator,评最终答案正确率。这才是用户真正感知的指标。
  • 还要关注 faithfulness(回答是否忠实于检索内容,没幻觉)和 context relevance(检索的东西真的相关吗)——Ragas 和 TruLens 的标准指标。
指标分层:
  retriever:  Recall@k, hit@k, nDCG@k
  generator:  answer_correctness | gold context
  e2e:        answer_correctness | retrieved context
              + faithfulness (no hallucination)
              + answer_relevancy (答到点子上)

加分回答:工程上常见陷阱:retriever hit@10 = 90% 但 e2e 只有 60%——原因一般是 generator 被噪声上下文带偏(lost-in-the-middle)或 gold doc 没排进 top-3。所以 rerank 阶段对 e2e 影响比 recall 提升更大。评测集要人工标 gold passage + 答案,不能只看答案。

6.2 Agent 里 ReAct、Plan-and-Execute、Reflexion 的区别

这三种 agent 范式分别适合什么场景?

要点:

  • ReAct(Reason + Act):交错产生 thought / action / observation 三段式,每步都能根据新观察调整。灵活,适合工具调用多、需要中途探索的场景。缺点:没有长远规划,容易 loop。
  • Plan-and-Execute:先 plan 出完整 step list,再逐步 execute(可带一个 replan 步骤)。结构清晰、便于并行/缓存,但 plan 错了下游全错。适合任务相对确定的 workflow。
  • Reflexion:在失败的 trajectory 后让 LLM 反思失败原因,写入 memory,下一轮带着 reflection 重试。本质是 self-improvement with verbal memory,适合有明确 success signal 的任务(代码跑通、数学答对)。
范式规划粒度反馈利用典型场景
ReAct逐步下一步调整搜索/问答/多工具
Plan & Execute预先全局中途 replan稳定工作流
Reflexion每 trajectory失败后自省代码/数学/可验证任务

加分回答:现代 agent 框架通常混合:上层 plan-and-execute 给整体方向,每个子任务内 ReAct,失败后 Reflexion。OpenAI 的 Swarm / Anthropic 的 claude-agent-sdk 都是这种复合结构。另外 agent 评测硬——SWE-bench、WebArena 这些才是真正反映能力的 benchmark,light-weight toy tasks 上的指标会过度乐观。

6.3 MCP 协议解决了什么问题?

为什么需要 MCP?它和传统 function calling 有什么不同?

要点:

  • 背景:每个应用(Cursor、Claude Desktop、VSCode 插件)都想让 LLM 调用各种工具(文件、数据库、Jira、Slack...),每个组合都要写一份胶水代码,N 应用 × M 工具 = N·M 工程复杂度。
  • MCP(Model Context Protocol)做的是:标准化 LLM 和工具之间的协议,让工具实现一次就能被任何支持 MCP 的 host 使用。类似 LSP 之于 IDE 和语言服务器。
  • 核心抽象:Tools(可调用函数)、Resources(可读数据源)、Prompts(可复用模板)。以 JSON-RPC over stdio / SSE 传输。
  • 和 function calling 的关系:function calling 是 单次调用 的约定;MCP 是 工具的发现、生命周期、上下文管理 的协议,FC 是 MCP 之下的一部分。
问题: N 应用 × M 工具 = N·M 工程
解法: N 应用 ↔ MCP ↔ M server = N + M 工程

加分回答:MCP 火起来的原因不是技术多复杂,而是生态决定的——Anthropic 首推、OpenAI/Google 跟进,形成事实标准。类似 early days 的 OpenAPI。工程上的坑:权限模型(server 能不能读你整个家目录?)、上下文长度(把 resource 全塞 prompt 会爆)、本地 vs 远程 server 的信任边界。新 agent 框架都在往 MCP 兼容方向收敛。

6.4 CLIP 的对比学习 loss(InfoNCE)推导

写出 InfoNCE 的形式,为什么叫"对比"?

要点:

  • CLIP 同时训 image encoder 和 text encoder,把图文 embedding 投到同一空间。Batch 内 N 对 (image, text) 正样本,N·(N-1) 个负样本(其他配对)。
  • InfoNCE loss = 对称的交叉熵:给定 image_i,在 N 个 text 里把 text_i 当正例;反过来给定 text_i,在 N 个 image 里把 image_i 当正例。
  • 温度 τ(CLIP 里是可学习的 log-parameterized)控制相似度分布的锐度。
相似度矩阵 S_ij = (I_i · T_j) / (||I_i||·||T_j|| · τ)

L = (L_i2t + L_t2i) / 2
L_i2t = -1/N Σ_i log( exp(S_ii) / Σ_j exp(S_ij) )
L_t2i = -1/N Σ_i log( exp(S_ii) / Σ_j exp(S_ji) )

"对比" = 把正对拉近, 所有其他对推远

加分回答:InfoNCE 本质是 mutual information 下界的变分估计(van den Oord 的 CPC 论文)。Batch size 直接决定负例数——CLIP 原论文用 batch=32768。小 batch 下对比学习效果差很多,这就是 MoCo 搞 memory queue、SimCLR 坚持大 batch 的原因。温度 τ 太小(< 0.01)容易崩塌,太大(> 0.5)学不细。CLIP 学到的可学习 τ 稳定收敛在 0.01 附近。

6.5 VLM 里 cross-attention 融合 vs concat token 的优劣

Flamingo 和 LLaVA 的视觉融合方式分别是什么?哪种更主流?

要点:

  • Cross-attention 融合(Flamingo 路线):语言 decoder 每隔几层插入一个 cross-attention 层,Q 来自语言 hidden,K/V 来自视觉特征。视觉 token 不进 self-attention 序列,所以不占 LLM 的 context length。需要改 LLM 架构。
  • Concat token 融合(LLaVA / Qwen-VL 路线):视觉编码器输出 N 个 token(通常 256~576),经 projector 映射到 LLM 的 embedding 空间,和文本 token concat 后一起喂 LLM。不改 LLM 架构,可以直接复用任何 LLM。
维度Cross-Attn (Flamingo)Concat (LLaVA/Qwen-VL)
改 LLM 架构是 (加层)
占 context不占占 N 个 token
多图/视频天然友好context 吃不消
训练成本需要冻结 LLM 训练 x-attn只训 projector 即可冷启动
生态兼容极好

加分回答:目前主流是 concat token——原因是生态:你能无缝接任何新出的 LLM(Llama 3、Qwen2.5)来做多模态。Cross-attention 要专门训一个架构改过的 LLM,迭代慢。代价是长视频/多图场景的 context 爆炸,所以会配合 token compression(resampler、Q-Former、pixel shuffle)把 N 压到 64–144。Idefics 和 Chameleon 是少数还在搞 native 多模态的。2025 年的趋势是 any-to-any(Gemini 原生、GPT-4o),架构上更像统一 token space 而不是 concat 或 cross-attn 的二选一。

读完之后怎么办:挑每道题里"加分回答"那段自己复述一遍。如果复述不出来,说明还没真理解。面试高频度:1.2、1.4、1.5、2.1、3.1、3.3、4.1、4.3、5.1、5.2、6.1——这 11 道是 2026 年各家都会问的"必考题"。