Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Dataset Merging Script | |
| Lightweight wrapper around transformer_analysis.weight_analysis merge functions. | |
| This script supports two modes: | |
| 1. Merge all versions/checkpoints of a single model (--model flag) | |
| 2. Merge multiple different models into a combined dataset (no --model flag) | |
| Examples: | |
| # Merge all checkpoints of pythia-70m-deduped | |
| python merge_datasets.py --model pythia-70m-deduped --path outputs | |
| # Merge multiple models from a directory | |
| python merge_datasets.py --path outputs --out-name cross_model_study | |
| # Archive inputs before deleting them | |
| python merge_datasets.py --model pythia-70m-deduped --path outputs --archive --delete | |
| """ | |
| import shutil | |
| import tarfile | |
| from datetime import datetime | |
| from pathlib import Path | |
| from transformer_analysis.weight_analysis import merge_versions, merge_datasets | |
| def archive_datasets(dataset_paths: list[Path], archive_name: str, base_path: Path) -> Path: | |
| """ | |
| Bundle dataset directories into a compressed tar archive. | |
| Args: | |
| dataset_paths: List of dataset directory paths to archive | |
| archive_name: Base name for the archive file | |
| base_path: Base directory where archive will be created | |
| Returns: | |
| Path to the created archive file | |
| """ | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| archive_path = base_path / f"{archive_name}_inputs_{timestamp}.tar.gz" | |
| print(f"\nCreating archive: {archive_path}") | |
| with tarfile.open(archive_path, "w:gz") as tar: | |
| for dataset_path in dataset_paths: | |
| if dataset_path.exists(): | |
| print(f" Adding: {dataset_path.name}") | |
| tar.add(dataset_path, arcname=dataset_path.name) | |
| print(f"Archive created successfully: {archive_path}") | |
| return archive_path | |
| def delete_datasets(dataset_paths: list[Path]) -> None: | |
| """ | |
| Delete dataset directories. | |
| Args: | |
| dataset_paths: List of dataset directory paths to delete | |
| """ | |
| print("\nDeleting input datasets:") | |
| for dataset_path in dataset_paths: | |
| if dataset_path.exists(): | |
| print(f" Deleting: {dataset_path}") | |
| shutil.rmtree(dataset_path) | |
| print("Input datasets deleted successfully") | |
| if __name__ == "__main__": | |
| import argparse | |
| parser = argparse.ArgumentParser( | |
| description="Merge weight analysis datasets", | |
| formatter_class=argparse.RawDescriptionHelpFormatter, | |
| ) | |
| parser.add_argument( | |
| "--model", | |
| type=str, | |
| default=None, | |
| help="Single model name to merge all versions/checkpoints", | |
| ) | |
| parser.add_argument( | |
| "--path", type=str, default="histos", help="Base directory containing datasets" | |
| ) | |
| parser.add_argument( | |
| "--out-name", | |
| type=str, | |
| default="weight_study", | |
| help="Output name for merged dataset", | |
| ) | |
| parser.add_argument( | |
| "--suffix", | |
| type=str, | |
| default="all_checkpoints", | |
| help="Suffix for single-model merge output", | |
| ) | |
| parser.add_argument( | |
| "--archive", | |
| action="store_true", | |
| help="Bundle input datasets into a tar.gz archive before deletion", | |
| ) | |
| parser.add_argument( | |
| "--delete", | |
| action="store_true", | |
| help="Delete input datasets after merging (use with --archive to preserve)", | |
| ) | |
| args = parser.parse_args() | |
| base_path = Path(args.path) | |
| input_datasets = [] | |
| if args.model is not None: | |
| # Mode 1: Merge all versions of a single model | |
| # The output directory will be named: {model_name}_{suffix} | |
| output_dir_name = f"{args.model}_{args.suffix}" | |
| # Collect input datasets (all versions/checkpoints of the model) | |
| # BEFORE merging to avoid including the output directory | |
| for d in base_path.glob("*/"): | |
| if d.name.startswith(args.model) and d.name != output_dir_name: | |
| input_datasets.append(d) | |
| merge_versions(model_name=args.model, path=args.path, suffix=args.suffix) | |
| archive_name = output_dir_name | |
| else: | |
| # Mode 2: Merge multiple models | |
| # The output directory will be named: {out_name} | |
| output_dir_name = args.out_name | |
| # Collect input datasets (all model directories except output and logs) | |
| model_list = [] | |
| for d in base_path.glob("*/"): | |
| # Exclude the output directory, logs, and any archive directories | |
| if d.name == output_dir_name or "logs" in d.name: | |
| continue | |
| model_list.append(d.name) | |
| input_datasets.append(d) | |
| print(d.name) | |
| merge_datasets(model_list, path=args.path, out_name=args.out_name) | |
| archive_name = output_dir_name | |
| # Post-merge operations: archive and/or delete | |
| if args.archive and input_datasets: | |
| archive_datasets(input_datasets, archive_name, base_path) | |
| if args.delete and input_datasets: | |
| if not args.archive: | |
| print("\nWARNING: Deleting inputs without archiving!") | |
| response = input("Continue? (y/N): ") | |
| if response.lower() != 'y': | |
| print("Deletion cancelled") | |
| exit(0) | |
| delete_datasets(input_datasets) | |