面灵AI→

PDD Infra二面凉经

轮次
一面+二面
结果
已挂
时间
2026-10
来源
牛客网

《面试题目》

一面

  1. 手撕:GEMM 矩阵乘(实现并优化)。
  2. 推理引擎相关的原理问题。

二面

  1. 介绍一下你的课题和项目。
  2. 分布式并行有哪些方法?各自有什么特性?
  3. 举例一个 PP(流水线并行)的训练场景:如何提高串行的几个显卡的负载?
  4. 训练时占用显存的数据有哪些?
  5. 手撕:一道力扣中等题(被指出时间复杂度偏高)。

《参考解析》

分布式并行必须能按「切什么」把几条路线区分开,并能报出通信量和适用边界:数据并行(DP/DDP)每张卡持有完整模型、切分数据,反向时用 all-reduce 同步梯度,通信量与参数量成正比,优点是实现简单,缺点是显存不省(优化器状态、梯度都是全量)。ZeRO 在数据并行上做显存分片:stage 1 切优化器状态、stage 2 再切梯度、stage 3 连参数也切,代价是前向时参数需要 all-gather,通信量上升。张量并行(TP)把单层内的矩阵乘法按行或列切开,每层都要通信(列并行后接行并行,反向再补一次 all-reduce),通信频繁,所以基本限制在单机 NVLink 内。流水线并行(PP)按层把模型切成若干 stage 放到不同卡上,只在 stage 边界传激活值,通信量小但会引入气泡(bubble),适合跨机。专家并行(EP)服务 MoE,把不同专家放到不同卡上,靠 all-to-all 分发 token。序列并行(SP)切序列维度以降低长序列的激活显存。回答时给一句总结:TP 换显存、通信最密;PP 换显存、通信最疏但有气泡;DP 换吞吐、显存最吃;实际大模型训练是 3D 并行的组合,按「单卡显存放不下 → 网络带宽 → 集群规模」的顺序做决策。

PP 负载不均的题,标准解法是「把气泡填掉」,可以按从易到难给方案:先解释气泡从哪来:朴素 PP 里同一时刻只有一部分 stage 在算,其余在等,前向和反向之间有依赖,GPU 利用率随 stage 数增加而下降。第一层优化是 micro-batch 切分配合 GPipe 的「先做完所有 micro-batch 的前向、再做反向」,能提高并行度但激活显存占用高;第二层是 1F1B(one-forward-one-backward)交错调度,让每张卡尽早进入反向,显存峰值明显下降,这是 Megatron 的默认做法;第三层是 interleaved / virtual pipeline stages,把每张卡负责的层再切成多段,减少气泡比例,代价是通信次数增加;第四层是 zero-bubble pipeline,通过拆分反向计算为「输入梯度」和「权重梯度」两部分,把权重梯度计算塞到气泡里,几乎消掉气泡。除了调度,还要提「切分均衡」:按每层的计算量与显存来切,而不是按层数平均,同时让 embedding、loss 这类特殊层单独处理。最后落到指标上:用 bubble ratio ≈ (p-1)/(m+p-1)(p 为 stage 数、m 为 micro-batch 数)来说明「增大 micro-batch 数、减少 stage 数、或做交错」都能降低气泡,这句公式能直接体现你懂原理。

「训练时占显存的数据有哪些」是必答题,按组成逐项报并给出优化对应关系:主要几块:① 模型参数(fp16/bf16 每参数 2 字节,fp32 4 字节);② 梯度(与参数同量级);③ 优化器状态(Adam 需要一阶、二阶动量和 fp32 主权重,混合精度下约为参数量的 12 字节/参数,是显存杀手);④ 激活值(与 batch size、序列长度、层数、hidden size 正相关,长序列时可能超过参数本身);⑤ 通信缓冲区(all-reduce/all-gather 的临时空间、NCCL buffer);⑥ 框架开销(CUDA context、cuDNN workspace、显存碎片、预分配缓存池)。对应的优化手段要能一一映射:激活值多 → activation checkpointing(重计算换显存)、sequence parallel、更小的 micro-batch;优化器状态大 → ZeRO-1/2/3、offload 到 CPU/NVMe、8-bit Adam;参数与梯度 → 混合精度、参数分片;碎片问题 → PYTORCH_CUDA_ALLOC_CONF=expandable_segments、及时释放缓存。回答时可以给一个粗略口径:混合精度 + Adam 下,每 10 亿参数大约需要 16–20 GB 显存(不含激活),这能说明你有实感。

遇到面试官方向不匹配,处理方式比知识量更影响结果:这场的核心问题是「一面考推理、二面换成分布式训练」,说明 Infra 岗位内部方向划分很细。可行的应对是:第一,坦诚划出边界,明确说「训练侧的工程实践我做得不多,我熟悉的是推理引擎与算子优化」,然后主动做知识迁移——比如 PP 的负载均衡和推理服务的调度有共通处(continuous batching 也是把不同请求拼批来填满算力),把话题拉回自己能深入的地方,让对方看到你的思考方式;第二,不要硬编,这场的自述就是「很多内容完全不会」时被追着问更容易露馅,一旦被识别为编造,前面答对的部分也会被折价;第三,面试后主动补齐短板,分布式训练这条线的入门路径很清楚:读 Megatron-LM 与 DeepSpeed 的并行文档,理解 DP/TP/PP/ZeRO 的切分逻辑,跑一次小规模多卡训练观察显存与通信占比,看懂 bubble ratio 公式。对推理方向的候选人来说,补上训练侧知识是拓展 Infra 岗位面的必要投资。

「时间复杂度偏高」的反馈要当成具体信号来复盘:面试官说复杂度高,通常意味着你给的解法比预期多了一个数量级,而你没有在讲思路时主动比较过候选方案。正确的答题习惯是:先用一两句话给出暴力解及其复杂度(例如 O(n²)),指出瓶颈,再给优化方向(排序 + 双指针、前缀和、二分答案、单调栈、哈希换空间、DP 状态压缩),落地一个能写出来的版本,最后说明为什么不能再快。这场的另一处教训是「不要用印象刷题」:遇到看着眼熟的题先重读约束与问法——是求方案数、求最小操作数还是求是否可行,三者对应的 DP 状态设计完全不同(比如力扣 115 不同的子序列求的是方案数,转移是 dp[i][j] = dp[i-1][j] + (s[i]==t[j] ? dp[i-1][j-1] : 0),而编辑距离求的是操作数)。平时按题型整理模板与常见追问,比追求刷题数量更能应付现场变形。