diff --git a/.claude/skills/ci/SKILL.md b/.claude/skills/ci/SKILL.md new file mode 100644 index 0000000000..71896425d7 --- /dev/null +++ b/.claude/skills/ci/SKILL.md @@ -0,0 +1,77 @@ +--- +name: ci-context +description: Constraints and environment details for Claude running inside the GitHub Actions workflow on pytorch/tutorials. This skill is automatically loaded in the CI context. Use when Claude is invoked via @claude mentions on issues or PRs. +--- + +# CI Environment Skill + +This skill applies when Claude is running inside the GitHub Actions workflow (`claude-code.yml`) on `pytorch/tutorials`. It defines what is available, what is allowed, and what is forbidden in this context. + +## Environment + +| Detail | Value | +|--------|-------| +| Runner | `ubuntu-latest` | +| Python | 3.12 (pre-installed via `actions/setup-python`) | +| Lintrunner | 0.12.5 (pre-installed and initialized) | +| Timeout | 60 minutes | +| Model | `claude-opus-4-6-v1` via AWS Bedrock | + +**All tools you need are already installed.** Do not run `pip install`, `apt-get`, or any other installation commands. If a tool is missing, state that it is unavailable and move on. + +## Permissions + +The workflow grants these GitHub token permissions: + +| Permission | Level | What it allows | +|------------|-------|----------------| +| `contents` | `read` | Read repo files, checkout code | +| `pull-requests` | `write` | Comment on PRs, post reviews | +| `issues` | `write` | Comment on issues, add/remove labels | +| `id-token` | `write` | OIDC authentication to AWS Bedrock | + +## What You MUST NOT Do + +- **Commit or push** — You have read-only access to repo contents. Never attempt `git commit`, `git push`, or create branches. +- **Merge or close PRs** — You cannot and should not merge pull requests. +- **Close issues** — Never close issues. Only add comments and labels. +- **Install packages** — Everything needed is pre-installed. Do not run `pip install`, `npm install`, `apt-get`, etc. +- **Modify workflow files** — Do not suggest changes to `.github/workflows/` files in automated comments. +- **Assign users** — Do not assign issues or PRs to specific people. +- **Add labels that require human judgment** — See the triage skill for the full restricted labels list. + +## What You CAN Do + +- **Read all repo files** — Full checkout is available at the workspace root. +- **Run lintrunner** — `lintrunner -m main` or `lintrunner --all-files` are available. +- **Run make (dry/noplot)** — `make html-noplot` works for RST/Sphinx validation (no GPU). +- **Comment on PRs and issues** — Post review comments, inline suggestions, and general comments. +- **Add/remove labels on issues** — Apply triage labels from the approved list. +- **Search for similar issues** — Use GitHub MCP tools to find duplicates or related issues. + +## Available MCP Tools + +| Tool | Purpose | +|------|---------| +| `mcp__github__issue_read` | Read issue details, comments, and labels | +| `mcp__github__issue_write` | Add/remove labels on issues (do NOT close) | +| `mcp__github__add_issue_comment` | Post a comment on an issue | +| `mcp__github__search_issues` | Search for similar/duplicate issues | +| `mcp__github__pr_read` | Read PR details, diff, and review comments | +| `mcp__github__pr_comment` | Post a comment or review on a PR | + +## Trigger Context + +Claude is invoked when a user mentions `@claude` in: +- An issue comment (`issue_comment` event) +- A PR review comment (`pull_request_review_comment` event) +- A new issue body (`issues.opened` event) + +The triggering comment or issue body is passed as the prompt. Respond directly to what the user asked — do not perform unrequested actions. + +## Interaction Style + +- You are responding asynchronously via GitHub comments. There is no interactive terminal session. +- Be concise — GitHub comments should be scannable, not walls of text. +- Use markdown formatting (headers, tables, code blocks) for readability. +- If you cannot complete a request due to permission constraints, explain what you tried and what the user should do instead. diff --git a/.claude/skills/pr-review/SKILL.md b/.claude/skills/pr-review/SKILL.md new file mode 100644 index 0000000000..2a61b84a72 --- /dev/null +++ b/.claude/skills/pr-review/SKILL.md @@ -0,0 +1,186 @@ +--- +name: pr-review +description: Review PyTorch tutorials pull requests for content quality, code correctness, build compatibility, and style. Use when reviewing PRs, when asked to review code changes, or when the user mentions "review PR", "code review", or "check this PR". +--- + +# Tutorials PR Review Skill + +Review PyTorch tutorials pull requests for content quality, code correctness, tutorial structure, and Sphinx/RST formatting. CI lintrunner only checks trailing whitespace, tabs, and newlines — it does not validate RST syntax, Python formatting, or Sphinx directives, so those must be reviewed manually. + +## Usage Modes + +### No Argument + +If the user invokes `/pr-review` with no arguments, **do not perform a review**. Instead, ask the user what they would like to review: + +> What would you like me to review? +> - A PR number or URL (e.g., `/pr-review 12345`) +> - A local branch (e.g., `/pr-review branch`) + +### Local CLI Mode + +The user provides a PR number or URL: + +``` +/pr-review 12345 +/pr-review https://github.com/pytorch/tutorials/pull/12345 +``` + +For a detailed review with line-by-line specific comments: + +``` +/pr-review 12345 detailed +``` + +Use `gh` CLI to fetch PR data: + +```bash +# Get PR details +gh pr view --json title,body,author,baseRefName,headRefName,files,additions,deletions,commits + +# Get the diff +gh pr diff + +# Get PR comments +gh pr view --json comments,reviews +``` + +### Local Branch Mode + +Review changes in the current branch that are not in `main`: + +``` +/pr-review branch +/pr-review branch detailed +``` + +Use git commands to get branch changes: + +```bash +# Get current branch name +git branch --show-current + +# Get list of changed files compared to main +git diff --name-only main...HEAD + +# Get full diff compared to main +git diff main...HEAD + +# Get commit log for the branch +git log main..HEAD --oneline + +# Get diff stats (files changed, insertions, deletions) +git diff --stat main...HEAD +``` + +For local branch reviews: +- The "Summary" should describe what the branch changes accomplish based on commit messages and diff +- Use the current branch name in the review header instead of a PR number +- All other review criteria apply the same as PR reviews + +### GitHub Actions Mode + +When invoked via workflow, PR data is passed as context. The PR number or diff will be available in the prompt. See the [CI Environment Skill](../ci/SKILL.md) for environment constraints, available tools, and permissions. + +## Review Workflow + +### Step 1: Fetch PR Information + +For local mode, use `gh` commands to get: +1. PR metadata (title, description, author) +2. List of changed files +3. Full diff of changes +4. Existing comments/reviews + +### Step 2: Analyze Changes + +Read through the diff systematically: +1. Identify the purpose of the change from title/description +2. Group changes by type (tutorial content, config, build, infra) +3. Note the scope of changes (files affected, lines changed) + +### Step 3: Deep Review + +Perform thorough analysis using the review checklist. See [review-checklist.md](review-checklist.md) for detailed criteria covering: +- Tutorial content quality and accuracy +- Code correctness in tutorial examples +- Sphinx/RST formatting +- Build compatibility +- Project structure compliance + +### Step 4: Formulate Review + +Structure your review with actionable feedback organized by category. + +## Review Areas + +| Area | Focus | Reference | +|------|-------|-----------| +| Content Quality | Accuracy, clarity, learning objectives | [review-checklist.md](review-checklist.md) | +| Code Correctness | Working examples, imports, API usage | [review-checklist.md](review-checklist.md) | +| Structure | File placement, index entries, toctree | [review-checklist.md](review-checklist.md) | +| Formatting | RST/Sphinx syntax, Sphinx Gallery conventions | [review-checklist.md](review-checklist.md) | +| Build | Dependencies, data downloads, CI compat | [review-checklist.md](review-checklist.md) | + +## Output Format + +Structure your review as follows: + +```markdown +## PR Review: # + +## Branch Review: (vs main) + +### Summary +Brief overall assessment of the changes (1-2 sentences). + +### Content Quality +[Issues and suggestions, or "No concerns" if none] + +### Code Correctness +[Issues with tutorial code examples, imports, API usage, or "No concerns"] + +### Structure & Formatting +[File placement, RST/Sphinx issues, index/toctree entries, or "No concerns"] + +### Build Compatibility +[Dependency issues, data download concerns, CI compatibility, or "No concerns"] + +### Recommendation +**Approve** / **Request Changes** / **Needs Discussion** + +[Brief justification for recommendation] +``` + +### Specific Comments (Detailed Review Only) + +**Only include this section if the user requests a "detailed" or "in depth" review.** + +**Do not repeat observations already made in other sections.** This section is for additional file-specific feedback that doesn't fit into the categorized sections above. + +When requested, add file-specific feedback with line references: + +```markdown +### Specific Comments +- `beginner_source/my_tutorial.py:42` - Docstring prose is unclear; rephrase for non-native speakers +- `index.rst:150` - Missing customcarditem entry for the new tutorial +- `requirements.txt:30` - New dependency should be pinned to a specific version +``` + +## Key Principles + +1. **No repetition** - Each observation appears in exactly one section +2. **Focus on what CI cannot check** - Don't comment on trailing whitespace or tab characters (caught by lintrunner). RST syntax, Sphinx directives, and Python code style must still be reviewed +3. **Be specific** - Reference file paths and line numbers +4. **Be actionable** - Provide concrete suggestions, not vague concerns +5. **Be proportionate** - Minor issues shouldn't block, but note them +6. **Audience awareness** - Tutorials are read by beginners; clarity matters more than brevity + +## Files to Reference + +When reviewing, consult these project files for context: +- `CLAUDE.md` - Project structure and coding style +- `CONTRIBUTING.md` - Submission process, tutorial types, and authoring guidance +- `conf.py` - Sphinx Gallery configuration and extensions +- `requirements.txt` - Approved dependencies +- `index.rst` - Card listings and toctree structure diff --git a/.claude/skills/pr-review/review-checklist.md b/.claude/skills/pr-review/review-checklist.md new file mode 100644 index 0000000000..dbe0ac8ecf --- /dev/null +++ b/.claude/skills/pr-review/review-checklist.md @@ -0,0 +1,182 @@ +# PR Review Checklist + +This checklist covers areas that CI cannot check. CI lintrunner only catches trailing whitespace, tabs, and missing newlines — it does **not** validate RST syntax, Python formatting, import ordering, or Sphinx directives. Those must all be reviewed manually. + +References: +- [CONTRIBUTING.md](../../../CONTRIBUTING.md) — Authoring guidance, submission process, tutorial structure template +- [tutorial_submission_policy.md](../../../tutorial_submission_policy.md) — Acceptance criteria, community submission process, maintenance expectations +- [beginner_source/template_tutorial.py](../../../beginner_source/template_tutorial.py) — Official tutorial template with required structure +- [conf.py](../../../conf.py) — Sphinx Gallery configuration and build settings + +## Acceptance Criteria (tutorial_submission_policy.md § "Acceptance Criteria") + +For **new tutorial** PRs, verify the submission meets one of the two accepted use cases: + +- [ ] **New PyTorch feature tutorial** — Authored by engineers developing the feature for an upcoming release. Typically one tutorial per feature. Does not require the community submission process +- [ ] **Community tutorial (PyTorch + other tools)** — Illustrates innovative uses of PyTorch alongside other open-source projects, models, and tools. Must remain neutral and not promote or endorse proprietary technologies over others + +### Community Submission Process (tutorial_submission_policy.md § "Submission Process") + +For community-contributed tutorials, verify: + +- [ ] **Corresponding issue exists** — An issue was filed in pytorch/tutorials proposing the tutorial using the [Feature request template](https://github.com/pytorch/tutorials/blob/main/.github/ISSUE_TEMPLATE/feature-request.yml), explaining importance and confirming no existing tutorial covers the same topic +- [ ] **Issue has `approved` label** — A maintainer reviewed and approved the proposal. PRs without a corresponding approved issue may take longer to review +- [ ] **PR links the approved issue** — The PR description references the issue where approval was granted + +## Tutorial Content Quality + +### Learning Objectives (CONTRIBUTING.md § "Learning objectives") + +- [ ] **Explicit learning objectives** — Tutorial states what the user will implement by the end. Focus on what the user will *do*, not abstract concepts. Examples: "Create a custom dataset", "Implement greedy-search decoding", "Train encoder and decoder models using mini-batches" +- [ ] **Actionable content** — Tutorials and recipes are always actionable. If the material is purely informative, it belongs in the API docs, not a tutorial +- [ ] **No duplication** — Tutorial demonstrates PyTorch functionality not already covered by existing tutorials. Check existing tutorials at https://pytorch.org/tutorials/ + +### Tutorial Structure (CONTRIBUTING.md § "Structure") + +The recommended structure from CONTRIBUTING.md: + +1. [ ] **Introduction** — What the tutorial is about +2. [ ] **Motivation** — Why this topic is important +3. [ ] **Background links** — Links to relevant research papers or background material +4. [ ] **Learning objectives** — Clearly state what the tutorial covers and what users will implement by the end (see the [TensorBoard tutorial](https://pytorch.org/tutorials/intermediate/tensorboard_tutorial.html) as a good example) +5. [ ] **Setup and requirements** — Call out any required setup or data downloads upfront +6. [ ] **Step-by-step instructions** — Steps should map back to the learning objectives. Code comments should correspond to these steps +7. [ ] **Links to PyTorch documentation** — Reference relevant [API docs](https://pytorch.org/docs/stable/index.html) to give readers context +8. [ ] **Recap/Conclusion** — Summarize the steps and concepts covered, highlight key takeaways +9. [ ] **Additional resources** — Links for further learning (docs, other tutorials, research) +10. [ ] *(Optional)* **Practice exercises** — For users to test their knowledge (see the [NLP From Scratch tutorial](https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutorial.html#exercises) for an example) + +### Template Compliance (beginner_source/template_tutorial.py) + +For `.py` tutorials, verify use of the official template structure: + +- [ ] **"What you will learn" grid card** — Uses the `.. grid:: 2` / `.. grid-item-card::` RST directive with `:octicon:\`mortar-board;1em;\`` to list what the user will learn +- [ ] **"Prerequisites" grid card** — Adjacent grid card with `:octicon:\`list-unordered;1em;\`` listing prerequisites (PyTorch version, GPU requirements, etc.) +- [ ] **Overview section** — Describes why the topic is important, links to relevant research +- [ ] **Steps section** — Code with inline explanations +- [ ] **Conclusion section** — Summarizes steps and concepts, highlights key takeaways +- [ ] **Further Reading section** — Links for additional learning + +### Voice and Writing Style (CONTRIBUTING.md § "Voice and writing style") + +- [ ] **Global audience** — Clear, easy to understand language. No idioms or figures of speech +- [ ] **Active voice** — Instructions are instructive and directive, not passive +- [ ] **Concise** — No extraneous information; content serves the learning objectives +- [ ] **Neutral tone** — Does not disproportionately endorse one technology over another (per submission policy) + +## Tutorial Types and File Format (CONTRIBUTING.md § "New Tutorials") + +### Interactive Tutorials (`.py` files) + +- [ ] **Filename ends in `_tutorial.py`** — Required naming convention (e.g., `cool_pytorch_feature_tutorial.py`) +- [ ] **Not a Jupyter notebook** — `.ipynb` files are not accepted. Must be a `.py` file using Sphinx Gallery format +- [ ] **Python format preferred** — Per submission policy: unless the tutorial involves multi-GPU, parallel/distributed training, or requires extended execution time (25+ minutes), `.py` format is preferred over `.rst` +- [ ] **Top docstring is RST** — First triple-quoted docstring becomes the tutorial title and intro prose. Must use RST formatting with a proper heading (underlined with `===`) +- [ ] **`######################################################################` separators** — Code blocks are separated by comment blocks starting with `#` lines. The `#` comment lines between code blocks become RST prose +- [ ] **Code blocks are logical** — Each code cell does one clear thing +- [ ] **Prose between code blocks** — Comment blocks between code explain the next step, mapping back to learning objectives +- [ ] **No `!pip install` or `%magic` commands** — Notebook magic syntax is not allowed. The `first_notebook_cell` in `conf.py` handles `%matplotlib inline` automatically +- [ ] **Author attribution** — Includes `**Author:** \`Name \`_` in the opening docstring + +### Non-Interactive Tutorials (`.rst` files) + +- [ ] **Valid RST syntax** — Directives, roles, and cross-references are well-formed +- [ ] **Code blocks have language specified** — Use `.. code-block:: python`, not bare `::` +- [ ] **Used appropriately** — `.rst` format should only be used for tutorials involving multi-GPU, parallel/distributed training, or extended execution time (25+ minutes) + +### Recipes (CONTRIBUTING.md § "New Tutorials") + +- [ ] **Bite-sized and scoped** — Recipes demonstrate how to use a specific feature, not a full end-to-end workflow +- [ ] **Added to `recipes_source/`** — Recipes go in `recipes_source/`, not the other `*_source/` directories +- [ ] **Listed in `recipes_source/recipes/README.txt`** — Recipe is added to the recipes README + +## Project Structure and Index (CONTRIBUTING.md § "Submission Process") + +### File Placement + +- [ ] **Correct source directory** — File is in the right directory based on difficulty level: + - `beginner_source/` — Introductory content + - `intermediate_source/` — Intermediate content + - `advanced_source/` — Advanced content + - `recipes_source/` — Recipes (any difficulty) + +### Card Entry (CONTRIBUTING.md § "Include Your Tutorial in index.rst") + +- [ ] **`customcarditem` added** — Card entry exists in `index.rst` (or `recipes_index.rst` for recipes) with all required fields: + ```rst + .. customcarditem:: + :header: Tutorial Title + :card_description: A short description of the tutorial. + :image: _static/img/thumbnails/cropped/my-thumbnail.png + :link: beginner/my_tutorial.html + :tags: Getting-Started + ``` +- [ ] **Tags are valid** — Tags chosen from existing tags in the file. Multi-word tags are hyphenated (e.g., `Getting-Started`). No whitespace between tag words — incorrect tags will break the build and cards won't display +- [ ] **Link path is correct** — The `link` value matches the tutorial's location (e.g., `beginner/my_tutorial.html` for a file in `beginner_source/`) + +### Toctree Entry + +- [ ] **Added to the appropriate toctree** — Tutorial listed under the correct topic section in `index.rst` + +### Thumbnail Image (CONTRIBUTING.md § "Image") + +- [ ] **Image added to `_static/img/thumbnails/cropped/`** — Thumbnail exists +- [ ] **Square dimensions** — Equal `x` and `y` dimensions render best +- [ ] **High resolution** — Image is clear and not pixelated + +## Code Correctness + +### Python Code in Tutorials + +- [ ] **Code runs correctly** — Examples produce the described output +- [ ] **Imports are complete** — All necessary imports are present +- [ ] **API usage is current** — Uses non-deprecated PyTorch APIs +- [ ] **No hardcoded paths** — No absolute paths or user-specific paths in code +- [ ] **Reproducibility** — Random seeds set where results need to be deterministic + +## Dependencies and Data (CONTRIBUTING.md § "Managing data" and "Python packages") + +### Data + +- [ ] **Data downloads via `.jenkins/download_data.py`** — Follow the same pattern as other download functions. Do NOT add download logic to `Makefile` (it incurs overhead for all CI shards) +- [ ] **Data stored on reliable external storage** — Recommended: Amazon S3 or similar. URLs should be long-lived +- [ ] **No large files committed** — Data and models are downloaded at build time, not checked into the repo + +### Python Packages + +- [ ] **New dependencies added to `requirements.txt`** — Any package not already listed must be added +- [ ] **Mature, well-supported packages only** — Obscure or poorly maintained packages may break with Python/PyTorch updates and lead to tutorial deprecation (per submission policy: tutorials broken for 90+ days may be deleted) +- [ ] **Versions pinned** — New dependencies should have pinned versions for reproducibility + +## Build Compatibility + +- [ ] **No CI-breaking changes** — Tutorial doesn't introduce untested imports or missing data +- [ ] **GPU requirements noted** — If tutorial needs GPU, it's documented and CI can handle it +- [ ] **Reasonable execution time** — Tutorials requiring 25+ minutes of execution time should be `.rst` format (per submission policy). Keep individual `.py` tutorials well under CI timeout limits +- [ ] **Clean build with `make html-noplot`** — RST structure is valid even without executing code + +## Maintenance Expectations (tutorial_submission_policy.md § "Maintaining Tutorials") + +When reviewing new tutorials, consider long-term maintainability: + +- [ ] **Author can maintain it** — The contributor should be able to keep the tutorial in sync with PyTorch updates +- [ ] **Not fragile** — Tutorial doesn't depend on rapidly-changing external APIs or unstable packages that are likely to break +- [ ] **90-day fix window** — If a tutorial breaks against main, it will be excluded from the build. If not resolved within 90 days, it may be deleted from the repository +- [ ] **Annual review expectation** — Each tutorial should be reviewed at least once a year to ensure relevance + +## Common Issues to Flag + +- Tutorials that import packages not in `requirements.txt` +- Broken or outdated links to pytorch.org/docs +- Code that only works on specific PyTorch versions without noting the requirement +- Missing or incorrect card tags in `index.rst` (tags must be hyphenated, no spaces between words) +- Tutorials that download data in the Makefile instead of `.jenkins/download_data.py` +- Jupyter notebooks submitted instead of `.py` files +- Copy-pasted code from notebooks with leftover `!pip` or `%magic` commands +- Missing author attribution in the opening docstring +- Tutorials with purely informative content that belongs in API docs instead +- PRs where the author tries to self-merge (only maintainers authorize publishing) +- Community tutorials submitted without a corresponding approved issue +- Tutorials that promote proprietary technologies or are not neutral +- Tutorials duplicating content already covered by existing tutorials +- Missing "What you will learn" / "Prerequisites" grid cards from the official template diff --git a/.claude/skills/triage/SKILL.md b/.claude/skills/triage/SKILL.md new file mode 100644 index 0000000000..1954cff171 --- /dev/null +++ b/.claude/skills/triage/SKILL.md @@ -0,0 +1,147 @@ +--- +name: triaging-issues +description: Triages GitHub issues in the pytorch/tutorials repo by applying labels, routing to domain areas, and responding to questions. Use when processing new tutorial issues or when asked to triage an issue. +--- + +# Tutorials Issue Triage Skill + +This skill helps triage GitHub issues in the `pytorch/tutorials` repo by classifying issues, applying labels, and leaving first-line responses. + +## Contents +- [MCP Tools Available](#mcp-tools-available) +- [Labels You Must NEVER Add](#labels-you-must-never-add) +- [Issue Triage Steps](#issue-triage-for-each-issue) + - Step 0: Already Triaged — SKIP + - Step 1: Question vs Bug/Feature + - Step 2: Redirect to PyTorch Core + - Step 3: Classify the Issue + - Step 4: Label the Issue + - Step 5: High Priority — REQUIRES HUMAN REVIEW + - Step 6: Mark Triaged +- [V1 Constraints](#v1-constraints) + +**Labels reference:** See [labels.json](labels.json) for the catalog of labels suitable for triage. **ONLY apply labels that exist in this file.** Do not invent or guess label names. + +**Response templates:** See [templates.json](templates.json) for standard response messages. + +--- + +## MCP Tools Available + +For the full list of available tools and CI environment constraints, see the [CI Environment Skill](../ci/SKILL.md). + +Key tools for triage: + +| Tool | Purpose | +|------|---------| +| `mcp__github__issue_read` | Get issue details, comments, and existing labels | +| `mcp__github__issue_write` | Add/remove labels (do NOT close issues) | +| `mcp__github__add_issue_comment` | Post a comment on an issue | +| `mcp__github__search_issues` | Find similar issues for context | + +--- + +## Labels You Must NEVER Add + +| Prefix/Category | Reason | +|-----------------|--------| +| Labels not in `labels.json` | Only apply labels that exist in the allowlist | +| `ciflow/*` | CI job triggers for PRs only | +| Version labels (`1.7`, `2.11`, etc.) | Release tracking, added by maintainers | +| `cla signed` | Automated by CLA bot | +| `stale` | Automated by stale bot | +| `do-not-merge` | Requires human decision | +| `approved` | Requires human decision | +| `no-stale` | Requires human decision | + +--- + +## Issue Triage (for each issue) + +### 0) Already Triaged — SKIP + +**If an issue already has the `triaged` label, SKIP IT entirely.** Do not: +- Add any labels +- Leave comments +- Do any triage work + +### 1) Question vs Bug/Feature + +- If it is a usage question (e.g., "How do I...", "Why doesn't this work in my setup...") and not a bug in the tutorial itself: add a comment using the `redirect_to_forum` template from `templates.json`. Do NOT close the issue. +- If unclear whether it is a tutorial bug vs a user environment issue: request additional information using the `request_more_info` template and stop. + +### 2) Redirect to PyTorch Core + +If the issue is actually a PyTorch framework bug (not a tutorial content issue), use the `redirect_to_pytorch` template to point the user to `pytorch/pytorch`. Do NOT transfer or close the issue — only add a comment. + +**Indicators of a core PyTorch bug:** +- Error occurs with the user's own code, not tutorial code +- Bug is in `torch.*` API behavior, not tutorial instructions +- Issue involves a PyTorch build/installation problem + +### 3) Classify the Issue + +Determine the issue type: + +| Type | Description | Label | +|------|-------------|-------| +| Tutorial bug | Code errors, outdated API usage, wrong output in a tutorial | `bug` | +| Content issue | Incorrect descriptions, unclear explanations, grammar | `content` | +| Broken link | Dead or incorrect links in tutorials | `incorrect link` | +| Build issue | Tutorial fails to build in CI | `build issue` | +| New tutorial request | Request for a tutorial on a new topic | `new tutorial` or `tutorial-proposal` | +| Enhancement | Improvement to an existing tutorial | `enhancement` | +| Website rendering | Display/formatting issues on pytorch.org/tutorials | `website` | + +### 4) Label the Issue + +Apply labels from [labels.json](labels.json): + +1. **Type label** — One of: `bug`, `content`, `incorrect link`, `build issue`, `new tutorial`, `tutorial-proposal`, `enhancement`, `website` +2. **Domain label** — Based on the tutorial topic area. Common domain labels: + - `distributed` — distributed training tutorials + - `torch.compile` — torch.compile related tutorials + - `core` — core PyTorch functionality + - `nlp` — NLP tutorials + - `torchvision`, `torchaudio`, `torchserve`, `torchrec` — domain library tutorials + - `CUDA`, `mps`, `intel`, `amd` — platform-specific + - `C++` — C++ frontend tutorials + - `Mobile` — mobile deployment tutorials + - `onnx` — ONNX export tutorials + - `quantization` — quantization tutorials + - `module: export`, `module: inductor`, `module: profiler` — specific module areas +3. **Difficulty label** (for new tutorial requests only) — `easy`, `medium`, `hard` + +### 5) High Priority — REQUIRES HUMAN REVIEW + +**CRITICAL:** If you believe an issue is high priority, you MUST: +1. Add `triage review` label (if it exists) or leave a comment noting it needs maintainer attention +2. Do NOT attempt to fix or close the issue + +High priority criteria for tutorials: +- Tutorial produces silently wrong results (incorrect code output) +- Tutorial uses a removed or dangerous API +- Build is broken for a popular tutorial +- Security concern (e.g., tutorial instructs users to disable safety features) +- Regression: tutorial that previously worked is now broken + +### 6) Mark Triaged + +If not flagged for human review, add `triaged`. + +--- + +## V1 Constraints + +**DO NOT:** +- Close any issues — only add comments and labels, never close +- Assign issues to users +- Add comments to bug reports or feature requests, except when requesting more info +- Add release version labels + +**DO:** +- Comment on usage questions and point to discuss.pytorch.org (per Step 1), but leave the issue open +- Be conservative — when in doubt, leave for human attention +- Apply type labels (`bug`, `content`, `enhancement`, `new tutorial`) when confident +- Apply domain labels when the affected tutorial area is clear +- Add `triaged` label when classification is complete diff --git a/.claude/skills/triage/labels.json b/.claude/skills/triage/labels.json new file mode 100644 index 0000000000..cf982892cd --- /dev/null +++ b/.claude/skills/triage/labels.json @@ -0,0 +1,310 @@ +{ + "description": "Labels suitable for issue triage in pytorch/tutorials. Excludes CI triggers, version/release labels, automated labels, and PR-only labels.", + "repo": "pytorch/tutorials", + "labels": [ + { + "name": "bug", + "description": "Tutorial code is broken or produces incorrect results" + }, + { + "name": "content", + "description": "Incorrect or unclear descriptions that need to be updated" + }, + { + "name": "enhancement", + "description": "Improvement to an existing tutorial" + }, + { + "name": "new tutorial", + "description": "Request for a new tutorial" + }, + { + "name": "tutorial-proposal", + "description": "Proposal for a new tutorial topic" + }, + { + "name": "build issue", + "description": "Issues relating to the tutorials build" + }, + { + "name": "incorrect link", + "description": "Broken or incorrect links in tutorials" + }, + { + "name": "website", + "description": "Issues related to website rendering" + }, + { + "name": "grammar", + "description": "Grammar or spelling issues in tutorial text" + }, + { + "name": "duplicate", + "description": "Issue is a duplicate of another" + }, + { + "name": "question", + "description": "Usage question, not a bug or feature request" + }, + { + "name": "help wanted", + "description": "Looking for community contributions" + }, + { + "name": "easy", + "description": "Easy difficulty for docathon/contributions" + }, + { + "name": "medium", + "description": "Medium difficulty for docathon/contributions" + }, + { + "name": "hard", + "description": "Hard difficulty for docathon/contributions" + }, + { + "name": "regression", + "description": "Tutorial that previously worked is now broken" + }, + { + "name": "not-reproducible", + "description": "Issue could not be reproduced" + }, + { + "name": "wontfix", + "description": "Issue will not be addressed" + }, + { + "name": "deprecate", + "description": "Tutorial should be deprecated" + }, + { + "name": "triaged", + "description": "Issue has been looked at by a team member and triaged" + }, + { + "name": "page-feedback", + "description": "Feedback submitted via the tutorial page" + }, + { + "name": "core", + "description": "Tutorials related to core PyTorch functionality" + }, + { + "name": "distributed", + "description": "Distributed training tutorials" + }, + { + "name": "torch.compile", + "description": "Torch compile and related tutorials" + }, + { + "name": "nlp", + "description": "NLP tutorials" + }, + { + "name": "torchvision", + "description": "Issues relating to image/video tutorials" + }, + { + "name": "torchaudio", + "description": "Issues relating to torchaudio tutorials" + }, + { + "name": "torchrec", + "description": "PR related to the TorchRec library" + }, + { + "name": "torchserve", + "description": "TorchServe tutorials" + }, + { + "name": "torchscript", + "description": "Issues relating to TorchScript tutorials" + }, + { + "name": "tensorboard", + "description": "TensorBoard tutorials" + }, + { + "name": "tensordict", + "description": "TensorDict tutorials" + }, + { + "name": "functorch", + "description": "Functorch tutorials" + }, + { + "name": "onnx", + "description": "Issues relating to ONNX" + }, + { + "name": "quantization", + "description": "Issues relating to quantization tutorials" + }, + { + "name": "amp", + "description": "Issues relating to the automatic mixed precision tutorial" + }, + { + "name": "CUDA", + "description": "Issues relating to CUDA" + }, + { + "name": "mps", + "description": "Apple M1 / MPS related changes" + }, + { + "name": "intel", + "description": "Intel platform tutorials" + }, + { + "name": "amd", + "description": "AMD platform tutorials" + }, + { + "name": "C++", + "description": "Issues relating to C++ tutorials" + }, + { + "name": "Mobile", + "description": "Issues relating to mobile tutorials" + }, + { + "name": "Reinforcement Learning", + "description": "Issues relating to reinforcement learning tutorials" + }, + { + "name": "rl", + "description": "Reinforced Learning related issues and PRs" + }, + { + "name": "data loading", + "description": "Issues relating to the data loading tutorial" + }, + { + "name": "Frontend", + "description": "Issues relating to frontend API tutorials" + }, + { + "name": "Profiler", + "description": "Issues relating to profiler tutorials" + }, + { + "name": "Tensors", + "description": "Issues relating to tensors tutorials" + }, + { + "name": "Text", + "description": "Issues relating to text tutorials" + }, + { + "name": "captum", + "description": "Captum tutorials" + }, + { + "name": "ax", + "description": "AX tutorials" + }, + { + "name": "fx", + "description": "Issues related to fx" + }, + { + "name": "ray", + "description": "PRs related to tutorials that use the ray project" + }, + { + "name": "colab", + "description": "Google Colab related issues" + }, + { + "name": "notebook", + "description": "Jupyter notebook related issues" + }, + { + "name": "windows", + "description": "Windows platform issues" + }, + { + "name": "nvidia", + "description": "NVIDIA platform tutorials" + }, + { + "name": "triton", + "description": "Triton related tutorials" + }, + { + "name": "monarch", + "description": "Monarch related tutorials" + }, + { + "name": "mosaic", + "description": "Mosaic related tutorials" + }, + { + "name": "module: custom-operators", + "description": "PRs related to custom ops tutorials" + }, + { + "name": "module: distributed_checkpoint", + "description": "Distributed checkpoint tutorials" + }, + { + "name": "module: export", + "description": "torch.export tutorials" + }, + { + "name": "module: inductor", + "description": "Inductor tutorials" + }, + { + "name": "module: profiler", + "description": "Profiler module tutorials" + }, + { + "name": "module: quantization", + "description": "Quantization module tutorials" + }, + { + "name": "module: rocm", + "description": "ROCm related tutorials" + }, + { + "name": "module: torchtext", + "description": "TorchText module tutorials" + }, + { + "name": "module: torchx", + "description": "TorchX module tutorials" + }, + { + "name": "module: vision", + "description": "Torchvision issues" + }, + { + "name": "module: vulkan", + "description": "Vulkan related tutorials" + }, + { + "name": "module: xpu", + "description": "XPU related issues" + }, + { + "name": "module: PrivateUse1", + "description": "PrivateUse1 related issues" + }, + { + "name": "arch-optimization", + "description": "Quantization, sparsity, neural search" + }, + { + "name": "intro", + "description": "Introductory tutorials" + }, + { + "name": "60_min_blitz", + "description": "Issues with the 60 min blitz tutorial" + } + ] +} diff --git a/.claude/skills/triage/templates.json b/.claude/skills/triage/templates.json new file mode 100644 index 0000000000..1da0be130a --- /dev/null +++ b/.claude/skills/triage/templates.json @@ -0,0 +1,30 @@ +{ + "description": "Standard response templates for issue triage actions in pytorch/tutorials. NEVER close issues — only add comments and labels.", + "templates": { + "redirect_to_forum": { + "action": "Add comment only", + "use_when": "Issue is a usage question, not a tutorial bug or feature request", + "comment": "Thank you for your interest in PyTorch tutorials! This issue appears to be a usage question rather than a bug in a tutorial or a feature request.\n\nFor usage questions, please use the [PyTorch Discussion Forum](https://discuss.pytorch.org/) where you'll get help from both the community and PyTorch maintainers.\n\nIf you believe this is actually a bug in a tutorial or a request for a new/improved tutorial, please update the issue with more details." + }, + "redirect_to_pytorch": { + "action": "Add comment only", + "use_when": "Issue is a PyTorch framework bug, not a tutorial content issue", + "comment": "Thank you for the report! This appears to be an issue with PyTorch itself rather than with the tutorial content.\n\nPlease file this issue in the main PyTorch repository: https://github.com/pytorch/pytorch/issues/new/choose \n\nThe PyTorch team will be able to help you there." + }, + "request_more_info": { + "action": "Add comment and stop", + "use_when": "Classification is unclear and more details are needed", + "comment": "Thanks for the report. To help us triage this, could you share:\n\n- A link to the specific tutorial page on https://pytorch.org/tutorials/ \n- The exact steps to reproduce the issue\n- Your environment (OS, PyTorch version, Python version, CUDA version if applicable)\n- The full error message or screenshot of the problem\n\nOnce we have that, we can classify and address this properly." + }, + "outdated_tutorial": { + "action": "Add comment, apply labels, and stop", + "use_when": "Issue reports that a tutorial uses deprecated or removed PyTorch APIs", + "comment": "Thank you for flagging this! It looks like this tutorial may be using outdated PyTorch APIs. We'll look into updating it.\n\nIf you'd like to contribute the fix yourself, we welcome PRs! See our [Contributing Guide](https://github.com/pytorch/tutorials/blob/main/CONTRIBUTING.md) for how to get started." + }, + "colab_environment": { + "action": "Add comment only", + "use_when": "Issue is about Google Colab environment, not the tutorial itself", + "comment": "This appears to be related to the Google Colab environment rather than the tutorial content itself. Colab environments may have different package versions or configurations than what the tutorial expects.\n\nPlease try:\n1. Restarting the Colab runtime\n2. Ensuring you're using the correct PyTorch version: `!pip install torch==`\n3. Checking the tutorial's prerequisites section for specific version requirements\n\nIf the issue persists with the correct environment setup, please update this issue with the details." + } + } +} diff --git a/.github/workflows/claude-code.yml b/.github/workflows/claude-code.yml new file mode 100644 index 0000000000..fd40ea7f3d --- /dev/null +++ b/.github/workflows/claude-code.yml @@ -0,0 +1,88 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened] + +jobs: + claude-code: + # Early exit conditions: + # 1. Must be pytorch org + # 2. Must be triggered by pilot user + # 3. Must mention @claude + if: | + github.repository_owner == 'pytorch' && + contains(fromJSON('[ + "huydhn", + "seemethere", + "malfet", + "ZainRizvi", + "jeanschmidt", + "atalman", + "wdvr", + "izaitsevfb", + "yangw-dev", + "ezyang", + "drisspg", + "albanD", + "eellison", + "pytorch-auto-revert[bot]", + "janeyx99", + "SherlockNoMad", + "svekars", + "sekyondaMeta", + "AlannaBurke", + "ngimel" + ]'), github.actor) && + ( + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'issues' && contains(github.event.issue.body, '@claude')) + ) + runs-on: ubuntu-latest + timeout-minutes: 60 + environment: bedrock + permissions: + contents: read + pull-requests: write + issues: write + id-token: write + steps: + # Fork PR support enabled by using izaitsevfb/claude-code-action@forked-pr-fix + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install lintrunner + run: | + pip install lintrunner==0.12.5 + lintrunner init + + - name: Configure AWS credentials via OIDC + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: arn:aws:iam::308535385114:role/gha_workflow_claude_code + aws-region: us-east-1 + + - name: Run Claude Code + uses: izaitsevfb/claude-code-action@forked-pr-fix + with: + # We filter by github.actor at workflow level, there is no point of filtering here as well + allowed_bots: "*" + claude_args: "--model global.anthropic.claude-opus-4-6-v1" + settings: '{"alwaysThinkingEnabled": true}' + use_bedrock: "true" + + - name: Upload usage metrics + if: always() + uses: pytorch/test-infra/.github/actions/upload-claude-usage@main diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..32cd16a2cd --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,62 @@ +# Project Structure + +This is the PyTorch Tutorials website (`pytorch.org/tutorials`), built with Sphinx and Sphinx Gallery. + +- `beginner_source/`, `intermediate_source/`, `advanced_source/`, `recipes_source/`, `unstable_source/` — tutorial source files (`.py` and `.rst`) +- `index.rst`, `recipes_index.rst` — card listings and toctrees for the website +- `conf.py` — Sphinx configuration (gallery dirs, extensions, theme) +- `_static/` — images, CSS, and thumbnails +- `requirements.txt` — all Python dependencies (Sphinx, tutorial packages) +- `.jenkins/` — CI build scripts, data download logic, post-processing +- `Makefile` — build entry points + +Tutorials authored as `.py` files use Sphinx Gallery format: top-level docstrings become RST prose, code blocks become executable cells. These are executed during builds and converted to Jupyter notebooks and HTML. Tutorials authored as `.rst` are static and their code is not executed. + +# Build + +- `make html-noplot` — builds HTML without executing tutorial code. Fast, no GPU needed. Use this for quick validation of RST/Sphinx structure. +- `make docs` — full build that downloads data, executes all `.py` tutorials, and produces the final site. Requires a GPU-powered machine with CUDA. +- `GALLERY_PATTERN="my_tutorial.py" make html` — build only a single tutorial by name (regex supported). + +The CI build runs inside Docker across 15 GPU-powered shards via `.jenkins/build.sh`. + +# Linting + +This repo uses `lintrunner`. Do not use `spin`, `flake8`, or other linters directly. + +- `lintrunner -m main` — lint changes relative to the main branch +- `lintrunner --all-files` — lint all files in the repo + +Lintrunner checks trailing whitespace, tabs, and newline issues only. It does not check Python formatting, RST syntax, or Sphinx directives. + +# Testing + +There is no unit test suite. Validation is done by building tutorials: + +- `make html-noplot` is the quick sanity check for RST and Sphinx errors. +- Full execution of `.py` tutorials runs in CI on GPU shards. +- To test a single tutorial: `GALLERY_PATTERN="my_tutorial.py" make html` + +# Tutorial File Format + +- Interactive tutorials are `.py` files using Sphinx Gallery conventions. Filenames should end in `_tutorial.py`. +- Non-interactive tutorials are `.rst` files. +- Data dependencies must be added via `.jenkins/download_data.py`, not the Makefile. Follow the existing patterns in that file. +- New Python package dependencies go in `requirements.txt`. + +# Adding a New Tutorial + +1. Place the file in the appropriate `*_source/` directory based on difficulty level. +2. Add a `customcarditem` entry in `index.rst` (or `recipes_index.rst` for recipes). +3. Add the tutorial to the corresponding `toctree` in `index.rst`. +4. Add a square, high-resolution thumbnail image to `_static/img/thumbnails/cropped/`. + +# Coding Style Guidelines + +Follow these rules for all code changes in this repository: + +- Minimize comments; be concise; code should be self-explanatory. +- Match existing code style and architectural patterns. +- Tutorial prose should be written for a global audience with clear, easy to understand language. Avoid idioms. +- Use active voice in tutorial instructions. +- If uncertain, choose the simpler, more concise implementation.