mindspore-ai / mindspore-ai/hyper-parallel

# 【RFC】分布式算子 ST 测试架构重构

Open
#688 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
53
Forks
63
Avg merge
23h 45m
Merged PRs (30d)
63

Description

【RFC】分布式算子 ST 测试架构重构

0. RFC 摘要

本 RFC 面向 HyperParallel 分布式算子系统测试(ST),将原有“每个算子独立 launcher + worker”的
脚本式测试方式重构为声明式、跨平台、可调度的测试架构。

核心目标是让算子开发者只描述:

  • 测试哪个算子;
  • 输入张量如何构造;
  • 输入如何切分到 DeviceMesh;
  • 结果采用何种比较方式;
  • 用例进入哪个平台和门禁等级。

测试框架统一承担单卡参考计算、分布式执行、结果汇聚、数值比较、进程编排、设备分配和报告聚合。

范围
  • 分布式算子 ST 的声明模型、注册发现、分组、调度、执行和报告;
  • Torch CPU(gloo)、Torch Ascend(hccl)和 MindSpore Ascend 三种后端;
  • 2/4/8 卡 DeviceMesh、level0/level1 门禁路由和 8 卡资源调度;
  • 存量 Torch/MindSpore 分布式算子 ST 用例迁移;
  • CLI、本地过滤和 CI 门禁入口。
非目标
  • 不替代算子 UT:参数校验、Layout 推导和错误路径仍由 UT 覆盖;
  • 不改变分布式算子实现及其数学语义;
  • 不把所有测试抽象为完全相同的用例,保留 derived_inputsneeds_meshsolo_launcher 等必要扩展点;
  • 不要求不同框架共享同一段算子调用函数,平台差异由后端适配和各自 case 文件表达。

1. 背景与问题

旧框架采用 test_parallel_op_X.py(pytest launcher)与 _test_parallel_op_X.py
(torchrun/msrun worker)双文件模式。每个算子和场景都重复实现初始化通信、创建 DeviceMesh、
构造输入、切分张量、汇聚输出和比较结果。

1.1 原框架问题
问题 根因 架构影响
样板代码重复 每个 worker 独立实现相同的分布式执行流程 用例维护成本高,修复需要霰弹式修改
launcher 启动成本高 每组少量用例独立启动 torchrun/msrun CANN/HCCL 初始化耗时占总耗时主体
设备利用率低 缺少按卡数和 mesh 拓扑统一规划 8 卡环境无法自动并发运行两个 4 卡 group
门禁路由分散 marker、level 和用例分组散落在不同入口 用例覆盖范围难审计,新增场景容易漏入门禁
跨平台逻辑重复 Torch、MindSpore 分别手写构造、切分、汇聚、比较 相同测试语义在不同后端出现实现漂移
失败诊断困难 多 rank 输出分散,缺少统一结果聚合 CI 失败难以快速定位到具体 case 和 rank
特殊场景缺少统一模型 派生输入、多输出、MC2、随机结果各自临时处理 扩展能力不可复用,测试语义不清晰
1.2 分布式测试硬约束
编号 约束 说明
C1 外部启动器 分布式 ST 必须由 torchrunmsrun 创建多个独立 rank 进程
C2 多 rank 协同 同一 case 必须在所有 rank 上以一致顺序执行,通信失败可能破坏整个进程组
C3 设备隔离 同批 group 必须使用互不重叠的设备切片
C4 启动昂贵 框架、CANN 和通信域初始化远慢于单个算子计算
C5 跨平台 同一测试语义要覆盖 Torch CPU、Torch NPU 和 MindSpore NPU
C6 混合 mesh 同一套件可能同时包含 2、4、8 卡用例,无法由一次固定 nproc 的 launcher 全部承载
C7 CI 兼容 新框架需要继续通过 @arg_mark 接入现有 level0/level1 门禁

2. 架构目标与质量属性

