К основному содержанию
скилл CX Codex

mcore-testing — скилл для Claude Code: тесты Megatron-LM

Скилл объясняет тестовую систему Megatron-LM: раскладку тестов, рецепты YAML, golden values и запуск unit-тестов локально.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add NVIDIA/skills --skill mcore-testing -a claude-code
Открыть на GitHub

Что делает mcore-testing

Скилл описывает, как устроено тестирование в Megatron-LM, и отвечает на вопросы вида «как добавить тест», «pytest падает», «где лежат golden values». Внутри — раскладка каталога tests/, структура recipe YAML, порядок добавления unit- и functional-тестов, маркеры pytest и воспроизведение сбоя CI локально.

Unit-тесты идут через torch.distributed.run, поэтому для любого запуска нужен доступ к GPU. Например, полный прогон выглядит так: uv run python -m torch.distributed.run --nproc-per-node 8 -m pytest -q tests/unit_tests. Отдельные тесты фильтруются по имени через -k или по маркерам: -m "not flaky and not flaky_in_dev". Для точного повторения сбоя из CI есть tests/unit_tests/run_ci_test.sh.

Functional-тесты живут в tests/functional_tests/test_cases/{model}/{test_case}/ и требуют model_config.yaml плюс запись в recipe YAML. После успешного прогона golden values скачивают скриптом download_golden_values.py и коммитят. Учтите: conftest.py ищет тестовые данные в /opt/data и пытается их докачать, если их нет — вне канонического контейнера данные придётся положить самому или пропустить зависящие от них тесты.

Какие задачи решает

  • разобраться в раскладке каталога tests/ и понять, куда класть новый тест
  • написать recipe YAML для functional-теста и не забыть обязательные поля
  • воспроизвести падение CI-бакета локально
  • скачать и закоммитить golden values после успешного прогона
  • отключить флейки-тест, не удаляя его из рецепта

Примеры запросов агенту

  • как добавить unit-тест в tests/unit_tests?
  • pytest падает на тесте модели, помоги воспроизвести локально
  • напиши recipe YAML для нового functional-теста

Как установить mcore-testing

1Через Skills CLI (Vercel)

npx skills add NVIDIA/skills --skill mcore-testing -a claude-code

2Вручную: положить файлы

~/.claude/skills/mcore-testing/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/mcore-testing/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о mcore-testing

Как установить mcore-testing в Claude?

Выполните npx skills add NVIDIA/skills --skill mcore-testing -a claude-code. Скилл окажется в ~/.claude/skills/mcore-testing/SKILL.md.

Что делает mcore-testing?

Описывает тестовую систему Megatron-LM: раскладку тестов, структуру recipe YAML, добавление и запуск unit- и functional-тестов, golden values, фильтры по маркерам и соответствие CI.

Как отключить тест, не удаляя его?

В recipe YAML допишите к значению scope суффикс -broken, например scope: [mr-github-broken]. Для unit-тестов вместо этого ставят маркеры @pytest.mark.flaky_in_dev или @pytest.mark.flaky.

Исходный текст

SKILL.md · Apache-2.0
---
name: mcore-testing
description: Test system for Megatron-LM. Covers test layout, recipe YAML structure, adding and running unit and functional tests, golden values, marker filters, and CI parity.
license: Apache-2.0
when_to_use: Adding or running a unit or functional test; understanding the test layout; writing a recipe YAML; downloading or updating golden values; reproducing a test failure locally; 'how do I add a test', 'run unit tests', 'pytest fails', 'test layout', 'golden values', 'recipe YAML', 'marker filter'.
metadata:
  author: Philip Petrakian <[email protected]>
---

# Testing Guide

---

## Answer-First Testing Facts

For questions about disabling tests without deleting them:

- Functional recipe entries stay in YAML; disable by suffixing scope with
  `-broken`, for example `scope: [mr-github]` -> `scope: [mr-github-broken]`.
