来源:AIGC深一度
混合专家模型(Mixture of Experts, MoE)用多个小型前馈网络(FFN)(称为专家)和一个可学习的路由/门控网络替代了密集型前馈块,其中路由网络会将每个token(或样本)发送给少数几个专家。这在保持每个token计算量较低的同时,提供了巨大的参数容量——因此你可以快速预训练超大模型——但这也增加了工程复杂性:存储所有专家所需的内存、路由逻辑、负载均衡以及跨设备通信。
什么是混合专家模型?
可以把MoE层想象成一个有许多专家的呼叫中心。对于每个进来的“呼叫”(输入token的隐藏向量),路由器会决定将呼叫转接到哪些专家。只有被选中的专家会进行计算并响应;它们的输出会被合并(通常是加权合并)以生成该层的输出。
对于输入x,形式化定义如下:
其中 是第i个专家, 是门控权重(通常是稀疏的,有很多零)。在稀疏MoE中,我们只计算非零的 。实际效果是:参数数量随N增长,但每个token的计算量随活跃专家数量(k)增长,而不是随N增长。
混合专家(MoE)模型由多个“专家”子网络和一个门控网络组成,门控网络负责选择对每个输入应用哪些专家。在经典MoE中(Jacobs等人,1991年;Jordan与Jacobs,1994年),软门控函数会输出一个关于专家的概率分布,最终输出是所有专家输出的加权和。现代稀疏MoE使用硬门控或稀疏门控:门控只为每个输入选择少数几个专家(通常1-2个),这大大增加了模型容量,同时不会按比例增加计算量。Shazeer等人(2017年)总结道:“MoE由……前馈子网络和一个可训练的门控网络组成,门控网络会选择稀疏的专家组合来处理每个输入。”换句话说,对于每个输入x,门控会为每个专家E_i生成分数g_i(x),然后通常只评估分数最高的k个专家,并将它们的输出E_i(x)合并。形式上,MoE层的输出可以写成
其中 仅在被选中的专家处非零。这种稀疏门控使得模型可以拥有巨大的参数数量(许多专家),但每个样本只需要评估少数几个专家。
经典MoE与现代MoE的对比
早期的MoE模型(20世纪90年代)使用软门控(例如softmax/EM算法),因此每个专家都会对每个输出有所贡献。Jacobs和Jordan的分层MoE使用期望最大化算法来训练门控网络和专家回归器。相比之下,现代MoE利用条件计算:每个输入只激活一小部分专家。Shazeer等人(2017年)通过在softmax门控中添加噪声和top-k选择,在深度学习中复兴了MoE,得到了参数可达数千亿的稀疏模型。最近,像GShard(Lepikhin等人,2020年)和Switch Transformer(Fedus等人,2021年)这样的架构通过高效路由将稀疏MoE扩展到了数万亿参数。例如,GShard在2048个TPU v3芯片上实现了一个6000亿参数的多语言翻译MoE,而Fedus等人报告称,训练一个1.5万亿参数的“Switch”模型的速度是密集基线模型的7倍。正如Mu和Lin(2025年)所观察到的,MoE采用“分而治之”的策略:模型不再为每个输入重用所有参数,而是为每个输入动态选择和激活一部分参数。这使得MoE能够大幅扩展容量(让专家专门化),而不会按比例增加计算量。
MoE中的稀疏性指的是:对于每个token,只有一小部分(k个)专家被激活。稀疏性带来的好处包括:
巨大的参数预算(许多专家),而每个token的FLOPs不会线性增加。
条件计算:不同的输入使用不同的参数。
两种常见的路由方式:
Top-k带噪声门控(Shazeer等人):添加噪声,保留top-k分数,然后对这些分数进行softmax。噪声有助于探索和负载均衡。
Top-1硬路由(Switch):将每个token路由到单个专家——通信/计算成本更低,且在实际中质量仍然很好。
问题:路由器可能会“坍缩”——许多token涌向少数几个专家→这些专家训练得更快,被选中的次数更多→形成正反馈循环。
常见解决方案:
辅助均衡损失(重要性×负载):计算每个专家的期望门控概率和实际token数量;添加一个鼓励均匀分布的惩罚项。这是GShard/Switch中使用的经典技术。
带噪声门控:在门控logit中添加小噪声,使token在训练早期探索不同的专家。
容量限制:为每个批次中的每个专家固定一个token容量——溢出的token会被重新路由、丢弃(或传递到残差路径)。这可以防止专家在运行时过载。调整这些参数(辅助损失权重、噪声规模、容量因子)至关重要——太少会导致坍缩;太多会导致强制随机化,损害专门化。
一种标准且影响深远的设计是:用MoE块替代Transformer中的密集前馈(FFN)块。原因如下:
FFN在Transformer中占参数数量的主导地位;用MoE替代它们可以低成本地增加容量。
注意力层仍然是密集的(共享权重),因此MoE在增加专门化的同时,保留了共享的上下文计算。
重要的实际影响:
预训练速度:因为每个token的计算量是有限的(k个专家),在固定的计算预算下,你可以更快地训练一个容量大得多的模型。
内存:所有专家的权重都必须存储(在VRAM中或跨设备分片),因此即使每个token的计算量很小,MoE的内存占用也会增加。这就是为什么一个例如有8×70亿参数专家的MoE可能需要与470亿参数的密集模型相当的内存。
Switch简化了路由:采用top-1路由(每个token只到一个专家)和一些训练技巧。Fedus等人展示的优势包括:
更低的路由器计算量和更少的通信。
更小的每个专家批次复杂度(更少的碎片化)。
实际预训练速度大幅提升(Switch的作者报告称,在某些设置下,速度是基线模型的约7倍)。Switch还形式化了容量因子,并表明top-1路由在简化系统工程的同时,仍能保持质量。
上面建议的容量会将批次中的token数量平均分配到各个专家。如果我们使用大于1的容量因子,就会为token分配不完全均匀的情况提供缓冲。增加容量会导致更昂贵的跨设备通信,因此这是一个需要权衡的因素。特别是,Switch Transformer在低容量因子下表现良好。
用路由器Z损失稳定训练
路由器的logit(softmax之前的分数)可能会在数值上变得很大或不稳定,这会破坏门控的训练。路由器Z损失是一个小的辅助项,用于惩罚大的logit幅度(z分数)。直观理解:保持路由器logit“表现良好”,以便在训练过程中softmax/top-k选择是稳定的。论文(例如ST-MoE/ST-MoE变体)报告称,这提高了稳定性,减少了坍缩,有时还能略微提升质量。在实际中,你可以在目标函数中添加λ * Z_loss,其中λ很小(可调整)。
PEER(参数高效专家检索)
PEER是一种稀疏路由层设计,它让Transformer能够从非常大的小型专家池中检索(例如数十万个——甚至一百万),使用乘积键风格的学习索引和参数高效的专家设计,因此模型容量与每个token的FLOPs解耦。
核心动机/高层视角
标准密集前馈(FFN)层在宽度增加时需要增加FLOPs/内存。稀疏MoE用许多小型专家替代大型FFN,并为每个token路由少数几个专家——以较小的运行时成本提供巨大的参数预算。但当尝试使用非常多的专家(例如>10万个)时,传统MoE会面临路由和扩展瓶颈。PEER解决了路由/带宽问题,使其能够扩展到数百万个小型专家。
PEER使用乘积键思想(Lample等人 earlier 为大型内存引入):将查询/键拆分为子组件,这样有效键空间是组合性的(C×C),而查找成本很小。这提供了一种从巨大池中快速筛选候选专家的廉价方法。
阶段A(非常廉价):从token隐藏状态生成查询向量,并使用乘积键查找(通常是多头)生成候选专家的短列表(亚线性检索成本)。
阶段B(更精确):在短列表上进行小型重排序,挑选最终的top-k专家进行激活。这种两阶段方法避免了扫描所有专家。PEER论文形式化并优化了这个流程。
与每个专家使用大型MLP块不同,PEER使用非常小的专家模块(例如单神经元MLP或小型FFN),并在专家之间共享神经元组件,以提高参数效率和专家之间的迁移能力。其理念是:许多小型专家专门处理细粒度行为,并且它们的参数存储/查找成本低。
PEER通常使用多头风格的检索(多个独立的乘积键查找),因此可以并行检索多个候选集并进行组合;这提高了召回率,并允许细粒度专门化(类似于多头注意力的思想)。
通过使用乘积键和组合键空间,候选选择复杂性从O(N·d)(与N个专家成线性关系)降至大约O((√N + k²)·d)或论文中讨论的类似亚线性形式——使数百万个专家无需线性成本即可扩展。
路由仍然是稀疏的:每个token只激活k个专家。PEER使用可端到端训练的学习索引(通过适当的近似或直通/top-k技巧),并利用批处理来聚合候选专家的token。小型专家设计减少了每个专家的计算和激活内存。
混合专家层通常由以下组件组成:
门控网络:一个小型网络(通常是单个线性层+softmax),将每个输入映射到一个关于n个专家的分数向量** g(x)∈R^n。softmax门控输出密集分布,而稀疏门控添加了使大多数条目为零的机制。Shazeer等人使用带噪声的Top-k门控**:向每个门控分数添加高斯噪声,然后只保留top-k值(其他设为零)。噪声有助于探索和平衡(防止单个专家占主导地位)。在实际中,k通常是1或2(例如Switch使用top-1),这意味着每个输入被路由到1-2个专家。
专家网络:每个专家E_i本身是一个神经子网络(例如前馈MLP或卷积块)。所有专家通常共享相同的输入/输出维度,但有独立的参数。例如,Shazeer等人使用的专家是两层MLP(带隐藏ReLU层)。在基于Transformer的MoE中,前馈层被许多并行专家替代。由于每个输入只选择少数专家,稀疏性意味着我们只计算那些专家的输出。正如Shazeer所指出的,“我们有多达数千个专家,但每个样本只需要评估少数几个”,这节省了计算量。
分层MoE:MoE层也可以分层堆叠:顶层门控网络选择一组专家,其中每个专家本身可能是一个带有自己门控的MoE。在实际中,大多数系统每层使用单级MoE,但当专家数量极多时,分层门控可以减少“分支因子”。