质量属性 质量属性场景 设计响应与验收方式
正确性 一个算子在指定切分策略下执行 对同一份完整输入先计算单卡参考,再切分执行并汇聚,比较完整输出
确定性 随机初始化用例重复运行 InputSpec.seed 固定输入;数值可比较场景必须得到稳定参考结果
性能 大量同拓扑 case 进入同一套件 同 mesh 用例共享 launcher,减少重复初始化;以 suite wall-clock 验收
资源效率 8 卡机器同时存在多个 2/4 卡 group 按卡数装箱,同一 batch 在不重叠设备切片上并发执行
可移植性 同一测试模型运行于三个后端 平台无关核心只依赖 ShardBackend 接口,后端独立完成设备操作
可扩展性 新增后端、新比较方式或特殊输入 通过 Backend、CompareSpec、DerivedSpec 等扩展点实现,不修改 case 执行骨架
可靠性 某个 case 断言失败或通信异常 聚合所有 rank 状态;非断言异常后执行通信健康探测,避免污染后续 case
可诊断性 CI 中某个 rank 失败 Reporter 记录 case、rank、状态、耗时和错误,并汇总为人类可读结果
易用性 开发者新增算子 ST 只需创建 case_{op}.py 并声明 OpShardCase,无需手写 launcher/worker 样板
可维护性 调整公共执行或门禁策略 在 framework/suite/runner 中集中修改,存量 case 无需同步改写
2.1 关键性能目标
  • launcher 启动成本由“每个用例或小组重复支付”变为“同一 group 内用例共享”;
  • 支持按 8 卡预算并发调度多个 2/4 卡 group;
  • 新框架运行完整 level0 套件的耗时应低于旧框架运行少量代表用例的耗时;
  • 性能结论使用 wall-clock、用例数量、串行 batch 数和后端环境共同描述,避免只比较单 case 时间。

3. 4+1 架构视图

3.1 逻辑视图

框架由声明模型、注册发现、套件规划、父进程调度、rank 执行、后端适配和报告聚合组成。

classDiagram
    direction LR

    class OpShardCase {
        +name
        +fn
        +inputs
        +placements
        +mesh_shape
        +tags
    }

    class InputSpec
    class DerivedSpec
    class CompareSpec
    class Registry {
        +register(case)
        +load_cases_from_package(package)
    }
    class SuitePlanner {
        +build_suite_groups(...)
        +pack_into_batches(...)
    }
    class Runner {
        +run_groups(groups, framework, device_type)
    }
    class ShardBackend {
        <<interface>>
        +maybe_init_dist()
        +make_tensor(spec)
        +distribute(tensor, mesh, placement)
        +local_to_global(tensor)
        +assert_close(expected, actual, compare)
        +recover_after_failure()
    }
    class TorchHcclBackend
    class TorchGlooBackend
    class MindSporeAscendBackend
    class Reporter

    OpShardCase *-- InputSpec
    OpShardCase *-- DerivedSpec
    OpShardCase *-- CompareSpec
    Registry o-- OpShardCase
    SuitePlanner --> Registry
    Runner --> SuitePlanner
    Runner --> ShardBackend
    Runner --> Reporter
    ShardBackend <|.. TorchHcclBackend
    ShardBackend <|.. TorchGlooBackend
    ShardBackend <|.. MindSporeAscendBackend

核心职责边界:

  • OpShardCase 只描述测试意图,不处理进程、设备和通信;
  • SuitePlanner 只规划 case、group、batch 和设备预算,不执行算子;
  • Runner 管理 launcher 生命周期和设备隔离,不包含平台张量操作;
  • ShardBackend 封装平台张量、分布式初始化、切分、汇聚和比较;
  • entry 在各 rank 上执行统一流水线,并将结果交给 Reporter。
