Download code/scripts/run_ablation_eval.py from TTS-AGI/laionbox-ablation-checkpoints: direct link, hf CLI and curl.
- Browser
- Download file 5.02 kB
-
https://huggingface.co/TTS-AGI/laionbox-ablation-checkpoints/resolve/main/code/scripts/run_ablation_eval.py
- Command line
-
hf download hf://TTS-AGI/laionbox-ablation-checkpoints/code/scripts/run_ablation_eval.py
-
curl -L -o run_ablation_eval.py https://huggingface.co/TTS-AGI/laionbox-ablation-checkpoints/resolve/main/code/scripts/run_ablation_eval.py
5.02 kB
| #!/usr/bin/env python3 | |
| """Ablation evaluation — loads models from JSON file instead of hardcoded dict. | |
| Usage: | |
| python scripts/run_ablation_eval.py --models-json ablation_eval_models.json \ | |
| --num-gpus 8 --output-dir ablation_eval | |
| """ | |
| import argparse | |
| import json | |
| import logging | |
| import os | |
| import sys | |
| import time | |
| # Reuse everything from the comprehensive eval script | |
| sys.path.insert(0, os.path.dirname(__file__)) | |
| from run_comprehensive_eval import ( | |
| select_prompts, | |
| get_ref_audios, | |
| build_task_list, | |
| run_generation_phase, | |
| score_all_audio, | |
| build_html_report, | |
| VAP_DIR, | |
| ) | |
| logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Run ablation evaluation with models from JSON") | |
| parser.add_argument("--models-json", required=True, help="Path to JSON file with models dict") | |
| parser.add_argument("--output-dir", default=os.path.join(VAP_DIR, "ablation_eval")) | |
| parser.add_argument("--refs-dir", default="/home/deployer/laion/test-refs") | |
| parser.add_argument("--num-gpus", type=int, default=8) | |
| parser.add_argument("--seeds", type=int, nargs="+", default=[42]) | |
| parser.add_argument("--classifiers-dir", default=os.path.join(VAP_DIR, "classifiers")) | |
| parser.add_argument("--skip-generation", action="store_true") | |
| parser.add_argument("--skip-scoring", action="store_true") | |
| args = parser.parse_args() | |
| # Load models from JSON | |
| with open(args.models_json) as f: | |
| models = json.load(f) | |
| logging.info(f"Loaded {len(models)} models from {args.models_json}") | |
| for key, minfo in models.items(): | |
| lora_str = os.path.basename(minfo["lora"]) if minfo.get("lora") else "None" | |
| logging.info(f" {key}: {minfo['name']} (lora={lora_str})") | |
| # Verify all LoRA files exist | |
| for key, minfo in models.items(): | |
| if minfo.get("lora") and not os.path.exists(minfo["lora"]): | |
| logging.error(f"LoRA file not found for {key}: {minfo['lora']}") | |
| sys.exit(1) | |
| args.output_dir = os.path.abspath(args.output_dir) | |
| os.makedirs(os.path.join(args.output_dir, "wavs"), exist_ok=True) | |
| # 1. Select prompts | |
| prompts = select_prompts() | |
| logging.info(f"Selected {len(prompts)} prompts") | |
| with open(os.path.join(args.output_dir, "prompts.json"), "w") as f: | |
| json.dump(prompts, f, indent=2) | |
| # 2. Get reference audios | |
| refs = get_ref_audios(args.refs_dir) | |
| logging.info(f"Found {len(refs)} reference audios") | |
| # 3. Build task list | |
| tasks = build_task_list(models, prompts, refs, args.seeds, args.output_dir) | |
| logging.info(f"Total tasks: {len(tasks)} ({len(models)} models × {len(prompts)} prompts × ({len(refs)} refs + 1 uncond) × {len(args.seeds)} seeds)") | |
| # 4. Generate (skip tasks where WAV already exists) | |
| if not args.skip_generation: | |
| tasks_to_gen = [t for t in tasks if not os.path.exists(t["output"])] | |
| tasks_existing = [t for t in tasks if os.path.exists(t["output"])] | |
| logging.info(f"Skipping {len(tasks_existing)} existing WAVs, generating {len(tasks_to_gen)} new samples") | |
| if tasks_to_gen: | |
| gen_results = run_generation_phase(tasks_to_gen, args.num_gpus) | |
| else: | |
| gen_results = [] | |
| existing_results = [{**t, "success": True, "elapsed": 0, "gpu": -1} for t in tasks_existing] | |
| results = existing_results + gen_results | |
| with open(os.path.join(args.output_dir, "gen_results.json"), "w") as f: | |
| json.dump(results, f, indent=2, default=str) | |
| else: | |
| with open(os.path.join(args.output_dir, "gen_results.json")) as f: | |
| results = json.load(f) | |
| # 5. Score | |
| if not args.skip_scoring: | |
| scored = score_all_audio(results, args.classifiers_dir) | |
| with open(os.path.join(args.output_dir, "scored_results.json"), "w") as f: | |
| json.dump(scored, f, indent=2, default=str) | |
| else: | |
| with open(os.path.join(args.output_dir, "scored_results.json")) as f: | |
| scored = json.load(f) | |
| # 6. Build HTML | |
| model_means = build_html_report( | |
| scored, models, prompts, refs, | |
| os.path.join(args.output_dir, "eval_report.html") | |
| ) | |
| # Print summary | |
| print("\n" + "="*70) | |
| print("ABLATION EVALUATION SUMMARY") | |
| print("="*70) | |
| for mk, minfo in models.items(): | |
| means = model_means.get(mk, {}) | |
| print(f"\n{minfo['name']}:") | |
| for metric in ["naturalness_small", "naturalness_large", "centroid", "quality", "speaker_sim"]: | |
| val = means.get(metric) | |
| print(f" {metric:20s}: {val:.4f}" if val else f" {metric:20s}: N/A") | |
| print("="*70) | |
| # Save summary JSON | |
| summary = {mk: model_means.get(mk, {}) for mk in models} | |
| with open(os.path.join(args.output_dir, "summary.json"), "w") as f: | |
| json.dump(summary, f, indent=2) | |
| logging.info(f"Summary saved to {os.path.join(args.output_dir, 'summary.json')}") | |
| if __name__ == "__main__": | |
| main() | |