跳至主要内容
校招大模型笔试:基础不丢分,工程能算账

校招大模型笔试:基础不丢分,工程能算账

上个月帮实验室两个师弟看笔试复盘,一个把 attention 公式背得很熟,手推没问题,最后挂在“估算 7B 模型推理显存”上;另一个代码题基本全过,简答题写的是“加 GPU 就行了”。我的判断是,大模型笔试不是考谁更懂论文,是考谁能把模型从公式搬到机器上。基础题决定下限,工程题决定上限。

先搞清楚卷子长什么样

我见过的校招大模型笔试卷,大致分四块:机器学习与深度学习基础(选择、填空、简答),手写代码(numpy 或 torch 实现算子),工程估算(显存、FLOPs、并行、推理延迟),以及少量开放题(长文本、RAG、对齐)。不同公司权重不一样,但有个共同点:纯推导题不会太偏,工程题一定和“你有没有真正跑过模型”有关。

基础部分高频的有:attention 的 QKV 维度与计算复杂度、softmax 数值稳定、LayerNorm 和 BatchNorm 的区别、残差与梯度、交叉熵和 KL、Adam 的更新式、位置编码的直觉。这些不是背结论,要能在纸上用小矩阵走一遍。比如 attention 里为什么除以 sqrt(d_k),我会从点积方差随维度变大、softmax 容易饱和讲起,再落到梯度变小。

代码部分常考:手写 multi-head attention、layernorm、softmax、cross entropy、top-k/top-p sampling、beam search、KV cache 的 decode。也有公司出 LeetCode 风格题,但会包一层 tensor 操作,比如“给一个 [B, L, H] 的张量,按最后一维做 masked softmax”。

工程估算常考:给一个模型规模,问权重、梯度、优化器状态、激活各占多少;给 batch 和序列长度,问 KV cache 多大;问 TP/PP/DP 怎么切。这类题最容易被当成简答糊弄过去,也最容易拉开差距。

基础题:能推一遍,比背十遍强

具体做法:拿一张 A4 纸,把 transformer block 从输入到输出画一遍,标上每个张量的 shape。不要看书。画完再对照。这个动作我做大概三遍,比刷视频有用。

几个必须能现场写出来的:稳定的 softmax 和交叉熵。很多人知道减最大值,但被问到“为什么减最大值不会改变结果、什么时候会溢出”就卡住。我会写成这样:

PYTHON4 行
1
2
3
4
def log_softmax(x, axis=-1):
x_max = x.max(axis=axis, keepdims=True)
shifted = x - x_max
return shifted - np.log(np.exp(shifted).sum(axis=axis, keepdims=True))

交叉熵不要先 softmax 再 log,直接从 logits 算:

PYTHON3 行
1
2
3
def cross_entropy(logits, labels):
log_probs = log_softmax(logits, axis=-1)
return -log_probs[np.arange(len(labels)), labels].mean()

还有 attention 的缩放、mask 加在 softmax 之前还是之后、LayerNorm 的 eps 加在哪、残差连接的位置(pre-LN 和 post-LN 训练稳定性的差别)。这些点出题人换个问法就能知道你是真写过还是只看过图。

概率题也别忽略。贝叶斯、期望方差、最大似然和交叉熵的关系、采样里的 temperature 和 top-p 分别改变什么。我在模拟题里遇到过一次“top-p 采样在什么情况下会退化成 greedy”,当时答得不好,后来才想清楚:当 p 很小时,候选集只剩一个概率最高的 token。

工程题:把字节算出来

这是我觉得校招生最该补的一块,也是最容易被忽略的。学校项目里通常用现成脚本跑通就结束了,很少有人算过一张卡能放多大 batch。

先算权重。一个 7B 模型,fp16 推理,权重大约 14GB。这个数要能脱口而出,因为后面所有估算都从它出发。训练时还要加梯度(同精度 14GB)、Adam 的 fp32 一阶二阶矩和 master weights,光权重、梯度、优化器状态加起来就超过 100GB,所以才有 ZeRO 和切分。具体数字不同实现有差异,但量级要清楚。

KV cache 我更建议背下来算法而不是数字。每个 token 在每一层、每个 KV head 上存 K 和 V,元素数大致是:

TEXT1 行
1
2 * num_layers * num_kv_heads * head_dim * seq_len * batch * dtype_bytes

拿一个 32 层、32 个 KV head、head_dim 128、fp16 的模型,batch=8、seq=4096 来算,一层一个 token 的 KV 是 232128*2 bytes ≈ 16KB,32 层就是 512KB,乘 4096 和 8 大概是 16GB。这个量级能解释为什么长上下文推理先爆的是显存而不是算力。MQA/GQA 为什么能省 cache,也就一目了然。

还有几个常考的工程点:flash attention 省的是哪部分显存(不物化完整的 attention 矩阵);PagedAttention 解决的是碎片还是重复计算(碎片和按页管理);continuous batching 提升的是吞吐还是单请求延迟(吞吐,代价是延迟抖动);TP 切什么维度、通信发生在哪。答题时不用写出论文细节,但要说出“省在哪、代价是什么”。

我自己的练习方式是拿一个开源小模型(比如 1B 级别)的 config,把 hidden_size、num_layers、num_heads 抄下来,手算一遍权重、KV cache、每 token FLOPs,再用代码验证。前向每 token 的 FLOPs 大致是 2 乘以参数量,7B 模型大约 14 GFLOPs,训练还要再乘上反向的大约两倍。算错一次比看十篇文章记得牢。

时间怎么排

如果距离笔试还有四周,我会这么分:前两周补基础和手写算子,每天一道手写题加一个知识点推导;第三周集中做工程估算和真题,把近几年的卷子按题型归类;最后一周限时模拟,重点练简答题的写法——先给结论,再给公式,最后说边界。

刷题量不用很大,LeetCode 中等难度保持手感即可,重点放在 tensor 编程。手写 attention 我能闭卷写到不出 shape 错误,大概练了五六遍。错题本按“不会”“算错”“写慢”三类记,不要只抄答案;写慢的题往往是因为不熟,隔两天重写一遍。

开放题别空着。问到长文本,我会说清楚“扩位置编码、稀疏注意力、检索”各自的代价;问到 RAG,我会先问一句“是知识更新问题还是上下文太长问题”。校招生不需要给完美方案,但要让对方看到你会拆问题。

今晚找一张纸,把 7B 模型 fp16 推理的权重、KV cache(batch=1, seq=2048)和每 token 的大致 FLOPs 算一遍,算到每个数字都能解释来源。第二天再闭卷写一遍 stable softmax 和 cross entropy。哪个卡住,就先补哪个。

关于本文

由 Lu's Blog 撰写,采用 CC BY-NC 4.0 许可协议。

#大模型 #校招 #笔试

评论