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
133 lines
5.3 KiB
Bash
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"
|