按训练链路整理的面试问题与答案
文档定位:把训练相关面试题按“真实训练流程”组织,而不是按分布式、通信、显存等专题散放。这样更适合建立端到端系统观,也更方便面试时顺着流程展开。
先纠正训练过程
训练不像推理那样只有一条固定链路。更合理的主线应该是:
- 数据准备与 Tokenization
- Batch 组织与 DataLoader
- Forward
- Loss 计算
- Backward
- 梯度同步与并行通信
- Optimizer Step 与参数更新
- 显存 / 吞吐优化
- Checkpoint / Eval / 长时间稳定运行
如果是 RL / RLHF,则会在这条主链路前面插入一个额外阶段:
Rollout 生成 -> Reward / Advantage 计算 -> 再进入训练更新
所以不能把 RL 训练机械看成普通 SFT 的加强版,它本质上是“推理链路 + 训练链路”拼在一起。
目录
- 模块 1:数据准备与 Tokenization
- 模块 2:Batch 组织与 DataLoader
- 模块 3:Forward
- 模块 4:Loss 计算
- 模块 5:Backward
- 模块 6:梯度同步与并行通信
- 模块 7:Optimizer Step 与参数更新
- 模块 8:显存与吞吐优化
- 模块 9:Checkpoint、Eval 与稳定性
- 模块 10:SFT 与 RLHF 的流程差异
- LoRA 与微调面试题
- MoE 架构面试题
模块 1:数据准备与 Tokenization
这一模块在干什么
训练不是从 GPU 开始的,而是从样本构造开始的。文本清洗、切分、tokenization、样本长度分布,都会直接影响后面的 padding 浪费、吞吐和收敛稳定性。
高频问题 1:为什么训练岗位也会问数据处理和 tokenization?
答:
因为训练吞吐不只由模型决定,还由“喂给模型的数据形态”决定。如果样本长度分布极不均匀、tokenization 速度慢、无效样本比例高,后面的 GPU 再强也吃不满。面试官问这个,本质上是在看你是不是只会盯模型,而忽略整个训练系统的输入质量。
高频问题 2:BPE、WordPiece、SentencePiece 在训练里为什么重要?
答:
它们不只是 tokenizer 算法名词,背后影响的是词表大小、平均序列长度、未登录词处理方式,以及数据预处理复杂度。训练里如果平均 token 数变长,attention 计算和显存压力都会跟着上升,所以 tokenizer 设计会间接影响训练成本。
高频问题 3:为什么预训练和 SFT 的数据组织方式差别很大?
答:
因为预训练的数据规模大、长度分布相对可控,更适合追求长时间稳定吞吐;SFT 的样本长度通常更离散,padding 浪费严重,所以更依赖 sequence packing 和动态 batch 组织。换句话说,预训练更像“工业流水线”,SFT 更像“高波动混合流量”。
模块 2:Batch 组织与 DataLoader
这一模块在干什么
这一阶段决定样本怎么拼成 batch、数据如何送到 GPU,以及 CPU 是否会拖住训练主链路。它通常是“GPU 吃不满”时最先要排查的地方之一。
高频问题 1:如果训练过程中 GPU 经常吃不满,你会先查什么?
答:
先查三件事:
- DataLoader 是否跟得上,有没有 CPU 或 IO 瓶颈
- Batch 是否太小,padding 是否浪费严重
- 时间到底花在计算、访存还是通信
面试里更好的说法是:先看 top 和数据加载,再看 nvidia-smi,最后用 Nsight Systems 看 timeline。
高频问题 2:什么是 sequence packing?为什么 SFT 特别依赖它?
答:
sequence packing 是把多个短样本紧凑地拼接进同一个序列窗口,减少 padding 浪费。SFT 数据长度分布通常非常不均匀,如果不做 packing,大量算力会浪费在空 token 上,所以 SFT 比预训练更依赖它。
高频问题 3:梯度累积和增大 batch size 的关系是什么?
答:
梯度累积是在显存不变的前提下,连续做多次前向和反向、只在最后统一更新参数,从而获得更大的等效 batch size。它的好处是容易立刻落地;代价是总计算量不变,而且会拉长一次参数更新的等待时间。
模块 3:Forward
这一模块在干什么
Forward 是训练的正向计算阶段:输入 token 经过 embedding、attention、FFN / MoE,最终得到 logits。它既决定算力热点,也决定中间激活的保存成本。
高频问题 1:训练里的 forward 和推理里的 prefill 有什么像的地方?
答:
两者都属于“一次性处理整段输入”的大矩阵计算,所以都更偏 compute-bound,也都容易从 FlashAttention、混合精度、Tensor Core kernel 中受益。区别在于训练 forward 还要为 backward 保存足够的中间激活,而推理 prefill 通常只关心得到 KV Cache。
高频问题 2:Transformer 训练中参数主要分布在哪些模块?计算热点又在哪?
答:
从参数量角度看,FFN 往往是大头;从长序列计算角度看,attention 又常常是热点,尤其在上下文很长时更明显。所以面试里不要把“参数最多的模块”和“最慢的模块”直接画等号。
高频问题 3:为什么 FlashAttention 对训练也很重要?
答:
因为训练 forward/backward 都会受 attention 的 HBM 访存影响。FlashAttention 通过 IO-aware 的实现减少中间张量回写,既能提速,也能省显存,所以它在训练里不只是“快一点”,而是可能直接改变可训练的 batch size 和序列长度上限。
模块 4:Loss 计算
这一模块在干什么
模型 forward 得到 logits 后,要和标签结合计算 loss。虽然这一步看起来简单,但它决定了数值稳定性、梯度缩放方式,以及训练目标到底是什么。
高频问题 1:为什么训练里不能只关心吞吐,还要关心收敛?
答:
因为训练的目标不是“每秒算更多 token”,而是“在合理时间内把模型训好”。有些优化能提高吞吐,但可能会降低数值稳定性、破坏梯度质量或者让最终效果变差,所以训练和推理最大的不同之一,就是必须同时看性能和收敛。
高频问题 2:为什么大 batch 提高吞吐后,收敛不一定更好?
答:
因为更大的 batch 虽然能减少 step 数、提高硬件利用率,但也会改变梯度噪声特性,可能导致泛化变差或优化陷入次优点。面试里讲这题时,最好明确说:吞吐最优不一定等于训练效果最优。
高频问题 3:混合精度训练为什么要关心 loss scaling?
答:
因为 FP16 的动态范围比较小,反向传播里一些很小的梯度容易 underflow 变成 0。loss scaling 的本质是先把 loss 放大,让梯度进入可表示范围,反向之后再缩回来。它解决的不是“让训练更快”,而是“避免梯度精度直接崩掉”。
模块 5:Backward
这一模块在干什么
Backward 从 loss 反向传播到所有参数,计算梯度。它不仅是训练的核心步骤,也是激活显存、通信 overlap 和梯度同步触发的关键阶段。
高频问题 1:反向传播为什么常常比前向更贵?
答:
因为 backward 不只是重复一遍 forward,而是要沿计算图逐层传播梯度,还会伴随更多中间张量访问和梯度写回。训练里很多通信优化,比如 DDP bucket overlap,也都是在 backward 阶段触发的。
高频问题 2:激活检查点(Activation Checkpointing)是什么?为什么能省显存?
答:
它的思路是:前向时不保存所有中间激活,只保存少数 checkpoint;反向需要时,再把缺失的那部分前向重算一遍。这样做的本质是 用额外计算换显存,所以非常适合“算力还能接受,但显存先爆了”的训练场景。
高频问题 3:为什么说训练显存里激活值经常是大头?
答:
因为训练为了 backward,必须保留 forward 的中间结果;序列越长、batch 越大、层越深,激活存储就越夸张。推理通常只关心前向结果,而训练要为反向“留证据”,这就是两者显存结构的本质区别。
模块 6:梯度同步与并行通信
这一模块在干什么
单卡训练规模有限,所以训练一旦上到多卡,梯度同步和模型并行通信就成了主线之一。这个模块决定“多卡有没有真的比单卡更划算”。
高频问题 1:DDP 的基本原理是什么?梯度同步怎么做?
答:
DDP 是多进程多卡训练:初始化时保证各卡参数一致,训练时各卡独立做前向和反向,然后在 backward 过程中对梯度做 All-Reduce。它的关键优化是 bucket 机制,也就是某些层的梯度一旦准备好,就立刻开始通信,把通信时间尽量隐藏在后续反向计算里。
高频问题 2:数据并行、张量并行、流水线并行分别解决什么问题?
答:
- DP:模型复制多份,解决数据量大、单卡算得慢
- TP:单层权重切分到多卡,解决单层太大、单卡装不下
- PP:按层切分模型,解决整体太深、跨机更友好
面试里更重要的是补一句:三者解决的不是同一个问题,所以不是替代关系,而是常常组合使用。
高频问题 3:为什么通信会成为大模型训练瓶颈?
答:
因为 GPU 算力增长往往比网络带宽快,模型越大、并行越细,通信占比就越高。最终会出现“算得太快,传得太慢”的情况,导致计算无法完全掩盖通信延迟。
高频问题 4:通信与计算重叠是什么意思?为什么重要?
答:
意思是让 GPU 在做第 N-1 层反向计算时,同时发第 N 层的梯度通信。因为 SM 和网卡 DMA / NVLink 这类通信单元在物理上是独立的,如果调度得好,部分通信时间可以被“藏”进计算阶段里,从而降低端到端 step 时间。
高频问题 5:MoE 训练为什么更容易出通信问题?
答:
因为 token 需要根据 router 结果在 expert 之间做 AllToAll 分发,而 expert 往往跨卡甚至跨机部署。这样就不仅有普通训练的梯度同步,还有额外的 token 路由通信,所以经常出现“算力省了,但网络先炸了”的情况。
模块 7:Optimizer Step 与参数更新
这一模块在干什么
所有梯度准备好之后,优化器根据这些梯度更新参数。这个阶段还会涉及优化器状态、参数分片、零梯度和学习率调度等问题。
高频问题 1:为什么 Adam 会让训练显存压力特别大?
答:
因为 Adam 不只存参数本身,还要额外存梯度以及一阶、二阶动量等优化器状态。粗略看,训练里的显存不只是“参数有多大”,而是“参数 + 梯度 + 优化器状态”一起堆出来的,所以大模型一上来就很容易遇到显存墙。
高频问题 2:ZeRO / FSDP 的核心思想是什么?
答:
核心是 用通信换显存。传统数据并行要求每张卡都保存完整的参数、梯度和优化器状态;ZeRO / FSDP 则把这些状态分片到多张卡上,单卡只保存一部分,需要计算时再临时 All-Gather 拿回来。
高频问题 3:ZeRO-1 / 2 / 3 的区别怎么答?
答:
- Stage 1:分片优化器状态
- Stage 2:再加上分片梯度
- Stage 3:进一步连参数也分片
阶段越高,显存越省,但通信和实现复杂度也越高。面试里最好补一句:它不是免费省显存,而是把压力转移到了网络和调度上。
模块 8:显存与吞吐优化
这一模块在干什么
这是训练里最常被问的“工程优化区”:怎么省显存、怎么提吞吐、怎么区分瓶颈、怎么平衡训练速度和最终效果。
高频问题 1:影响大模型训练吞吐的主要因素有哪些?
答:
通常是四类:
- 算子没优化好,compute-bound
- HBM 访存压力大,memory-bound
- NCCL 或跨机通信慢,communication-bound
- DataLoader / CPU / IO 跟不上,input-bound
回答这题时,不要只列名词,要补一句“我会用 profiler 去判断到底是哪一类为主”。
高频问题 2:如何提升训练中的资源利用率?
答:
常见方向包括:
- 增大 micro-batch
- 用梯度累积获得更大等效 batch
- 做 sequence packing,减少 padding
- 优化通信拓扑和 overlap
- 使用 FlashAttention、混合精度、融合算子
但面试里最好补充 trade-off:利用率提高并不自动等于最终训练更优。
高频问题 3:混合精度训练为什么能提升效率?会带来什么问题?
答:
因为 FP16 / BF16 会减小权重和激活的存储体积,也能更好利用 Tensor Core,所以通常能同时省显存和提吞吐。问题在于 FP16 容易 underflow / overflow,BF16 虽然范围更稳,但精度位更少,所以需要结合任务和硬件选择。
高频问题 4:训练显存爆了,从哪些方向解决?
答:
优先级通常可以这么答:
- 调小 batch size,必要时加梯度累积
- 开 activation checkpointing
- 提升 ZeRO / FSDP 分片等级
- 需要时做 CPU offload
- 再考虑更激进的结构和算子优化
这类题的关键不是背招数,而是说明你知道每种方法在“算力、通信、实现复杂度”上的代价。
模块 9:Checkpoint、Eval 与稳定性
这一模块在干什么
训练不是只要 step 能跑就行,还要能长时间稳定跑下去、随时恢复、评估是否真的在变好。这一块经常在资深面试里被追问。
高频问题 1:为什么预训练特别强调长时间稳定运行?
答:
因为预训练往往要跑很多天甚至很多周,任何一次故障都可能造成极大浪费。预训练系统追求的不只是瞬时吞吐高,而是“高吞吐能持续稳定地维持很久”。
高频问题 2:Checkpoint 为什么是训练系统设计的重要组成部分?
答:
因为大规模训练不可能假设“永不失败”。Checkpoint 决定了故障恢复时间、磁盘 / 网络开销以及训练中断后的损失上限。面试里讲这题,最好把它和“长时间稳定性、故障恢复、分布式一致性”放在一起说。
高频问题 3:为什么 benchmark 不能替代真实训练验证?
答:
因为 benchmark 往往只覆盖短窗口吞吐,而真实训练还要看收敛曲线、loss 稳定性、故障恢复、长时间资源波动和最终效果。很多优化在 10 分钟压测里看起来很好,放到几天训练里未必成立。
模块 10:SFT 与 RLHF 的流程差异
为什么单独拆这一块
因为普通预训练 / SFT 基本遵循“数据 -> forward -> backward -> 更新”这条主链路,而 RLHF 会把推理链路插进训练系统内部。如果不单独拆开,很容易讲混。
高频问题 1:预训练、SFT、RL 训练在系统优化上的不同?
答:
- Pretrain:追求极致吞吐、极致 MFU、长时间稳定性
- SFT:更关注变长数据、packing、padding 浪费
- RL:是“生成 + 训练”的双链路系统,不只卡训练,还很卡 rollout 推理
一句话概括就是:Pretrain 像大规模工业流水线,SFT 像高波动监督学习,RLHF 像推理系统和训练系统绑在一起。
高频问题 2:RLHF / PPO 为什么比普通 SFT 复杂得多?
答:
因为 PPO 通常需要同时维护 Actor、Critic、Reward、Reference 四类模型,显存常态就比 SFT 紧张得多;同时它前面还有 rollout 生成、reward 打分、advantage 计算这些步骤,后面才进入标准训练更新。所以 RLHF 的复杂度不只来自“模型更多”,还来自“系统链路更长”。
高频问题 3:RL 训练的主链路怎么讲?
答:
更合理的回答是:
prompt 输入 -> Actor rollout 生成 -> Reward / Critic 评估 -> 计算 advantage / target -> PPO 或其他算法更新 Actor / Critic
这条链路说明 RL 训练不是纯训练系统,而是把“推理阶段的 rollout”放进了训练闭环。
高频问题 4:RL 训练效率瓶颈通常不只在 GPU 算力,还可能在哪?
答:
常见还有三类:
- rollout 生成太慢
- reward model 打分串行阻塞
- experience buffer 在 CPU / GPU 间搬运代价高
所以 RL 训练往往要同时优化训练引擎和推理引擎,很多工程系统会把 vLLM 一类高效 rollout 引擎和 DeepSpeed 一类训练引擎结合起来。
LoRA 与微调面试题
说下 LoRA 原理
答:
LoRA(Low-Rank Adaptation) 的核心思想:冻结预训练权重 W,用低秩分解 ΔW = BA 近似微调更新。
原始前向:h = Wx
LoRA 前向:h = Wx + BAx × (α/r)
其中:
W ∈ R^{d×k} ← 冻结,不更新
B ∈ R^{d×r} ← 可训练
A ∈ R^{r×k} ← 可训练
r << min(d, k) ← 低秩(通常 4~64)
α ← 缩放因子
理论基础: 微调过程中的权重更新矩阵 ΔW 具有低内在秩(intrinsic rank),即大部分信息可以用少量维度表示。
参数量对比:
- 全参微调:d × k 参数
- LoRA:r × (d + k) 参数
- 例如 d=k=4096, r=16:全参=16.7M,LoRA=131K(减少 99%)
LoRA 两个权重矩阵怎么初始化,能全 0 吗
答:
标准初始化:
- A:高斯随机初始化
N(0, σ²)(Kaiming 初始化) - B:全零初始化
为什么这样设计:
训练开始时:ΔW = B × A = 0 × A = 0
→ 模型从预训练权重原点出发,不破坏原始能力
B=0 的梯度:∂L/∂B = (∂L/∂h) · (Ax)^T ← A 非零,梯度正常流动
A=0 的梯度:∂L/∂A = B^T · (∂L/∂h) · x^T ← 如果 B=0,梯度也是 0!
能全 0 吗? 不能!如果 A 和 B 都初始化为 0:
- ΔW = 0 × 0 = 0 ✓(初始不改变模型)
- 但梯度 ∂L/∂A = B^T · (...) = 0^T · (...) = 0 ❌
- 梯度 ∂L/∂B = (...) · (Ax)^T = (...) · 0 = 0 ❌
- 死初始化:所有梯度为零,参数永远不更新
矩阵的秩: 秩是矩阵中线性无关的行(或列)的最大数量。LoRA 中 r 是人为选择的秩上限,决定了 ΔW 的表达能力。r 越大表达能力越强,但参数量越多。
除了 LoRA,还了解哪些训练推理优化技术
答:
参数高效微调(PEFT)方法:
| 方法 | 原理 | 参数量 | 特点 |
|---|---|---|---|
| LoRA | 低秩分解 ΔW = BA | 极少 | 最主流,多任务友好 |
| QLoRA | 4-bit 基座 + FP16 LoRA | 极少 | 显存极省(7B→6GB) |
| Adapter | 在层间插入小瓶颈模块 | 少 | 改变模型结构 |
| Prefix-tuning | 在输入前加可学习的虚拟 token | 极少 | 不改变模型参数 |
| Prompt-tuning | 学习连续 prompt embedding | 极少 | 最轻量 |
| 全参微调 | 更新所有参数 | 全部 | 效果最好,成本最高 |
其他优化技术:
- 知识蒸馏:大模型教小模型,部署时用小模型
- 模型剪枝:去除不重要的权重/头/层
- 量化:降低权重/激活精度(INT8/INT4/FP8)
- 投机解码:小模型 draft + 大模型 verify
LoRA 一般加在哪些层,怎么初始化
答:
常见策略:
| 层 | 是否加 LoRA | 原因 |
|---|---|---|
| W_Q, W_V | ✅ 原论文推荐 | 实验效果最好的组合 |
| W_K | 可选 | 加上通常有微小提升 |
| W_O | 可选 | 输出投影 |
| W_up, W_gate, W_down | ✅ 现代实践 | FFN 层加 LoRA 提升明显 |
| Embedding / LM Head | 很少加 | 参数量大,LoRA 收益低 |
现代最佳实践: 所有线性层都加 LoRA(QKV + O + FFN),配合较小的 r(如 16-32)。
初始化方法:
- A:Kaiming uniform 或 Gaussian
N(0, 1/r) - B:全零
- 缩放因子:
α/r(α 通常等于 r 或 2r)
全参微调和 LoRA 各有什么缺点?怎么决定用哪种
答:
| 维度 | 全参微调 | LoRA |
|---|---|---|
| 显存 | 非常大(16 bytes/参数 + 激活) | 很小(冻结基座 + 少量参数) |
| 效果 | 通常最好 | 接近全参(复杂任务可能差 1-3%) |
| 多任务 | 每个任务一份完整模型 | 每个任务只需一份 LoRA 权重(几 MB) |
| 灾难性遗忘 | 较严重 | 较轻(原始权重冻结) |
| 训练速度 | 慢(更新所有参数) | 较快(只更新少量参数) |
| 过拟合风险 | 数据少时容易过拟合 | 较低(参数少,正则效果) |
决策指南:
数据量大(>100K)+ GPU 充足 + 单任务 → 全参微调
数据量小(<10K)+ GPU 有限 + 多任务 → LoRA
极端显存限制(单卡 24GB 跑 7B)→ QLoRA
需要部署多个任务版本 → LoRA(动态加载不同 adapter)
主流 SFT 方法有哪些,各自优势和适用场景
答:
| 方法 | 显存需求 | 效果 | 训练速度 | 适用场景 |
|---|---|---|---|---|
| 全参微调 | 最高 | 最好 | 最慢 | 充足资源、单任务、追求极致效果 |
| LoRA | 低 | 接近全参 | 较快 | 多任务、中等资源、快速迭代 |
| QLoRA | 最低 | 略低于 LoRA | 中等 | 消费级 GPU(24GB)、极限资源 |
| Adapter | 低 | 接近 LoRA | 较快 | 需要模块化切换的场景 |
| Prefix-tuning | 最低 | 偏低 | 最快 | 极轻量任务、API 调用场景 |
工程实践建议:
- 先试 LoRA(平衡效果和成本,大多数场景够用)
- 效果不够 → 加大 LoRA rank 或 增加 LoRA 层数
- 仍不够 → 全参微调
- 资源极限 → QLoRA
MoE 架构面试题
MoE 一般加在哪?从训练和推理角度看有什么好处
答:
MoE 替换 FFN 层(不替换 Attention 层):
标准 Transformer Block:
Input → Attention → [FFN] → Output
MoE Transformer Block:
Input → Attention → [Router → Top-K Experts (FFN × N)] → Output
训练角度的好处:
- 参数量大但计算量小:671B 参数模型(如 DeepSeek-V3),每 token 只激活 37B
- 更好的 Scaling:相同计算预算下,MoE 模型质量优于 Dense 模型
- 专家可以学习不同领域知识(代码、数学、语言等)
推理角度的好处:
- 每 token FLOPs 与更小的 Dense 模型相当
- 理论延迟接近小模型,但质量接近大模型
- 劣势: 总参数量大 → 需要更多显存存放所有 expert 权重
推导 MoE 架构的负载均衡损失函数,如何避免专家坍缩
答:
专家坍缩问题: 如果不加约束,Router 可能学会只把 token 发给少数几个 expert → 其他 expert 参数浪费 → 模型退化为小 Dense 模型。
负载均衡损失(Auxiliary Load Balancing Loss):
L_aux = α · N · Σ_{i=1}^{N} f_i · P_i
其中:
N = expert 总数
f_i = expert i 实际接收的 token 比例 = (分到 expert i 的 token 数) / (总 token 数)
P_i = expert i 的平均 gate 概率 = (1/T) · Σ_{t} p_i(x_t)
α = 平衡系数(通常 0.01-0.1)
理想情况:f_i = P_i = 1/N(均匀分配)
L_aux 在均匀分配时取最小值
直觉理解:
- f_i · P_i 是"实际比例 × 期望比例"的点积
- 当分配不均匀时,热门 expert 的 f_i 和 P_i 都大 → 乘积大 → loss 大
- 优化 L_aux 会推动 Router 更均匀地分配 token
DeepSeek-V3 的创新:Auxiliary-Loss-Free Load Balancing
不用辅助 loss,而是给每个 expert 加一个 bias 项:
gate_i = softmax(W_r · x + b_i)
动态调整 b_i:
- 如果 expert i 负载过高 → 降低 b_i
- 如果 expert i 负载过低 → 提高 b_i
优势:不干扰主 loss 的优化方向
什么是 MoE,核心设计思想
答:
MoE(Mixture of Experts) = 稀疏激活的条件计算架构。
核心组成:
┌─→ Expert 1 (FFN) ─┐
├─→ Expert 2 (FFN) ─┤
x → Router ├─→ Expert 3 (FFN) ─┼─→ Σ(weight_i × expert_i(x)) → output
├─→ ... ─┤
└─→ Expert N (FFN) ─┘
↑
只激活 Top-K 个
核心设计思想: "用更多参数,不成比例增加计算量"
| Dense 模型 | MoE 模型 |
|---|---|
| 所有参数每次都参与计算 | 每次只激活一小部分参数 |
| 参数量 = 计算量 | 参数量 >> 计算量 |
| 计算效率高,参数利用率 100% | 参数多但利用率低(每 token ~10-15%) |
条件计算: 不同输入 token 走不同 expert → 模型容量大但计算稀疏。
DeepSeek MoE 架构设计特点
答:
DeepSeek(深度求索,中国 AI 公司)的 MoE 架构有以下关键创新:
1. 细粒度专家(Fine-grained Experts):
传统 MoE (Mixtral): 8 个大 expert,Top-2 激活
DeepSeek MoE: 256 个小 expert,Top-8 激活(V3)
同样的激活参数量,但组合更灵活
2. 共享专家(Shared Experts):
所有 token 必经的共享 expert(1-2 个)
+ 按 routing 选择的 routed expert(Top-K)
共享 expert 处理通用知识,routed expert 处理专业知识
避免每个 expert 都冗余学习基础能力
3. DeepSeek 系列演进:
| 版本 | 总参数 | 激活参数 | Expert 数 | 关键创新 |
|---|---|---|---|---|
| V1 | 16B | Dense | - | 基线 Dense 模型 |
| V2 | 236B | 21B | 160 routed + 2 shared | MLA + 细粒度 MoE |
| V3 | 671B | 37B | 256 routed + 1 shared | 无辅助 loss 均衡 + FP8 训练 |
如何解决 MoE 中专家负载不均衡问题
答:
| 方法 | 原理 | 效果 |
|---|---|---|
| Auxiliary Loss | 添加负载均衡损失 L_aux | 最常用,但干扰主 loss |
| Expert Capacity | 每个 expert 设最大 token 数上限,超出丢弃 | 简单粗暴,但丢 token 影响精度 |
| Token Dropping | 负载超限时随机丢弃 token | 训练时常用 |
| Bias Adjustment | DeepSeek-V3:动态调整 gate bias | 不干扰主 loss |
| Device-limited Routing | 限制 token 只能路由到本卡 expert | 减少跨卡通信 |
| Stochastic Routing | 在 Top-K 基础上加入随机性 | 促进更均匀的探索 |
分布式训练中 MoE 如何实现专家参数高效更新
答:
Expert Parallelism (EP):
GPU 0: Expert 0-63 GPU 1: Expert 64-127
GPU 2: Expert 128-191 GPU 3: Expert 192-255
Token 分发(AllToAll):
Step 1: 每个 GPU 的 Router 决定本地 token 去哪个 expert
Step 2: AllToAll 通信 → 把 token 发送到 expert 所在的 GPU
Step 3: 各 GPU 本地计算各自 expert
Step 4: AllToAll 通信 → 把结果发回原始 GPU
优化策略:
- 分层 AllToAll:先机内通信(NVLink),再跨机通信(RDMA)
- 通信-计算重叠:边发送下一批 token,边计算当前批
- Expert Grouping:相关 expert 放在同一节点减少跨机通信
- TP + EP 混合:单个 expert 用 TP 切到多卡(超大 expert 时)
Qwen3 和 DeepSeek 的 MoE 有什么区别
答:
| 维度 | Qwen3 MoE | DeepSeek V3 MoE |
|---|---|---|
| Expert 数量 | 128 routed | 256 routed |
| 激活 Expert | Top-8 | Top-8 |
| Expert 粒度 | 中等 | 更细粒度 |
| 共享 Expert | 有(1 个) | 有(1 个) |
| 负载均衡 | 传统 Auxiliary Loss | 无辅助 loss(Bias 调整) |
| Device-limited Routing | 未强调 | ✅ 限制跨设备路由 |
| MLA | 未使用(用 GQA) | ✅ MLA 压缩 KV Cache |
核心区别:
- 负载均衡策略:DeepSeek 的无辅助 loss 方法更优雅,不干扰主训练目标
- Expert 粒度:DeepSeek 256 vs Qwen3 128,更细粒度允许更精确的专家组合
- 注意力机制:DeepSeek 用 MLA(低秩 KV 压缩),Qwen3 用 GQA
MoE vs Dense 训练难点,DeepSeekMoE 的创新
答:
MoE 训练难点:
| 难点 | 说明 |
|---|---|
| 负载不均衡 | 热门 expert 过载、冷门 expert 饥饿 → 专家坍缩 |
| 训练不稳定 | Router 的 softmax 梯度、expert 间竞争 → loss 波动 |
| 通信开销 | AllToAll 在跨机场景下开销巨大 |
| 路由波动 | 训练早期 routing 不稳定 → 相同 token 频繁切换 expert |
| 显存瓶颈 | 总参数量大,即使稀疏激活也需要全量 expert 常驻 |
| 评估困难 | 如何判断 expert 是否真正专业化 |
DeepSeekMoE 的创新点及价值:
-
细粒度专家设计(16→256 个小 expert)
- 更多 expert → 组合空间指数增长 → 更精确的专家分配
- 每个小 expert 更容易专业化
-
共享专家机制
- 1-2 个 expert 始终激活,处理通用知识
- routed expert 可以专注于差异化能力
- 避免每个 expert 都冗余学习"通用语法"
-
Auxiliary-Loss-Free 均衡(V3)
- 传统辅助 loss 会干扰主训练目标
- Bias 动态调整 → 均衡与主 loss 解耦
-
Device-limited Routing(V3)
- token 优先路由到本卡 expert → 大幅减少 AllToAll 通信
为什么效果好: 细粒度 + 共享 → 更好的专家专业化 + 基础能力保底;无辅助 loss → 主训练不受干扰;设备限制路由 → 通信可控。
推荐使用方式
如果你是按训练链路准备面试,建议这样读:
- 先读
模块 3 ~ 模块 7,把标准训练主链路搞清楚 - 再读
模块 8,掌握显存、吞吐和瓶颈分析 - 最后读
模块 10,把 SFT 和 RLHF 的流程差异补上 - 补充阅读
LoRA 与微调面试题和MoE 架构面试题
对照到旧文档
- 如果想看分布式主线,看 DistributedTraining.md
- 如果想看吞吐和资源利用率,看 TrainingOptimization.md
- 如果想看通信主线,看 CommunicationOptimization.md
- 如果想看显存和 ZeRO / FSDP,看 MemoryOptimization.md
- 如果想看 SFT / RLHF 差异,看 RLTraining.md