- Unit-test skips use pytest markers instead: `@pytest.mark.flaky_in_dev` skips
  in the default dev environment, and `@pytest.mark.flaky` skips in LTS.
- Do not delete the test case or recipe entry when the goal is discoverability
  and easy re-enable.

---

## Test Layout

```text
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, …)
```

---

## How Tests Execute

The GitHub Actions runner invokes `launch_nemo_run_workload.py`, which uses
**nemo-run** to launch a `DockerExecutor` container. The repo is bind-mounted
at `/opt/megatron-lm`; training data is mounted at `/mnt/artifacts`.

**Unit tests** are dispatched through `torch.distributed.run`:

- Ranks 0 and 3 are tee-d to stdout; all other ranks write only to log files.
- Per-rank log files land at `{assets_dir}/logs/1/` and are uploaded as a
  GitHub artifact after the run.

**Functional tests** are driven by
`tests/functional_tests/shell_test_utils/run_ci_test.sh`. Only rank 0 runs the
pytest validation step; training output from all ranks is uploaded as an artifact.

**Flaky-failure auto-retry**: `launch_nemo_run_workload.py` retries up to
**3 times** for known transient patterns (NCCL timeout, ECC error, segfault,
HuggingFace connectivity, …) before declaring a genuine failure.

---

## Recipe YAML Structure

Recipes live in `tests/test_utils/recipes/` and are parsed by
`tests/test_utils/python_scripts/recipe_parser.py`. Each file expands a
cartesian `products` block into individual workload specs:

```yaml
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]
```

Key runtime placeholders: `{assets_dir}`, `{artifacts_dir}`, `{test_case}`,
`{environment}`, `{platforms}`, `{n_repeat}`.

### Disabling a Test Without Deleting It

To temporarily disable a test case in a recipe YAML, suffix its `scope` value
with `-broken` — **do not delete the entry**:

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

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

---

## Running Unit Tests Locally

All unit tests initialize a `torch.distributed` group, so every invocation
requires GPU access and must go through `torch.distributed.run`:

```bash
# 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
```

### Marker filters

