已开启
【RFC】EP 通算掩盖:共享专家重叠、DualPipe 与 W/D 掩盖 #110
hedongdong创建于  4月27日
hedongdong成员
4月27日 创建

EP 通算掩盖:共享专家重叠、1F1B 通算掩盖、W/D 拆分与 DualPipe

本文档描述 Expert Parallel 的四类计算与通信重叠优化:

  • A — 共享专家与 combine 通信的异步重叠(本期目标)
  • B — 1F1B 通算掩盖:BWD ↔ FWD a2a 跨线程交错(Phase 1,参考实现已落在 examples/torch/pp_overlap/pp_overlap_moe_example.py,待产品化)
  • C — W/D 拆分 + deferred W 队列(Phase 2,本文档仅定义范围,本期不实施)
  • D — 双向流水线 DualPipe(远期规划,本文档仅说明情况)

侧重背景、职责边界、接口与契约、测试与验收,不包含具体代码实现。


1. 背景

1.1 EP 通信的时序瓶颈

标准 EP 的 forward 执行时序为:

dispatch all-to-all ─→ 本地 expert 计算 ─→ combine all-to-all

三阶段串行执行,计算与通信完全顺序。在 ep_degree 较大、机间带宽受限时,两次 all-to-all 的时延直接叠加在关键路径上,成为 MoE 层的主要耗时。反向链路上还会再叠加 combine_bwd 与 dispatch_bwd 两次 a2a,通信总量比前向更大。

1.2 已有基础与缺口

已实现:

  • AllToAllTokenDispatcher.dispatch() 与 combine() 的基础流程(同步 all-to-all);
  • MoE 内的 shared_expert(可选 FeedForward,输出与 expert 输出相加);
  • platform.differentiable_all_to_all_single 同步版本;
  • platform.differentiable_all_to_all_single_async 异步版本(已在 example 中验证);
  • CommComputeOverlap 多线程通算协调器与 A/B/C/D 同步 hook 原语(example 中使用);
  • ScheduleInterleaved1F1B(overlap_b_f=True) 调度器,能在 1F1B 稳态发出 OVERLAP_B_F 复合步。

缺口:

  • shared_expert 与 combine all-to-all 串行执行(A 的目标);
  • ExpertParallel 把 _input_splits / _output_splits / _input_shape / _permuted_indices 挂在 EP 实例上,跨层只能靠"每层一个 EP 实例"绕开,跨 microbatch 不安全(B 产品化前置);
  • example 仅 Torch + NPU 实测,未跨平台对齐;
  • 缺少把反向拆成 D 段 / W 段、并把 W 段移入通信等待窗口的机制(C);
  • 缺少双向流水线调度(D)。

2. 四类优化的定义与范围

2.1 子方向 A:共享专家与 combine 通信异步重叠

核心思想:

combine all-to-all 发起后,在等待通信结果的时间窗口内,并行执行 shared expert 的前向计算,将两者的时延进行掩盖。

时序对比:

当前(串行):
  combine all-to-all ──────────► 完成
                                  shared_expert 计算 ──► sum

目标(重叠):
  combine all-to-all ─────────────────────► 完成 ─►  sum
  shared_expert 计算 ────────────────►              (与通信并行)

依赖:

  • platform.differentiable_all_to_all_single 支持异步发起,返回句柄(AsyncHandle);
  • TokenDispatcher.combine() 分解为「发起」和「等待 + 合并」两个阶段;
  • shared_expert 在「发起」之后、「等待」之前执行。

2.2 子方向 B:1F1B 通算掩盖(BWD ↔ FWD a2a 跨线程交错)

核心思想:

ScheduleInterleaved1F1B 的 1F1B 稳态把 BWD microbatch i 与 FWD microbatch i+1(来自不同虚拟 chunk)打包成 OVERLAP_B_F 复合步,两条线程分别承载 FWD 与 BWD:

  • 同一 ep_group 上的 a2a 由 CommComputeOverlap 的协调器全局串行(同 group 两个 a2a 并发会触发 HCCL 数据损坏);
  • 通信占用通信流时,对侧线程的计算占用计算流,通过"通信 vs 计算"在不同流上并行完成掩盖;
  • A/B/C/D 4 个 differentiable_sync_hook 把 dispatch a2a 和 combine a2a 各自夹在一对 hook 中间,hook 之间是 compute 区,coordinator 在 hook 上交接 HCCL 发射权。