门控输出与路由:门控生成分数后,要么对top-k专家进行软加权求和(保留门控值作为权重),要么使用硬独热路由(如Switch中)。例如,top-1硬门控选择分数最高的单个专家,并使用其输出(可选地通过该门控的softmax概率缩放)。在top-k门控中,输出是 。因为未被选中的g_i为零,所以g_i=0的专家不需要计算。(一些较新的变体甚至在许多专家之间进行软加权——例如“Soft MoE”——但主流稀疏MoE专注于硬路由。)
负载均衡:一个众所周知的问题是,如果不加以注意,一个专家可能会过载,而其他专家则处于空闲状态。MoE系统引入均衡损失或噪声以确保负载均匀。Shazeer等人在门控输出上添加了一个辅助损失:他们估计每个专家的期望样本数量,并惩罚不平衡。注入的门控噪声也鼓励不同的输入使用不同的专家。如果没有这些措施,门控可能会“坍缩”到少数几个受欢迎的专家上(一种自我强化的反馈)。在实际中,高斯噪声和重要性损失的组合可以实现专家使用的大致均匀性。
专门化:专家倾向于专门处理输入分布的集群——特定的token模式、语言、领域、token位置或句法/语义特征。
涌现行为:你可能会看到一些专家专注于数字,另一些专注于代码,还有一些专注于对话token——但确切的专门化是涌现的,并受数据集、初始化和路由偏差的影响。
通过门控混合:路由器将输入路由到专家;因此专家的角色既受其局部梯度的影响,也受它们接收的token(这又取决于门控)的影响。良好的负载均衡提高了覆盖范围,避免了“死亡专家”。
更多专家→更大容量:在固定k(每个token的活跃专家数量)的情况下,容量几乎随专家数量线性增长,而每个token的计算量大致保持不变。如果有足够的基础设施和数据集来利用这一点,这通常会提高预训练速度/质量。
收益递减与数据饥渴:更大的容量需要更多的数据和仔细的正则化——没有足够的数据或良好的路由,额外的专家可能表现不佳(死亡专家)或过拟合。
系统扩展:极多的专家数量需要将专家跨设备分片(专家并行)、高效调度和良好的IO。GShard和Switch描述了跨数千个设备分片的策略。
训练稀疏MoE与标准网络类似,但需要特殊处理稀疏路由:所有参数(专家和门控)都通过反向传播训练。梯度流过被选中的专家,也流过门控网络。重要的是,因为门控涉及离散选择,Shazeer等人澄清说,梯度只在top-k门控条目上传播:这些条目通过门控权重有非零梯度。(未被选中的专家不会从该样本中接收梯度。)实际上,可以通过直通梯度或类REINFORCE方法训练门控网络,但Shazeer使用简单的连续softmax加top-k截断,并发现反向传播足够有效。
MoE的常见训练技术包括:
辅助负载损失:如前所述,通常会在训练目标中添加负载均衡损失(例如专家负载的变异系数)。这鼓励每个专家在每个批次中看到大致相等的总门控权重。
大批次与并行:因为每个专家实际上只看到输入批次的一小部分(批次缩小问题),MoE通常需要大的总批次大小才能实现稳定训练。这可能会占用内存,需要仔细调整学习率。
正则化:标准技术(dropout、权重衰减)应用于专家。一些工作还引入专家dropout或容量限制,以确保没有专家被迫处理超过每批次固定数量的token。
梯度流考虑:因为有些专家可能在早期“死亡”(从未被选中),有时需要仔细的初始化或门控温度调度。Shazeer发现,从零门控权重开始(因此门控最初是随机的)有助于分配初始负载。其他技术(如逐渐增加稀疏性)在实际中也有使用。
MoE的应用场景
混合专家模型在需要大规模容量或专门化的应用中表现出色。主要应用场景包括:
自然语言处理(NLP):MoE广泛用于大型语言模型和翻译。Shazeer等人(2017年)在LSTM之间应用MoE层进行语言建模和机器翻译,取得了最先进的结果。谷歌的多语言模型(GShard)和T5/PaLM后续模型(Switch Transformer)使用MoE扩展到数千亿参数。例如,GLaM模型(Du等人,2022年)是一个1.2万亿参数的稀疏激活模型,其能耗仅为GPT-3的约1/3,同时性能优于GPT-3。MoE还有助于多任务和低资源NLP,通过将不同语言或任务路由到专门的专家。
计算机视觉:最近的工作将MoE融入视觉模型。例如,基于ViT的MoE(“V-MoE”)用稀疏MoE块替代Vision Transformer中的前馈MLP,将视觉模型扩展到150亿参数,同时提高了效率。MoE层还被应用于目标检测和分割,其中不同的专家可以专门处理不同的对象类型或特征。总体而言,MoE帮助视觉模型在大规模图像任务中增加容量,而不会按比例增加速度成本。
推荐系统和多任务系统:在推荐和用户个性化系统中,MoE允许为不同的用户群体或任务使用不同的“专家”网络,提高了灵活性。研究表明,MoE架构可以同时满足多个用户视角的建模需求。例如,基于MoE的推荐器可以分配不同的专家来捕捉 genre偏好、上下文特征或用户子群体,但需要注意平衡专家之间的负载。
其他领域:MoE还用于语音识别(例如为不同语言/口音路由不同的声学模型)、多模态和多任务学习,甚至强化学习(带专家策略的模块化RL)。在每种情况下,关键优势是动态参数选择:只有相关专家计算每个输出,允许巨大的整体容量,同时为输入量身定制计算。
以下是类PyTorch伪代码实现的简单MoE层(展示top-1硬路由):
import torch import torch.nn as nn import torch.nn.functional as F class MoELayer(nn.Module): def __init__(self, input_dim, hidden_dim, num_experts): super().__init__() # 门控网络:线性映射到专家分数 self.gate = nn.Linear(input_dim, num_experts) # 专家网络:每个都是简单的两层MLP self.experts = nn.ModuleList([ nn.Sequential(nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, input_dim)) for _ in range(num_experts) ]) def forward(self, x): # x: 形状为(batch_size, input_dim)的张量 gate_logits = self.gate(x) # (batch_size, num_experts) # 如果使用加权组合,可选择添加softmax gate_probs = F.softmax(gate_logits, dim=1) # Top-1硬路由:为每个样本选择门控分数最高的专家 expert_idx = torch.argmax(gate_probs, dim=1) # (batch_size,) # 将每个样本路由到其选择的专家 outputs = [] for i, x_i in enumerate(x): idx = expert_idx[i].item() # 在该输入上运行选中的专家(带批次维度) out_i = self.experts[idx](x_i.unsqueeze(0)) # (1, input_dim) # 可选地将门控权重相乘(此处权重=gate_probs[i, idx]) weight = gate_probs[i, idx].unsqueeze(0).unsqueeze(-1) # (1,1) outputs.append(out_i * weight) # 将输出拼接回(batch_size, input_dim) return torch.cat(outputs, dim=0)在这段伪代码中,门控网络为每个输入计算关于专家的概率gate_probs。我们为每个批次元素选择top-1专家(expert_idx),并只计算该专家的输出。输出可选地通过softmax概率缩放(对于top-1门控,此权重通常为1)。在实际中,会使用更高效的批处理操作(例如按专家分组输入),但这展示了将输入稀疏调度到专家的核心思想。
实现用于自定义LLM的混合专家(MoE)层
# 混合专家层及LLM包装器 import torch import torch.nn as nn import torch.nn.functional as F class MoELayer(nn.Module): def __init__(self, input_dim, hidden_dim, num_experts, k=1): super().__init__() self.num_experts = num_experts self.k = k self.gate = nn.Linear(input_dim, num_experts) self.experts = nn.ModuleList([ nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, input_dim) ) for _ in range(num_experts) ]) def forward(self, x): b, s, d = x.shape flat = x.view(-1, d) scores = self.gate(flat) probs = F.softmax(scores, dim=-1) topk_vals, topk_idx = torch.topk(probs, self.k, dim=-1) out = torch.zeros_like(flat) for i in range(flat.size(0)): for j in range(self.k): expert_id = topk_idx[i, j] weight = topk_vals[i, j] out[i] += weight * self.experts[expert_id](flat[i].unsqueeze(0)).squeeze(0) return out.view(b, s, d) class GPTWithMoE(nn.Module): def __init__(self, base_model, moe_hidden, num_experts, k=1): super().__init__() self.base = base_model # GPT2LMHeadModel self.moe = MoELayer(base_model.config.n_embd, moe_hidden, num_experts, k) def forward(self, input_ids, attention_mask=None): base_out = self.base.transformer(input_ids=input_ids, attention_mask=attention_mask) hidden_states = base_out.last_hidden_state moe_out = self.moe(hidden_states) logits = self.base.lm_head(moe_out) return logits# 基于LangChain + MoE-GPT2的RAG设置 from langchain.chains import RetrievalQA from langchain.llms.base import LLM from langchain.vectorstores import FAISS from langchain.embeddings import HuggingFaceEmbeddings from transformers import GPT2LMHeadModel, GPT2Tokenizer import torch from moe_model import GPTWithMoE class MoELLMLangChain(LLM): def __init__(self, model, tokenizer, device="cpu"): self.model = model.to(device) self.tokenizer = tokenizer self.device = device @property def _llm_type(self): return "moe-llm" def _call(self, prompt: str, stop=None) -> str: # 编码输入 inputs = self.tokenizer(prompt, return_tensors="pt", padding=True, truncation=True).to(self.device) input_ids = inputs["input_ids"] attention_mask = inputs["attention_mask"] with torch.no_grad(): logits = self.model(input_ids=input_ids, attention_mask=attention_mask) gen_ids = torch.argmax(logits, dim=-1) generated = self.tokenizer.decode(gen_ids[0], skip_special_tokens=True) return generated # --- 构建RAG链使用示例 --- if __name__ == "__main__": from langchain.docstore.document import Document # 1. 准备FAISS检索器 docs = [ Document(page_content="反向传播是通过计算梯度来训练神经网络的过程。"), Document(page_content="混合专家模型允许动态选择子网络。") ] embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2") vectorstore = FAISS.from_documents(docs, embedding_model) # 2. 构建MoE-LLM tokenizer = GPT2Tokenizer.from_pretrained("gpt2") base_model = GPT2LMHeadModel.from_pretrained("gpt2") model = GPTWithMoE(base_model, moe_hidden=4096, num_experts=4, k=1) moe_llm = MoELLMLangChain(model, tokenizer, device="cpu") # 3. 设置RetrievalQA链 qa_chain = RetrievalQA.from_chain_type( llm=moe_llm, retriever=vectorstore.as_retriever(), return_source_documents=True ) # 4. 提问 question = "反向传播是如何工作的?" result = qa_chain(question) print("答案:\n", result["result"]) print("来源:\n", [doc.page_content for doc in result["source_documents"]])微调MoE微调MoE比微调密集模型更复杂。典型策略:
微调专家+路由器,冻结主干:常见,因为比全量微调便宜,且能让专家专门适应任务。
仅调门控:保持专家权重冻结,只微调路由器以将输入重新映射到现有专家——当无法更改专家内部时有用。
专家内的PEFT(LoRA/适配器):在专家内部插入参数高效适配器,只训练这些适配器——存储和计算量小。
仔细的正则化和辅助损失:微调可能导致坍缩或灾难性专门化;通常保留负载均衡损失,并对路由器使用小学习率。
指令微调与MoE的混合:最近的工作和HF说明显示,对MoE进行指令微调很有前景,但需要避免过拟合和确保广泛覆盖的技术。
预训练需要大规模参数容量,且有基础设施存储/分片专家。
希望在相同计算预算下更快预训练,或在固定计算下获得更高质量。
当以下情况时使用密集模型:
延迟和最小化工程复杂性很重要。
内存受到严格限制,或无法跨设备分片专家。
任务/数据规模不值得MoE的复杂性。
简而言之:MoE是大规模场景的强大工具——非常适合训练超大模型的组织——但对于小型团队或没有专门基础设施的低延迟生产环境,并不总是正确选择。
让MoE高效运行——(工程与系统) 专家并行
将专家跨多个设备分片,因此每个设备存储一部分专家。在前向传播期间:
路由器决定哪些token需要哪些专家。
token被调度到拥有这些专家的设备。
专家计算后,输出被收集回来并重新组装。这种分散/收集是通信成本和复杂性的主要来源;像GShard、DeepSpeed-MoE和Megatron这样的框架会处理这一点。
容量因子决定每个专家在每个批次中可接受的最大token数量(通常容量 = (每批次token数 / 专家数) * 容量因子)。较低的因子→更少的额外内存和更少的通信,但token溢出的可能性更大。较高的因子→更多缓冲(更少丢弃token)但更多通信和内存。Switch的作者发现小容量因子(1-1.25)通常表现良好。根据你的批次大小和网络调整此值。
部署技术
在高VRAM机器上加载所有专家权重,或跨多个GPU分片。部署MoE需要内存来容纳所有权重(即使未使用)——就像部署大型密集模型一样。
推理时的路由可以优化:使用top-1路由减少分散/收集;缓存重复请求的路由模式;批处理调度是关键。
卸载:冷专家可以存储在CPU/NVMe上,并在处理热门请求时换入,代价是不频繁路径的延迟增加。
使用混合精度(支持的情况下首选bfloat16)。
使用大全局批次大小,以便每个专家在每个步骤看到足够的token(有助于收敛)。
使用实现优化调度内核和通信的框架(DeepSpeed-MoE、Tutel、Megatron)。这些减少了工程负担并提高了吞吐量。
Switch风格和GShard风格的模型及工具包(例如DeepSpeed-MoE、Tutel)。
Hugging Face有博客文章+一些模型卡片/仓库,用于MoE风格的发布和社区示例。在小规模实验时可以使用这些。
稀疏MoE提供大规模扩展,而额外计算有限。Shazeer等人报告称,模型容量(参数)增加>1000倍,而计算效率仅略有损失。例如,插入一个有数千个专家的MoE层可以极大地增加模型大小,而每个前向传播只需要计算少数几个专家。Fedus等人(Switch)通过使用top-1路由和每个token更小的计算量,实现了比类似大小的密集Transformer快7倍的训练速度。同样,谷歌的GLaM(1.2万亿参数)由于稀疏性,训练能耗仅为GPT-3的约1/3,推理FLOPs为其一半。
然而,也存在权衡:
计算效率:每个输入token会产生门控网络(小型线性投影)加上少数选中专家的开销。理论上,每个token的FLOPs大致恒定(由活跃专家数量决定),即使专家数量增加。这使得MoE具有非常有利的参数-计算比。
内存使用:所有专家参数必须驻留在内存中(或跨设备),因此MoE的内存消耗与专家数量成比例增加。然而,每个样本的工作内存很小,因为只存储少数专家的激活。
并行性:大型MoE利用并行硬件:可以在不同加速器上托管不同的专家(模型并行),并跨数据并行分片分布训练样本。Shazeer等人混合数据并行和模型并行,以便每个专家看到完整的合并批次(从所有数据副本收集输入)。这保持了每个专家的大批次大小,并提高了设备利用率。在部署系统中,专家可能跨多个GPU/TPU分片,因此路由输入需要其激活的跨设备通信。
通信与带宽:当输入和输出被发送到远程专家时,稀疏模型可能会产生通信开销。Shazeer等人指出,专家应该相对计算密集(大隐藏层),以分摊通信成本。Switch Transformer通过使用top-1路由减轻了一些开销:每个token只发送到一个专家,与top-2或更多相比,减少了跨设备的分散/收集。
尽管功能强大,MoE模型仍有几个挑战:
训练不稳定性:稀疏路由可能导致不稳定性。一个常见问题是专家坍缩:如果不进行平衡,门控可能会集中在少数专家上,而其他专家则被忽略,导致未充分使用的专家梯度减小。Shazeer等人观察到了这一点,并采用噪声和辅助损失来应对。如果不处理,坍缩会降低泛化能力并浪费参数。
负载不平衡:某些token(例如“常见”情况)可能会使某些专家过载。即使有平衡损失,也很难实现完美均匀。当专家过载时,系统通常为每个专家设置固定容量,并丢弃或重新路由多余的token,这增加了实现复杂性。
批次大小与收敛:因为每个专家实际上看到的批次更小(批次大小/专家数量),MoE通常需要更大的全局批次大小才能实现稳定训练。这可能会占用内存,并需要仔细调整学习率。
路由开销:门控决策和调度逻辑增加了复杂性和延迟,特别是在实时系统中。需要专门的内核或模型部署管道来高效地将张量路由到不同的专家。
资源浪费:如果某些专家训练不足,它们的参数可能会被浪费。此外,使用稀疏MoE通常意味着必须在内存中存储所有专家权重(即使很少使用),这在内存有限的设备上可能是一个负担。
实现复杂性:构建高效的稀疏MoE层需要复杂的工程(动态调度、并行收集等)。框架支持正在改进(例如TensorFlow Mesh、PyTorch FSDP/Deepspeed MoE),但仍比标准层更复杂。
尽管存在这些问题,MoE在大规模模型中已被证明是有价值的。正在进行的研究解决了上述许多问题:例如,“soft MoE”(加权组合)和“无token遗留”路由等技术已被提出以提高稳定性。然而,从业者必须仔细调整超参数(专家数量、门控温度、负载损失权重)和基础设施,才能实现其优势。
阅读最新前沿科技趋势报告,请访问欧米伽研究所的“未来知识库”
https://wx.zsxq.com/group/454854145828
未来知识库是“ 欧米伽 未来研究所”建立的在线知识库平台,收藏的资料范围包括人工智能、脑科学、互联网、超级智能,数智大脑、能源、军事、经济、人类风险等等领域的前沿进展与未来趋势。目前拥有超过8000篇重要资料。每周更新不少于100篇世界范围最新研究资料。 欢迎扫描二维码或访问https://wx.zsxq.com/group/454854145828进入。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.