Initial commit
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""Build the combined behavioral and format Profile for one model."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from ..paths import (
|
||||
FINAL_PROFILE_ROOT,
|
||||
MODEL_PREFERENCE_PROFILE_ROOT,
|
||||
PROJECT_ROOT,
|
||||
model_profile_path,
|
||||
)
|
||||
|
||||
|
||||
MODEL_PROFILE_MODULE = (
|
||||
"scripts.static_compile.profile_generation.model_preference.run_profile"
|
||||
)
|
||||
FORMAT_PROFILE_MODULE = (
|
||||
"scripts.static_compile.profile_generation.format_preference.run_format_preference"
|
||||
)
|
||||
|
||||
|
||||
def run_stage(label: str, command: list[str]) -> None:
|
||||
print(f"\n{'=' * 72}\n{label}\n{'=' * 72}", flush=True)
|
||||
subprocess.run(command, check=True, cwd=PROJECT_ROOT)
|
||||
|
||||
|
||||
def profile_paths(model_identifier: str) -> tuple[Path, Path]:
|
||||
"""Return the behavioral source Profile and final combined Profile paths."""
|
||||
|
||||
upstream = model_profile_path(MODEL_PREFERENCE_PROFILE_ROOT, model_identifier)
|
||||
final = model_profile_path(FINAL_PROFILE_ROOT, model_identifier)
|
||||
return upstream, final
|
||||
|
||||
|
||||
def profile_is_reusable(profile_path: Path, model_identifier: str) -> bool:
|
||||
"""Return whether a complete combined Profile matches the requested model."""
|
||||
|
||||
try:
|
||||
profile = json.loads(profile_path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return False
|
||||
model = profile.get("model")
|
||||
return bool(
|
||||
isinstance(model, dict)
|
||||
and model.get("id") == model_identifier.strip("/")
|
||||
and model.get("profile_status") == "complete"
|
||||
and isinstance(profile.get("behavioral_profile"), dict)
|
||||
and isinstance(profile.get("format_preference"), dict)
|
||||
)
|
||||
|
||||
|
||||
def generate_profile(
|
||||
model_identifier: str,
|
||||
*,
|
||||
refresh_model_preference: bool = False,
|
||||
) -> Path:
|
||||
"""Run behavioral profiling followed by format profiling."""
|
||||
|
||||
model_id = model_identifier.strip("/")
|
||||
upstream_profile_path, final_profile_path = profile_paths(model_id)
|
||||
|
||||
model_command = [sys.executable, "-m", MODEL_PROFILE_MODULE, model_id]
|
||||
if refresh_model_preference:
|
||||
model_command.append("--refresh")
|
||||
run_stage(
|
||||
"1/2 Model-preference profiling: collecting and evaluating behavior",
|
||||
model_command,
|
||||
)
|
||||
run_stage(
|
||||
"2/2 Format-preference profiling: measuring output-format sensitivity",
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
FORMAT_PROFILE_MODULE,
|
||||
"--model",
|
||||
model_id,
|
||||
"--profile_path",
|
||||
str(final_profile_path),
|
||||
"--base_profile_path",
|
||||
str(upstream_profile_path),
|
||||
],
|
||||
)
|
||||
if not profile_is_reusable(final_profile_path, model_id):
|
||||
raise RuntimeError(
|
||||
"profile generation did not produce a complete combined Profile at "
|
||||
f"{final_profile_path}"
|
||||
)
|
||||
return final_profile_path
|
||||
|
||||
|
||||
def ensure_profile(model_identifier: str, *, refresh: bool = False) -> tuple[Path, bool]:
|
||||
"""Reuse the final Profile when present, otherwise generate it."""
|
||||
|
||||
_, final_profile_path = profile_paths(model_identifier)
|
||||
if profile_is_reusable(final_profile_path, model_identifier) and not refresh:
|
||||
return final_profile_path, False
|
||||
return (
|
||||
generate_profile(
|
||||
model_identifier,
|
||||
refresh_model_preference=refresh,
|
||||
),
|
||||
True,
|
||||
)
|
||||
Reference in New Issue
Block a user