时序示意(一对 BWD↔FWD 配对内的一层 MoE):

sequenceDiagram
    participant CS as 计算流
    participant CO as Coordinator
    participant XS as 通信流(HCCL)<br/>同 ep_group 全局串行

    Note over CS,XS: 配对开始<br/>FWD microbatch i+1(MoE 层 L)<br/>BWD microbatch i(MoE 层 L+1,反向遍历)

    rect rgb(220, 240, 220)
        Note left of CS: 并发计算:<br/>BWD 上一层 expert_w 残段
        CO->>XS: FWD dispatch a2a(hook A→B 内异步发射)
        XS-->>CO: 完成
    end

    rect rgb(220, 240, 220)
        Note left of CS: 并发计算:<br/>FWD permute + expert FFN(hook B 之后的 compute 区)
        CO->>XS: BWD combine_bwd a2a 异步发射
        XS-->>CO: 完成
    end

    rect rgb(220, 240, 220)
        Note left of CS: 并发计算:<br/>BWD expert_bwd D 段
        CO->>XS: FWD combine a2a(hook C→D 内异步发射)
        XS-->>CO: 完成
    end

    rect rgb(220, 240, 220)
        Note left of CS: 并发计算:<br/>FWD 下一层 attn / qkv
        CO->>XS: BWD dispatch_bwd a2a 异步发射
        XS-->>CO: 完成
    end

    Note over CS,XS: 进入下一对 BWD↔FWD 配对

注:上图为一对 BWD↔FWD 配对里 一层 MoE 的半周期 概念示意,重在表达「HCCL 同 ep_group 全局串行 + 对侧计算填窗」的资源占用模型。example 实际每 chunk 含 2 层 MoE(moe_layers_per_chunk = 2,用于解锁跨层 D → A_next 的 attn 掩盖窗口),完整周期是 8 个 a2a 槽位;且 chunk 最后一层的 D hook 标为 D_LAST,BWD 起点的 combine_bwd 自由发射、不参与 rendezvous,与中间层并不对称。每个槽位上「对侧 compute」的具体内容(如 expert_w 残段 / 下一层 attn 等标签)由 HookCoordinator 配对规则 + 两层 MoE 交错相位决定,图中标注为示意,可能存在 ±1 hook 的相位偏移。

与文档前一版「DualPipeExpertParallel」的关系:前一版用「Micro-batch N 的 combine 与 Micro-batch N+1 的 dispatch 在前向接力」描述 B,落到 HCCL/NCCL 上同 group 两 a2a 无法真正并发,需要 BWD 同时在场才能用 BWD 的计算去掩盖 FWD 的通信。example 的实现是这一观察的工程化产物,与 DeepSeek 完整 DualPipe(见 2.4)不同,没有双向流水线、没有 chunk 内 4 段细粒度切分、没有 W/D 拆分,但已能拿到主要收益。为避免名称混淆,本期内部命名采用 OverlapExpertParallel + CommComputeOverlap + ScheduleInterleaved1F1B(overlap_b_f=True) 三件套,不再使用 "DualPipeExpertParallel" 这一名称。

依赖:

  • 异步 a2a 接口(与 A 共用 platform.differentiable_all_to_all_single_async);
  • CommComputeOverlap + differentiable_sync_hook("A"|"B"|"C"|"D"|"D_LAST") 协调器;
  • ScheduleInterleaved1F1B 支持 overlap_b_f=True / overlap_p2p=True;
  • MoE 层每层独立持有 _input_splits 等状态(或迁移至 DispatchMetadata 栈式对象);
  • chunk 的最后一层 MoE 用 is_last_layer=True 标记,使 D hook 退化为 D_LAST(前向后无 attn、反向 combine_bwd 已自由发射,无需 rendezvous);
  • BWD 线程显式 set_device(local):current device 是 thread-local,缺失会让 HCCL 跑到 device 0 死锁。