```bash
# 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 parity

Use `tests/unit_tests/run_ci_test.sh` to reproduce a CI bucket failure exactly.
For ad-hoc runs, prefer the direct `torch.distributed.run` invocations above.

### Gotchas

- `pyproject.toml` sets `addopts = --durations=15 -s -rA` — stdout is not
  captured (`-s`), so ranks interleave during multi-rank runs. Override with
  `--capture=fd` when debugging a specific rank.
- `tests/unit_tests/conftest.py` looks for test data under `/opt/data` and
  attempts a download if missing. Supply it manually or skip data-dependent
  tests when running outside the canonical container.

---

## Adding a Unit Test

1. Create `tests/unit_tests/<category>/test_<name>.py`.
2. Use fixtures from `tests/unit_tests/conftest.py`.
3. Apply markers as needed:
   - `@pytest.mark.internal` — skipped on `legacy` tag
   - `@pytest.mark.flaky_in_dev` — skipped in `dev` environment (CI default; use this to disable a flaky test without blocking the standard pipeline)
   - `@pytest.mark.flaky` — skipped in `lts` environment
   - `@pytest.mark.experimental` — `latest` tag only
4. Verify locally (see Running Unit Tests Locally above).
5. If the test needs a dedicated CI bucket, add an entry to
   `tests/test_utils/recipes/h100/unit-tests.yaml`.

---

## Adding a Functional / Integration Test

1. Create `tests/functional_tests/test_cases/<model>/<test_name>/`.
2. Write `model_config.yaml` with `MODEL_ARGS`, `ENV_VARS`, and `TEST_TYPE`.
3. Add a YAML recipe under `tests/test_utils/recipes/h100/` (and `gb200/` if
   needed). Required fields: `scope`, `environment`, `platform`, `n_repeat`,
   `time_limit`.
4. Push the PR, add the label **"Run functional tests"** to trigger a full run.
5. After a successful run, download golden values:

   ```bash
   python tests/test_utils/python_scripts/download_golden_values.py \
     --source github --pipeline-id <run-id>
   ```

6. Commit the downloaded golden values.

---

## Common Pitfalls

| Problem | Cause | Fix |
|---------|-------|-----|
| Test passes locally but fails in CI | Different environment or data path | Check `DATA_PATH`, `DATA_CACHE_PATH`, and the `environment` tag (`dev` vs `lts`) |
| Golden value mismatch after a code change | Numerical regression | Download new golden values via `download_golden_values.py` after a clean run |
| `cicd-integration-tests-gb200` not triggered | GB200 jobs require maintainer status | Ask a maintainer to trigger, or add the `Run functional tests` label |

© Philip Petrakian · Apache-2.0 · NVIDIA/skills

Похожие скиллы

Всё по теме «Тесты и QA» →
python-testing-patterns Seth Hobson Скилл помогает писать тесты Python с pytest, фикстурами и моками. Подходит для настройки тестового набора и отладки падающих проверок. CX Codex 36 943установок python-testing affaan-m Скилл задаёт подход к тестам Python на pytest: TDD, фикстуры, моки, параметризацию и проверку покрытия. Пригодится при создании и ревью тестов. CX Codex +1 4 900установок unit-testing kindlmann Скилл для написания юнит-тестов: подсказывает, какие тест-двойники брать, как настроить порог покрытия и как проверить тесты мутационным тестированием. CX Codex +1 1 100установок api-testing secondsky Скилл учит агента писать тесты HTTP API: Supertest в TypeScript, httpx и pytest в Python. Пригодится, когда нужно закрыть REST, GraphQL и проверку ошибок. CX Codex +1 890установок unit-testing-framework aj-geddes Скилл задаёт агенту правила написания юнит-тестов: структура Arrange-Act-Assert, моки, граничные случаи. Пригодится, когда нужно покрыть тестами новую функцию или класс. CX Codex +1 593установок

Из того же набора178

holoscan-install-conda Проверяет доступность пакетов Conda для Holoscan SDK 5.x. Скилл предупреждает об отсутствии сборки для 5.0 и предлагает проверенные альтернативы. CX Codex +1 1 800установок holoscan-install-container Проверяет хост и ставит контейнер разработки Holoscan SDK 5.x с CUDA 13. Нужен перед запуском SDK в Docker с GPU. CX Codex +1 1 800установок holoscan-setup Проверяет хост и помогает выбрать способ установки Holoscan SDK 5.x: контейнер, Debian-пакеты, wheels или сборка из исходников. CX Codex +1 1 800установок tilegym-adding-cutile-kernel Пошагово проводит агента через добавление нового GPU-оператора на cuTile в библиотеку TileGym. Пригодится при расширении набора ядер и их интеграции в проект. CX Codex +1 1 800установок mcore-create-issue Скилл исследует упавшие прогоны GitHub Actions в NVIDIA/Megatron-LM, находит причину сбоя и оформляет готовый баг-репорт. CX Codex +1 1 800установок mcore-run-on-slurm Скилл помогает подготовить запуск распределённого обучения Megatron-LM на SLURM-кластере. Пригодится для настройки sbatch, мног узлового запуска и разбора сбоев по логам рангов. CX Codex +1 1 800установок nemo-rl-brev-etiquette Скилл задаёт агенту правила хранения файлов на инстансе Brev: код остаётся в репозитории, тяжёлые артефакты уезжают на /ephemeral. CX Codex +1 1 800установок mcore-linting-and-formatting Скилл настраивает проверку и форматирование кода в проекте Megatron-LM. Помогает исправить ошибки ruff, mypy и отсортировать импорты перед открытием PR. CX Codex +1 1 800установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой