Prhub

#26619 [CI] ci-coverage-overview: schedule + manual only, include XPU/MUSA/multimodal_gen

原始 PR 作者 alisonshao 合并时间 2026-05-30 16:39 文件变更 3 提交数 4 评论 2 代码增减 +205 / -29

执行摘要

优化 CI 覆盖率报告触发与覆盖范围,新增 XPU/MUSA 和多模态测试

随着测试注册框架迁移,大量测试文件移入 test/registered/,导致 CI 覆盖率报告被大量不相关的 PR 触发。同时,XPU 测试在报告中不可见,MUSA 缺乏基础注册支持,多模态生成测试因使用独立运行框架被完全忽略。本 PR 旨在优化触发策略、统一后端列表、添加缺失的测试覆盖,以提供更准确的每日覆盖率快照。

建议合入本 PR。基础设施改进,通过断言保障可维护性,启发式规则有告警机制,风险可控。后续可继续减少 CPU 测试数量或迁移更多测试至注册框架。

讨论亮点

本 PR 无实质 review 讨论。作者在 PR body 中细致说明了变更背景和验证结果(本地运行和 workflow_dispatch 效果),并明确列出了未涉及的范围(HPU、MPS、RVV、SMG、Xeon)以及可能的后续工作(减少 CPU 测试数量)。

实现拆解

  1. 触发频率优化:在 ci-coverage-overview.yml 中移除 pull_request 触发器,仅保留 schedule(每日 6 AM UTC)和 workflow_dispatch 手动触发。同时删除作业级别的 if: github.event_name != 'pull_request' 条件判断。

  2. 统一后端列表:在 ci_coverage_report.py 中定义 BACKEND_DISPLAY_ORDER 常量,包含所有 HWBackend 成员(CUDA、AMD、NPU、CPU、XPU、MUSA)并加断言确保同步,替换原来五处硬编码的列表。新增的 MUSA 后端在 ci_register.py 中添加 HWBackend.MUSA 枚举成员和 register_musa_ci 标记函数,并更新 REGISTER_MAPPING

  3. 多模态测试集成:实现 collect_multimodal_gen_tests 函数,通过解析 python/sglang/multimodal_gen/test/ 目录下的文件路径和文件名 token 规则,挂载仿真 CIRegistry 记录,使多模态生成测试(约 53 个文件)出现在覆盖率报告中。规则默认按子目录分配后端(如 server/ → CUDA+AMD,server/musa/ → MUSA),同时支持文件名 token 覆盖(musanpu),并过滤无测试函数的管理文件。

  4. 修复 CI 作业依赖:由于 unit-test-coverage 作业需要 Rust 工具链来构建原生 gRPC 扩展,但运行镜像默认没有,导致定时运行一直失败。在作业中添加安装 Rust 和 protoc 的步骤,使用与 ci_install_dependency.sh 相同的安装脚本。

文件 模块 状态 重要度
scripts/ci/utils/ci_coverage_report.py CI 脚本 modified 6.47
python/sglang/test/ci/ci_register.py CI 注册 modified 5.22
.github/workflows/ci-coverage-overview.yml CI 工作流 modified 4.14

关键符号

collect_multimodal_gen_tests register_musa_ci

关键源码片段

scripts/ci/utils/ci_coverage_report.py infrastructure

核心变更文件,包含后端列表统一、多模态测试分类逻辑,以及报告生成的核心改动。