2.3 子方向 C:W/D 拆分 + deferred W 队列(本期不实施,仅定义范围)

核心思想:

反向天然由 D = ∂L/∂x(输入梯度,传给上层)+ W = ∂L/∂w(权重梯度,本地消费)两部分组成。标准 autograd 把它们绑在同一个 backward node 一次性算完。W/D 拆分把它们解耦:

  • D 段留在 backward 关键路径上,与 a2a 通信交错(B 已经做到这一步);
  • W 段入 deferred 队列,由 pipeline scheduler 在仍未被掩盖的 comm 等待窗口里 flush。

时序示意:

flowchart TB
    subgraph standard[标准反向(B 已实现的状态)]
        direction LR
        s1[layer L+1<br/>expert_bwd<br/>同时算 dX+dW] --> s2[a2a comm<br/>对侧 compute<br/>已被掩盖]
        s2 --> s3[layer L<br/>expert_bwd<br/>同时算 dX+dW]
    end
    subgraph withwd[W/D 拆分反向]
        direction LR
        w1[layer L+1<br/>expert_bwd 仅 dX] --> w2[a2a comm 发射]
        w1 -.W 任务入队<br/>持有激活.-> wq[(deferred<br/>W queue)]
        w2 --> w4[layer L<br/>expert_bwd 仅 dX]
        w4 -.W 任务入队.-> wq
        w2 -.flush 填残余窗口.-> wq
    end
    style s2 fill:#ffe0b0
    style wq fill:#c0e8c0

范围(一旦 Phase 2 立项需要改的面):

  1. 自定义 GEMM autograd:在 expert / attn_qkv / attn_proj / ffn 关键 GEMM 上提供 backward_d_only(grad_out, weight) → grad_in 与 backward_w_only(grad_out, input_saved) → grad_w 两个独立入口,绕开标准 autograd 的「原子 backward」假设。
  2. deferred W 队列:挂在 pipeline scheduler 上,per-rank 一个;条目包含 (grad_out_ref, input_saved_ref, weight_ref, target_grad_buffer)。
  3. MoE / Attention / FFN 协作:backward 不再调用整块算子,而是按 D-only 调用 + 把 W 任务推入队列。
  4. flush 时机:在 OVERLAP_B_F 复合步的 a2a 等待窗口里调度 W 任务;在 1F1B cooldown 阶段统一 drain 剩余 W。
  5. 激活生命周期:W 任务需要持有 forward 激活到任务执行为止,激活释放被推迟,显存上升是 W/D 的硬成本。

本期不实施的原因:

  • 收益相对 B 是「填窗」性质,B 已掩盖主要通信;C 在 B 之上再提一档,但绝对值有限;
  • 改动面跨 MoE / Attention / FFN / scheduler 四个模块,PR 体量大;
  • 自定义 autograd 在 Torch / MindSpore 上需各写一套;
  • 显存成本需要先在 Phase 1 上量化才能判断是否值得引入。

2.4 子方向 D:双向流水线 DualPipe(远期规划)

核心思想:

DeepSeek-V3 DualPipe 与本仓现状(含 B/C)的根本区别是 pipeline 调度:

  • 标准 1F1B:单向流水,每个 rank 持有 1 个 stage 的参数,气泡 ≈ (P - 1) × (F + B);
  • DualPipe:双向流水,每个 rank 同时持有相邻 2 个 stage 的参数(正向流的 stage k 和反向流的 stage 2P - 1 - k),来自两条对头 microbatch 流,气泡 ≈ (P/2 - 1) × (F + B - 2W)。

每个 rank 任一时刻同时有一个 FWD microbatch 与一个 BWD microbatch 在场,且这两个 microbatch 来自不同方向的 pipeline 流、互无数据依赖,比 1F1B 稳态下「同条流的 BWD_i + FWD_{i+1}」并行度更高。

