Skip to content

Commit 5ae9e8a

Browse files
authored
Pair the torch-nightly triage by day against the pinned nightly (#8522)
## Why The triage compared a torch-nightly build only against a baseline that ran the **same commit** within 900s. That held while both fired in the same cron slot. It stopped holding when torch-nightly moved to 10:00 and the baselines stayed at 06:00/21:00 — four hours of merges apart, they can never agree on a commit again. `find_latest_pair` walks newest-first and *skips* any nightly without a match, so rather than reporting nothing it silently pinned every run to the last same-commit pair, **#82789/#82790 from 2026-08-07**. The workflow kept succeeding and #8491 kept being told *"still reproducing on #82789"* while #83159, #83338 and #83539 went unexamined. No failure, no warning — just an increasingly old build number. ``` 83539 Aug 12 10:00 -> no same-commit baseline skipped 83338 Aug 11 10:00 -> no same-commit baseline skipped 83159 Aug 10 15:14 -> no same-commit baseline skipped 82789 Aug 7 06:00 -> 82790 selected ``` ## What changes **1. Pair on the same UTC day** rather than the same commit. | | same-commit | same-day | | --- | --- | --- | | torch-nightly builds paired (21d) | 6/12 | **12/12** | | baseline chosen on the 6 days both rules work | — | **identical** | Nothing regresses; the coverage gap closes. **2. Prefer `Full CI run - nightly` over `Full CI run - daily`**, then closest in time. The plain nightly is the *pinned-torch counterpart* of the torch-nightly build — same pipeline, same schedule, differing only by `TORCH_NIGHTLY=1`. Under a time-first ordering, 2026-08-10 would have compared against the daily (+5.8h) instead of the pinned nightly (-9.2h). Resulting pairings over 21 days — every one against a pinned `- nightly`: ``` 83539 2026-08-12 -> 83511 (nightly -4.0h) 83338 2026-08-11 -> 83298 (nightly -4.0h) 83159 2026-08-10 -> 83094 (nightly -9.2h) 82789 2026-08-07 -> 82790 (nightly +0.0h) 82682 2026-08-06 -> 82629 (nightly -7.4h) 82454 2026-08-05 -> 82455 (nightly +0.0h) ... ``` ## The trade-off, made explicit With different commits the pair is no longer a controlled A/B — a regression may come from vLLM commits landing between the two builds rather than from torch. Reports now say which case they are: > ⚠️ The two builds ran **different commits** (`6accb779a361` vs `02ac17851dfb`), so this is a same-day comparison rather than a controlled A/B. A regression here may be caused by vLLM commits landing between the builds rather than by torch nightly. plus the `±Nh` gap and both commits in the summary table (which gains a commit column). Same-commit pairs read exactly as before. ## Test plan - `find_latest_pair` against live ClickHouse rows now returns **#83539 (torch nightly, Aug 12 10:00) vs #83511 (pinned nightly, Aug 12 06:00)**; before: #82789/#82790 from Aug 7. - Simulated over 21 days: 12/12 paired (was 6/12), all against `- nightly`, identical to the old choice on every day the old rule worked. - Job-set sizes are comparable across the three build types (315–321 distinct job names), so the comparison is not skewed by one type running a materially different set. - Rendered a report both ways — the warning appears only when commits differ. - `ruff check` / `ruff format --check` clean. Fixes the staleness behind #8491. Authored with the assistance of Claude Code.
1 parent 7313fe5 commit 5ae9e8a

1 file changed

Lines changed: 45 additions & 31 deletions

File tree

tools/torchci/vllm_torch_nightly_triage.py

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
``0 14 * * *`` Full CI run - daily (none)
1313
=========================== ====================== =========================
1414
15-
On Mon/Tue/Thu the torch-nightly build and the plain nightly fire in the *same
16-
second* on the *same commit*, differing only by ``TORCH_NIGHTLY=1``. That pair is
17-
a controlled A/B: a job failing in the former and passing in the latter is
18-
attributable to torch nightly, with the vLLM variable held constant.
15+
The baseline is the plain nightly from the *same UTC day*, differing only by
16+
``TORCH_NIGHTLY=1``. When both fire in the same cron slot they also share a
17+
commit and the pair is a controlled A/B; otherwise the comparison is
18+
day-over-day and a regression may instead come from vLLM commits landing
19+
between the builds. Reports state which case they are.
1920
2021
This script finds the most recent such pair and reports the delta. It reads only
2122
job metadata from ClickHouse -- log *contents* are not ingested (the tables carry
@@ -40,14 +41,10 @@
4041
PIPELINE = "CI"
4142

4243
TORCH_NIGHTLY_MSG = "Full CI run torch nightly"
43-
# The plain nightly shares the torch-nightly cron slot; the daily is the fallback
44-
# baseline when a same-second sibling is missing.
44+
# The plain nightly is the pinned-torch counterpart of the torch-nightly build;
45+
# the daily is the fallback when a day has no plain nightly.
4546
BASELINE_MSGS = ("Full CI run - nightly", "Full CI run - daily")
4647

47-
# A build is only a valid control if it ran the same commit. Buildkite schedules
48-
# fire at the same instant but a commit can land between them in principle.
49-
SIBLING_WINDOW_SECONDS = 900
50-
5148
BAD_STATES = ("failed", "timed_out")
5249

5350
# Job names are frequently sharded ("Multi-Modal Processor (CPU) 1..4") or
@@ -80,9 +77,10 @@ def find_latest_pair(
8077
) -> Optional[Tuple[Dict[str, Any], Dict[str, Any]]]:
8178
"""Return (torch_nightly_build, baseline_build) for the newest complete pair.
8279
83-
Returns None when no torch-nightly build exists in the window, or when the
84-
newest one has no same-commit baseline (in which case there is nothing to
85-
compare against and reporting raw failures would be misleading).
80+
The baseline is the scheduled run closest in time on the same UTC day. Returns
81+
None when no torch-nightly build exists in the window, or when none of them ran
82+
on a day that also had a baseline (in which case there is nothing to compare
83+
against and reporting raw failures would be misleading).
8684
"""
8785
builds = _rows(
8886
client,
@@ -114,26 +112,22 @@ def as_dict(row: Tuple) -> Dict[str, Any]:
114112
if not nightlies:
115113
return None
116114

117-
# Walk newest-first rather than taking only nightlies[0]. Off-schedule
118-
# torch-nightly builds happen (manual triggers land outside the 06:00 slot and
119-
# have no sibling); stopping at the newest would let one of those mask the most
120-
# recent genuinely comparable pair.
115+
# Walk newest-first rather than taking only nightlies[0]: a torch-nightly build
116+
# can land on a day with no scheduled baseline at all.
121117
for target in nightlies:
122118
candidates = [
123119
b
124120
for b in parsed
125121
if b["title"].startswith(BASELINE_MSGS)
126-
and b["commit"] == target["commit"]
127-
and abs((b["created_at"] - target["created_at"]).total_seconds())
128-
<= SIBLING_WINDOW_SECONDS
122+
and b["created_at"].date() == target["created_at"].date()
129123
]
130124
if not candidates:
131125
continue
132-
# Prefer the closest in time; ties favour the plain nightly (same cron slot).
126+
# Plain nightly first, then closest in time.
133127
candidates.sort(
134128
key=lambda b: (
135-
abs((b["created_at"] - target["created_at"]).total_seconds()),
136129
0 if b["title"].startswith(BASELINE_MSGS[0]) else 1,
130+
abs((b["created_at"] - target["created_at"]).total_seconds()),
137131
)
138132
)
139133
return target, candidates[0]
@@ -243,17 +237,37 @@ def render(
243237
agents = agent_concentration(regressed)
244238
top_agent_share = (agents[0][1] / len(regressed)) if regressed else 0.0
245239

240+
same_commit = tn["commit"] == base["commit"]
246241
out: List[str] = []
242+
if same_commit:
243+
out.append(
244+
f"**{len(regressed)} job(s) regressed** on torch nightly "
245+
f"[#{tn['number']}]({tn['url']}) versus baseline "
246+
f"[#{base['number']}]({base['url']}), both at commit "
247+
f"`{tn['commit'][:12]}`.\n"
248+
)
249+
else:
250+
gap_hours = (base["created_at"] - tn["created_at"]).total_seconds() / 3600
251+
out.append(
252+
f"**{len(regressed)} job(s) regressed** on torch nightly "
253+
f"[#{tn['number']}]({tn['url']}) versus same-day baseline "
254+
f"[#{base['number']}]({base['url']}) ({gap_hours:+.1f}h).\n\n"
255+
f"> :warning: The two builds ran **different commits** "
256+
f"(`{tn['commit'][:12]}` vs `{base['commit'][:12]}`), so this is a "
257+
f"same-day comparison rather than a controlled A/B. A regression here "
258+
f"may be caused by vLLM commits landing between the builds rather than "
259+
f"by torch nightly.\n"
260+
)
261+
out.append("| | build | commit | outcome |")
262+
out.append("|---|---|---|---|")
263+
out.append(
264+
f"| torch nightly | [#{tn['number']}]({tn['url']}) "
265+
f"| `{tn['commit'][:12]}` | {tn['state']} |"
266+
)
247267
out.append(
248-
f"**{len(regressed)} job(s) regressed** on torch nightly "
249-
f"[#{tn['number']}]({tn['url']}) versus baseline "
250-
f"[#{base['number']}]({base['url']}), both at commit "
251-
f"`{tn['commit'][:12]}`.\n"
268+
f"| baseline | [#{base['number']}]({base['url']}) "
269+
f"| `{base['commit'][:12]}` | {base['state']} |"
252270
)
253-
out.append("| | build | outcome |")
254-
out.append("|---|---|---|")
255-
out.append(f"| torch nightly | [#{tn['number']}]({tn['url']}) | {tn['state']} |")
256-
out.append(f"| baseline | [#{base['number']}]({base['url']}) | {base['state']} |")
257271
out.append(
258272
f"\n- regressed (fails here, passes on baseline): **{len(regressed)}**\n"
259273
f"- fails on both (pre-existing, not torch): {len(buckets['both'])}\n"
@@ -443,7 +457,7 @@ def main() -> int:
443457
pair = find_latest_pair(client, args.lookback_days)
444458
if pair is None:
445459
print(
446-
f"No torch-nightly build with a same-commit baseline in the last "
460+
f"No torch-nightly build with a same-day baseline in the last "
447461
f"{args.lookback_days} days; nothing to compare.",
448462
file=sys.stderr,
449463
)

0 commit comments

Comments
 (0)