3.2 开发视图
tests/
├── shard_ops/framework/                    # 平台无关核心
│   ├── case_spec.py                        # OpShardCase/InputSpec/DerivedSpec/CompareSpec
│   ├── registry.py                         # 注册和发现
│   ├── backend.py                          # ShardBackend ABC 与后端注册
│   ├── suite.py                            # 分桶、group 和并发规划
│   ├── runner.py                           # 父进程、launcher、设备分配和超时
│   ├── entry.py                            # rank 进程执行入口
│   ├── reporter.py                         # JSONL 和汇总
│   └── cli.py / __main__.py                # 本地运行入口
├── torch/shard/ops/
│   ├── test_shard_ops_suite.py             # Torch CI 入口
│   ├── cases/case_{op}.py                  # Torch 声明式用例
│   └── framework/backend_torch.py          # gloo/hccl 适配
└── mindspore/st/shard/ops/
    ├── test_shard_ops_suite.py             # MindSpore CI 入口
    ├── cases/case_{op}.py                  # MindSpore 声明式用例
    └── framework/backend_mindspore.py       # Ascend 适配

平台无关共享框架本身不直接依赖 PyTorch 或 MindSpore;平台张量和通信操作统一通过
ShardBackend 实现。case package 在用例发现阶段注册声明,真正的分布式初始化和设备执行发生在
launcher 创建的 rank 进程中。

3.3 进程视图
sequenceDiagram
    actor CI as CI / Developer
    participant Pytest as pytest parent
    participant Suite as SuitePlanner
    participant Runner
    participant Launcher as torchrun / msrun
    participant Rank as rank processes
    participant Backend as ShardBackend
    participant Report as Reporter

    CI->>Pytest: run suite entry or CLI
    Pytest->>Suite: build_suite_groups(tags, filter)
    Suite-->>Pytest: GroupSpec list
    Pytest->>Runner: run_groups(groups)
    Runner->>Runner: pack groups into 8-card batches

    loop each serial batch
        par non-overlapping device groups
            Runner->>Launcher: start group with assigned devices
            Launcher->>Rank: create N rank processes
            Rank->>Backend: init distributed and DeviceMesh

            loop each case in group
                Rank->>Backend: build full tensors
                Rank->>Rank: derive full inputs if configured
                Rank->>Rank: run standalone reference
                Rank->>Backend: distribute inputs
                Rank->>Rank: run distributed function
                Rank->>Backend: gather distributed output
                Rank->>Backend: compare expected and actual
                Rank->>Report: append per-rank JSONL result
            end

            Launcher-->>Runner: group exit status
        end
    end

    Runner->>Report: summarize all groups and ranks
    Report-->>Pytest: pass or aggregated failure

不包含派生输入时,每个 case 执行原稿定义的基础六步流水线:

build → reference → distribute → run → gather → compare

配置 derived_inputs 后,在 build 与 reference 之间增加 derive,扩展为七步流程:

build → derive → reference → distribute → run → gather → compare

derive 必须在完整主输入上执行一次,再按声明的 placement 切分;不能在各 rank 的局部分片上重算
依赖全局信息的派生量。七步流程是六步基础模型对 attention 等场景的兼容扩展,不是两套执行架构。

3.4 部署视图
部署组合 launcher Backend 设备/通信
Torch CPU torchrun TorchGlooBackend CPU + gloo
Torch Ascend torchrun TorchHcclBackend Ascend NPU + hccl
MindSpore Ascend msrun MindSporeAscendBackend Ascend NPU + HCCL/通信接口

一台 8 卡节点同时承担两类角色:

  • 控制面:单个 pytest 父进程负责 suite 规划、batch 装箱、设备切片和 launcher 生命周期;
  • 执行面:一个或多个 launcher 分别创建 2/4/8 个 rank,使用互不重叠的设备集合执行 group。

mesh_shape 决定 num_proc,必须满足 num_proc == math.prod(mesh_shape)。对普通算子,mesh 轴名是
文档标签并可按 ndim 归一化;对 needs_mesh=True 的 MC2 算子,轴名参与通信组解析,必须保留真实名称。

