已开启
# 【RFC】分布式算子 ST 测试架构重构 #223
hedongdong创建于  6月16日
hedongdong成员
6月16日 创建

【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_inputs、needs_mesh、solo_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 必须由 torchrun 或 msrun 创建多个独立 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 OpShardCase、InputSpec、CompareSpec 将“测试什么”与“如何启动和执行”分离
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-pass 与 ci-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_count 按 global_num_proc // num_proc 计算并发槽位;4 卡 case 最多两路并发;
  • _pack_into_batches 按 num_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 功能与迁移

迁移覆盖 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 交付状态


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_inputs、CompareSpec.shape()、compare_outputs、needs_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 方案。

likedislike
Hhedongdong成员
6月16日 修改了issue 的描述
Hhedongdong成员
6月16日 修改了issue 的描述
Hhedongdong成员
6月16日 修改了issue 的描述
Hhedongdong成员
6月16日 修改标题为 “【RFC】shard_ops 分布式算子测试框架重构”,原标题为“shard_ops 分布式算子测试框架重构”
Hhedongdong成员
6月16日 修改了issue 的描述
Hhedongdong成员
6月16日 修改了issue 的描述
Hhedongdong成员
6月17日 修改了issue 的描述
Hhedongdong成员
6月21日 修改了issue 的描述
Hhedongdong成员
6月21日 修改了issue 的描述
Hhedongdong成员
6月21日 关联了pull request:test: gate fail-fast and error reporting validation for #223
rongyuerongyue
6月23日 关联了pull request:feat: migrate getitem and setitem ST to new declarative case scheme
Hhedongdong成员
6月24日 关联了pull request:test(shard-ops): finalize OpShardCase migration, remove legacy ST tests
rongyuerongyue
6月25日 关联了pull request:chore: demote 83 npu_level0 cases to level1 to reduce ST timeout
rongyuerongyue
6月26日 关联了pull request:chore: revert npu_level0 demotion and demote test_submesh_group1
Hhedongdong成员
7月2日 关联了pull request:test(shard-ops): finalize OpShardCase migration, remove legacy ST tests
rongyuerongyue
7月2日 关联了pull request:test: mark submesh case as level1
Hhedongdong成员
8月22日 修改标题为 “# 【RFC】分布式算子 ST 测试架构重构”,原标题为“【RFC】shard_ops 分布式算子测试框架重构”
Hhedongdong成员
8月22日 修改了issue 的描述
Hhedongdong成员
8月22日 修改了issue 的描述