From 09b86c9129f9c0e7b079204ad81f2e58b1504119 Mon Sep 17 00:00:00 2001 From: Quanyou Shen <52127540+skyous779@users.noreply.github.com> Date: Tue, 2 Dec 2025 20:38:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?2025=E5=B9=B4=E6=98=87=E8=85=BEAI=E5=88=9B?= =?UTF-8?q?=E6=96=B0=E5=A4=A7=E8=B5=9B-=E6=98=87=E6=80=9D=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=BC=80=E5=8F=91=E6=8C=91=E6=88=98=E8=B5=9B=EF=BC=88?= =?UTF-8?q?S1=E8=B5=9B=E5=AD=A3)--MoE=E8=B5=9B=E9=A2=98--blueblue=E9=98=9F?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../S1/MoE/blueblue/README.md | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md diff --git a/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md b/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md new file mode 100644 index 00000000..002b3989 --- /dev/null +++ b/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md @@ -0,0 +1,132 @@ +# MindNLP 模型优化详细说明 (DeepSeek & Qwen2-MoE) + +本文档详细记录了针对 DeepSeek 和 Qwen2-MoE 模型的关键性能优化点,并附带了相应的核心代码实现。 + +## 1. DeepSeek 模型优化 (DeepseekMoE) + +### 1.1 MoE 推理加速:Decode 阶段 (消除 Host-Device 同步) + +优化痛点: 原有实现在循环中频繁调用 .item() 获取 scalar 值,导致每一次循环都会触发 Host 与 Device 之间的同步,严重拖慢小 Batch/单 Token 的推理速度。 + +改进方案: 一次性将所有 Expert 的索引和权重同步至 CPU (.tolist()),循环全程在 Host 端执行,无同步开销。 + +**源码实现** (`moe_infer_decode`): + +**Python** + +``` +def moe_infer_decode(self, x, flat_expert_indices, flat_expert_weights): + """ + 优化后的 'decode' 模式推理 (seq_len=1)。 + 优化点: 在循环外使用 .tolist() 替换循环内的 .item(),避免多次 Host-Device 同步。 + """ + expert_cache = ops.zeros_like(x) + + # 1. 一次性将 IDs 和 weights 同步到 CPU + # flat_expert_indices 形状 (num_experts_per_tok,) + # flat_expert_weights 形状 (num_experts_per_tok, 1) + expert_ids_list = flat_expert_indices.tolist() + weights_list = flat_expert_weights.view(-1).tolist() # .view(-1) 压缩形状 + + # 2. 循环现在完全在 Host 上运行,没有同步 + for i in range(self.num_experts_per_tok): + expert_id = expert_ids_list[i] + weight = weights_list[i] + + expert = self.experts[expert_id] + expert_out = expert(x) + expert_cache += expert_out * weight + return expert_cache +``` + +### 1.2 MoE 推理加速:Prefill 阶段 (循环控制上移) + +优化痛点: 在处理长序列时,MoE 层的循环控制逻辑(计算每个 Expert 分配到的 token 数量)如果依赖 Tensor 操作,会导致图执行中断或多次同步。 + +改进方案: 将 bincount 和 cumsum 的结果转为 numpy/list,在 CPU 上计算切片索引 (start_idx, end_idx),仅将必要的计算算子下发 Device。 + +**源码实现** (`moe_infer`): + +**Python** + +``` +# 准备: 排序和计算每个expert的token数量 +expert_cache = ops.zeros_like(x) +idxs = flat_expert_indices.argsort() +tokens_per_expert_cumsum = flat_expert_indices.bincount().cumsum(0) + +# -------- 优化点: 将循环控制数据移至 CPU -------- +# 一次性将累积和数组同步到CPU,避免在循环中逐个同步 +tokens_per_expert_cumsum_cpu = tokens_per_expert_cumsum.asnumpy() +tokens_per_expert_list = tokens_per_expert_cumsum_cpu.tolist() + +# 在CPU上预先计算好start_idx +start_indices_list = [0] * len(tokens_per_expert_list) +if len(tokens_per_expert_list) > 1: + start_indices_list[1:] = tokens_per_expert_cumsum_cpu[:-1].tolist() + +token_idxs = idxs // self.num_experts_per_tok + +# 迭代: 在CPU上控制循环,在Device上执行计算 +for i, end_idx in enumerate(tokens_per_expert_list): + start_idx = start_indices_list[i] + if start_idx == end_idx: + continue + # ... (后续 Gather-Compute-Scatter 逻辑) +``` + +## 2. Qwen2-MoE 模型优化 + +### 2.1 MoE 路由逻辑优化 (索引计算) + +优化痛点: 原始实现可能使用了低效的循环或不兼容动态图的索引方式。 + +改进方案: 利用 mint.nonzero 获取稀疏索引,并优化索引加法逻辑。 + +**源码实现** (`Qwen2MoeSparseMoeBlock`): + +**Python** + +``` +# 获取非零专家的索引 [row_idx, expert_idx, top_k_idx] +non_zero_df = mint.nonzero(expert_mask).asnumpy() +if non_zero_df.shape[0] > 0: + expert_idx = non_zero_df[0][0] + # ... (分组处理相同 expert 的 token) ... + for i in range(1, non_zero_df.shape[0]): + # 逻辑:将属于同一个 Expert 的 token 攒在一起处理 + if non_zero_df[i][0] == expert_idx: + k += 1 + else: + # 执行计算 + expert_layer = self.experts[expert_idx] + # 使用 Tensor 索引 + idx = mindspore.Tensor(non_zero_df[j:j + k, 1], mindspore.int32) + top_x = mindspore.Tensor(non_zero_df[j:j + k, 2], mindspore.int32) + current_state = hidden_states[None, top_x].reshape(-1, hidden_dim) + + # 加权并累加回主干 + current_hidden_states = expert_layer(current_state) * routing_weights[top_x, idx, None] + final_hidden_states = final_hidden_states.index_add(0, top_x.int(), current_hidden_states.to(hidden_states.dtype)) + + # 重置计数器 + expert_idx = non_zero_df[i][0] + j = i + k = 1 +``` + +## 最终收益 +| model_name | memory_reserved | memory_allocated | avg_prefill_latency | avg_decode_latency | +| :--- | :--- | :--- | :--- | :--- | +| Qwen1.5-MoE-A2.7B-Chat | 31.138512896 | 29.234176512 | 1.3811829090118408 | 0.1579372354156434 | +| deepseek-moe-16b-chat | 34.359738368 | 32.813018112 | 2.4653173287709556 | 0.1202096897995133 | + + +## 评测结果 + +| 评测指标 | 平均得分 | +|---------|---------| +| 峰值显存得分 | 100 | +| Prefill时延得分 | 142.3168 | +| Decode时延得分 | 427.4573 | +| **总分** | **223.258** | \ No newline at end of file From 3dcb6e1db78694c135db3bc27a6796e42f7c3170 Mon Sep 17 00:00:00 2001 From: Quanyou Shen <52127540+skyous779@users.noreply.github.com> Date: Tue, 2 Dec 2025 20:42:15 +0800 Subject: [PATCH 2/3] =?UTF-8?q?2025=E5=B9=B4=E6=98=87=E8=85=BEAI=E5=88=9B?= =?UTF-8?q?=E6=96=B0=E5=A4=A7=E8=B5=9B-=E6=98=87=E6=80=9D=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=BC=80=E5=8F=91=E6=8C=91=E6=88=98=E8=B5=9B=EF=BC=88?= =?UTF-8?q?S1=E8=B5=9B=E5=AD=A3)--MoE=E8=B5=9B=E9=A2=98--blueblue=E9=98=9F?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../S1/MoE/blueblue/patches.zip | Bin 0 -> 23117 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 2025-Ascend-Innovation-Contest/S1/MoE/blueblue/patches.zip diff --git a/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/patches.zip b/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/patches.zip new file mode 100644 index 0000000000000000000000000000000000000000..cd23c202655a7b327b8bf5ce9c6f1abb111579d6 GIT binary patch literal 23117 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 T5d{VB_PM?_L5u7C Date: Wed, 3 Dec 2025 11:03:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md b/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md index 002b3989..01acef2e 100644 --- a/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md +++ b/2025-Ascend-Innovation-Contest/S1/MoE/blueblue/README.md @@ -1,8 +1,8 @@ -# MindNLP 模型优化详细说明 (DeepSeek & Qwen2-MoE) +# MindNLP 模型优化详细说明 (DeepseekMoE & Qwen2-MoE) -本文档详细记录了针对 DeepSeek 和 Qwen2-MoE 模型的关键性能优化点,并附带了相应的核心代码实现。 +本文档详细记录了针对 DeepseekMoE 和 Qwen2-MoE 模型的关键性能优化点,并附带了相应的核心代码实现。 -## 1. DeepSeek 模型优化 (DeepseekMoE) +## 1. DeepseekMoE 模型优化 ### 1.1 MoE 推理加速:Decode 阶段 (消除 Host-Device 同步)