3.5 场景视图(+1)
场景 关键机制 预期结果
新增普通算子用例 register(OpShardCase(...)) 自动发现并按 tags/mesh 进入对应 suite
多输出算子 compare_outputs=(...) 只汇聚和比较指定输出,忽略随机或非关注输出
不可确定值 CompareSpec.shape() 只验证 shape 和 dtype,不伪造数值正确性
Attention 派生统计 DerivedSpec 在完整 Q/K 等输入上计算统计量,再切分到各 rank
MC2 算子 needs_mesh、真实 mesh_dim_names case 取得正确通信组,并遵守 launcher 隔离约束
本地复现 CLI 或 HYPER_PARALLEL_SHARD_CASE_FILTER 无需修改 suite 即可只运行单文件或单 case
通信异常 recover_after_failure() 判断进程组是否可继续使用,避免后续 case 产生级联失败

4. 架构模式

模式 在本方案中的体现 目的
Declarative Model / Internal DSL OpShardCaseInputSpecCompareSpec 将“测试什么”与“如何启动和执行”分离
Ports and Adapters ShardBackend 为端口,三个 Backend 为适配器 平台无关核心复用,后端差异受控
Strategy 根据 framework/device_type 选择 Backend,根据 CompareSpec 选择比较策略 避免在执行流程中散布平台判断
Registry register() 和 case/backend 注册表 支持声明式发现和扩展
Pipeline 六步基础模型 + 可选 derive 扩展 固化参考、分布式执行和比较的对称语义
Parent-Worker pytest/Runner 为控制面,launcher/rank 为执行面 隔离进程生命周期、设备环境和分布式状态
Batch Scheduler mesh 分桶、并发槽位和 8 卡首次适应装箱 减少串行 launcher 数并提高设备利用率
Aggregator Reporter 聚合多 rank JSONL 输出单一、可诊断的 suite 结果

5. 架构决策与权衡

5.1 ADR:自定义 Runner 还是 pytest fixture
备选方案 A:纯 pytest conftest + fixture

torchrun/msrun 放在最外层,由 session fixture 初始化通信和 DeviceMesh,使用
pytest_generate_tests/parametrize 驱动全部 case。

优点:

  • 标准 pytest 语义,IDE、coverage、--lf--durations 等生态能力可直接使用;
  • 框架代码更少,开发者学习成本低;
  • 单一 mesh_shape、单 launcher 场景下同样能实现启动复用。

局限:

  • 一个 launcher 的 nproc 固定,无法自动承载混合 2/4/8 卡用例;
  • 多 group 并发、设备切片和装箱需要移到 shell/CI 外部实现;
  • 通信组损坏后的恢复和跨 rank 报告需要额外机制;
  • 现有 CI 需要从普通 pytest 入口改为 launcher 包裹 pytest。
备选方案 B:自定义 Suite + Runner + Entry

普通 pytest 父进程完成分桶、装箱和调度,每个 group 启动独立 torchrun/msrun,rank 进程通过统一 entry
执行声明式 case。

优点:

  • 一次 pytest 调用自动覆盖混合 mesh;
  • 内建 8 卡装箱、设备隔离、通信健康探测和跨 rank 报告;
  • 保持 @arg_mark 门禁入口,CI 无需重构;
  • 对 launcher 数和 suite wall-clock 具有统一优化空间。

代价:

  • 自建框架代码和环境协议更多;
  • case 不是原生 pytest item,部分 pytest/IDE 生态能力不能直接使用;
  • 需要维护调度、超时、进程清理和报告组件。
决策

采用方案 B。当前项目同时存在 2/4/8 卡 case、设备并发调度和通信恢复的真实需求,调度是框架的核心能力,
不能简单外移给 CI。对于只含单一 mesh 的新项目,方案 A 仍然是更轻量的选择。

5.2 其他关键决策
决策点 选择 原因与代价
用例表达 声明式 OpShardCase,而非每个 case 手写流程 消除样板;代价是复杂场景必须设计明确扩展点
参考值生成 完整输入上执行同一 fn 保证单卡/多卡路径对称;要求 fn 尽量保持纯算子语义
派生输入 完整输入预计算后切分 保留全局统计语义;代价是需要额外的 DerivedSpec 模型
门禁路由 case tags + suite tag_include 路由集中可审计;需要维护标签命名约定
mesh 分组 普通算子归一化轴名,MC2 保留真实轴名 减少无意义分桶;对读取通信组名称的算子保留语义
失败策略 level0 fail-fast,level1 收集全部失败 兼顾 PR 反馈速度和日级诊断完整性
特殊硬件限制 solo_launcher 作为隔离逃生口 避免少数 MC2 冲突污染通用调度;代价是增加 launcher 数

