定时与按需测试#
除了针对每个 PR 的检查外,FlagGems 还会按计划运行更大范围的测试, 以捕获那些只在全量算子测试或某个 PR 未涉及的厂商后端上才会暴露的回归问题。
daily.yaml — NVIDIA 平台全量回归测试#
触发条件: cron 表达式 3 16 * * *(每天北京时间 00:03);此外支持手动
触发(workflow_dispatch)。
在 NVIDIA runner 上运行完整的算子测试套件(而非仅测试变更的算子):
cpp-op—— 完整的 C++ 扩展测试套件。python-op—— 以CHANGED_FILES=__ALL__运行tools/test-op.sh, 该设置会展开为tests/test*.py下的所有测试文件。同时收集覆盖率数据 并作为op-ut-coverage构件(artifact)上传。examples—— 对所有示例/模型测试运行tools/test-examples.sh。
coverage.yaml — 将覆盖率发布到文档站点#
触发条件: daily 工作流执行完成后触发(workflow_run);此外支持手动
触发(workflow_dispatch),需提供 run_id 参数。
下载 daily.yaml 生成的 op-ut-coverage 构件,解压 HTML 覆盖率报告和
汇总 markdown 文件,将其提交到 docs/static/coverage/<date> 和
docs/content/en/references/test/unit/ 目录下,并直接推送到 gh-pages
分支。hugo-site.yaml 随后会响应该推送,重新构建并发布站点。
ops-test.yaml —— 多厂商 QA 验收测试#
触发条件: 仅支持手动触发(workflow_dispatch),可选参数包括
branch、vendors、ops、upload_log、send_feishu。该工作流不使用
GitHub Actions 原生的 schedule 触发器——因为在负载较高时,原生定时触发
曾出现延迟甚至丢失运行的情况(延迟 1-5 小时),这对于 GPU 测试的调度而言
是不可接受的。取而代之的方案是:在一台常驻运行的控制面服务器上部署
.github/scripts/trigger_workflow.sh 作为 crontab 任务,默认按
30 21 * * 3,6(每周三、周六北京时间 21:30)的节奏调用 GitHub API 来
触发本工作流,实际的 runner 分配和执行仍由 GitHub 完成。该脚本在失败时
会自动重试,并在重试前检查是否已有重复运行,以避免重复触发。
针对所有已启用的厂商后端运行完整(或经过筛选)的算子测试套件,用于 QA
验收测试——既可以是通过外部调度脚本发起的定期全量测试,也可以是发布前
针对指定分支/厂商/算子手动发起的测试。prepare 作业会解析代码检出引用
(默认为 master),并基于 .github/configs/backends/config.yaml 以及
每个后端对应的独立 YAML 文件构建后端矩阵,根据 vendors 输入参数进行
筛选(不区分大小写,留空表示所有已启用的厂商);ops 输入参数同样用于
将测试范围缩小到指定算子(留空则通过 --stages all 运行全部测试阶段)。
各后端按两种执行方式划分:
- 基于容器(
test-container) —— 在后端对应的 Docker 镜像内运行, 适用于以容器形式分发 SDK 的厂商。作业超时时间为 1440 分钟(24 小时), 以适配耗时最长的厂商测试(例如 Ascend 910B)。 - 原生运行(
test-native) —— 直接在自托管 runner 上运行,不使用 容器,作业超时时间为 1080 分钟(18 小时)。
矩阵中的每个作业最多尝试检出代码 3 次(首次失败后最多重试 2 次,
每次重试前等待 30 秒),随后安装
FlagGems、检查 GPU 可用性、运行 tools/run_tests.py(通过 --ops 或
--stages all 参数控制测试范围)、使用
add_labels/psum_text/psum_html 汇总结果,并将结果打包为每个厂商
对应的压缩包;除非通过 upload_log/send_feishu 输入参数禁用,还会将
压缩包上传到内部 op-monitor 服务,并发送包含结果的飞书通知。
手动触发的辅助工作流#
以下工作流只有 workflow_dispatch 触发器,需要在 Actions 页面点击
Run workflow,或通过 gh workflow run 手动运行。
random-test.yaml —— 在指定 runner 上测试指定算子#
触发方式: workflow_dispatch,包含三个必填输入:
| 输入 | 含义 | 示例 |
|---|---|---|
runner | 运行所用的 runner 标签 | a100、h100、h20、ascend、cann9、metax、maca381、enflame、cambricon |
operators | 以逗号分隔的算子名 | add,mul,softmax |
gpus | 以逗号分隔的 GPU 编号 | 0,1 |
gh workflow run random-test.yaml \
-f runner=a100 -f operators=add,mul,softmax -f gpus=0,1check-permission 作业会先检查触发者是否属于 FlagGems 团队,不属于则跳过
测试作业。随后 test-operator 作业把 runner 标签映射为厂商和 backend
profile(例如 a100/h100/h20 → nvidia-cuda133,ascend/cann9 →
ascend-cann900;标签未知时直接用标签本身作为两者的值),检出代码,运行对应
厂商的 GPU 检查脚本和 setup-flaggems,再执行
tools/run_tests.py --ops <operators> --gpus <gpus>。results/ 目录会作为
名为 random-test 的构件上传。
operators 和 gpus 会直接拼接到命令行,因此其中不要带空格。如需在本地复现,
可直接运行 tools/run_tests.py。
probe-node.yaml —— 探测自托管 runner 的环境#
触发方式: workflow_dispatch,有一个必填输入 runner(runner 标签,
默认 h100)。
收集自托管 runner 的环境信息,用于为其选择合适的 backend profile(例如
nvidia-cuda133 还是 nvidia-cuda128)。它只要求 runner 上有 bash,也不会
检出仓库。输出内容包括:
- 系统与 Python:
uname -a、python3 --version - 容器 / 虚拟化:
/.dockerenv、/proc/1/cgroup、systemd-detect-virt、 PID 1 - 内存:
free -h以及 cgroup 内存上限 - GPU:
nvidia-smi,以及每张卡的显存总量 / 已用 / 空闲 - CUDA 工具链:
nvcc --version和/usr/local/cuda*
输出会写入作业日志和该次运行的 Summary 页面($GITHUB_STEP_SUMMARY)。
该探测是只读的,且没有团队成员权限检查。GPU 与 CUDA 相关探测仅针对 NVIDIA;
在其他厂商的机器上这些项会显示 "not found",其余部分仍然有效。
review-stats.yaml —— 拉取请求分析报告#
触发方式: workflow_dispatch,有两个可选输入 report_date_start 和
report_date_end,格式均为 dd/MM/YYYY。
在 ubuntu-latest 上运行,使用
AlexSim93/pull-request-analytics-action
统计 flagos-ai/FlagGems 在给定日期范围内的拉取请求数据(评审响应时间、活跃度
等指标)。工作时间配置为 Asia/Shanghai 时区的 9:00–23:00。报告会以 issue
的形式创建在 flagos-ai/FlagGems 仓库中,因此该作业需要 issues: write
权限(以及对 contents、pull requests、statuses 的读权限)。
gh workflow run review-stats.yaml \
-f report_date_start=01/09/2026 -f report_date_end=30/09/2026由评论触发的 PR 命令#
command.yaml(/test <算子名>:<runner>)和 fix-sort.yaml(/fix-sort)
是通过在 PR 下评论启动的,而非 workflow_dispatch 或定时触发,因此它们与各自
配合的检查一并记录在拉取请求检查中。
飞书与监控集成#
ci-report-feishu.yaml会将每一次rule-check的执行结果上报到飞书 多维表格(Bitable),用于跟踪长期的通过/失败趋势。它由workflow_run(而非pull_request)触发,因此在基础仓库上下文中执行,即使是来自 fork 的 PR 也能拿到密钥;该运行本身只需要tools/ci_report_feishu.py和令牌, 所以采用只检出该路径的稀疏检出。由于 GitHub API 可能滞后于已完成的工作流, 脚本会先等待 5 秒,再以 10 秒 / 20 秒的退避最多重试 3 次。它在 PR 流程中的 作用见拉取请求检查。ops-test.yaml和command.yaml的失败处理路径会通过.github/scripts/notify_feishu.py发送飞书群消息通知。ops-test.yaml还会将结果上传到内部的 "op-monitor" HTTP 服务,用于 生成长期监控看板。
这些均属于可观测性(observability)相关的工作流,并不会阻塞 PR 的合并。