|
12 | 12 | ``0 14 * * *`` Full CI run - daily (none) |
13 | 13 | =========================== ====================== ========================= |
14 | 14 |
|
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 closest scheduled run on the *same UTC day*. When the two |
| 16 | +fire in the same cron slot they also share a commit, which makes the pair a |
| 17 | +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. When the |
| 19 | +schedules drift apart the commits differ and the comparison is day-over-day |
| 20 | +rather than controlled -- still useful, but a regression may then be caused by |
| 21 | +vLLM commits landing between the builds. Reports flag which case they are. |
19 | 22 |
|
20 | 23 | This script finds the most recent such pair and reports the delta. It reads only |
21 | 24 | job metadata from ClickHouse -- log *contents* are not ingested (the tables carry |
|
40 | 43 | PIPELINE = "CI" |
41 | 44 |
|
42 | 45 | 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. |
| 46 | +# The baseline is whichever of these ran closest in time on the same UTC day; the |
| 47 | +# plain nightly wins ties because it shares the torch-nightly cron slot. |
| 48 | +# |
| 49 | +# Same-commit used to be required as well. That holds only while the two share a |
| 50 | +# slot, and stopped holding when torch-nightly moved to 10:00 while the baselines |
| 51 | +# stayed at 06:00/21:00: four hours of merges apart, they can never agree on a |
| 52 | +# commit again. Requiring it silently pinned every report to the last same-commit |
| 53 | +# pair (2026-08-07) while newer builds went unreported. |
| 54 | +# |
| 55 | +# The trade-off is deliberate. With different commits, a job that fails here and |
| 56 | +# passes on the baseline is no longer attributable to torch alone -- intervening |
| 57 | +# vLLM commits are also in scope -- so reports say which case they are. |
45 | 58 | BASELINE_MSGS = ("Full CI run - nightly", "Full CI run - daily") |
46 | 59 |
|
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 | | - |
51 | 60 | BAD_STATES = ("failed", "timed_out") |
52 | 61 |
|
53 | 62 | # Job names are frequently sharded ("Multi-Modal Processor (CPU) 1..4") or |
@@ -80,9 +89,10 @@ def find_latest_pair( |
80 | 89 | ) -> Optional[Tuple[Dict[str, Any], Dict[str, Any]]]: |
81 | 90 | """Return (torch_nightly_build, baseline_build) for the newest complete pair. |
82 | 91 |
|
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). |
| 92 | + The baseline is the scheduled run closest in time on the same UTC day. Returns |
| 93 | + None when no torch-nightly build exists in the window, or when none of them ran |
| 94 | + on a day that also had a baseline (in which case there is nothing to compare |
| 95 | + against and reporting raw failures would be misleading). |
86 | 96 | """ |
87 | 97 | builds = _rows( |
88 | 98 | client, |
@@ -114,18 +124,16 @@ def as_dict(row: Tuple) -> Dict[str, Any]: |
114 | 124 | if not nightlies: |
115 | 125 | return None |
116 | 126 |
|
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. |
| 127 | + # Walk newest-first rather than taking only nightlies[0]. A torch-nightly build |
| 128 | + # can still land on a day with no scheduled baseline at all (manual trigger on a |
| 129 | + # weekend); stopping at the newest would then report nothing rather than falling |
| 130 | + # back to the most recent day that is comparable. |
121 | 131 | for target in nightlies: |
122 | 132 | candidates = [ |
123 | 133 | b |
124 | 134 | for b in parsed |
125 | 135 | 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 |
| 136 | + and b["created_at"].date() == target["created_at"].date() |
129 | 137 | ] |
130 | 138 | if not candidates: |
131 | 139 | continue |
@@ -243,17 +251,39 @@ def render( |
243 | 251 | agents = agent_concentration(regressed) |
244 | 252 | top_agent_share = (agents[0][1] / len(regressed)) if regressed else 0.0 |
245 | 253 |
|
| 254 | + same_commit = tn["commit"] == base["commit"] |
246 | 255 | out: List[str] = [] |
| 256 | + if same_commit: |
| 257 | + out.append( |
| 258 | + f"**{len(regressed)} job(s) regressed** on torch nightly " |
| 259 | + f"[#{tn['number']}]({tn['url']}) versus baseline " |
| 260 | + f"[#{base['number']}]({base['url']}), both at commit " |
| 261 | + f"`{tn['commit'][:12]}`.\n" |
| 262 | + ) |
| 263 | + else: |
| 264 | + # Different commits: the comparison is same-day, not a controlled A/B, so |
| 265 | + # a "regression" can also come from vLLM commits landing between the two. |
| 266 | + gap_hours = (base["created_at"] - tn["created_at"]).total_seconds() / 3600 |
| 267 | + out.append( |
| 268 | + f"**{len(regressed)} job(s) regressed** on torch nightly " |
| 269 | + f"[#{tn['number']}]({tn['url']}) versus same-day baseline " |
| 270 | + f"[#{base['number']}]({base['url']}) ({gap_hours:+.1f}h).\n\n" |
| 271 | + f"> :warning: The two builds ran **different commits** " |
| 272 | + f"(`{tn['commit'][:12]}` vs `{base['commit'][:12]}`), so this is a " |
| 273 | + f"same-day comparison rather than a controlled A/B. A regression here " |
| 274 | + f"may be caused by vLLM commits landing between the builds rather than " |
| 275 | + f"by torch nightly.\n" |
| 276 | + ) |
| 277 | + out.append("| | build | commit | outcome |") |
| 278 | + out.append("|---|---|---|---|") |
| 279 | + out.append( |
| 280 | + f"| torch nightly | [#{tn['number']}]({tn['url']}) " |
| 281 | + f"| `{tn['commit'][:12]}` | {tn['state']} |" |
| 282 | + ) |
247 | 283 | 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" |
| 284 | + f"| baseline | [#{base['number']}]({base['url']}) " |
| 285 | + f"| `{base['commit'][:12]}` | {base['state']} |" |
252 | 286 | ) |
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']} |") |
257 | 287 | out.append( |
258 | 288 | f"\n- regressed (fails here, passes on baseline): **{len(regressed)}**\n" |
259 | 289 | f"- fails on both (pre-existing, not torch): {len(buckets['both'])}\n" |
@@ -443,7 +473,7 @@ def main() -> int: |
443 | 473 | pair = find_latest_pair(client, args.lookback_days) |
444 | 474 | if pair is None: |
445 | 475 | print( |
446 | | - f"No torch-nightly build with a same-commit baseline in the last " |
| 476 | + f"No torch-nightly build with a same-day baseline in the last " |
447 | 477 | f"{args.lookback_days} days; nothing to compare.", |
448 | 478 | file=sys.stderr, |
449 | 479 | ) |
|
0 commit comments