6. 设计与交付过程

阶段 主要工作 交付物 / 验证
需求分析 统计旧用例重复、启动次数、门禁路由和跨平台差异 ISSUE 223 背景、目标和硬约束
方案设计 设计声明模型、Backend 端口、执行流水线和进程协议 架构分层、接口定义、时序和目录设计
方案权衡 对比自定义 Runner 与 conftest/fixture ADR,明确采纳理由和已知代价
框架实现 实现 framework 核心及三个 Backend tests/shard_ops/framework/ 和平台适配层
试点验证 选择典型单输出、多输出、attention、MC2 用例 验证扩展点和异常路径
全量迁移 将 Torch/MindSpore 存量 ST 转为声明式 case 248 个 Torch case、238 个 MindSpore case
性能调优 合并 launcher、mesh 分桶、8 卡装箱、轴名归一化 减少串行 batch 和 suite wall-clock
验收交付 三后端 level0/level1 回归、门禁和文档 PR 857 合入,pr-check-passci-pipeline-passed

这套过程体现了“问题与约束识别 → 质量属性定义 → 多方案权衡 → 架构设计 → 试点 → 全量迁移 →
量化验证 → 门禁交付”的架构设计和交付闭环。


7. 风险与缓解

风险 缓解措施
placement 元组与 mesh 维数不匹配 注册时校验;文档明确“每个 mesh 轴一个 placement”
num_proc 与 mesh 大小不一致导致 HCCL 挂起 由 mesh_shape 推导并在 CLI/Runner 边界校验
用例发现阶段加载平台 case 增加收集成本 平台无关核心不直接依赖后端;控制 case package 的导入边界,必要时演进为元数据扫描
不同 rank 执行 case 顺序不一致 group 使用统一 case 清单和确定性排序
通信异常污染后续 case 非断言失败后执行健康探测,必要时终止当前 group
派生输入在分片上重算导致语义错误 DerivedSpec 强制在完整输入上计算一次后再切分
多个高卡 MC2 共用 launcher 触发 CANN 限制 保留真实 mesh 轴名,限制同组数量,必要时 solo_launcher=True
声明模型扩展过度 只有可复用且具备明确语义的场景才新增字段,特殊逻辑优先留在 case fn
自定义框架维护成本高 用 ADR 明确适用边界,核心模块保持单一职责,并提供 CLI/实践指南

8. 接口与执行规范

8.1 最小用例
import torch

from hyper_parallel.core.dtensor.placement_types import Replicate, Shard
from tests.shard_ops.framework import CompareSpec, InputSpec, OpShardCase, register


def _cat_dim1(x, y):
    return torch.cat((x, y), dim=1)


register(OpShardCase(
    name="cat_ops_dp_dim1",
    fn=_cat_dim1,
    inputs=[
        InputSpec(shape=(8, 16), init="randn", seed=42),
        InputSpec(shape=(8, 8), init="randn", seed=43),
    ],
    placements=[
        (Shard(0), Replicate()),
        (Shard(0), Replicate()),
    ],
    compare=CompareSpec.allclose(rtol=1e-4, atol=1e-4),
    mesh_shape=(2, 2),
    mesh_dim_names=("dp", "tp"),
    tags=("cpu_level0", "npu_level0"),
))
8.2 InputSpec 字段
字段 默认值 说明
shape 必填 张量维度;空 tuple () 表示标量张量
init "randn" randn / uniform / ones / zeros / arange
seed None 随机种子,用于确定性构造输入
dtype "float32" 平台无关 dtype 名
data None np.ndarray 精确值,设置后覆盖 init
8.3 平台抽象接口

