| import argparse | |
| import json | |
| from pathlib import Path | |
| import torch | |
| from bit_transformer import BitTransformerLM | |
| def list_candidates(path: Path): | |
| models = sorted(path.glob("*.pt")) | |
| for m in models: | |
| metrics_file = m.with_suffix(m.suffix + ".json") | |
| metrics = {} | |
| if metrics_file.exists(): | |
| with open(metrics_file) as f: | |
| metrics = json.load(f) | |
| yield m, metrics | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Review distilled submodels") | |
| parser.add_argument("directory", type=Path, help="Directory with candidate models") | |
| parser.add_argument("--approve-dir", type=Path, default=Path("approved"), help="Directory to store approved models") | |
| args = parser.parse_args() | |
| args.approve_dir.mkdir(exist_ok=True) | |
| log_file = args.approve_dir / "review_log.jsonl" | |
| for model_path, metrics in list_candidates(args.directory): | |
| print("Candidate:", model_path.name) | |
| for k, v in metrics.items(): | |
| print(f" {k}: {v}") | |
| ans = input("Approve this model? [y/N] ").strip().lower() | |
| if ans == "y": | |
| approved_path = args.approve_dir / model_path.name | |
| torch.save(torch.load(model_path), approved_path) | |
| entry = {"model": approved_path.name, "metrics": metrics, "approved": True} | |
| with open(log_file, "a") as lf: | |
| lf.write(json.dumps(entry) + "\n") | |
| print("Approved and saved to", approved_path) | |
| else: | |
| entry = {"model": model_path.name, "metrics": metrics, "approved": False} | |
| with open(log_file, "a") as lf: | |
| lf.write(json.dumps(entry) + "\n") | |
| print("Rejected", model_path.name) | |
| if __name__ == "__main__": | |
| main() | |