Post the model linter's first pass as a PR review - #47760
Conversation
New model PRs currently get their structural conventions taught by hand, one line comment at a time, across several review rounds: reuse the MLP that exists, read the dimension off the config, drop the wrapper module, name it hidden_size. The linter already knows all of it, but nobody sees its output until a maintainer runs it. This runs transformers-mlinter on the model files a PR touches and posts the result as a single review with inline comments, so the mechanical pass is done before a human starts reading. Each comment carries the rule id, what to change, a collapsed rationale with an example diff, and the `# trf-ignore: TRFxxx` escape hatch. It is advisory and does not block. Fires on `opened`/`reopened` only, and refuses to post twice on the same PR, so it is a first pass rather than a bot commenting on every push. Split across two workflows for the usual reason: the job that runs untrusted PR code has `contents: read` and only uploads an artifact, and a separate `workflow_run` job holds `pull-requests: write` and never checks out PR code. Follows the pattern already used by pr-ci-post-dashboard-link.yml. - utils/collect_mlinter_findings.py writes findings + the rule explanations that fired to JSON. - utils/post_mlinter_review.py turns that into the review, anchoring each comment to a line that is actually in the diff and listing the rest in a collapsed summary. Falls back to a summary-only review if the API rejects the anchors. - tests/utils/test_post_mlinter_review.py covers the diff parser and the rendering.
CI recapDashboard: View test results in Grafana |
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
stevhliu
left a comment
There was a problem hiding this comment.
PR: #47760
Decision: NO
Reasoning: This PR adds GitHub Actions workflows and helper/test code for an automated, advisory model-linter review on model PRs. It changes CI/contributor automation only; it introduces no public API, runtime behavior, common user workflow, dependency requirement, CLI, or migration.
Docs to update: None
Notes: Existing docs/source/en/modeling_rules.md and docs/source/en/pr_checks.md already cover the model-structure rules, local linter commands, suppressions, and pull-request checks.
What this does
Runs
transformers-mlinteron the model files a PR touches and posts the result as one review with inline comments, so the mechanical pass is already done when a human starts reading.Each inline comment carries the rule id, what to change, a collapsed rationale with an example diff, and the
# trf-ignore: TRFxxxescape hatch. The review body opens with a per-rule table and a plain statement that it is automated and advisory.Here is the actual output, generated locally against a synthetic new model:
…and one of the inline comments:
Why
New model PRs get their structural conventions taught by hand, one line comment at a time, across several rounds. Across the 52 PRs in this repo that drew more than 100 review comments, reuse an existing model appears in 50 of them, config hygiene in 51, naming in 51, tests in 52 — and one reviewer carries 40% of that labour. The linter already knows most of it; nobody sees its output until a maintainer runs it.
Triggering
openedandreopenedonly, and the poster refuses to post twice on the same PR (it looks for its own marker in existing reviews). This is a first pass, not a bot that comments on every push.Security
Split across two workflows, following
pr-ci-post-dashboard-link.yml:mlinter.yml—pull_request,contents: read. Runs the linter over untrusted PR code and only uploads an artifact. No token that can write anything.mlinter-review.yml—workflow_run, holdspull-requests: write, never checks out PR code. It downloads the artifact and fetches the review script bygithub.workflow_sharather than from the PR branch, so a PR cannot alter the script that runs with write access.No
pull_request_targetand no checkout of a fork's head in a privileged context.Robustness
Testing
tests/utils/test_post_mlinter_review.py— 9 tests over the diff parser (hunk headers with and without counts, deletions excluded, malformed patches) and the rendering. I also ran the collector end-to-end against a synthetic new model in a real checkout to produce the output quoted above.One note: my first attempt to test this planted a violation in
modeling_llama.pyand got zero findings — llama predates the rules'cutoff_date, so it is exempt. Worth knowing if you test this by hand: use a new model directory.Depends on
The rules quoted above (
TRF023,TRF025–TRF031) are in flight in huggingface/transformers-mlinter#15, #16, #18 and #19. This PR works with whatever is released — it readsDEFAULT_ENABLED_TRF_RULESat runtime — but it pinstransformers-mlinter>=0.1.2, which today shipsTRF001–TRF021. Bump that floor once the new rules are released if you want them included.