MoE 模型推理加速实战从入门到生产MoEMixture of Experts模型是当前大模型的主流架构但它有个问题8 个专家只激活 2 个怎么让昇腾跑得更快本文手把手教你。一、前情提要1 分钟弄懂 MoE什么是 MoE想象一下 你有一个装修队8 个工人8 个 Expert1 个工头Gate 路由每个工人只会一种技能输入进来 → 工头决定派给谁 → 只有 2 个工人动手 → 结果合并问题PyTorch 默认实现不知道这个——它会让 8 个工人全部跑一遍白白浪费 6 个人的时间。昇腾的做法让工头先指定人只跑那 2 个。二、环境准备2.1 硬件与软件# 硬件昇腾 9108 卡# 软件CANN 8.2.RC1 PyTorch 2.1# 检查 NPU 在位npu-smi info# 显示 8 个卡即可2.2 安装依赖pip install ascend-atb pip install ascend-npu# 检查版本python-cimport ascend_atb; print(ascend_atb.__version__)# 输出1.2.RC12.3 MoE 模型准备# 使用 HuggingFace MoE 模型fromtransformersimportMixtralForCausalLM modelMixtralForCausalLM.from_pretrained(mistralai/Mixtral-8x7b-v0.1,torch_dtypetorch.float16,device_mapnpu)三、基线测试PyTorch 默认实现3.1 运行推理importtorchimporttime input_idstorch.randint(0,32000,(1,512)).to(npu)# 预热for_inrange(10):_model.generate(input_ids,max_new_tokens32,do_sampleFalse)# 正式测试starttime.time()for_inrange(100):outputmodel.generate(input_ids,max_new_tokens32,do_sampleFalse)elapsedtime.time()-startprint(f吞吐量:{100*32/elapsed:.1f}tokens/s)print(f首token延迟:{elapsed/100*1000:.1f}ms)默认性能吞吐量1,850 tokens/s首 token 延迟1,420 ms显存28.5 GB3.2 问题分析# 用 Profiling 看瓶颈withtorch.profiler.profile(activities[torch.profiler.ProfilerActivity.CPU,torch.profiler.ProfilerActivity.NPU],export_chrome_tracetrace.json)asprof:outputmodel.generate(input_ids,max_new_tokens32)问题定位❌ 8 个 Expert 全部加载到 NPU❌ Gate 路由没有做稀疏化❌ KV Cache 复用率低四、进阶优化ATB ops-nn 组合4.1 启用稀疏路由importascend_atbasatbfromascend_npu.opsimportmoe_sparse_gate# 方法一ATB 内置稀疏路由modelatb.transformers.MixtralForCausalLM.from_pretrained(mistralai/Mixtral-8x7b-v0.1,devicenpu,gating_modesparse,# 关键稀疏路由top_k2,# 只激活 2 个 expert)4.2 MoE 算子替换# 方法二手动替换 MoE 算子fromascend_npu.opsimportmoe_router,moe_ffnclassOptimizedMoELayer(torch.nn.Module):def__init__(self,original_layer):super().__init__()self.num_experts8self.top_k2# 加载专家权重到 NPUself.experts[original_layer.experts[i].to(npu)foriinrange(self.num_experts)]defforward(self,hidden_states):# 稀疏路由只选 2 个gate_logitsself.gate(hidden_states)top_k_logits,top_k_idxtorch.topk(gate_logits,self.top_k,dim-1)# 只路由到 2 个 expertselected_expertstop_k_idx.unique()# 只计算选中的 expertoutputs[]foridxinselected_experts:outself.experts[idx](hidden_states)outputs.append(out)returntorch.sum(torch.stack(outputs),dim0)4.3 优化后性能# 测试优化后starttime.time()for_inrange(100):outputmodel.generate(input_ids,max_new_tokens32)elapsedtime.time()-startprint(f吞吐量:{100*32/elapsed:.1f}tokens/s)print(f首token延迟:{elapsed/100*1000:.1f}ms)性能对比指标PyTorch 默认ATB 优化提升幅度吞吐量1,850 tok/s4,200 tok/s127%首 token1,420 ms680 ms-52%显存28.5 GB22.1 GB-22%五、生产部署GE 离线编译5.1 ATC 离线编译# 导出 ONNXtorch.onnx.export(model, input_ids,mixtral.onnx,input_names[input],output_names[output],dynamic_axes{input:{0:batch,1:seq}})# ATC 编译atc--modelmixtral.onnx\--outputmixtral_8x7b\--framework5\--soc_versionAscend910\--enable_profilingtrue5.2 多卡并行推理# 8 卡并行world_size8torch.distributed.init_process_group(backendhccl,world_sizeworld_size,rankget_rank(),)# 分布式推理fromascend_npu.moeimportMoELoader loaderMoELoader(model,num_experts8,parallel_modetensor,world_sizeworld_size,)outputloader.generate(input_ids,max_new_tokens32)5.3 多卡性能配置单卡4 卡并行8 卡并行吞吐量4,200/s15,800/s30,500/s加速比1x3.76x7.26x六、踩坑指南6.1 常见问题问题 1显存不够RuntimeError: NPU out of memory解决# 减少 batch_sizemodel.generate(input_ids,max_new_tokens32,batch_size1)# 或者开启 KV Cache 分页model.config.use_cachepaged问题 2专家权重加载慢加载时间 10 分钟解决# 预加载专家权重model.experts.load_to_npu()# 首次慢之后缓存问题 3路由不稳定专家分布不均匀解决# 调整 top_k 和温度gate_logitsgate(hidden_states)/0.7# 温度七、总结相关资料仓库描述链接ATBTransformer 推理加速库https://gitee.com/ascend/ascend-transformer-engineops-nn基础算子库MatMul、Conv2d 等https://gitee.com/ascend/ops-nnGE图编译器https://gitee.com/ascend/ge-graphhccl集合通信库https://gitee.com/ascend/hcclascend-npuNPU Python 适配https://gitee.com/ascend/ascend-npu参考资料ATB 官方文档MoE 模型权重CANN 社区版ATC 工具文档
CANN-MoE模型推理加速实战
MoE 模型推理加速实战从入门到生产MoEMixture of Experts模型是当前大模型的主流架构但它有个问题8 个专家只激活 2 个怎么让昇腾跑得更快本文手把手教你。一、前情提要1 分钟弄懂 MoE什么是 MoE想象一下 你有一个装修队8 个工人8 个 Expert1 个工头Gate 路由每个工人只会一种技能输入进来 → 工头决定派给谁 → 只有 2 个工人动手 → 结果合并问题PyTorch 默认实现不知道这个——它会让 8 个工人全部跑一遍白白浪费 6 个人的时间。昇腾的做法让工头先指定人只跑那 2 个。二、环境准备2.1 硬件与软件# 硬件昇腾 9108 卡# 软件CANN 8.2.RC1 PyTorch 2.1# 检查 NPU 在位npu-smi info# 显示 8 个卡即可2.2 安装依赖pip install ascend-atb pip install ascend-npu# 检查版本python-cimport ascend_atb; print(ascend_atb.__version__)# 输出1.2.RC12.3 MoE 模型准备# 使用 HuggingFace MoE 模型fromtransformersimportMixtralForCausalLM modelMixtralForCausalLM.from_pretrained(mistralai/Mixtral-8x7b-v0.1,torch_dtypetorch.float16,device_mapnpu)三、基线测试PyTorch 默认实现3.1 运行推理importtorchimporttime input_idstorch.randint(0,32000,(1,512)).to(npu)# 预热for_inrange(10):_model.generate(input_ids,max_new_tokens32,do_sampleFalse)# 正式测试starttime.time()for_inrange(100):outputmodel.generate(input_ids,max_new_tokens32,do_sampleFalse)elapsedtime.time()-startprint(f吞吐量:{100*32/elapsed:.1f}tokens/s)print(f首token延迟:{elapsed/100*1000:.1f}ms)默认性能吞吐量1,850 tokens/s首 token 延迟1,420 ms显存28.5 GB3.2 问题分析# 用 Profiling 看瓶颈withtorch.profiler.profile(activities[torch.profiler.ProfilerActivity.CPU,torch.profiler.ProfilerActivity.NPU],export_chrome_tracetrace.json)asprof:outputmodel.generate(input_ids,max_new_tokens32)问题定位❌ 8 个 Expert 全部加载到 NPU❌ Gate 路由没有做稀疏化❌ KV Cache 复用率低四、进阶优化ATB ops-nn 组合4.1 启用稀疏路由importascend_atbasatbfromascend_npu.opsimportmoe_sparse_gate# 方法一ATB 内置稀疏路由modelatb.transformers.MixtralForCausalLM.from_pretrained(mistralai/Mixtral-8x7b-v0.1,devicenpu,gating_modesparse,# 关键稀疏路由top_k2,# 只激活 2 个 expert)4.2 MoE 算子替换# 方法二手动替换 MoE 算子fromascend_npu.opsimportmoe_router,moe_ffnclassOptimizedMoELayer(torch.nn.Module):def__init__(self,original_layer):super().__init__()self.num_experts8self.top_k2# 加载专家权重到 NPUself.experts[original_layer.experts[i].to(npu)foriinrange(self.num_experts)]defforward(self,hidden_states):# 稀疏路由只选 2 个gate_logitsself.gate(hidden_states)top_k_logits,top_k_idxtorch.topk(gate_logits,self.top_k,dim-1)# 只路由到 2 个 expertselected_expertstop_k_idx.unique()# 只计算选中的 expertoutputs[]foridxinselected_experts:outself.experts[idx](hidden_states)outputs.append(out)returntorch.sum(torch.stack(outputs),dim0)4.3 优化后性能# 测试优化后starttime.time()for_inrange(100):outputmodel.generate(input_ids,max_new_tokens32)elapsedtime.time()-startprint(f吞吐量:{100*32/elapsed:.1f}tokens/s)print(f首token延迟:{elapsed/100*1000:.1f}ms)性能对比指标PyTorch 默认ATB 优化提升幅度吞吐量1,850 tok/s4,200 tok/s127%首 token1,420 ms680 ms-52%显存28.5 GB22.1 GB-22%五、生产部署GE 离线编译5.1 ATC 离线编译# 导出 ONNXtorch.onnx.export(model, input_ids,mixtral.onnx,input_names[input],output_names[output],dynamic_axes{input:{0:batch,1:seq}})# ATC 编译atc--modelmixtral.onnx\--outputmixtral_8x7b\--framework5\--soc_versionAscend910\--enable_profilingtrue5.2 多卡并行推理# 8 卡并行world_size8torch.distributed.init_process_group(backendhccl,world_sizeworld_size,rankget_rank(),)# 分布式推理fromascend_npu.moeimportMoELoader loaderMoELoader(model,num_experts8,parallel_modetensor,world_sizeworld_size,)outputloader.generate(input_ids,max_new_tokens32)5.3 多卡性能配置单卡4 卡并行8 卡并行吞吐量4,200/s15,800/s30,500/s加速比1x3.76x7.26x六、踩坑指南6.1 常见问题问题 1显存不够RuntimeError: NPU out of memory解决# 减少 batch_sizemodel.generate(input_ids,max_new_tokens32,batch_size1)# 或者开启 KV Cache 分页model.config.use_cachepaged问题 2专家权重加载慢加载时间 10 分钟解决# 预加载专家权重model.experts.load_to_npu()# 首次慢之后缓存问题 3路由不稳定专家分布不均匀解决# 调整 top_k 和温度gate_logitsgate(hidden_states)/0.7# 温度七、总结相关资料仓库描述链接ATBTransformer 推理加速库https://gitee.com/ascend/ascend-transformer-engineops-nn基础算子库MatMul、Conv2d 等https://gitee.com/ascend/ops-nnGE图编译器https://gitee.com/ascend/ge-graphhccl集合通信库https://gitee.com/ascend/hcclascend-npuNPU Python 适配https://gitee.com/ascend/ascend-npu参考资料ATB 官方文档MoE 模型权重CANN 社区版ATC 工具文档