示意:

flowchart LR
    subgraph baseline["标准 1F1B(单向)"]
        direction LR
        s0["rank 0<br/>stage 0"] --> s1["rank 1<br/>stage 1"] --> s2["rank 2<br/>stage 2"] --> s3["rank 3<br/>stage 3"]
        s3 -.反向回传.-> s2
        s2 -.-> s1
        s1 -.-> s0
    end
    subgraph dualpipe["DualPipe(双向,每 rank 持 2 stage)"]
        direction LR
        d0["rank 0<br/>stage 0 (正)<br/>stage 7 (反)"]
        d1["rank 1<br/>stage 1 (正)<br/>stage 6 (反)"]
        d2["rank 2<br/>stage 2 (正)<br/>stage 5 (反)"]
        d3["rank 3<br/>stage 3 (正)<br/>stage 4 (反)"]
        d0 ==正向流==> d1 ==> d2 ==> d3
        d3 ==反向流==> d2 ==> d1 ==> d0
    end
    style dualpipe fill:#eef

chunk 内 4 段交错:DualPipe 把每个 chunk 切成 ATTN / DISPATCH / MLP / COMBINE 四段,让 FWD chunk 的 comm 段与对头 BWD chunk 的 compute 段两两咬合,比 B 的 A/B/C/D 4 hook 粒度更细。

与 B/C 的关系:

  • D 与 B 互不相同:B 是「单向 1F1B 上用 BWD 配 FWD」,D 是「双向流水线」,B 的 example 可视作 D 的同向简化版;
  • D 强依赖 C 的 W/D 拆分:DualPipe 的气泡公式里那个 -2W 项就是 W 段填洞带来的;
  • 双向流水线需要 core/pipeline_parallel/ 引入新调度器,与现有 ScheduleInterleaved1F1B 并列。

本期不立项的原因:

  • 2× 参数显存:每 rank 持 2 个 stage 的参数,叠加 FSDP 后仍然实打实多一倍持久参数显存,对中等规模反而退化;
  • 调度器需要重写,FSDP / EP / CP / activation checkpoint 全组合都要重测;
  • 收益曲线在 pp_size ≥ 16 的大规模 MoE 才显著,需要先有明确用户场景;
  • 决策点放在 Phase 2 完成后再评估,本文档仅保留概念。

3. 目标与非目标

3.1 目标(本期)

子方向 A(本期唯一交付项):

  • 扩展 platform.differentiable_all_to_all_single,支持异步发起模式,返回 AsyncHandle;
  • AllToAllTokenDispatcher.combine() 分解为 combine_start() 和 combine_wait()(或通过 DispatchMetadata 携带句柄);
  • MoE.forward 在 combine_start() 和 combine_wait() 之间执行 shared_expert;
  • 无 shared_expert 时行为完全兼容(退化为同步路径)。

3.2 后续路线(按阶段排期,本期不交付)

Phase 1 — 子方向 B 产品化:

  • 把 examples/torch/pp_overlap/pp_overlap_moe_example.py 中的 OverlapExpertParallel 抬成正式 API,纳入 hyper_parallel/core/expert_parallel/;
  • 状态从 EP 实例迁移至 DispatchMetadata 或 MoE 模块,去掉「每层一个 EP 实例」的 workaround;
  • 跨平台对齐:补 MindSpore 路径;
  • 完善 ST 矩阵(PP × EP × FSDP,含 D_LAST 边界、零 token 边界)。

Phase 2 — 子方向 C W/D 拆分:

  • 自定义 GEMM autograd(先 Torch);
  • deferred W 队列与 ScheduleInterleaved1F1B 集成;
  • 量化激活显存上升与端到端收益,决定是否再做 MindSpore 路径。

Phase 3 — 子方向 D 评估:

  • 仅当出现 pp_size ≥ 16 的真实用户场景时立项;
  • 立项前先评估 2× 参数显存是否可接受。

