微信扫码
添加专属顾问
在本文中,梳理了近期 (24年7月前)部分 MOE 大模型的关键信息,包括它们的主要特点、亮点以及相关资源链接。涉及模型 Mixtral 8x7B,Mixtral 8x22B,DeepSeek-MoE,Qwen1.5-MoE,DeepSeek-V2。
原文:https://zhuanlan.zhihu.com/p/712676995
对于 MOE 的基础,相比 dense model,MOE 的预训练速度更快,推理速度更快,但需要大量的显存。此外,MOE 的训练也有一些独有的 tips,详细的 MOE 混合专家模型基础,推荐参考:混合专家模型基础
对于一些经典的 MOE 架构模型,可以参考:详解MoE模型的前世今生
论文: https://arxiv.org/abs/2401.04088
huggingface 模型权重: https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1
官方博客: https://mistral.ai/news/mixtral-of-experts/
huggingface 模型代码: https://github.com/huggingface/transformers/blob/main/src/transformers/models/mixtral/modeling_mixtral.py
官方给出的评分来看,mixtral 8*7 和 GPT3.5 有的一比。
发布时间:23年12月
模型大小:8 个 expert MLP 层,一共45B 大小。
训练:除了预训练外,Mixtral MOE 后续还开源了一个经过 SFT + DPO 微调的版本。
模型效果:
对 moe 架构不太了解的朋友,可以参考这篇博客 混合专家模型基础(推荐)。
参考 huggingface 中的 mixtral 和 mistral 实现对比,差异在于 mixtral 中将传统 transformer decoder layer 中的 FFN 替换为了 block_sparse_moe。
主要逻辑为:
其中 为专家对应的网络,具体展示为下面 huggingface 实现中的 MixtralBlockSparseTop2MLP。mixtral 中采用了 8 个 expert,每次推理使用选取 top 2 的 expert 进行推理。比如输入一句话 你好,今天,那么我们每个 token 都会选出 top 2 的 expert 来负责这个 token 的预测,因此在推理 你好,今天 时,有概率所有 expert 都会参与到计算当中,具体可以参考 MixtralSparseMoeBlock 的实现。
mixtral 论文中提到专家分配在不同主题(如ArXiv论文、生物学和哲学文档)中没有明显的模式,只有在DM数学中显示出边际上的差异,这可能是由于其数据集的合成性质和有限的自然语言覆盖范围所致。router 在某些句法结构上表现出一定的结构化行为(比如 python 的 self 等),同时连续标记通常被分配给相同的专家。
class MixtralDecoderLayer(nn.Module):
def __init__(self, config: MixtralConfig, layer_idx: int):
super().__init__()
self.hidden_size = config.hidden_size
self.self_attn = MIXTRAL_ATTENTION_CLASSES[config._attn_implementation](config, layer_idx)
self.block_sparse_moe = MixtralSparseMoeBlock(config)
self.input_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
self.post_attention_layernorm = MixtralRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
def forward(
hidden_states: torch.Tensor,
attention_mask: Optional[torch.Tensor] = None,
# 此处省略参数 ..
) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
residual = hidden_states
hidden_states = self.input_layernorm(hidden_states)
hidden_states, self_attn_weights, present_key_value = self.self_attn(
# 此处省略参数
)
hidden_states = residual + hidden_states
residual = hidden_states
hidden_states = self.post_attention_layernorm(hidden_states)
# Mixtral 将原本的 hidden_states = self.FFN(hidden_states) 替换为了:
hidden_states, router_logits = self.block_sparse_moe(hidden_states)
hidden_states = residual + hidden_states
outputs = (hidden_states,)
return outputs
huggingface 中 block_sparse_moe 的实现(省略部分次要代码):
class MixtralSparseMoeBlock(nn.Module):
def __init__(self, config):
super().__init__()
self.hidden_dim = config.hidden_size
self.ffn_dim = config.intermediate_size
self.num_experts = config.num_local_experts
self.top_k = config.num_experts_per_tok
self.gate = nn.Linear(self.hidden_dim, self.num_experts, bias=False)
self.experts = nn.ModuleList([MixtralBlockSparseTop2MLP(config) for _ in range(self.num_experts)])
self.jitter_noise = config.router_jitter_noise
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
batch_size, sequence_length, hidden_dim = hidden_states.shape
hidden_states = hidden_states.view(-1, hidden_dim)
router_logits = self.gate(hidden_states) # (batch * sequence_length, n_experts)
routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float)
routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1)
routing_weights /= routing_weights.sum(dim=-1, keepdim=True)
# we cast back to the input dtype
routing_weights = routing_weights.to(hidden_states.dtype)
final_hidden_states = torch.zeros(
(batch_size * sequence_length, hidden_dim), dtype=hidden_states.dtype, device=hidden_states.device
)
# One hot encode the selected experts to create an expert mask
# this will be used to easily index which expert is going to be sollicitated
expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0)
# Loop over all available experts in the model and perform the computation on each expert
for expert_idx in range(self.num_experts):
expert_layer = self.experts[expert_idx]
idx, top_x = torch.where(expert_mask[expert_idx])
# Index the correct hidden states and compute the expert hidden state for
# the current expert. We need to make sure to multiply the output hidden
# states by `routing_weights` on the corresponding tokens (top-1 and top-2)
current_state = hidden_states[None, top_x].reshape(-1, hidden_dim)
# current_state: shape (n_i, hidden_dim)
# 所有 current_state 的长度 n 总和为 batch * sequence_length
current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None]
# However `index_add_` only support torch tensors for indexing so we'll use
# the `top_x` tensor here.
final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype))
final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim)
return final_hidden_states, router_logits
其中:MixtralBlockSparseTop2MLP 长这样:
class MixtralBlockSparseTop2MLP(nn.Module):
def __init__(self, config: MixtralConfig):
super().__init__()
self.ffn_dim = config.intermediate_size
self.hidden_dim = config.hidden_size
self.w1 = nn.Linear(self.hidden_dim, self.ffn_dim, bias=False)
self.w2 = nn.Linear(self.ffn_dim, self.hidden_dim, bias=False)
self.w3 = nn.Linear(self.hidden_dim, self.ffn_dim, bias=False)
self.act_fn = ACT2FN[config.hidden_act]
def forward(self, hidden_states):
current_hidden_states = self.act_fn(self.w1(hidden_states)) * self.w3(hidden_states)
current_hidden_states = self.w2(current_hidden_states)
return current_hidden_states
根据模型参数量 45B 来推理的话,如果用 fp16 的话推理的话,得需要至少 90GB 以上的显存,如果用 4 bit的话,30GB 显存就够了。量化的生成速度,可以参考下面 redis 中的评论,大致为 :
| 推理精度 | 设备 | 速度 tokens/s |
|---|---|---|
| Q4_K_M | 单卡 4090 + 7950X3D | 20 |
| Q4_K_M | 2 x 3090 | 48.26 |
redis: https://www.reddit.com/r/LocalLLaMA/comments/18jslmf/tokens_per_second_mistral_8x7b_performance/
如果有 100+GB 以上显存,可以用 vllm 快速搭建测试 api:
docker run --gpus all \
-e HF_TOKEN=$HF_TOKEN -p 8000:8000 \
ghcr.io/mistralai/mistral-src/vllm:latest \
--host 0.0.0.0 \
--model mistralai/Mixtral-8x7B-Instruct-v0.1 \
--tensor-parallel-size 2 # 100+GB 显存 \
--load-format pt # needed since both `pt` and `safetensors` are available
NVIDIA 的 TensorRT-LLM 博客中发出了对 Mixtral 8*7B 的吞吐量 benchmark (using input and output sequence lengths of 128):
文中没有给出当 sequence lengths 最大时候的吞吐量,但根据上图数据,可以猜测 2个 H100 部署 8*7B 正常服务用户时,平均吞吐量应该可以大于 7500Tokens/秒,根据 H100 的功耗计算电费成本的话,生成 1M token 需要耗约为 0.02 度电。
github: https://github.com/deepseek-ai/DeepSeek-MoE
论文: https://arxiv.org/pdf/2401.06066
Fine-grained Expert Segmentation
如上图B,DeepSeek-MoE 在减少了每个 expert FFN intermediate hidden dimension 的同时,增加激活的 expert 的数量,依次保证总体激活的 expert 的参数量一致。DeepSeekMoE 论文种认为,组合数量的提升,有利于 gate 更准确地选择 expert。
如当我们有 16 个 expert,然后选 top 2 进行推理时,activate expert 的组合数量有 种组合,但当将每个 expert 参数缩小 4 倍,expert 个数增加为 64 时,选取 top 8 进行推理时, activate expert 的组合书来给你就有 种。
Shared Expert Isolation
如上图C,设立一部分 Shared Expert,每次推理的时候都会激活。
官方博客: https://qwenlm.github.io/zh/blog/qwen-moe/
github: https://github.com/QwenLM/Qwen2
huggingface 权重: https://huggingface.co/Qwen/Qwen1.5-MoE-A2.7B-Chat
官方博客中发布了采用 vllm 部署时候的性能(单个NVIDIA A100-80G GPU 部署 Qwen1.5-7B和Qwen1.5-MoE-A2.7B):
看来 MoE 架构在不牺牲生成质量的情况下,的确可以极大提高吞吐量,降低大模型生成成本。
github: https://github.com/deepseek-ai/DeepSeek-V2
论文: https://arxiv.org/abs/2405.04434
权重下载: https://huggingface.co/collections/deepseek-ai/deepseek-v2-669a1c8b8f2dbc203fbd7746
huggingface 模型代码: https://huggingface.co/deepseek-ai/DeepSeek-V2-Chat-0628/blob/main/modeling_deepseek.py
DeepSeek-V2 文中推出了 DeepSeek-V2-Lite 与 DeepSeek-V2 一小一大 2个版本。
模型大小: DeepSeek-V2 整个模型有 236B 参数,其中推理激活参数为 21B。具体的架构参数可以查看:huggingface DeepSeek V2 config
模型效果:
推理速度:
DeepSeek V2 首先对模型进行了 KV Cache 量化,将参数转换为了 FP8。在单机 8卡 H800 的节点上部署 DeepSeek-V2,可以达到约 50K tokens/秒 的吞吐量
推理效果,中文水平更强一些,英文水平于 Mixtral 8*22B 有的一比:
如上图展示的,DeepSeek-V2同样采用了 DeepSeekMoE 的策略,其中有 2 个 shared experts , 160 个 routed experts(每次只激活 6 个)
DeepSeek-V2 中着重讲了这一部分的优化。
Low-Rank Key-Value Joint Compression
为了减少 KV cache,MLA 提出将 k, v 的计算方式变为:
其中,
q 的计算方法变为:
其中,
因此,k,v 均从 进一步计算得来。在推理时候,传统 MHA 需要 cache ,但通过以上变化后,只需要 cache 即可。这样, 点积就变成了。
推理过程中,可以合并 ,以此达到减少 cache 同时,不会增加太多的计算量。
Decoupled Rotary Position Embedding
以上方案的一个问题是,不兼容 RoPE。由于 RoPE 的存在,
不再是单纯的 ,而是需要内积上相对位置矩阵 ,因此就无法简单得合并 。
MLA 采用了以下 decoupled RoPE 方案:
大概思路是,在原先的 qk 中,增加几个维度,用来注入 RoPE 位置信息,比较值得注意的是,k 新增加的维度 是所有 head 共享的。其中,, , 因此,q,k 的维度增加到了 。
更深入的 MLA 解读,可以参考:缓存与效果的极限拉扯:从MHA、MQA、GQA到MLA 或 deepseek v2 原论文。
文中给出了 MLA 与 MHA, GQA 的效果对比:
MLA 的 KV 的 cache 数量比 MHA, GQA 少了不少。
MLA KV cache 比 MHA 小的同时,效果也不会太差。
在 RLHF 训练过程中,采取了 2 阶段训练。首先进行了 reasoning alignment,而后进行 human preference alignment。
更多训练细节欢迎参考 DeepSeek-V2 论文
官方博客: https://mistral.ai/news/mixtral-8x22b/
huggingface 开源模型: https://huggingface.co/mistralai/Mixtral-8x22B-Instruct-v0.1
MixtralForCausalLM ,但 22B 的各方面参数大一点,比较特别的是 context window 从 32k 升级到了 65k, vocab_size 也更大一些。Mistral 团队开源的模型,都比较注重 coding 和 math 的能力,Mixtral 系列的模型在这方便表现也是比较好:
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-07-05
Hermes 的记忆层有 8 种实现,我为什么选了最反常识的那个
2026-07-05
Codex 负责人谈 AI 时代唯一值钱的能力
2026-07-05
复旦期末考「造反」了:51名学生联手围攻Claude、DeepSeek,谁能让AI交白卷谁就是学霸
2026-07-05
Loop Engineering 会是 AI 的下个关键词吗?
2026-07-04
Cursor 如何把 AI 部署进企业内部
2026-07-04
字节跳动CEO梁汝波最新万字分享深度拆解:这可能是2026年最重要的一堂管理课
2026-07-03
开发者转向 AI 应用工程,真正要迁移的是工程判断力
2026-07-02
不改一行代码,看透 AI Agent 的每一次调用
2026-04-15
2026-04-07
2026-04-07
2026-04-24
2026-04-17
2026-04-14
2026-04-24
2026-04-22
2026-05-19
2026-04-24
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。