music3lab / scripts /evaluate_music3_objective.py
coolpoodle's picture
code and training scripts
90884df verified
Raw
History Blame Contribute Delete
3.59 kB
#!/usr/bin/env python3
"""Build and verify the frozen eight-source objective-only evaluation."""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Sequence
from music3lab.eval import (
canonical_json_bytes,
evaluate_objective_only,
load_objective_config,
make_synthetic_candidate,
prepare_corpus,
publication_order,
publish_evaluation,
verify_evaluation_bundle,
)
def _parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description=(
"Freeze eight opaque audio sources, run deterministic objective "
"metrics/canaries, and publish canonical JSON plus Markdown."
)
)
parser.add_argument("--config", required=True)
parser.add_argument(
"--source",
action="append",
required=True,
help="Input audio path; pass exactly eight times.",
)
parser.add_argument("--ffmpeg", default="/usr/bin/ffmpeg")
parser.add_argument("--corpus-root", required=True)
parser.add_argument("--candidate-root", required=True)
parser.add_argument("--bundle-root", required=True)
parser.add_argument("--staging-root", required=True)
parser.add_argument(
"--corruption",
default="identity",
choices=(
"identity",
"clipping",
"noise",
"silence",
"phase_inversion",
"lowpass",
"duplicate",
"shuffle",
"nan",
"short",
"missing",
),
)
return parser
def run(arguments: argparse.Namespace) -> dict[str, object]:
loaded = load_objective_config(arguments.config)
optional = tuple(
sorted(
loaded.config.metric_policy.optional_evaluators.model_dump(
mode="json"
)
)
)
with prepare_corpus(
sources=arguments.source,
output_root=arguments.corpus_root,
ffmpeg_path=arguments.ffmpeg,
config_path=arguments.config,
) as authority:
candidate = make_synthetic_candidate(
authority,
output_root=arguments.candidate_root,
corruption=arguments.corruption,
)
result = evaluate_objective_only(
authority=authority,
candidate_root=candidate,
protected_baseline=None,
optional_evaluators=optional,
)
published = publish_evaluation(
result=result,
output_root=arguments.bundle_root,
staging_root=arguments.staging_root,
)
verified = verify_evaluation_bundle(published, authority=authority)
report = Path(published, "report.md").read_bytes()
return {
"bundle_root": str(published),
"candidate_semantic_digest": verified.candidate_semantic_digest,
"corpus_aggregate_sha256": verified.corpus_aggregate_sha256,
"optional_evaluators": verified.optional,
"promotion": verified.promotion,
"publication_order": publication_order(published),
"report_sha256": hashlib.sha256(report).hexdigest(),
"result_semantic_digest": verified.semantic_digest,
"status": verified.status,
}
def main(argv: Sequence[str] | None = None) -> int:
arguments = _parser().parse_args(argv)
print(canonical_json_bytes(run(arguments)).decode("utf-8"), end="")
return 0
if __name__ == "__main__":
raise SystemExit(main())