mcpField
M
mcore-testing

mcore-testing

github.com/promptingcompany测试与质量039 次安装17 周前更新
代码仓库

关于 mcore-testing

mcore-testing 是面向 Megatron Core 开发者的测试指南,说明单元测试和功能测试的运行方式、CI 配方、易失败测试处理,以及添加或停用测试的方法。

主要功能

  1. 01单元与功能测试目录说明
  2. 02分布式单元测试命令
  3. 03CI 配方配置
  4. 04易失败测试标记与重试行为
  5. 05添加或停用测试的指引

适用场景

  1. 01在本地跨 GPU 运行单元测试
  2. 02复现 CI 测试分组故障
  3. 03保留配方并暂时停用易失败测试
  4. 04添加功能测试和黄金值

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/promptingcompany/nv-skills --skill mcore-testing

安装后在 Claude Code 中输入/mcore-testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

BENCHMARK.md
skill-card.md
skill.oms.sig
evals/
evals.json

详细介绍

测试指南


测试事实速览

关于如何禁用测试而不删除测试的问题:

  • 功能测试配方条目保留在 YAML 中;在 scope 后添加 -broken 即可禁用,例如 scope: [mr-github] -> scope: [mr-github-broken]。
  • 单元测试使用 pytest 标记来跳过:@pytest.mark.flaky_in_dev 会在默认开发环境中跳过,@pytest.mark.flaky 会在 LTS 中跳过。
  • 如果目的是让测试易于发现并方便重新启用,请勿删除测试用例或配方条目。

测试目录结构

tests/
├── unit_tests/          # pytest, 1 node × 8 GPUs, torch.distributed runner
├── functional_tests/    # end-to-end shell + training scripts
│   └── test_cases/
│       └── {model}/{test_case}/
│           ├── model_config.yaml          # training args
│           └── golden_values_{env}_{platform}.json
└── test_utils/
    ├── recipes/
    │   ├── h100/        # YAML recipes for H100 jobs
    │   └── gb200/       # YAML recipes for GB200 jobs
    └── python_scripts/  # helpers (recipe_parser, golden-value download, …)

测试执行方式

GitHub Actions runner 会调用 launch_nemo_run_workload.py,该脚本使用 nemo-run 启动 DockerExecutor 容器。仓库挂载到 /opt/megatron-lm;训练数据挂载到 /mnt/artifacts。

单元测试通过 torch.distributed.run 分发:

  • Ranks 0 和 3 的输出会转发到 stdout;其他所有 ranks 只写入日志文件。
  • 每个 rank 的日志文件会存放在 {assets_dir}/logs/1/,并在运行结束后作为 GitHub artifact 上传。

功能测试由 tests/functional_tests/shell_test_utils/run_ci_test.sh 驱动。只有 rank 0 会运行 pytest 验证步骤;所有 ranks 的训练输出都会作为 artifact 上传。

不稳定失败自动重试:对于已知的瞬时错误模式(NCCL 超时、ECC 错误、段错误、HuggingFace 连接问题等),launch_nemo_run_workload.py 最多重试 3 次,然后才会判定为真正失败。


配方 YAML 结构

配方位于 tests/test_utils/recipes/,由 tests/test_utils/python_scripts/recipe_parser.py 解析。每个文件会将笛卡尔积 products 块展开为多个工作负载规格:

type: basic
format_version: 1
maintainers: [mcore]
loggers: [stdout]
spec:
  name: "{test_case}_{environment}_{platforms}"
  model: gpt              # maps to tests/functional_tests/test_cases/{model}/
  build: mcore-pyt-{environment}
  nodes: 1
  gpus: 8
  n_repeat: 5
  platforms: dgx_h100
  time_limit: 1800
  script_setup: |
    ...
  script: |-
    bash tests/functional_tests/shell_test_utils/run_ci_test.sh ...
products:
  - test_case: [my_test]
    products:
      - environment: [dev, lts]
        scope: [mr-github]
        platforms: [dgx_h100]

关键运行时占位符:{assets_dir}、{artifacts_dir}、{test_case}、{environment}、{platforms}、{n_repeat}。

禁用测试而不删除

若要在配方 YAML 中临时禁用某个测试用例,请在其 scope 值后添加 -broken——请勿删除该条目:

# before (test runs in CI)
scope: [mr-github]

# after (test is skipped; entry preserved for easy re-enable)
scope: [mr-github-broken]

在本地运行单元测试

所有单元测试都会初始化 torch.distributed 进程组,因此每次运行都需要 GPU 访问权限,并且必须通过 torch.distributed.run 执行:

# Full suite
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests

# Single file
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests/models/test_gpt_model.py

# Single test
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests/models/test_gpt_model.py::TestGPTModel::test_constructor

# Filter by name substring
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests -k optimizer
标记筛选器
# Exclude flaky tests during development
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests -m "not flaky and not flaky_in_dev"

# Include experimental tests
uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q \
  tests/unit_tests --experimental
与 CI 保持一致

使用 tests/unit_tests/run_ci_test.sh 精确复现 CI 分桶失败。对于临时运行,优先使用上述直接调用 torch.distributed.run 的命令。

注意事项
  • pyproject.toml 设置了 addopts = --durations=15 -s -rA——stdout 不会被捕获(-s),因此多 rank 运行时各 rank 的输出会交错。调试特定 rank 时,可用 --capture=fd 覆盖此设置。
  • tests/unit_tests/conftest.py 会在 /opt/data 下查找测试数据,若缺失则尝试下载。在规范容器之外运行时,请手动提供数据,或跳过依赖数据的测试。

添加单元测试

  1. 创建 tests/unit_tests/<category>/test_<name>.py。
  2. 使用 tests/unit_tests/conftest.py 中的 fixtures。
  3. 根据需要应用标记:
    • @pytest.mark.internal — 在 legacy 标签下跳过
    • @pytest.mark.flaky_in_dev — 在 dev 环境中跳过(CI 默认环境;使用此标记可禁用不稳定测试,同时不阻塞标准流水线)
    • @pytest.mark.flaky — 在 lts 环境中跳过
    • @pytest.mark.experimental — 仅适用于 latest 标签
  4. 在本地验证(参见上文“在本地运行单元测试”)。
  5. 如果测试需要专用 CI 分桶,请在 tests/test_utils/recipes/h100/unit-tests.yaml 中添加一个条目。

添加功能/集成测试

  1. 创建 tests/functional_tests/test_cases/<model>/<test_name>/。

  2. 编写 model_config.yaml,包含 MODEL_ARGS、ENV_VARS 和 TEST_TYPE。

  3. 在 tests/test_utils/recipes/h100/ 下添加 YAML 配方(如有需要,也在 gb200/ 下添加)。必填字段:scope、environment、platform、n_repeat、 time_limit。

  4. 推送 PR,添加标签 "Run functional tests" 以触发完整运行。

  5. 成功运行后,下载黄金值:

    python tests/test_utils/python_scripts/download_golden_values.py \
      --source github --pipeline-id <run-id>
    
  6. 提交下载的黄金值。


常见问题

问题原因修复方法
测试在本地通过,但在 CI 中失败环境或数据路径不同检查 DATA_PATH、DATA_CACHE_PATH 和 environment 标签(dev 与 lts)
代码更改后黄金值不匹配数值回归在干净运行后,通过 download_golden_values.py 下载新的黄金值
未触发 cicd-integration-tests-gb200GB200 作业要求维护者身份请维护者触发,或添加 Run functional tests 标签

评论

支持 Markdown