3.3 非目标

  • 不修改 attention 或 FFN 的计算逻辑(A/B 范围);
  • 不在本期实现 B/C/D;
  • 不引入 DeepEP / 自定义通信库。

4. 接口与契约

4.1 异步 all-to-all 平台接口(A 依赖)

platform.differentiable_all_to_all_single(
    input_tensor, input_splits, output_splits, group,
    async_op: bool = False,
) -> Tensor | (AsyncHandle, Tensor)
参数 说明
async_op=False(默认) 同步执行,行为与当前实现完全兼容
async_op=True 异步发起,返回 (handle, output_tensor);调用方须在使用 output_tensor 前调用 handle.wait()

约束:

  • async_op=True 时,output_tensor 是已分配但未填充的 Tensor,访问需在 handle.wait() 后;
  • handle.wait() 是幂等的;
  • 平台抽象层(platform/platform.py)需在抽象接口中声明此参数,PyTorch 和 MindSpore 分别实现;
  • Phase 1 复用同名 platform.differentiable_all_to_all_single_async,含义等价。

4.2 AllToAllTokenDispatcher 的分阶段 combine(A)

class AllToAllTokenDispatcher:

    def combine_start(
        self,
        expert_output: Tensor,
        top_scores: Tensor,
        metadata: DispatchMetadata,
    ) -> (AsyncHandle, CombinePartialResult):
        """
        发起 combine all-to-all(异步),返回句柄与中间状态。
        不等待通信完成。
        """

    def combine_wait(
        self,
        handle: AsyncHandle,
        partial: CombinePartialResult,
    ) -> Tensor:
        """
        等待 handle 完成,执行 unpermute + scatter_add,返回最终 combined tensor。
        """

CombinePartialResult 携带 unpermute 所需的中间状态,生命周期与本次 forward 调用绑定,不持有对 dispatcher 的引用。

向后兼容:保留 combine(expert_output, top_scores, metadata) 同步版本,内部调用 combine_start + combine_wait,对不需要 shared_expert 重叠的场景透明。

4.3 MoE.forward 的新时序(A)

# 1. Dispatch
permuted_input, local_counts, dispatch_meta = dispatcher.dispatch(x_flat, ...)

# 2. Expert 计算
expert_output = self.experts(permuted_input, local_counts)

# 3. 发起 combine(异步)
handle, combine_partial = dispatcher.combine_start(expert_output, top_scores, dispatch_meta)

# 4. Shared expert 计算(与 combine 通信并行)
shared_out = self.shared_expert(x_flat) if self.shared_expert else None

# 5. 等待 combine 完成
combined = dispatcher.combine_wait(handle, combine_partial)

# 6. 合并输出
out = combined + shared_out if shared_out is not None else combined

约束:

  • 若无 shared_expert(shared_expert is None),步骤 3~5 退化为同步 combine(),无额外开销;
  • x_flat 在步骤 4 中被 shared_expert 使用,需保证在步骤 3 发起通信后未被修改(即不可原地操作)。

4.4 B 参考实现接口(Phase 1 产品化目标)

example 已落地的 API(Phase 1 把它们从 example 移入 hyper_parallel/core/expert_parallel/):

class OverlapExpertParallel(ExpertParallel):
    def __init__(self, overlap: CommComputeOverlap, is_last_layer: bool = False) -> None:
        ...

    # forward / backward 入口照常,内部用 differentiable_sync_hook
    # 把 dispatch a2a 夹在 A/B 之间、combine a2a 夹在 C/D(或 C/D_LAST)之间。

class CommComputeOverlap:
    coordinator: HookCoordinator
    def run(self, fwd_fn, bwd_fn) -> None: ...   # 两线程执行 FWD + BWD

调度侧入口:

ScheduleInterleaved1F1B(stages, micro_batch_num, overlap_p2p=True, overlap_b_f=True)
schedule.register_custom_function(MetaStepType.OVERLAP_B_F, callback)

