Files
aituner/runs/active-intervention-v0/extract_training.py

325 lines
14 KiB
Python

#!/usr/bin/env python3
"""Extract paired source/action examples from the accepted action-aware run."""
from __future__ import annotations
import argparse
import hashlib
import json
import math
import os
import sys
from pathlib import Path
from statistics import fmean
from typing import Any, Mapping
PHASES = ("0.25", "0.50", "0.75", "1.00")
HERE = Path(__file__).resolve().parent
COMMON_STATE = HERE.parent / "telemetry-residual"
sys.path.insert(0, str(COMMON_STATE))
from common_state import summarize_engine # noqa: E402
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as source:
for chunk in iter(lambda: source.read(1 << 20), b""):
digest.update(chunk)
return digest.hexdigest()
def atomic_json(path: Path, payload: Any) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
temporary = path.with_suffix(path.suffix + ".tmp")
temporary.write_text(
json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
os.replace(temporary, path)
def load_jsonl(path: Path) -> list[dict[str, Any]]:
records = []
with path.open(encoding="utf-8") as source:
for line_number, line in enumerate(source, 1):
if not line.strip():
continue
try:
records.append(json.loads(line))
except json.JSONDecodeError as error:
raise ValueError(f"{path}:{line_number}: invalid JSON") from error
if not records:
raise ValueError(f"{path}: no request records")
return records
def prefix_outcome(
requests: list[Mapping[str, Any]], *, cutoff_s: float, offered_total: float
) -> dict[str, float]:
admitted = [request for request in requests if float(request["arrival_s"]) <= cutoff_s]
completed = [
request
for request in requests
if request.get("completed_elapsed_s") is not None
and float(request["completed_elapsed_s"]) <= cutoff_s
]
if not admitted:
raise ValueError("prefix has no admitted requests")
admitted_ids = {str(request["request_id"]) for request in admitted}
if any(str(request["request_id"]) not in admitted_ids for request in completed):
raise ValueError("prefix completion precedes admission")
passed = sum(bool(request["slo_pass"]) for request in completed)
ttft = [float(request["ttft_ms"]) for request in completed]
tpot = [float(request["tpot_ms"]) for request in completed]
total = len(requests)
return {
"normalized_slo_goodput": passed / cutoff_s / offered_total,
"admitted_fraction": len(admitted) / total,
"completed_over_admitted": len(completed) / len(admitted),
"completed_pass_rate": passed / max(1, len(completed)),
"completed_fail_fraction_of_total": (len(completed) - passed) / total,
"outstanding_over_admitted": (len(admitted) - len(completed)) / len(admitted),
"ttft_max_over_slo_max": max(ttft, default=0.0) / 6000.0,
"ttft_mean_over_slo_max": fmean(ttft) / 6000.0 if ttft else 0.0,
"tpot_max_over_slo": max(tpot, default=0.0) / 50.0,
"tpot_mean_over_slo": fmean(tpot) / 50.0 if tpot else 0.0,
"admitted_input_tokens_mean_over_limit": fmean(
float(request["raw_input_tokens"]) for request in admitted
)
/ 8192.0,
}
def telemetry_record(state: Mapping[str, Any]) -> dict[str, float]:
common = state["common"]
engine = state["engine_only"]
executed_steps = int(state["sanity"]["executed_steps"])
if executed_steps <= 0:
raise ValueError("telemetry phase contains no executed engine steps")
return {
"scheduler_steps_per_s": float(common["scheduler_steps_per_s"]),
"batch_size_mean": float(common["batch_size"]["mean"]),
"batch_size_cv": float(common["batch_size"]["cv"]),
"batch_tokens_mean": float(common["batch_tokens"]["mean"]),
"batch_tokens_cv": float(common["batch_tokens"]["cv"]),
"decode_batch_size_mean": float(common["decode_batch_size"]["mean"]),
"decode_batch_size_cv": float(common["decode_batch_size"]["cv"]),
"prefill_token_fraction": float(common["prefill_token_fraction"]),
"queue_waiting_mean": float(common["queue_waiting_mean"]),
"queue_running_mean": float(common["queue_running_mean"]),
"preemptions_per_step": float(common["preemptions"]) / executed_steps,
"kv_usage_mean": float(engine["kv_usage_mean"]),
"kv_usage_max": float(engine["kv_usage_max"]),
"kv_usage_end_minus_start": float(engine["kv_usage_end_minus_start"]),
"graph_none_share": float(engine["graph_none_share"]),
"graph_full_share": float(engine["graph_full_share"]),
"graph_padding_fraction": float(engine["graph_padding_fraction"]),
}
def load_stream(path: Path, *, expected_sha256: str) -> list[dict[str, Any]]:
if sha256_file(path) != expected_sha256:
raise ValueError(f"engine stream hash mismatch: {path}")
decoded = load_jsonl(path)
records = [row for row in decoded if "step_index" in row]
if not records:
raise ValueError(f"engine stream has no Layer-1 records: {path}")
return records
def build_dataset(
*, audit_path: Path, manifest_path: Path, run_root: Path
) -> dict[str, Any]:
audit = json.loads(audit_path.read_text(encoding="utf-8"))
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
if audit.get("schema") != "action-aware-constraint-pilot-audit-v0":
raise ValueError("unexpected action-aware audit schema")
if audit["sanity"]["red_flags"]:
raise ValueError(f"action-aware audit red flags: {audit['sanity']['red_flags']}")
configs = {str(item["id"]): item for item in manifest["configs"]}
runs = {
(str(run["config_id"]), int(run["repetition"])): run
for run in audit["runs"]
}
source_ids = {str(regime["source"]) for regime in manifest["regimes"].values()}
stream_entries = {
str(item["config_id"]): item
for item in audit["streams"]
if str(item["config_id"]) in source_ids
}
if set(stream_entries) != source_ids:
raise ValueError("audit is missing a source config engine stream")
streams = {
config_id: load_stream(
Path(item["stream"]), expected_sha256=str(item["stream_sha256"])
)
for config_id, item in stream_entries.items()
}
examples = []
request_hashes = []
for regime_name, regime in sorted(manifest["regimes"].items()):
source_id = str(regime["source"])
for repetition in sorted(int(value) for value in manifest["repetitions"]):
source_run = runs[(source_id, repetition)]
source_config = configs[source_id]
request_path = run_root / "sessions" / source_id / f"rep{repetition}" / "requests.jsonl"
requests = load_jsonl(request_path)
request_hashes.append(sha256_file(request_path))
offered_rate_per_gpu = float(
manifest["repetitions"][str(repetition)]["selection"][
"offered_req_s_per_gpu"
]
)
offered_total = offered_rate_per_gpu * int(manifest["engine"]["tp"])
source_goodput = float(source_run["outcome"]["slo_goodput_req_s"])
source_normalized = min(1.0, source_goodput / offered_total)
decision_id = f"{regime_name}-rep{repetition}"
for phase in PHASES:
cutoff_s = float(manifest["engine"]["duration_s"]) * float(phase)
outcome = prefix_outcome(
requests, cutoff_s=cutoff_s, offered_total=offered_total
)
admitted_count = sum(
float(request["arrival_s"]) <= cutoff_s for request in requests
)
start_ns = int(source_run["state"]["interval"]["start_ns"])
phase_state = summarize_engine(
streams[source_id],
start_ns=start_ns,
end_ns=start_ns + round(cutoff_s * 1e9),
request_count=admitted_count,
)
if not all(phase_state["sanity"]["invariants"].values()):
raise ValueError(
f"engine state invariant failed: {decision_id} phase {phase}"
)
telemetry = telemetry_record(phase_state)
actions = {"noop": source_id, **regime["actions"]}
for action_name, target_id in sorted(actions.items()):
target_run = runs[(str(target_id), repetition)]
target_config = configs[str(target_id)]
target_goodput = float(target_run["outcome"]["slo_goodput_req_s"])
normalized = target_goodput / offered_total
if not 0.0 <= normalized <= 1.0 + 1e-12:
raise ValueError("target normalized goodput is outside [0, 1]")
examples.append(
{
"phase": phase,
"cutoff_s": cutoff_s,
"decision_id": decision_id,
"regime": regime_name,
"repetition": repetition,
"source": {
"config_id": source_id,
"mns": int(source_config["mns"]),
"mbbt": int(source_config["mbbt"]),
"offered_rate_per_gpu": offered_rate_per_gpu,
"outcome": outcome,
"telemetry": telemetry,
},
"action": {
"id": action_name,
"target_config_id": str(target_id),
"target_mns": int(target_config["mns"]),
"target_mbbt": int(target_config["mbbt"]),
},
"target_slo_goodput_req_s": target_goodput,
"target_normalized_goodput": min(1.0, normalized),
"source_normalized_goodput": source_normalized,
"target_delta_normalized_goodput": min(1.0, normalized)
- source_normalized,
}
)
invariants = {
"expected_examples": len(examples) == len(PHASES) * 2 * 3 * 3,
"four_phases": sorted({example["phase"] for example in examples})
== sorted(PHASES),
"six_decisions": len({example["decision_id"] for example in examples}) == 6,
"three_actions_per_decision_phase": all(
sum(
item["decision_id"] == decision
and item["phase"] == phase
for item in examples
)
== 3
for decision in {item["decision_id"] for item in examples}
for phase in PHASES
),
"targets_not_all_identical": len(
{example["target_normalized_goodput"] for example in examples}
)
> 1,
"bounded_prefix_ratios": all(
0.0 <= float(value) <= 1.0
for example in examples
for key, value in example["source"]["outcome"].items()
if key
in {
"admitted_fraction",
"completed_over_admitted",
"completed_pass_rate",
"completed_fail_fraction_of_total",
"outstanding_over_admitted",
}
),
"direct_telemetry_without_binding_labels": all(
not any(token in key for token in ("exclusive", "unresolved", "both"))
for example in examples
for key in example["source"]["telemetry"]
),
"treatment_effects_bounded": all(
-1.0 <= float(example["target_delta_normalized_goodput"]) <= 1.0
for example in examples
),
}
red_flags = [name for name, passed in invariants.items() if not passed]
if red_flags:
raise RuntimeError(f"training dataset sanity failed: {red_flags}")
return {
"schema": "active-intervention-training-v0",
"status": "VALID",
"provenance": {
"audit": str(audit_path),
"audit_sha256": sha256_file(audit_path),
"manifest": str(manifest_path),
"manifest_sha256": sha256_file(manifest_path),
"run_root": str(run_root),
"source_request_sha256": sorted(set(request_hashes)),
"source_stream_sha256": sorted(
str(item["stream_sha256"]) for item in stream_entries.values()
),
},
"examples": examples,
"sanity": {"invariants": invariants, "red_flags": red_flags},
}
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--audit", type=Path, required=True)
parser.add_argument("--manifest", type=Path, required=True)
parser.add_argument("--run-root", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
dataset = build_dataset(
audit_path=args.audit,
manifest_path=args.manifest,
run_root=args.run_root,
)
atomic_json(args.output, dataset)
print(
json.dumps(
{
"status": dataset["status"],
"examples": len(dataset["examples"]),
"sanity": dataset["sanity"],
},
sort_keys=True,
)
)
if __name__ == "__main__":
main()