# Display order for backend tables / sections.
# 源从 HWBackend 取,通过断言确保同步
BACKEND_DISPLAY_ORDER = ("CUDA", "AMD", "NPU", "CPU", "XPU", "MUSA")
assert set(BACKEND_DISPLAY_ORDER) == {
    b.name for b in HWBackend
}, "BACKEND_DISPLAY_ORDER is out of sync with HWBackend"# multimodal_gen 测试分类规则
MULTIMODAL_GEN_TEST_DIR = "python/sglang/multimodal_gen/test"# 子目录默认后端映射
_MM_GEN_SUBDIR_BACKENDS = {
    "": ("CUDA",), # 顶级
    "server": ("CUDA", "AMD"),
    "server/musa": ("MUSA",),
    "server/ascend": ("NPU",),
    "layers": ("CUDA",),
    "unit": ("CUDA",),
    "cli": ("CUDA",),
    "manual": ("CUDA",),
}# 文件名 token 后端覆盖(musa、npu 标记)
_MM_GEN_FILENAME_BACKEND_TOKENS = {
    "musa": ("MUSA",),
    "npu": ("NPU",),
}def collect_multimodal_gen_tests(
    mm_gen_dir: str,
) -> list[CIRegistry]:
    """扫描 multimodal_gen 测试目录,合成 CIRegistry 记录。"""
    if not mm_gen_dir or not os.path.isdir(mm_gen_dir):
        return []
    results = []
    for root, dirs, files in os.walk(mm_gen_dir):
        for f in files:
            if not f.startswith("test_") or not f.endswith(".py"):
                continue
            if f in _MM_GEN_HELPER_FILENAMES:
                continue
            full = os.path.join(root, f)
            rel = os.path.relpath(full, mm_gen_dir)
            subdir = os.path.dirname(rel)
            stem = os.path.splitext(f)[0]
            tokens = set(stem.split("_"))
            # token 覆盖优先
            backends = None
            for token, b in _MM_GEN_FILENAME_BACKEND_TOKENS.items():
                if token in tokens:
                    backends = b
                    break
            if backends is None:
                # 子目录默认
                backends = _MM_GEN_SUBDIR_BACKENDS.get(subdir, ("CUDA",))
            for backend_name in backends:
                backend = HWBackend[backend_name]
                # 判定 nightly
                nightly = "nightly" in tokens
                results.append(
                    CIRegistry(
                        backend=backend,
                        filename=full,
                        est_time=1.0,
                        nightly=nightly,
                        suite="unit-test-generated",
                    )
                )
    return results
python/sglang/test/ci/ci_register.py test-coverage

添加 MUSA 后端支持,包括 HWBackend.MUSA、register_musa_ci 和 REGISTER_MAPPING 更新。

# HWBackend 新增 MUSA 成员
class HWBackend(Enum):
    CPU = auto()
    CUDA = auto()
    AMD = auto()
    NPU = auto()
    XPU = auto()
    MUSA = auto() # 新增 MUSA 后端# register_musa_ci 函数,作为 AST 标记,运行时 no-op
def register_musa_ci(
    est_time: float,
    suite: Optional[str] = None,
    nightly: bool = False,
    disabled: Optional[str] = None,
    *,
    stage: Optional[str] = None,
    runner_config: Optional[str] = None,
):
    """Marker for MUSA CI registration (parsed via AST; runtime no-op)."""
    return None# 更新 REGISTER_MAPPING
REGISTER_MAPPING = {
    "register_cpu_ci": HWBackend.CPU,
    "register_cuda_ci": HWBackend.CUDA,
    "register_amd_ci": HWBackend.AMD,
    "register_npu_ci": HWBackend.NPU,
    "register_xpu_ci": HWBackend.XPU,
    "register_musa_ci": HWBackend.MUSA, # 新增映射
}

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

风险较低。主要变更集中在 CI 机械配置,不涉及核心推理或调度逻辑。潜在风险包括:1)BACKEND_DISPLAY_ORDER 断言在添加新后端时若忘记更新会阻止报告生成(已通过断言主动告警);2)多模态测试分类启发式规则可能漂移(已设计 stderr 警告);3)Rust 工具链安装可能失败(已使用 CI 通用脚本)。

对 SGLang 用户无影响。对 CI 系统:减少不必要的覆盖率报告运行(之前 20 次全部是 PR 触发),节省 runner 资源。对开发者:覆盖率报告现在更准确地反映测试覆盖,包括之前缺失的 XPU(5 个)、MUSA(5 个)和多模态生成测试(52 个),有利于识别测试盲区。

CI 配置变更 多模态分类启发式 断言可能导致报告失败

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论