Qwen1.5 MoE解析稀疏大模型的高效智能
引言2025年3月28日,阿里正式宣布开源其首个MoE技术大模型——Qwen1 5-MoE-A2 7B。这一消息在当时引发了广泛关注,背后逻辑颇具深意:用更少的激活参数,去挑战更大参数规模模型的性能表现,为稀疏大模型的高效智能落地开辟了新路径。该模型基于已有的Qwen-1 8B模型,激活参数仅为2
引言
2025年3月28日,阿里正式宣布开源其首个MoE技术大模型——Qwen1.5-MoE-A2.7B。这一消息在当时引发了广泛关注,背后逻辑颇具深意:用更少的激活参数,去挑战更大参数规模模型的性能表现,为稀疏大模型的高效智能落地开辟了新路径。

该模型基于已有的Qwen-1.8B模型,激活参数仅为2.7亿,但在多项基准评估中表现出色,达到了7B级别模型的水准。更重要的是,相比传统7B模型,它在训练成本和推理速度上均展现出显著优势。接下来,我们将结合官方博客与开源代码,详细拆解模型的设计细节与实现逻辑。
文章将从参数规模、模型结构、训练推理效率等核心维度展开,并深入代码层面,剖析MoE机制的具体运作方式。
参数量
Qwen1.5-MoE-A2.7B的名称直接揭示了关键信息:它仅包含27亿个激活参数,但性能足以与当前最优秀的70亿参数模型——如Mistral 7B和Qwen1.5-7B——正面抗衡。
对比一下更直观:Qwen1.5-7B的Non-Embedding参数为65亿,而Qwen1.5-MoE-A2.7B仅有20亿,仅为前者的三分之一。实际效果如何?训练成本直降75%,推理速度提升至1.74倍。换句话说,投入更少、运行更快、效果相当——这正是MoE架构的独特魅力。
官方评测也佐证了这一点:Qwen1.5-MoE-A2.7B在与最佳7B模型的对标中,取得了非常接近的性能。
模型结构
Qwen1.5-MoE在结构上进行了若干富有创意的改进。通常,像Mixtral这类模型会在每个Transformer块安排8个专家,并采用top-2门控路由。但Qwen团队认为其中仍有优化空间,于是从三个方面着手改进:
Finegrained Experts
这一概念在DeepSeek-MoE和DBRX中已验证有效。从FFN层过渡到MoE层时,常见做法是简单复制多次FFN以生成多个专家。但Finegrained Experts的思路不同:它旨在在不增加总参数数的前提下,生成更多专家。具体做法是将单个FFN分割成几个部分,每一部分作为一个独立专家。最终,Qwen1.5-MoE设计了总共64个专家,该配置在效果与效率之间找到了不错的平衡点。
初始化策略
初始化环节至关重要。早期实验表明,从零开始训练MoE模型不仅效率低,而且难以达到预期的理想性能。因此,Qwen团队选择了一条更务实的路径:直接基于已有的Qwen-1.8B进行改造,将其升级为Qwen1.5-MoE-A2.7B。同时,在初始化阶段引入一定程度的随机性,可显著加快收敛速度。不过,该随机性具体施加在哪个环节,目前博客与代码中尚未明确体现,这仍是一个值得深挖的技术细节。
新的路由机制
当前MoE领域有一个明显趋势:引入共享专家与路由专家相结合的机制。从宏观角度看,这本质是一种广义路由方法——如果去掉共享专家,就会退化为传统MoE路由设置。Qwen1.5-MoE的做法是:整合4个始终被激活的共享专家,以及60个路由专家,每次只激活其中4个。这种设计既灵活,又在实验中表现出最佳效率。
总结该模型的MoE配置如下:
- “类似”8×1.8B的Top2激活MoE:但实际上并非8个专家,而是采用了Finegrained Experts,总共64个专家,每次激活8个“Finegrained Expert”
- Finegrained Experts:参照DeepSeek-MoE和DBRX的思路,将单个FFN拆分多个部分,最终形成64个专家,激活8个
- 初始化:基于Qwen-1.8B,并引入随机性以加速收敛
- 路由机制:4个共享专家(始终激活) + 60个路由专家(每次激活4个)
训练成本与推理效率
MoE模型与Dense模型在训练成本上的差异十分显著。虽然MoE模型的总参数规模通常更大,但得益于稀疏性,训练开销反而能明显降低。我们先看几个关键参数:总参数量、激活参数量和Non-Embedding参数量。
- 尽管MoE模型的总参数量较大,但Non-Embedding激活参数量远小于7B模型
- 实际操作中,使用Qwen1.5-MoE-A2.7B相比Qwen1.5-7B,训练成本降低了75%
- 由于采用了特殊的初始化方法,模型无需训练相同数量的token即可达到良好效果,这进一步压低了训练成本
代码解读
Config配置解析
从配置文件中,我们可以洞察许多设计细节:
{
"architectures": [
"Qwen2MoeForCausalLM"
],
"attention_dropout": 0.0,
"bos_token_id": 151643,
"eos_token_id": 151643,
"hidden_act": "silu",
"hidden_size": 2048,
"initializer_range": 0.02,
"intermediate_size": 5632,
"max_position_embeddings": 8192,
"max_window_layers": 21,
"model_type": "qwen2_moe",
"num_attention_heads": 16,
"num_hidden_layers": 24,
"num_key_value_heads": 16,
"rms_norm_eps": 1e-06,
"rope_theta": 1000000.0,
"sliding_window": 32768,
"tie_word_embeddings": false,
"torch_dtype": "bfloat16",
"transformers_version": "4.39.0.dev0",
"use_cache": true,
"use_sliding_window": false,
"vocab_size": 151936,
"decoder_sparse_step": 1,
"moe_intermediate_size": 1408,
"shared_expert_intermediate_size": 5632,
"num_experts_per_tok": 4,
"num_experts": 60,
"norm_topk_prob": false,
"output_router_logits": false,
"router_aux_loss_coef": 0.001
}- 激活函数:silu
- 上下文长度:8K
- rope_theta:100万
- tie_word_embeddings:未启用参数共享
- moe_intermediate_size与shared_expert_intermediate_size:对应4个共享专家
- num_experts_per_tok与num_experts:对应60个专家选4个
- router_aux_loss_coef:专家负载均衡的辅助损失系数
模型主结构介绍
Qwen2MoeForCausalLM基于混合专家架构,采用稀疏激活策略,每个输入序列只激活少数专家。下面拆解其核心组件:
模型构造(__init__方法)
self.model:由多个Qwen2MoeDecoderLayer组成的解码器模型,每个解码层包含注意力层和前馈网络(可能是Qwen2MoeMLP或Qwen2MoeSparseMoeBlock)self.lm_head:一个线性层,将解码器输出映射为词汇表长度的logitsself.router_aux_loss_coef:用于辅助损失计算的系数,帮助平衡各专家负载
前向传播(forward方法)
- 调用
self.model执行解码器前向传播 - 隐藏状态送入
self.lm_head生成logits - 如果提供了labels,则计算交叉熵损失
- 如果需要输出路由器logits,则计算并返回路由每个token到不同专家的概率分布
该模型的几个特色部分:
- Mixture of Experts(MoE):通过
Qwen2MoeSparseMoeBlock实现,根据路由决策将计算分配给不同专家 - 共享专家:通过
self.shared_expert定义了一个始终被激活的全连接层 - 稀疏激活:使用
routing_weights和selected_experts实现,每个输入仅激活权重最高的几个专家 - 路由器辅助损失:通过
load_balancing_loss_func促进负载均衡,避免少数专家被过度使用 - 参数初始化:通过
_init_weights方法引入随机性,提高收敛速度
简而言之,Qwen2MoeForCausalLM通过混合专家架构、稀疏激活、共享与路由专家结合、辅助损失以及精巧的初始化策略,实现了参数利用率与计算效率的双重提升。
路由机制
接下来是核心代码部分——Qwen2MoeSparseMoeBlock模块,它是整个MoE机制的关键实现:
class Qwen2MoeSparseMoeBlock(nn.Module):
def __init__(self, config):
super().__init__()
self.num_experts = config.num_experts
self.top_k = config.num_experts_per_tok
self.norm_topk_prob = config.norm_topk_prob
self.gate = nn.Linear(config.hidden_size, config.num_experts, bias=False)
self.experts = nn.ModuleList(
[Qwen2MoeMLP(config, intermediate_size=config.moe_intermediate_size) for _ in range(self.num_experts)]
)
self.shared_expert = Qwen2MoeMLP(config, intermediate_size=config.shared_expert_intermediate_size)
self.shared_expert_gate = torch.nn.Linear(config.hidden_size, 1, bias=False)
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)
routing_weights = F.softmax(router_logits, dim=1, dtype=torch.float)
routing_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1)
if self.norm_topk_prob:
routing_weights /= routing_weights.sum(dim=-1, keepdim=True)
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
)
expert_mask = torch.nn.functional.one_hot(selected_experts, num_classes=self.num_experts).permute(2, 1, 0)
for expert_idx in range(self.num_experts):
expert_layer = self.experts[expert_idx]
idx, top_x = torch.where(expert_mask[expert_idx])
if top_x.shape[0] == 0:
continue
top_x_list = top_x.tolist()
idx_list = idx.tolist()
current_state = hidden_states[None, top_x_list].reshape(-1, hidden_dim)
current_hidden_states = expert_layer(current_state) * routing_weights[top_x_list, idx_list, None]
final_hidden_states.index_add_(0, top_x, current_hidden_states.to(hidden_states.dtype))
shared_expert_output = self.shared_expert(hidden_states)
shared_expert_output = F.sigmoid(self.shared_expert_gate(hidden_states)) * shared_expert_output
final_hidden_states = final_hidden_states + shared_expert_output
final_hidden_states = final_hidden_states.reshape(batch_size, sequence_length, hidden_dim)
return final_hidden_states, router_logits__init__方法
num_experts:专家总数top_k:每个token选择的专家数norm_topk_prob:是否对top-k权重归一化gate:线性层,生成每个专家的logitsexperts:专家网络列表,每个都是Qwen2MoeMLPshared_expert:始终激活的共享专家shared_expert_gate:控制共享专家在最终输出中的权重
forward方法
- 将隐藏状态reshape为[batch_size * sequence_length, hidden_dim]
- 通过
gate计算路由器logits,再经softmax获得路由权重 - 选取top_k权重最大的专家
- 若启用归一化,则按行归一化
- 创建零张量用于累积专家计算结果
- 对每个专家:检查是否有token被分配,若有则计算该专家输出,并按路由权重缩放后累加
- 共享专家处理所有隐藏状态,经sigmoid门控缩放后加到最终结果上
- 将结果恢复为[batch_size, sequence_length, hidden_dim]并返回
整个流程清晰实现了MoE机制:将隐藏状态分配给各个专家和一个共享专家,汇总所有输出后再传递至下一层。这样既大幅提升了模型的表示能力,又保持了计算效率。
几个值得留意的点:
- 路由机制是60选4,通过
self.gate线性层和top-k实现 - 虽然代码中只出现了一个shared_expert,但在配置中shared_expert的隐藏层大小已经设置为4倍于普通专家——因此这4个共享专家被“打包”在了一起
总结
阿里首个MoE模型Qwen1.5-MoE-A2.7B,以不到三分之一的激活参数,达到了当前最优秀7B模型的性能水平。更重要的是,它在训练成本和推理速度上实现了相当显著的优化。对于正在探索平衡模型性能与计算成本的团队来说,这一方向确实值得深入研究。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:Qwen1.5 MoE解析稀疏大模型的高效智能要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点使用T2V-01-Director模型,将手冲咖啡过程按时间顺序拆为三段机位,每段标注编号与镜头类型。每个镜头绑定物理参照点,禁用抽象词,统一全局光源参数,从而生成多角度、高物理一致性的专业画面,实现精准分镜控制。
火龙果写作未内置快捷键自定义功能,但可通过系统工具实现:Mac用Automator绑定校对快捷键,Windows用PowerToys模拟热键,安卓借助无障碍服务模拟点击,iOS仅支持Siri语音捷径。各平台方法均需手动配置。
人工智能将推动工业互联网迈向全面深度智能化新阶段,能力从数据分析跃迁至复杂推理与自主决策,作用范围从局部优化延伸至全链条整体优化,价值模式从辅助决策转向端到端自主执行,并提炼出“10+1”个融合发展方向。
孙正义预言2040年人工智能将贡献全球经济增长20%,批评抵制者逆时代潮流。软银全面布局芯片、机器人及数据中心,预计AI将创造46万亿美元GDP增量。算力需求达3太瓦,短期靠燃气发电,长期依赖核聚变。投资者担忧软银杠杆攀升与OpenAI上市延期风险。
- 日榜
- 周榜
- 月榜
热点快看
