Spaces:
Sleeping
Sleeping
Download scripts/run_eval.py from angerami/transformer-weights: direct link, hf CLI and curl.
- Browser
- Download file 5.52 kB
-
https://huggingface.co/spaces/angerami/transformer-weights/resolve/main/scripts/run_eval.py
- Command line
-
hf download hf://spaces/angerami/transformer-weights/scripts/run_eval.py
-
curl -L -o run_eval.py https://huggingface.co/spaces/angerami/transformer-weights/resolve/main/scripts/run_eval.py
5.52 kB
| #!/usr/bin/env python3 | |
| """Thin CLI wrapper for eval_metrics. Called by rules/eval.smk.""" | |
| import argparse | |
| import os | |
| import sys | |
| import time | |
| from pathlib import Path | |
| import hashlib | |
| import json | |
| import mlflow | |
| from mlflow.entities import Dataset as DatasetEntity, DatasetInput | |
| import pandas as pd | |
| sys.path.insert(0, str(Path(__file__).parent.parent / "src")) | |
| from transformer_analysis.eval_metrics import evaluate_model, to_long_format | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--model", required=True) | |
| parser.add_argument("--revision", type=str, default=None) | |
| parser.add_argument("--corpus", type=str, default="wikitext103", | |
| choices=["wikitext103", "pile"]) | |
| parser.add_argument("--pile-tokens", type=int, default=204800) | |
| parser.add_argument("--pile-cache", type=str, default=None) | |
| parser.add_argument("--max-tokens", type=int, default=None) | |
| parser.add_argument("--stride", type=int, default=512) | |
| parser.add_argument("--out", type=str, required=True) | |
| parser.add_argument("--cache", type=str, default="model_cache") | |
| parser.add_argument("--device", type=str, default=None, choices=["cuda", "mps", "cpu"]) | |
| parser.add_argument("--dtype", type=str, default="auto", | |
| choices=["auto", "bf16", "fp16", "fp32"], | |
| help="Weight dtype. 'auto' uses the model's saved dtype (bf16/fp16 for most modern models, fp32 for GPT-2). Override with fp32 for a numerics reference.") | |
| parser.add_argument("--offload-layers", action="store_true", | |
| help="Stream layers from disk via accelerate. Enables models that don't fit fully in unified memory at the cost of much slower per-window inference. Numerics are unchanged.") | |
| parser.add_argument("--offload-folder", type=str, default=None, | |
| help="Where accelerate spills offloaded layer weights. Defaults to a tempfile.mkdtemp() on the system disk (best per-window bandwidth, auto-cleaned). Override to e.g. an external drive when the system disk is tight on space — pay 2-5x per-window cost in exchange.") | |
| parser.add_argument("--max-memory-gpu", type=str, default=None, | |
| help="Max memory budget for the accelerator (CUDA/MPS) when --offload-layers is on, e.g. '6GiB'. Layers beyond this spill to CPU then disk.") | |
| parser.add_argument("--max-memory-cpu", type=str, default=None, | |
| help="Max memory budget for CPU when --offload-layers is on, e.g. '2GiB'.") | |
| parser.add_argument("--mlflow-uri", default="file:./mlruns") | |
| parser.add_argument("--mlflow-experiment", default="production") | |
| args = parser.parse_args() | |
| revision = args.revision or None | |
| rev_label = revision or "main" | |
| mlflow.set_tracking_uri(args.mlflow_uri) | |
| mlflow.set_experiment(args.mlflow_experiment) | |
| with mlflow.start_run(run_name=f"{args.model}-{rev_label}-eval"): | |
| mlflow.set_tag("mlflow.note.content", "Evaluate model perplexity on corpus → parquet") | |
| mlflow.set_tag("model", args.model) | |
| # Assemble accelerate max_memory dict only if either knob is set. | |
| max_memory = None | |
| if args.offload_layers and (args.max_memory_gpu or args.max_memory_cpu): | |
| max_memory = {} | |
| if args.max_memory_gpu: | |
| # Key resolved inside evaluate_model based on actual device. | |
| max_memory["__gpu__"] = args.max_memory_gpu | |
| if args.max_memory_cpu: | |
| max_memory["cpu"] = args.max_memory_cpu | |
| mlflow.log_params({ | |
| "model": args.model, | |
| "revision": rev_label, | |
| "corpus": args.corpus, | |
| "pile_tokens": args.pile_tokens, | |
| "stride": args.stride, | |
| "dtype": args.dtype, | |
| "device": args.device or "auto", | |
| "offload_layers": args.offload_layers, | |
| "max_memory_gpu": args.max_memory_gpu or "", | |
| "max_memory_cpu": args.max_memory_cpu or "", | |
| "out": args.out, | |
| }) | |
| t0 = time.time() | |
| result = evaluate_model( | |
| model_name=args.model, revision=revision, | |
| corpus=args.corpus, pile_tokens=args.pile_tokens, | |
| cache_dir=args.cache, device_str=args.device, | |
| stride=args.stride, max_tokens=args.max_tokens, | |
| pile_cache=args.pile_cache, dtype=args.dtype, | |
| offload=args.offload_layers, | |
| offload_folder=args.offload_folder, | |
| max_memory=max_memory, | |
| ) | |
| wall_time = time.time() - t0 | |
| print(f" ppl={result['perplexity']:.2f} bpb={result['bpb']:.4f}") | |
| mlflow.log_metrics({ | |
| "perplexity": result["perplexity"], | |
| "nll": result["nll"], | |
| "bpb": result["bpb"], | |
| "wall_time_s": wall_time, | |
| }) | |
| df = pd.DataFrame(to_long_format(result)) | |
| os.makedirs(os.path.dirname(args.out) or ".", exist_ok=True) | |
| df.to_parquet(args.out, index=False) | |
| print(f" Saved {len(df)} rows → {args.out}") | |
| digest = hashlib.md5(args.out.encode()).hexdigest()[:8] | |
| entity = DatasetEntity( | |
| name=f"{args.model}-{rev_label}-eval", | |
| digest=digest, | |
| source_type="local", | |
| source=json.dumps({"uri": args.out}), | |
| ) | |
| mlflow.MlflowClient().log_inputs( | |
| mlflow.active_run().info.run_id, | |
| [DatasetInput(dataset=entity, tags=[])], | |
| ) | |
| if __name__ == "__main__": | |
| main() | |