transformer-weights / scripts /merge_datasets.py
angerami's picture
adding per model scale factor freedom; snapshot button in visuals
80f54d5
Raw
History Blame Contribute Delete
5.23 kB
#!/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)