Files
club-3090/scripts/tests/test-baselines.sh
T
noonghunnaandClaude Fable 5 34b31c0aa4 catalog-baselines slice 2c: canonical two-depth prefill/TTFT probe + anchor calibration
Decode-only TPS can't express real trade-offs anymore (the W8A8-vs-FP8
result was a prefill-corner-vs-decode-corner split) — this adds the
CANONICAL prefill/TTFT measurement to bench.sh per the design's sourcing
rule, with the protocol gotchas productized:

- bench.sh PREFILL PROBE (default-on; PREFILL_PROBE=0 / PREFILL_DEPTHS /
  PREFILL_RUNS): warm + n measured per depth (10K + 90K anchors; 90K is
  inside the DeltaNet degradation regime and pairs with the NIAH ladder's
  ~94K rung). CACHE-BUSTED: fresh salted haystack per request — composes
  serve enable_prefix_caching, an identical prompt re-measures the CACHE
  HIT (vLLM's prefix cache is block-chained; unique first line breaks the
  chain). SELF-CALIBRATING: word-count heuristics overshoot tokens ~1.3x;
  the warmup's reported prompt_toks scales the measured runs (target^2/
  actual) to within ~4% of the requested depth. Depths exceeding the
  served ctx SKIP with a note. DUAL METRIC, labeled: prompt_tokens/TTFT =
  client-observed (user-truth: incl tokenization+transfer+scheduling) AND
  the vLLM stats-log windowed rate = engine-internal (compute-truth) —
  at 93K on A1 they differ by ~7s of non-prefill overhead (5.5K vs ~10K
  t/s); never cross-compare kinds (stack LEARNINGS row added).

