`core bench --suite teaching-loop [--runs N]` runs the full reviewed- corpus extension pipeline (propose → real replay-equivalence gate → operator accept) N times against an identical input and asserts byte-identical artifacts every run: - proposal_id (SHA-256 of canonical-JSON payload) - replay_baseline (cognition lane metrics on active corpus) - replay_candidate (cognition lane metrics on transient corpus) - regressed_metrics (sorted tuple) - chain_id_written Also reports per-iteration latency (mean / p50 / p95) and total wall. 100-run result against today's main: unique(proposal_id)=1 unique(baseline)=1 unique(candidate)=1 unique(chain_id)=1 active_corpus_byte_eq=True mean=1.849s p50=1.838s p95=1.851s The full learning loop is replayable bit-identically across N independent invocations. Pairs naturally with ADR-0045's 100% exact- NIAH recall numbers — same epistemic class of guarantee, applied to the *learning loop* itself rather than only to retrieval. No LLM provider can publish equivalent numbers on a learning path. - benchmarks/teaching_loop.py — `run_teaching_loop_determinism(runs)` returns a typed `TeachingLoopBenchReport` with uniqueness counts, determinism flag, byte-identical-active-corpus flag, and latency distribution (mean / p50 / p95 / total). Pure-stdlib percentile — no numpy dep on this path. - benchmarks/run_benchmarks.py — `bench_teaching_loop_determinism` shim + `_SUITES["teaching-loop"]` registration + runs= passthrough. - core/cli.py — `--suite teaching-loop` choice added to bench parser. - tests/test_teaching_loop_bench.py — 5 tests pin determinism at small N, proposal_id SHA-256 shape, canonical chain_id layout, latency stats well-formedness, JSON serialisation. Trust boundary: every write is confined to a tempdir created inside the bench loop; the active corpus is read once at start, once at end, and any byte difference would fail the bench.
390 lines
12 KiB
Python
390 lines
12 KiB
Python
"""CORE benchmark harness — determinism, latency, backend speedup, and field invariants.
|
|
|
|
Measures properties that structurally distinguish CORE from stochastic LLMs:
|
|
- Determinism: same prompt -> identical trace hash across N runs (LLMs: 0%)
|
|
- Latency: time-to-first-surface for the pulse loop
|
|
- Backend speedup: Rust vs Python on the same pulse workload
|
|
- Versor closure: every intermediate state satisfies the field invariant
|
|
|
|
Usage:
|
|
core bench # run all benchmarks
|
|
core bench --suite determinism # run one suite
|
|
core bench --json # machine-readable output
|
|
core bench --runs 50 # override run count for determinism
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import time
|
|
from dataclasses import dataclass, field
|
|
|
|
import numpy as np
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class BenchResult:
|
|
name: str
|
|
passed: bool
|
|
metric: float
|
|
unit: str
|
|
detail: str
|
|
|
|
|
|
@dataclass(slots=True)
|
|
class BenchReport:
|
|
results: list[BenchResult] = field(default_factory=list)
|
|
|
|
def as_dict(self) -> dict:
|
|
return {
|
|
"results": [
|
|
{
|
|
"name": r.name,
|
|
"passed": r.passed,
|
|
"metric": round(r.metric, 6),
|
|
"unit": r.unit,
|
|
"detail": r.detail,
|
|
}
|
|
for r in self.results
|
|
],
|
|
"all_passed": all(r.passed for r in self.results),
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Determinism benchmark
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_determinism(runs: int = 20) -> BenchResult:
|
|
"""Run the same prompt N times, check that trace hashes are identical."""
|
|
from scripts.run_pulse import run_pulse
|
|
|
|
prompt = "What is truth?"
|
|
surfaces: list[str] = []
|
|
words: list[tuple[str, ...]] = []
|
|
|
|
for _ in range(runs):
|
|
result = run_pulse(prompt, use_glove=False)
|
|
surfaces.append(result.surface)
|
|
words.append(result.recalled_words)
|
|
|
|
unique_surfaces = len(set(surfaces))
|
|
unique_words = len(set(words))
|
|
passed = unique_surfaces == 1 and unique_words == 1
|
|
|
|
return BenchResult(
|
|
name="determinism",
|
|
passed=passed,
|
|
metric=1.0 if passed else unique_surfaces / runs,
|
|
unit="consistency_ratio",
|
|
detail=f"{runs} runs, {unique_surfaces} unique surfaces, {unique_words} unique recall sets",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Latency benchmark
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_latency(iterations: int = 10) -> BenchResult:
|
|
"""Measure time-to-first-surface for the pulse loop."""
|
|
from scripts.run_pulse import run_pulse
|
|
|
|
prompts = [
|
|
"What is truth?",
|
|
"Compare knowledge and wisdom",
|
|
"Why does light exist?",
|
|
"What is meaning?",
|
|
"How do I define a concept?",
|
|
]
|
|
|
|
times: list[float] = []
|
|
for _ in range(iterations):
|
|
for prompt in prompts:
|
|
t0 = time.perf_counter()
|
|
run_pulse(prompt, use_glove=False)
|
|
elapsed = time.perf_counter() - t0
|
|
times.append(elapsed)
|
|
|
|
median = float(np.median(times))
|
|
p95 = float(np.percentile(times, 95))
|
|
|
|
return BenchResult(
|
|
name="latency",
|
|
passed=True,
|
|
metric=median,
|
|
unit="seconds_median",
|
|
detail=f"median={median:.4f}s, p95={p95:.4f}s, n={len(times)} pulses",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Backend speedup benchmark
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_backend_speedup() -> BenchResult:
|
|
"""Compare Rust vs Python backend on the same pulse workload."""
|
|
from field.operators import GraphDiffusionOperator
|
|
from language_packs.compiler import load_pack
|
|
from scripts.run_pulse import _build_manifold
|
|
|
|
_, manifold = load_pack("en_core_cognition_v1")
|
|
state, _, _ = _build_manifold("what is truth and light and knowledge", manifold)
|
|
op = GraphDiffusionOperator(damping=0.5)
|
|
|
|
steps = 200
|
|
|
|
import importlib
|
|
import algebra.backend as _ab_mod
|
|
from field import operators as _ops_mod
|
|
|
|
# Rust path (default)
|
|
t0 = time.perf_counter()
|
|
s = state
|
|
for _ in range(steps):
|
|
s, _ = op.forward(s)
|
|
rust_time = time.perf_counter() - t0
|
|
|
|
# Python path
|
|
env_backup = os.environ.get("CORE_BACKEND")
|
|
os.environ["CORE_BACKEND"] = "python"
|
|
try:
|
|
importlib.reload(_ab_mod)
|
|
_ops_mod._rust_diffusion_step = _ab_mod.diffusion_step
|
|
_ops_mod._rust_unitize = _ab_mod.unitize_expmap
|
|
|
|
op_py = GraphDiffusionOperator(damping=0.5)
|
|
t0 = time.perf_counter()
|
|
s = state
|
|
for _ in range(steps):
|
|
s, _ = op_py.forward(s)
|
|
python_time = time.perf_counter() - t0
|
|
finally:
|
|
if env_backup is not None:
|
|
os.environ["CORE_BACKEND"] = env_backup
|
|
else:
|
|
os.environ.pop("CORE_BACKEND", None)
|
|
importlib.reload(_ab_mod)
|
|
_ops_mod._rust_diffusion_step = _ab_mod.diffusion_step
|
|
_ops_mod._rust_unitize = _ab_mod.unitize_expmap
|
|
|
|
speedup = python_time / rust_time if rust_time > 0 else float("inf")
|
|
|
|
return BenchResult(
|
|
name="backend_speedup",
|
|
passed=speedup > 1.0,
|
|
metric=speedup,
|
|
unit="x_faster",
|
|
detail=f"rust={rust_time:.4f}s, python={python_time:.4f}s, {steps} diffusion steps",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Versor closure audit
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_versor_closure_audit() -> BenchResult:
|
|
"""Run pulse for all eval cases, verify versor_condition < 1e-6 at every step."""
|
|
from algebra.backend import versor_condition
|
|
from field.operators import GraphDiffusionOperator, ConstraintCorrectionOperator
|
|
from language_packs.compiler import load_pack
|
|
from scripts.run_pulse import _build_manifold
|
|
|
|
_, manifold = load_pack("en_core_cognition_v1")
|
|
prompts = [
|
|
"What is truth?", "Compare knowledge and wisdom",
|
|
"Why does light exist?", "What is meaning?",
|
|
"How do I define a concept?", "Remember truth",
|
|
"Is truth coherent?", "No, that's wrong",
|
|
]
|
|
|
|
total_states = 0
|
|
violations = 0
|
|
max_vc = 0.0
|
|
|
|
for prompt in prompts:
|
|
state, _, target = _build_manifold(prompt, manifold)
|
|
diff_op = GraphDiffusionOperator(damping=0.5)
|
|
corr_op = ConstraintCorrectionOperator(
|
|
target_versor=target, correction_rate=0.3, node_index=-1,
|
|
)
|
|
|
|
for step in range(50):
|
|
state, _ = diff_op.forward(state)
|
|
state, _ = corr_op.adjoint_pass(state)
|
|
|
|
for i in range(state.fields.shape[0]):
|
|
vc = versor_condition(state.fields[i])
|
|
total_states += 1
|
|
if vc >= 1e-6:
|
|
violations += 1
|
|
max_vc = max(max_vc, vc)
|
|
|
|
passed = violations == 0
|
|
|
|
return BenchResult(
|
|
name="versor_closure_audit",
|
|
passed=passed,
|
|
metric=max_vc,
|
|
unit="max_versor_condition",
|
|
detail=f"{total_states} field states checked, {violations} violations, max_vc={max_vc:.2e}",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Convergence proof
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_convergence_proof() -> BenchResult:
|
|
"""Verify the pulse converges for all eval prompts.
|
|
|
|
Symmetric 2-token star topologies (e.g. 'Remember truth') oscillate
|
|
under pure diffusion — this is a known property of equal-weight
|
|
inputs, not a bug. The benchmark passes if all 3+-token prompts
|
|
converge and all 2-token prompts still produce valid output.
|
|
"""
|
|
from evals.run_cognition_eval import load_cases
|
|
from scripts.run_pulse import run_pulse
|
|
|
|
cases = load_cases()
|
|
prompts = [c["prompt"] for c in cases]
|
|
|
|
converged = 0
|
|
bounded = 0
|
|
total = len(prompts)
|
|
|
|
for prompt in prompts:
|
|
result = run_pulse(prompt, use_glove=False, use_correction=False)
|
|
if result.converged:
|
|
converged += 1
|
|
elif result.recalled_words and result.surface:
|
|
bounded += 1
|
|
|
|
passed = (converged + bounded) == total
|
|
|
|
return BenchResult(
|
|
name="convergence_proof",
|
|
passed=passed,
|
|
metric=converged / total if total else 0.0,
|
|
unit="exact_convergence_rate",
|
|
detail=f"{converged}/{total} exact, {bounded}/{total} bounded oscillation, all produce output",
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Realizer join coverage
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_realizer_coverage() -> BenchResult:
|
|
"""Every intent type produces a non-empty surface from the pulse."""
|
|
from scripts.run_pulse import run_pulse
|
|
|
|
intent_prompts = {
|
|
"definition": "What is truth?",
|
|
"comparison": "Compare knowledge and wisdom",
|
|
"cause": "Why does light exist?",
|
|
"procedure": "How do I define a concept?",
|
|
"recall": "Remember truth",
|
|
"verification": "Is truth coherent?",
|
|
"correction": "No, that's wrong",
|
|
"unknown": "truth",
|
|
}
|
|
|
|
covered = 0
|
|
total = len(intent_prompts)
|
|
failures: list[str] = []
|
|
|
|
for intent_name, prompt in intent_prompts.items():
|
|
result = run_pulse(prompt, use_glove=False)
|
|
if result.surface:
|
|
covered += 1
|
|
else:
|
|
failures.append(intent_name)
|
|
|
|
passed = covered == total
|
|
|
|
return BenchResult(
|
|
name="realizer_coverage",
|
|
passed=passed,
|
|
metric=covered / total if total else 0.0,
|
|
unit="coverage_rate",
|
|
detail=f"{covered}/{total} intent types produce non-empty surface"
|
|
+ (f", missing: {failures}" if failures else ""),
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Runner
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def bench_teaching_loop_determinism(runs: int = 10) -> BenchResult:
|
|
"""Run propose → replay → accept N times; assert byte-identical artifacts.
|
|
|
|
This is the determinism benchmark for the *learning loop* itself
|
|
(ADR-0055..0057): per-fact provenance, replay-equivalence gate,
|
|
operator-gated corpus write — all replayable bit-identically.
|
|
The active corpus on disk is byte-identical pre/post.
|
|
"""
|
|
from benchmarks.teaching_loop import run_teaching_loop_determinism
|
|
|
|
report = run_teaching_loop_determinism(runs=runs)
|
|
passed = report.deterministic and report.active_corpus_byte_identical
|
|
metric = 1.0 if passed else 0.0
|
|
detail = (
|
|
f"{report.runs} runs; unique(proposal_id)={report.unique_proposal_ids}, "
|
|
f"unique(baseline)={report.unique_replay_baselines}, "
|
|
f"unique(candidate)={report.unique_replay_candidates}, "
|
|
f"unique(chain_id)={report.unique_chain_ids}; "
|
|
f"mean={report.elapsed_mean_s:.3f}s p50={report.elapsed_p50_s:.3f}s "
|
|
f"p95={report.elapsed_p95_s:.3f}s; active_corpus_byte_eq="
|
|
f"{report.active_corpus_byte_identical}"
|
|
)
|
|
return BenchResult(
|
|
name="teaching_loop_determinism",
|
|
passed=passed,
|
|
metric=metric,
|
|
unit="byte_identity_ratio",
|
|
detail=detail,
|
|
)
|
|
|
|
|
|
_SUITES: dict[str, list] = {
|
|
"determinism": [bench_determinism],
|
|
"latency": [bench_latency],
|
|
"speedup": [bench_backend_speedup],
|
|
"versor": [bench_versor_closure_audit],
|
|
"convergence": [bench_convergence_proof],
|
|
"realizer": [bench_realizer_coverage],
|
|
"teaching-loop": [bench_teaching_loop_determinism],
|
|
}
|
|
|
|
_ALL = [
|
|
bench_determinism,
|
|
bench_latency,
|
|
bench_backend_speedup,
|
|
bench_versor_closure_audit,
|
|
bench_convergence_proof,
|
|
bench_realizer_coverage,
|
|
]
|
|
|
|
|
|
def run_benchmarks(
|
|
suite: str | None = None,
|
|
runs: int = 20,
|
|
) -> BenchReport:
|
|
report = BenchReport()
|
|
|
|
if suite:
|
|
funcs = _SUITES.get(suite, [])
|
|
else:
|
|
funcs = _ALL
|
|
|
|
for func in funcs:
|
|
if func is bench_determinism:
|
|
result = func(runs=runs)
|
|
elif func is bench_teaching_loop_determinism:
|
|
result = func(runs=runs)
|
|
else:
|
|
result = func()
|
|
report.results.append(result)
|
|
|
|
return report
|