ShardBackend 定义统一端口,各后端独立实现:

接口 Torch(hccl) Torch(gloo) MindSpore(Ascend)
maybe_init_dist() init_dist() init_dist_gloo() D.init() + ms.set_device("Ascend")
make_tensor(spec) torch.from_numpy().npu() torch.from_numpy() Tensor(arr)
distribute(...) distribute_tensor() 同左 distribute_tensor()
local_to_global(...) local_to_global() 同左 dist_tensor.full_tensor()
assert_close(...) torch.equal/allclose 同左 np.array_equal/allclose
recover_after_failure() dist.barrier() 同左 comm_func.all_reduce
8.4 Placement 约定

placement 元组长度必须等于 mesh 维数,而不是张量维数:

# 4-D tensor on a 2-D mesh (dp, tp)
mesh_shape = (2, 2)
placements = [(Shard(0), Shard(1))]

# 2-D tensor on a 1-D mesh (tp)
mesh_shape = (2,)
placements = [(Shard(1),)]
8.5 门禁路由
标签 入口 语义
cpu_level0 Torch CPU level0 PR 快速门禁,fail-fast
npu_level0 Torch/MS NPU level0 PR 快速门禁,fail-fast
cpu_level1 Torch CPU level1 扩展回归,收集全部失败
npu_level1 Torch/MS NPU level1 扩展回归,收集全部失败

tag 采用 {platform}_{level} 约定:

tags=("cpu_level0", "npu_level0")   # CPU/NPU 均进入 level0
tags=("cpu_level0", "npu_level1")   # 不同硬件进入不同等级
tags=("npu_level0",)                 # 仅 NPU

suite entry 通过 tag_include 进行单一入口过滤,再使用 @arg_mark 对接现有 CI:

_GROUPS_CPU_LEVEL0 = build_suite_groups(
    cases_pkg=CASES_PKG,
    tag_include={"cpu_level0"},
    fail_fast=True,
)


@arg_mark(
    plat_marks=["cpu_linux"],
    level_mark="level0",
    card_mark="allcards",
    essential_mark="essential",
)
def test_shard_ops_cpu_level0():
    _run_groups(_GROUPS_CPU_LEVEL0, "torch", "cpu", fail_fast=True)
8.6 8 卡并发调度
  • _plan_group_countglobal_num_proc // num_proc 计算并发槽位;4 卡 case 最多两路并发;
  • _pack_into_batchesnum_proc 降序,以 first-fit 方式装箱到 8 卡 batch;
  • 同一 batch 内的 group 由 mp.Process 并行启动,并分配互不重叠的设备切片;
  • max_cases_per_group=256 控制单组容量、避免过度碎片化;实际 group 数还会根据并发槽位规划;
  • 2/4/8 卡 group 分别按 batch 执行,墙钟时间主要由串行 batch 数和 launcher 初始化成本决定。
8.7 子进程执行流程

基础六步模型:

1. build_numpy(spec) → make_tensor
2. fn(*full_tensors) → expected
3. distribute(tensor, mesh, placements) → dist_inputs
4. fn(*dist_inputs) → actual
5. local_to_global(actual) → gathered
6. assert_close(expected, gathered)

配置 derived_inputs 时,在第 1、2 步之间增加 derive:在完整主输入上计算派生值,再分别供参考路径使用
并按 placement 切分到分布式路径。

8.8 本地运行
# CLI:运行文件内全部 case
python -m tests.shard_ops.framework tests/torch/shard/ops/cases/case_sort.py

# CLI:运行文件内单个 case
python -m tests.shard_ops.framework \
  tests/torch/shard/ops/cases/case_sort.py::sort_ops_2d_dp

# CLI:显式切换框架
python -m tests.shard_ops.framework --framework mindspore --case sort_ops_2d_dp

# Suite entry + 环境变量过滤
HYPER_PARALLEL_SHARD_CASE_FILTER="sort_ops_*" \
  pytest tests/torch/shard/ops/test_shard_ops_suite.py::test_shard_ops_cpu_level0 -vs