- measurement_record parser: per-block pass -> prefill_tps_by_ctx +
  ttft_ms_by_ctx extensions; the canonical short-prompt ttft_s is
  PROTECTED from the probe blocks (the old last-occurrence rule would
  have swallowed the 90K block's 17s TTFT).

- catalog-baseline.sh: rows gain prefill_tps {10k: N, 90k: M} (parsed
  via THE record parser, no second grammar) + ANCHOR CALIBRATION at
  induction: the probe's deep anchor vs the NIAH ladder's nearest rung —
  agreement (0.7-1.3) certifies the ladder's whole depth curve; A1 live:
  probe 5459-5584 t/s @93K vs ladder 7403 @94K = ratio 0.74-0.75, OK.
  Divergence warns with an investigate message (design: a finding).

- test-baselines schema: prefill_tps = dict of numeric depth points.
  test-catalog-baseline fixture: probe blocks + TTFT-pollution guard +
  anchor-OK assertion.

Live-validated 3x against the serving A1 (262K): 10K = 7977 t/s CV 1.1%
TTFT 1.25s; 93K = 5584 t/s CV 0.5% TTFT 16.1s; engine-log ~10K t/s.
Full scripts gate green.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EfF565T9eSLaqGzidyJ1Pm
2026-07-04 16:22:48 +00:00

133 lines
5.3 KiB
Bash

#!/usr/bin/env bash
# test-baselines — guards for scripts/lib/profiles/baselines.yml + its
# registry-emit join (catalog-baselines slice 1).
#
# REDs on: schema violations · unknown slugs · ctx parity breaks (functional
# slugs: compose MAX_MODEL_LEN/CTX_SIZE default must equal registry max_ctx) ·
# a seeded slug missing its joined baseline in the --json contract.
# WARNs (never reds) on: pin-staleness (engine_pin != current pin) — pin bumps
# must not block on immediate re-bench; the debt just stays visible.
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$ROOT_DIR"
# --- 1-3. schema + slug membership + ctx parity (pure python asserts) --------
python3 - <<'PY'
import re
import sys
from datetime import date
from pathlib import Path
import yaml
sys.path.insert(0, ".")
from scripts.lib.profiles.compose_registry import COMPOSE_REGISTRY # noqa: E402
doc = yaml.safe_load(Path("scripts/lib/profiles/baselines.yml").read_text())
assert doc.get("schema_version") == 1, "schema_version must be 1"
rows = doc.get("baselines") or {}
assert rows, "baselines.yml has no rows"
QUALITY_RE = re.compile(r"^\d{1,3}/150$")
errors = []
for slug, row in rows.items():
where = f"baselines[{slug}]"
if slug not in COMPOSE_REGISTRY:
errors.append(f"{where}: unknown registry slug"); continue
for k in ("narr_tps", "code_tps"):
if not isinstance(row.get(k), (int, float)):
errors.append(f"{where}.{k}: required numeric")
if not isinstance(row.get("date"), date):
errors.append(f"{where}.date: required YYYY-MM-DD")
for k in ("engine_pin", "rig", "submitted_by"):
if not (isinstance(row.get(k), str) and row[k].strip()):
errors.append(f"{where}.{k}: required non-empty string")
pw = row.get("power_cap_w")
if not (isinstance(pw, list) and pw and all(isinstance(x, int) for x in pw)):
errors.append(f"{where}.power_cap_w: required list of ints")
# optional, typed when present
if "ttft_ms" in row and not isinstance(row["ttft_ms"], (int, float)):
errors.append(f"{where}.ttft_ms: numeric")
for k in ("quality_8pk", "quality_8pk_think_on"):
if k in row and not QUALITY_RE.match(str(row[k])):
errors.append(f"{where}.{k}: must look like 'P/150'")
if "ctx_validated" in row:
cv = row["ctx_validated"]
ok = (isinstance(cv, dict) and isinstance(cv.get("tokens"), int)
and isinstance(cv.get("niah"), str))
if not ok:
errors.append(f"{where}.ctx_validated: {{tokens: int, niah: str}}")
if "prefill_tps" in row:
pf = row["prefill_tps"]
ok = (isinstance(pf, dict) and pf
and all(isinstance(v, (int, float)) for v in pf.values()))
if not ok:
errors.append(f"{where}.prefill_tps: dict of numeric depth points (e.g. {{10k: N, 90k: M}})")
if "source_tag" in row and not isinstance(row["source_tag"], str):
errors.append(f"{where}.source_tag: string")
# ctx parity (functional slugs): compose ctx-env default == registry max_ctx.
CTX_RE = re.compile(r"\$\{(?:MAX_MODEL_LEN|CTX_SIZE|MAX_CTX)[^:}]*:-(\d+)\}")
for slug, e in COMPOSE_REGISTRY.items():
if e["status"] not in ("production", "caveats"):
continue
try:
txt = Path(e["compose_path"]).read_text()
except OSError:
errors.append(f"ctx-parity[{slug}]: compose unreadable: {e['compose_path']}")
continue
m = CTX_RE.search(txt)
if m and int(m.group(1)) != e["max_ctx"]:
errors.append(
f"ctx-parity[{slug}]: compose default {m.group(1)} != registry max_ctx {e['max_ctx']}"
)
if errors:
print("test-baselines: FAIL", file=sys.stderr)
for err in errors:
print(f" ✗ {err}", file=sys.stderr)
sys.exit(1)
print(f" ✓ schema + slug membership + ctx parity ({len(rows)} rows)")
PY
# --- 4-5. the join contract + staleness WARNs --------------------------------
# shellcheck source=/dev/null
source scripts/lib/registry-emit.sh
json="$(registry_variant_rows_json "$ROOT_DIR")"
# Env (not a pipe): the heredoc below owns the python interpreter's stdin —
# the same trick registry-emit itself uses for REGISTRY_TAB.
EMIT_JSON="$json" python3 - <<'PY'
import json
import os
import sys
from pathlib import Path
import yaml
d = json.loads(os.environ["EMIT_JSON"])
by_slug = {v["slug"]: v for v in d["variants"]}
rows = yaml.safe_load(Path("scripts/lib/profiles/baselines.yml").read_text())["baselines"]
missing = [s for s in rows if not (by_slug.get(s) or {}).get("baseline")]
if missing:
print(f"test-baselines: FAIL — seeded slugs missing joined baseline: {missing}",
file=sys.stderr)
sys.exit(1)
# every joined row must carry the computed staleness verdict key
bad = [s for s in rows if "stale" not in by_slug[s]["baseline"]]
if bad:
print(f"test-baselines: FAIL — joined rows missing 'stale': {bad}", file=sys.stderr)
sys.exit(1)
stale = [s for s in rows if by_slug[s]["baseline"]["stale"] is True]
for s in stale:
b = by_slug[s]["baseline"]
print(f" WARN: {s} baseline is STALE — measured on {b['engine_pin']!r}, "
f"current pin {b['current_pin']!r} (re-bench owed; row stays, badge shows)")
print(f" ✓ join contract ({len(rows)} joined, {len(stale)} stale-warned)")
PY
echo "test-baselines: ok"