160个路由专家如何协同?DeepSeek-Coder-V2 MoE分组受限贪心路由算法与源码逐行精读
160个路由专家如何协同DeepSeek-Coder-V2 MoE分组受限贪心路由算法与源码逐行精读【免费下载链接】DeepSeek-Coder-V2-Base开源代码智能利器DeepSeek-Coder-V2性能比肩GPT4-Turbo支持338种编程语言128K代码上下文助力编程如虎添翼。项目地址: https://ai.gitcode.com/hf_mirrors/deepseek-ai/DeepSeek-Coder-V2-BaseDeepSeek-Coder-V2-Base 是一款开源的 MoE混合专家代码大模型总参数 236B、每个 token 仅激活约 21B 参数支持 338 种编程语言与 128K 代码上下文。它的核心秘密就藏在每个 MoE 层里 160 个路由专家的分组受限贪心group_limited_greedy路由算法中。本文带你读懂这套路由的 8 个关键超参数并逐行精读源码搞懂每个 token 如何被分发给 6 个专家。为什么是160个专家总参数236B、激活21B的秘密 DeepSeek-Coder-V2 基于 DeepSeekMoE 框架构建见 README.md模型共 60 层第 0 层是普通稠密 FFN其余 59 层都是 MoE 层由first_k_dense_replace1和moe_layer_freq1控制见 modeling_deepseek.py。每个 MoE 层的 FFN 被拆成160 个独立的专家小网络外加2 个永远工作的共享专家。每个 token 进来时只由门控网络选出 6 个路由专家参与计算——这就是总参数巨大、激活参数很少的来源知识容量大单 token 计算量却只有稠密模型的一小部分。路由超参数速查从config.json读懂8个关键参数 所有路由行为都由 config.json 中的超参数决定参数值含义n_routed_experts160每层路由专家总数config.jsonn_group8专家被划分为 8 个组每组 20 个topk_group3每个 token 先选出 3 个组共 60 个候选num_experts_per_tok6最终选 6 个专家处理该 tokenn_shared_experts22 个共享专家所有 token 必过routed_scaling_factor16.0专家输出放大系数scoring_funcsoftmax门控打分方式aux_loss_alpha0.001负载均衡辅助损失权重group_limited_greedy如何工作5步路由流程分组受限贪心可以拆成一条流水线理解它只需要 5 步打分门控网络为该 token 的 160 个专家各算一个 softmax 分数分组取最大160 个分数按 8 组×20 个折叠每组取组内最大值得到 8 个组分数选3个组取组分数最高的 3 个组候选池缩小到 60 人再选6个专家未入选组的专家分数清零从 60 人中贪心取最高的 6 个放大权重这 6 个专家的分数乘以 16.0作为最终融合权重。为什么要先选组如果直接对 160 个专家做贪心 Top-6流量容易集中到少数明星专家其余专家长期闲置。先锁定 3 个组相当于强制分散到不同组内兼顾了负载均衡与计算效率。源码逐行精读MoEGate.forward 的关键四步 ⚙️以下片段均出自 modeling_deepseek.py 的MoEGate.forward。第 1 步计算门控分数L424-L428logits F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32)) scores logits.softmax(dim-1, dtypetorch.float32)self.weight是 160×5120 的打分矩阵L410-L4125120 维隐藏状态 × 矩阵 → 160 个原始分再做 softmax 得到每个专家的兴趣分。特意提升到 float32 计算是防止低精度下的数值误差影响路由决策。第 2 步分组取组内最大分L440-L442group_scores scores.view(bsz * seq_len, self.n_group, -1).max(dim-1).values把 [tokens, 160] 视成 [tokens, 8, 20]对最后一维取 max得到 [tokens, 8] 的组分数——一行代码完成160 变 8。第 3 步选 3 个组并生成掩码L443-L457group_idx torch.topk(group_scores, kself.topk_group, dim-1, sortedFalse)[1] group_mask.scatter_(1, group_idx, 1) # 组级别 one-hot tmp_scores scores.masked_fill(~score_mask.bool(), 0.0) # 落选组分数清零先对 8 个组分数 Top-3 选出组号把组掩码0/1扩展回 160 维的专家掩码再用masked_fill把落选组的专家分数全部置 0。注意分数被清零但专家仍在它们只是这轮失去了竞争资格。第 4 步从 60 人中贪心取 6L458-L460topk_weight, topk_idx torch.topk(tmp_scores, kself.top_k, dim-1, sortedFalse)tmp_scores中非零值只可能落在 3 个被选中的组里所以这次 Top-6 天然满足组内分散的约束。路由到此完成输出专家索引topk_idx与权重topk_weight。为什么乘以16routed_scaling_factor的设计意图 ⚖️权重缩放L463-L467有两种模式topk_weight topk_weight * self.routed_scaling_factor # 本模型走这条softmax 在 160 个专家上摊开后单个专家的分数很小6 个专家加总也远小于 1——如果不做处理MoE 层输出会像被稀释一样偏弱。乘以 16.0本模型的取值就是把 6 个专家的贡献整体放大补偿稀疏路由带来的信号损失另一种模式是norm_topk_probtrue时把 6 个权重归一化为和为 1。本模型选择了前者norm_topk_probfalse见 config.json。辅助损失三行读懂160个专家如何不摸鱼 路由有个经典风险某些专家被反复选中另一些几乎无人问津。为此训练时self.training且alpha 0会额外计算负载均衡辅助损失L468-L496用scatter_add_统计每个专家被选中的频率L479-L483频率向量 × 门控概率向量再乘aux_loss_alpha0.001得到aux_lossL484-L486seq_auxtrue表示按序列聚合统计减少逐 token 统计的噪声。aux_loss通过 AddAuxiliaryLoss 这个自定义 autograd 函数挂在输出张量上前向时原样返回不影响输出反向时自动把辅助损失的梯度带回门控权重——训练时悄悄纠偏推理时零开销。选中之后训练与推理的两条计算路径 选完专家后真正的计算在 DeepseekV2MoE 中完成训练路径L574-L583每个 token 复制 6 份遍历 160 个专家让每个专家只处理属于自己的 token 子集最后按权重求和推理路径moe_infer先scatter_统计每个专家分到的 token 数L592-L594再把 token 按专家排序L595-L596逐个专家批量前向L632-L642最后打回原序加权求和L655-L663。当ep_size1时还会通过all_to_all把专家分片到多块 GPUL598-L629共享专家两条路径最后都会加上 2 个共享专家的输出L586-L587它们不受路由影响承载通用知识。打开权重索引 model.safetensors.index.json 可以亲眼验证除第 0 层外每层都有experts.0~experts.159共 160 个专家每个专家含 up/gate/down 三组投影矩阵中间维度为 1536moe_intermediate_size。快速上手本地运行DeepSeek-Coder-V2 ️git clone https://gitcode.com/hf_mirrors/deepseek-ai/DeepSeek-Coder-V2-Base用 transformers 加载trust_remote_codeTrue会加载仓库内的 modeling_deepseek.py 与 configuration_deepseek.pyfrom transformers import AutoTokenizer, AutoModelForCausalLM import torch path DeepSeek-Coder-V2-Base tokenizer AutoTokenizer.from_pretrained(path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( path, trust_remote_codeTrue, torch_dtypetorch.bfloat16 ).cuda()代码补全时把#write a quick sort algorithm之类的提示交给model.generate即可对话模板可参考 tokenizer_config.json。追求吞吐推荐 vLLM。注意236B 模型 BF16 推理约需 8×80GB 显存显存有限可考虑同系列的 16B Lite 版本。小结一句话回顾这套路由打分组分 → 选 3 个组 → 组内选 6 个专家 → 权重放大 16 倍辅以负载均衡损失与 2 个共享专家兜底。正是这个 5 步的 group_limited_greedy 算法让 DeepSeek-Coder-V2 用 21B 的激活算力装下 236B 的知识容量在代码补全、代码插入等任务上比肩闭源旗舰模型——理解它也就理解了当前 MoE 大模型的主流设计范式。【免费下载链接】DeepSeek-Coder-V2-Base开源代码智能利器DeepSeek-Coder-V2性能比肩GPT4-Turbo支持338种编程语言128K代码上下文助力编程如虎添翼。项目地址: https://ai.gitcode.com/hf_mirrors/deepseek-ai/DeepSeek-Coder-V2-Base创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考