ArthurZ's picture
ArthurZ HF Staff
wire /bisect endpoint + auto-clone transformers on first run
b021f63 verified
Raw
History Blame Contribute Delete
4.52 kB
"""Extract integration-test failures and intersect across days.
An "integration test" here = a failure whose pytest path uses a class whose name
ends with `IntegrationTest` or `IntegrationTests`. This matches the canonical
shape at `tests/models/llama4/test_modeling_llama4.py::Llama4IntegrationTest` and
`tests/models/deepseek_v4/...::DeepseekV4IntegrationTest`.
"""
from __future__ import annotations
from collections import defaultdict
from typing import Iterable
INTEGRATION_SUFFIXES = ("IntegrationTest", "IntegrationTests")
def is_integration_test(test_path: str) -> bool:
"""`tests/models/foo/test_modeling_foo.py::FooIntegrationTest::test_x` → True."""
if "::" not in test_path:
return False
cls = test_path.split("::")[1]
return cls.endswith(INTEGRATION_SUFFIXES)
def model_name_from_key(key: str) -> str:
"""`models_align` → `align`. (CI keys model_results entries this way.)"""
return key.removeprefix("models_")
def model_name_from_test_path(test_path: str) -> str:
"""`tests/models/foo/test_modeling_foo.py::...` → `foo`."""
parts = test_path.split("/")
if len(parts) < 3 or parts[0] != "tests" or parts[1] != "models":
return ""
return parts[2]
def iter_failures(model_results: dict) -> Iterable[dict]:
"""Yield one record per (model, gpu, test) failure from a single day's
`model_results.json`. Each record is:
{
"model": "align",
"gpu": "single" | "multi",
"test": "tests/models/.../...::Class::test_x",
"trace": "...",
}
Only integration-test failures are yielded.
"""
for key, entry in model_results.items():
if not isinstance(entry, dict):
continue
model = model_name_from_key(key)
failures = entry.get("failures") or {}
for gpu, items in failures.items():
# `failures` is `{"single": [...], "multi": [...]}` — strip the
# `-gpu` suffix CI sometimes uses to match `new_failures` shape.
gpu = gpu.replace("-gpu", "")
for it in items or []:
test = it.get("line", "")
if not is_integration_test(test):
continue
yield {
"model": model,
"gpu": gpu,
"test": test,
"trace": (it.get("trace") or "").strip(),
}
def intersect_across_days(per_day: dict[str, list[dict]], min_days: int = 5) -> list[dict]:
"""Keep `(model, gpu, test)` triples seen on ≥ min_days days.
Returns one record per surviving triple, enriched with `days_seen`,
`first_seen`, `latest_trace`.
"""
seen: dict[tuple[str, str, str], dict] = {}
for date in sorted(per_day): # ascending so latest_trace ends up newest
for rec in per_day[date]:
key = (rec["model"], rec["gpu"], rec["test"])
existing = seen.get(key)
if existing is None:
seen[key] = {
**rec,
"days_seen": 1,
"first_seen": date,
"latest_seen": date,
"latest_trace": rec["trace"],
}
else:
existing["days_seen"] += 1
existing["latest_seen"] = date
existing["latest_trace"] = rec["trace"]
return [r for r in seen.values() if r["days_seen"] >= min_days]
def per_day_integration_failures(daily: dict[str, dict[str, dict | None]]) -> dict[str, list[dict]]:
"""`daily` is the output of `fetch.fetch_last_n`."""
out: dict[str, list[dict]] = defaultdict(list)
for date, payload in daily.items():
mr = payload.get("model_results") if payload else None
if not mr:
continue
out[date] = list(iter_failures(mr))
return out
if __name__ == "__main__":
import sys
from fetch import fetch_last_n
daily = fetch_last_n(7, cache_dir=sys.argv[1] if len(sys.argv) > 1 else None)
per_day = per_day_integration_failures(daily)
for d, rows in sorted(per_day.items()):
print(f"{d}: {len(rows)} integration-test failures")
kept = intersect_across_days(per_day, min_days=5)
print(f"\nKept after ≥5/7 intersection: {len(kept)} unique failures")
for r in kept[:6]:
print(f" {r['model']:<28} {r['gpu']:<6} {r['days_seen']}/7 {r['test'].split('::')[-1]}")
if len(kept) > 6:
print(f" ... and {len(kept) - 6} more")