10.22 字节跳动大模型算法三面:Transformer 复杂度推导与训练工程追问
- 轮次
- 三面
- 结果
- 三面已过
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 核心优化方案具体改了什么,用一句话说清。
- 这个优化对应哪个指标、涨了多少,怎么把增长归因到你的改动?
- 同期还上线了什么?你怎么排除是它们的功劳?
- 基座微调还是从零训,为什么这么选?
- 训练数据的清洗流程和筛选规则是什么?一条一条说。
- 清洗过程中有没有误删、错筛?怎么估这个误差?
- 完整讲一遍 Transformer 的架构和每个模块的作用。
- 给定头数 H、序列长度 N、嵌入维度 D、层数 L,整体计算复杂度怎么推?
- 这个复杂度里哪一项在长序列下会先爆?爆了之后你怎么改?
- MHA、MQA、GQA 三者的 KV cache 大小差多少?各自牺牲了什么?
- 位置编码用绝对还是相对?要外推到 32K,你会动哪里?
- KV cache 为什么能省计算但不能省显存?显存占用公式写一下。
- 手写二分类交叉熵,并说明为什么不用 MSE。
- 讲一下生成式模型的基本原理。
- 手写 VAE 的 loss,并解释 KL 项在干什么。
- VAE 的 KL 项如果权重给太大,会出现什么现象?
- 混合精度训练里,为什么需要 loss scaling?
- 梯度检查点省的是什么,代价是什么?
- ZeRO 的 1/2/3 阶段分别切了什么?
- 数据并行和模型并行,什么规模下必须换?
- 你训这个模型用了多少卡、多少 token、多久?MFU 算一下。
- 如果 loss 突然尖峰,你的排查顺序是什么?
- 算法题:给一堆长宽高各不相同的积木,上层长宽必须严格小于下层,求最大堆叠高度,允许旋转。
《参考解析》
复杂度推导与成本结构:单层注意力的 QK^T 与 AV 各是 2N²D,合计 4N²D;FFN 隐层按 4D 算,升维降维各 8ND²,合计 16ND²。全模型 L(4N²D+16ND²),分头不改变总量,因为 H 个头只是把 D 切成 H 份分别算再拼回。两项相等时 N=4D,N=2048、D=4096 正落在 FFN 主导的区间,「注意力最贵」只在长序列成立。这也解释了长上下文为什么改架构而不是加卡:加卡买的是吞吐,改的是系数——FlashAttention 降的是 HBM 读写不是 FLOPs,GQA、MLA 压的是 KV cache,只有稀疏与线性注意力真正动 N² 这一项。
KV cache 与注意力变体:解码第 t 步只需算新 token 的 Q,历史 K/V 复用,每步由 O(N²) 降到 O(N),这是省下的计算;但 K/V 必须常驻,占用 2·L·N·H_kv·d_head·bytes,MHA 下即 2·L·N·D·bytes,随 batch 和序列线性涨。MQA 把 H_kv 压到 1,cache 是 MHA 的 1/H;GQA 取 G 组,是 G/H。代价在表达力:MQA 掉点明显,GQA 用很小的质量损失换数倍显存和解码带宽,所以成了主流。解码是带宽瓶颈而非算力瓶颈,压 KV 直接换吞吐。
位置编码与外推到 32K:绝对位置编码查表,超过训练长度只能扩表重训,天然不能外推;RoPE 靠旋转内积只依赖相对位置,但直接拉长会让高频维度过快旋转、注意力熵变大,困惑度在窗口边界陡增。工程上一般三件套一起上:位置插值把 32K 压回训练长度内,NTK-aware 按频率分段调 base,YaRN 再补注意力温度修正;同时必须补长文继续预训练,只改公式不补数据,长窗口里的检索能力照样很差。
交叉熵与 VAE 的 KL:二分类交叉熵配 sigmoid 时梯度就是 p−y,错得越离谱梯度越大;换成 MSE 会多乘一个 σ′(z),预测饱和时梯度趋近 0,这是不用 MSE 的实质原因。VAE 的 loss 是重建项加 β·KL,KL 把后验拉向标准正态,保证隐空间可采样、可插值;β 过大会 posterior collapse——KL 被压到 0,encoder 退化成常数、decoder 干脆忽略 z,样本模糊而训练 loss 还很低。
训练工程:FP16 最小正规数约 6e-5,反传中的小梯度会下溢成 0,所以把 loss 乘 S、梯度同比例放大,更新前再除回来,动态缩放靠检测 inf/NaN 调 S;bf16 指数位与 fp32 相同,通常不用缩放。梯度检查点不存中间激活、反向重算,省的是激活显存,代价约三成算力,且 RNG 状态必须一并存下。ZeRO-1 切优化器状态、2 再切梯度、3 连参数一起切,切得越深通信越多,3 阶段每层都要 all-gather。MFU 是实测 FLOPs/s 除峰值,训练每 token 约 6 倍参数量;远低于峰值时先看并行切分、序列长度与通信占比。loss 尖峰的排查顺序是数据(坏样本、标签、截断)→ 梯度范数与学习率 → 数值溢出与缩放 → 单卡硬件和通信。
归因与手撕:问「涨了多少、怎么归到你」,要给对照而不是绝对值:灰度分桶或 switchback、把同期其他改动做正交拆解、看护栏指标有没有被牺牲,拿不出实验就老实说这是相关性。三维积木先把每块拆成三个底面并规范化长≥宽,按长降序、宽降序排序,退化成二维严格递增链,O(n²) DP 可过;同尺寸必须按宽降序排,否则会自己叠自己,「严格小于」不能写成 ≤。要优化就用树状数组或 CDQ 做到 O(n log²n)。