Phase 1 产品化要补:

  1. 状态去实例化:现有 OverlapExpertParallel 仍把 _input_splits / _output_splits / _input_shape / _permuted_indices 写在自身上,跨 microbatch 不安全;改为通过 DispatchMetadata 显式回传给 combine,与 4.2 的 CombinePartialResult 统一。
  2. is_last_layer 自动推断:例子里靠用户手动传,产品化要让框架从 chunk 结构自动判定。
  3. MindSpore 路径:example 只跑了 Torch + NPU,需要补 MindSpore differentiable_all_to_all_single_async 与多线程协调器。
  4. 错误恢复:HCCL 错误下 coordinator 不能死锁(带超时 / 失败传播)。

4.5 C 接口草稿(Phase 2,本期不实现,供后续设计参考)

class GemmDeferred(torch.autograd.Function):
    @staticmethod
    def forward(ctx, input, weight): ...
    @staticmethod
    def backward(ctx, grad_out):
        # 仅算 dX;把 dW 任务推入 ctx.deferred_w_queue
        grad_in = ...
        DeferredWQueue.current().push(ctx.input_saved, ctx.weight, grad_out, ctx.grad_w_slot)
        return grad_in, None

class DeferredWQueue:
    def push(self, input_saved, weight, grad_out, grad_w_slot): ...
    def flush(self, deadline_event): ...
    @classmethod
    def current(cls) -> "DeferredWQueue": ...

约束:

  • 队列条目持有 forward 激活(input_saved),生命周期由调度器管理;
  • flush(deadline_event) 在 a2a 等待窗口里调用,事件触发时停止入队;
  • 1F1B cooldown 时统一 drain;
  • MoE 的 GroupedExperts 需要把 expert_w 注册到 DeferredWQueue.current()。

4.6 D 接口草稿(远期,本期不实现)

class DualPipeSchedule(PipelineScheduleBase):
    # 双向流水线:每 rank 持 2 stage,正反两条 microbatch 流。
    # chunk 切成 ATTN / DISPATCH / MLP / COMBINE 四段。
    # 复合步:FwdSlice(direction=↓) ⊕ BwdSlice(direction=↑) 对头配对。
    ...

前置条件:

  • 子方向 C 完成(W 段提供填洞料源);
  • Pipeline scheduler 框架允许同 rank 持有多 stage 参数。

4.7 平台支持矩阵

平台 A(异步 a2a + shared_expert 重叠) B(1F1B 通算掩盖) C(W/D 拆分) D(DualPipe)
PyTorch / CUDA ✅ 本期目标 Phase 1 验证 Phase 2 Phase 3 评估
Ascend NPU / CANN ✅ 本期目标 ✅ example 已验证,Phase 1 产品化 Phase 2 Phase 3 评估
MindSpore ⬜ 待 MindSpore EP 支持后评估 Phase 1 补齐 Phase 2 评估 —

5. 测试设计

5.1 子方向 A 单元测试

用例 ID 描述 期望
OV-01 combine_start + combine_wait round-trip,无 shared_expert 输出与同步 combine() 数值完全一致
OV-02 无 shared_expert 时,同步退化路径执行 与当前 EP 基线一致,无性能退化
OV-03 handle.wait() 幂等性:调用两次不报错 第二次调用安全返回
OV-04 shared_expert 在 combine 通信期间执行(模拟通信延迟) 两者时序正确,最终输出与串行执行数值一致

5.2 子方向 A 分布式测试

用例 ID 配置 期望
OV-D01 4 卡 EP + shared_expert,异步 combine 前向/反向输出与串行基线(同 token)数值对齐(rtol=1e-3)
OV-D02 性能对比:4 卡 EP,有/无 shared_expert 重叠 异步重叠版本的 MoE 层时延不高于串行版本(通过 profiling 验证)

5.3 子方向 B 产品化验收要点(Phase 1)

