Spaces:
Running on Zero
Running on Zero
Download scripts/dataset/cli.py from mukunds/loopformer-demo: direct link, hf CLI and curl.
- Browser
- Download file 7.34 kB
-
https://huggingface.co/spaces/mukunds/loopformer-demo/resolve/main/scripts/dataset/cli.py
- Command line
-
hf download hf://spaces/mukunds/loopformer-demo/scripts/dataset/cli.py
-
curl -L -o cli.py https://huggingface.co/spaces/mukunds/loopformer-demo/resolve/main/scripts/dataset/cli.py
7.34 kB
| """Generate or verify reproducible Stage 1 pointer data (no model training). | |
| Run from the repository root: python -m scripts.dataset --help | |
| """ | |
| import argparse | |
| from dataclasses import asdict | |
| import hashlib | |
| from importlib.metadata import version | |
| from pathlib import Path | |
| import platform | |
| import subprocess | |
| import sys | |
| from rich.console import Console | |
| from rich.panel import Panel | |
| from rich.table import Table | |
| from rich.text import Text | |
| from scripts.dataset.dataset import ( | |
| DatasetConfig, SPLITS, generate_dataset, make_record, preview_indices, | |
| verify_dataset, write_dataset, | |
| ) | |
| from scripts.dataset.symbols import MODEL_ID, MODEL_REVISION, validate_symbols | |
| def show_summary(console: Console, manifest: dict) -> None: | |
| table = Table(title="Validated pointer dataset") | |
| for column in ("Split", "Examples", "Depths (count)", "Prompt tokens"): | |
| table.add_column(column) | |
| for split in SPLITS: | |
| summary = manifest["splits"][split] | |
| depths = ", ".join(f"{depth}: {count}" for depth, count in sorted(summary["depth_counts"].items(), key=lambda item: int(item[0]))) | |
| table.add_row(split, f"{summary['count']:,}", depths, f"{summary['prompt_tokens_min']}–{summary['prompt_tokens_max']}") | |
| console.print(table) | |
| console.print("[green]PASS[/green] Exact targets, tokenizer contexts, declared graph sharing, disjoint split boundaries, and seed replay") | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--graph-mode", choices=("unique_path", "mixture", "random_function", "permutation", "full_cycle"), default="unique_path") | |
| parser.add_argument("--paired-horizons", action="store_true", help="Match each evaluation graph/start across depths; training graphs stay independent") | |
| parser.add_argument("--seed", type=int, default=17) | |
| parser.add_argument("--train-count", type=int, default=10_000) | |
| parser.add_argument("--validation-count", type=int, default=1_000) | |
| parser.add_argument("--test-count", type=int, default=1_000) | |
| parser.add_argument("--depth-test-count", type=int, default=1_000) | |
| parser.add_argument("--min-depth", type=int, default=1) | |
| parser.add_argument("--max-train-depth", type=int, default=8) | |
| parser.add_argument("--max-eval-depth", type=int, default=16) | |
| parser.add_argument("--train-depths", type=int, nargs="+", help="Explicit training depths; validation/test retain every depth through max-train-depth") | |
| parser.add_argument("--output", type=Path, help="New directory; default data/pointer/seed-<seed>") | |
| mode = parser.add_mutually_exclusive_group() | |
| mode.add_argument("--dry-run", nargs="?", const=5, type=int, choices=(5, 10), help="Preview up to 5 (default) or 10 examples spanning depths; write no dataset files") | |
| mode.add_argument("--verify", type=Path, metavar="DIRECTORY", help="Read and independently verify an existing dataset") | |
| args = parser.parse_args() | |
| config = DatasetConfig(**{key: getattr(args, key) for key in asdict(DatasetConfig())}) | |
| try: | |
| config.validate() | |
| except ValueError as error: | |
| parser.error(str(error)) | |
| output = args.output or Path("data/pointer") / f"seed-{args.seed}" | |
| if args.verify is None and args.dry_run is None and output.exists(): | |
| parser.error(f"Output already exists: {output}; choose a new --output (never overwritten)") | |
| from transformers import AutoTokenizer | |
| console = Console() | |
| console.print("[bold cyan]Stage 1 · pointer data[/bold cyan]") | |
| console.print(f"Cached tokenizer only: {MODEL_ID} @ {MODEL_REVISION}") | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, revision=MODEL_REVISION, local_files_only=True) | |
| if args.verify is not None: | |
| with console.status("Verifying saved files and replaying seeds…"): | |
| manifest = verify_dataset(args.verify, tokenizer) | |
| show_summary(console, manifest) | |
| console.print(f"Verified: {args.verify.resolve()}") | |
| return | |
| token_ids = validate_symbols(tokenizer) | |
| console.print(f"[green]PASS[/green] 26 unique single-token symbols in rule, start, and answer contexts; seed {config.seed}") | |
| console.print(f"Training depths: {list(config.depths('train'))}; validation/test: {config.min_depth}–{config.max_train_depth}; extrapolation depths: {config.max_train_depth + 1}–{config.max_eval_depth}") | |
| if args.dry_run is not None: | |
| distribution = Table(title="Configured dataset distribution (not preview frequencies)") | |
| for column in ("Split", "Total", "Steps: example count"): | |
| distribution.add_column(column) | |
| for split in SPLITS: | |
| depths = config.depths(split) | |
| quotient, remainder = divmod(config.count(split), len(depths)) | |
| counts = ", ".join(f"{depth}: {quotient + (index < remainder)}" for index, depth in enumerate(depths)) | |
| distribution.add_row(split, f"{config.count(split):,}", counts) | |
| console.print(distribution) | |
| selected = preview_indices(config, args.dry_run) | |
| console.print("[cyan]Preview spans shallow through deep tasks; it is not a random frequency sample.[/cyan]") | |
| for split, index in selected: | |
| record = make_record(config, split, index, tokenizer, token_ids) | |
| console.print(Panel(Text(record["prompt"]), title=f"{record['example_id']} · depth {record['task_depth']}")) | |
| table = Table(title=f"Start {record['initial_state']} · seed {record['seed']}") | |
| for column in ("Step / loop", "Expected symbol", "Answer token ID"): | |
| table.add_column(column) | |
| for step, (symbol, token_id) in enumerate(zip(record["intermediate_states"], record["intermediate_token_ids"]), 1): | |
| table.add_row(str(step), symbol, str(token_id)) | |
| console.print(table) | |
| console.print(f"[bold green]Final: {record['final_state']}[/bold green] · answer position {record['answer_position']}") | |
| console.print(f"[yellow]Dry run complete: {len(selected)} examples; no dataset files written.[/yellow]") | |
| return | |
| root = Path(__file__).resolve().parents[2] | |
| sources = sorted((root / "scripts/dataset").glob("*.py")) | |
| provenance = { | |
| "command": [sys.executable, "-m", "scripts.dataset", *sys.argv[1:]], | |
| "python": platform.python_version(), | |
| "packages": {name: version(name) for name in ("transformers", "tokenizers", "huggingface-hub", "rich")}, | |
| "git_head": subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=root, text=True).strip(), | |
| "git_status": subprocess.check_output(["git", "status", "--short"], cwd=root, text=True), | |
| "source_sha256": {str(path.relative_to(root)): hashlib.sha256(path.read_bytes()).hexdigest() for path in sources}, | |
| } | |
| with console.status("Generating and checking every example…"): | |
| dataset = generate_dataset(config, tokenizer, token_ids) | |
| write_dataset(output, dataset, config, token_ids, provenance) | |
| with console.status("Reading files back and independently replaying seeds…"): | |
| manifest = verify_dataset(output, tokenizer) | |
| show_summary(console, manifest) | |
| console.print(f"Dataset and manifest: [bold]{output.resolve()}[/bold]") | |
| console.print("Data milestone complete. No training performed.") | |
| if __name__ == "__main__": | |
| main() | |