完整字段、特殊场景和排错说明见
OpShardCase 介绍与实践指导


9. 验收结果

9.1 功能与迁移
  • 声明式用例模型:OpShardCase + InputSpec + CompareSpec + register()
  • 平台无关核心与 Torch/MindSpore 后端适配分层;
  • Torch CPU、Torch Ascend、MindSpore Ascend 三后端;
  • 2/4/8 卡混合 mesh 自动分桶和 8 卡并发规划;
  • tags 门禁路由、CLI 和环境变量过滤;
  • derived_inputscompare_outputsneeds_meshsolo_launcher 等扩展场景;
  • 248 个 Torch case、238 个 MindSpore case 完成迁移。

迁移覆盖 elementwise、reduce、view、index、embedding、matmul、softmax、attention、MC2,以及
DFunction DSA/MHC 等算子。确认属于 CANN/ACLNN 层且无法在 HyperParallel 测试框架内解决的问题,
单独记录为 D 类问题,不通过放宽断言或静默跳过掩盖。

9.2 回归与性能

PR 857 记录的六组回归结果:

套件 level0 level1
Torch CPU(gloo) 48.7s 72.4s
Torch NPU(hccl) 58.8s 86.2s
MindSpore NPU 70.8s 302.0s

level0 与旧框架代表用例对比:

后端 旧框架 新框架
Torch CPU 6 个用例 122s 201 个用例 48.7s
Torch NPU 6 个用例 158s 201 个用例 58.8s
MindSpore NPU 6 个用例 295s 105 个用例 70.8s

性能收益主要来自 launcher 启动合并和设备调度,而不是单个算子计算加速。评估时必须同时说明用例数量、
后端环境和 wall-clock,不能将两组数据误写成同规模 benchmark。

9.3 交付状态
  • 架构方案经过 Maintainer 评审;
  • 存量用例与新框架随 PR 857 一并交付;
  • 六组后端/等级回归通过;
  • pr-check-pass
  • ci-pipeline-passed
  • PR 857 已合入主干。

10. 影响范围

  • 新增平台无关核心tests/shard_ops/framework/ 11 个文件;
  • 新增后端适配:Torch、MindSpore framework/ 共 4 个文件;
  • 迁移用例:Torch 248 个、MindSpore 238 个声明式 case;
  • 新增本地入口python -m tests.shard_ops.framework
  • 新增过滤接口HYPER_PARALLEL_SHARD_CASE_FILTER
  • 新增扩展能力derived_inputsCompareSpec.shape()compare_outputsneeds_mesh
    solo_launcher 和非 MC2 mesh 轴名归一化;
  • 兼容性:PR 857 采用增量交付,旧 _test_parallel_op_*.py 文件未在该 PR 中破坏性删除;
  • 外部接口:不涉及 HyperParallel 用户态算子 API 变更。

11. 总结

本次重构将分布式算子 ST 从分散的 launcher/worker 脚本集合,演进为声明式测试平台:

  • 用例层聚焦测试意图;
  • Backend 层隔离平台差异;
  • Suite/Runner 层承担混合 mesh 和设备资源调度;
  • Entry 层保证单卡参考与多卡执行的对称语义;
  • Reporter 层统一多 rank 结果和失败诊断。

该架构以更多框架代码换取跨平台复用、自动调度、通信恢复和可量化的执行效率。ADR 明确了这一选择的
适用边界:HyperParallel 当前复杂的混合 mesh 和门禁场景需要自定义调度;对于单一 mesh、无设备并发
需求的新项目,应优先评估更轻量的 pytest fixture 方案。

schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 223
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/223

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the proposed tests/shard_ops/framework/ layout, especially case_spec.py, registry.py, suite.py, runner.py, entry.py, reporter.py, and cli.py, then compare it with the Torch and MindSpore suite entry points and backend adapters. Done means the declaration, discovery, scheduling, execution, reporting, CLI, and migration requirements described here are implemented and validated across the listed backends and gate levels.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools, distributed-systems, testing-qa
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.