用例 ID 配置 期望
OV-B01 example 当前配置(PP=2, EP=2, 4 卡,2 chunks/rank,2 MoE/chunk) 与无 overlap 基线数值对齐(rtol=1e-3)
OV-B02 DispatchMetadata 化后,跨 microbatch 状态不互相覆盖 多 microbatch 顺序运行结果与单 microbatch 拼接一致
OV-B03 零 token 边界:某 rank 在某 microbatch 收到 0 token autograd 不断(不出现 "element 0 does not require grad")
OV-B04 is_last_layer 自动推断与手动指定行为一致 输出与 baseline 数值对齐
OV-B05 MindSpore 路径数值对齐 与 Torch 路径同 seed 下 rtol=1e-3
OV-B06 Profiling:a2a 与对侧 compute 实际重叠比例 ≥ 60%(example 已观测数据为参照)

5.4 子方向 C / D 验收

在各自后续设计文档定义,本文档不展开。指标方向:

  • C:W/D 拆分后端到端 step 时延相对 B 的下降比例;激活显存上升幅度;
  • D:与 B + C 组合相比的气泡公式实测,要求 pp_size = 16 配置下下降到 (P/2 - 1) 量级。

5.5 回归

  • 现有 8 个 EP 分布式 ST 测试(无 shared_expert,同步路径)无回归;
  • 现有 5 个 shared_expert 相关 ST 测试无回归;
  • example 当前能跑通的 4 卡 PP+EP 用例,A 落地后仍跑通。

6. 风险与开放问题

风险 缓解
异步 all-to-all 在 NPU CANN 版本上的 API 兼容性 平台层封装隔离,NPU 路径单独测试并锁定 CANN 版本
combine_start 后 x_flat 被 shared_expert 并发访问的内存安全 x_flat 为 combine 发起前的只读输入,dispatch 结束后不再修改,shared_expert 仅读取,无并发写冲突
异步 combine 反向梯度路径(autograd graph) differentiable_all_to_all_single 的 autograd function 需与异步句柄的 wait() 正确绑定;backward 中 wait() 必须先于梯度计算
B 跨 microbatch 状态污染 Phase 1 强制把 _input_splits 等迁出 EP 实例,统一走 DispatchMetadata
B 协调器死锁(HCCL 错误 / 边界 microbatch) D_LAST 标签 + 超时机制 + 失败传播;example 已踩过的坑(last layer 不 rendezvous、BWD 线程 set_device)必须复刻
C 引入显存上升(deferred 激活) Phase 2 立项前先在 Phase 1 数据上量化预算
D 的 2× 参数显存 Phase 3 评估时与 FSDP / activation swap 联合考虑
CombinePartialResult 的内存开销(持有 unpermute 中间状态) 中间状态大小与 token 数线性相关,与 dispatch 阶段保存的 permuted_indices 相当,可接受

7. 验收标准

子方向 A(本期)

子方向 B(Phase 1)

子方向 C(Phase 2)

子方向 D(评估期)


8. 参考

  • HyperParallel:hyper_parallel/platform/torch/common/moe.py — MoE.forward(shared_expert 当前串行位置);
  • HyperParallel:hyper_parallel/core/expert_parallel/expert_parallel.py — ExpertParallel._token_dispatch、_token_combine;
  • HyperParallel:hyper_parallel/platform/platform.py — differentiable_all_to_all_single 平台接口;
  • HyperParallel:hyper_parallel/core/pipeline_parallel/ — Pipeline scheduler、CommComputeOverlap、ScheduleInterleaved1F1B;
  • HyperParallel:examples/torch/pp_overlap/pp_overlap_moe_example.py — B 子方向参考实现;
  • HyperParallel:docs/expert_parallel.md;
  • DeepSeek-V3 Technical Report — DualPipe 调度与 W/D 拆分原始描述(D 子方向背景)。
likedislike
Hhedongdong成员
6月2日 修改了issue 的描述
Hhedongdong成员
6月2日 修改了issue 的描述
RoverrrrrRoverrrrr
6月4日 关联了pull request:feat(expert_parallel): add async combine overlap for shared expert optimization
RoverrrrrRoverrrrr
6月10日 关联了pull request:feat(expert_parallel): async combine a2a overlap with shared expert
RoverrrrrRoverrrrr
7月1日 关联了pull request:fix(expert_parallel): fix async combine distributed tests using wrong init helper