Download task_finetuning/prepare_data.py from edeneldith/WiggleGPT: direct link, hf CLI and curl.
- Browser
- Download file 5.88 kB
-
https://huggingface.co/edeneldith/WiggleGPT/resolve/main/task_finetuning/prepare_data.py
- Command line
-
hf download hf://edeneldith/WiggleGPT/task_finetuning/prepare_data.py
-
curl -L -o prepare_data.py https://huggingface.co/edeneldith/WiggleGPT/resolve/main/task_finetuning/prepare_data.py
5.88 kB
| """Download public benchmark parquets and preserve exact normalized task splits. | |
| This script performs no model work. Public SST-2 test labels are withheld (-1); | |
| the validation split is therefore the labelled held-out evaluation split. | |
| """ | |
| from __future__ import annotations | |
| import hashlib | |
| import json | |
| import time | |
| import urllib.parse | |
| import urllib.request | |
| from collections import Counter | |
| from concurrent.futures import ThreadPoolExecutor | |
| from datetime import datetime, timezone | |
| from pathlib import Path | |
| import pyarrow as pa | |
| import pyarrow.parquet as pq | |
| ROOT = Path(__file__).resolve().parent / "data" | |
| SOURCES = [("sst2", "stanfordnlp/sst2", "default"), ("race_middle", "ehovy/race", "middle")] | |
| def digest(path: Path) -> str: | |
| value = hashlib.sha256() | |
| with path.open("rb") as stream: | |
| for block in iter(lambda: stream.read(1024 * 1024), b""): | |
| value.update(block) | |
| return value.hexdigest() | |
| def fetch(url: str, path: Path) -> None: | |
| if path.exists(): | |
| return | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| temporary = path.with_suffix(path.suffix + ".partial") | |
| for attempt in range(4): | |
| try: | |
| request = urllib.request.Request(url, headers={"User-Agent": "WiggleGPT-benchmark-preparation/1.0"}) | |
| with urllib.request.urlopen(request, timeout=90) as response, temporary.open("wb") as stream: | |
| while block := response.read(1024 * 1024): | |
| stream.write(block) | |
| temporary.replace(path) | |
| return | |
| except Exception: | |
| if attempt == 3: | |
| raise | |
| time.sleep(2 ** attempt) | |
| def normalize(task: str, row: dict, index: int, split: str) -> dict: | |
| if task == "sst2": | |
| return {"example_id": f"sst2/{split}/{row.get('idx', index)}", "text": row["sentence"], "label": int(row["label"])} | |
| answer = row["answer"] | |
| label = "ABCD".index(answer) if isinstance(answer, str) else int(answer) | |
| options = list(row["options"]) | |
| if len(options) != 4 or not 0 <= label < 4: | |
| raise ValueError(f"Invalid RACE record {index}") | |
| return {"example_id": str(row.get("example_id", f"race_middle/{split}/{index}")), | |
| "article": row["article"], "question": row["question"], "options": options, "label": label} | |
| def prepare_source(spec: tuple[str, str, str]) -> dict: | |
| task, dataset, config = spec | |
| metadata_url = "https://datasets-server.huggingface.co/parquet?" + urllib.parse.urlencode({"dataset": dataset}) | |
| metadata_path = ROOT / "source_parquets" / task / "parquet_metadata.json" | |
| fetch(metadata_url, metadata_path) | |
| metadata = json.loads(metadata_path.read_text(encoding="utf-8")) | |
| if metadata.get("partial"): | |
| raise RuntimeError(f"Partial parquet conversion for {dataset}") | |
| files = [entry for entry in metadata["parquet_files"] if entry["config"] == config] | |
| result = {"dataset": dataset, "config": config, "metadata_url": metadata_url, "splits": {}} | |
| for split in ("train", "validation", "test"): | |
| split_files = sorted([entry for entry in files if entry["split"] == split], key=lambda entry: entry["filename"]) | |
| if not split_files: | |
| raise RuntimeError(f"Missing {dataset} {config} {split}") | |
| destination = ROOT / f"{task}_{split}.jsonl" | |
| temporary = destination.with_suffix(".jsonl.partial") | |
| count, labels, source_files = 0, Counter(), [] | |
| with temporary.open("w", encoding="utf-8", newline="\n") as output: | |
| for ordinal, entry in enumerate(split_files): | |
| parquet_path = ROOT / "source_parquets" / task / split / f"{ordinal:03d}_{entry['filename']}" | |
| fetch(entry["url"], parquet_path) | |
| if parquet_path.stat().st_size != entry["size"]: | |
| raise RuntimeError(f"Size mismatch for {parquet_path}") | |
| source_files.append({"url": entry["url"], "path": str(parquet_path), "bytes": parquet_path.stat().st_size, "sha256": digest(parquet_path)}) | |
| for batch in pq.ParquetFile(parquet_path).iter_batches(batch_size=1024): | |
| for row in batch.to_pylist(): | |
| item = normalize(task, row, count, split) | |
| output.write(json.dumps(item, ensure_ascii=False) + "\n") | |
| labels[str(item["label"])] += 1 | |
| count += 1 | |
| temporary.replace(destination) | |
| result["splits"][split] = {"path": str(destination), "rows": count, "sha256": digest(destination), "label_counts": dict(sorted(labels.items())), "labelled": all(int(label) >= 0 for label in labels), "source_parquets": source_files} | |
| print(f"{task} {split}: {count:,} rows; labels={dict(labels)}", flush=True) | |
| return result | |
| def main() -> None: | |
| ROOT.mkdir(parents=True, exist_ok=True) | |
| pa.set_cpu_count(2) | |
| pa.set_io_thread_count(2) | |
| with ThreadPoolExecutor(max_workers=2) as pool: | |
| prepared = list(pool.map(prepare_source, SOURCES)) | |
| manifest = {"prepared_at_utc": datetime.now(timezone.utc).isoformat(), "tasks": {spec[0]: result for spec, result in zip(SOURCES, prepared)}, | |
| "split_policy": {"sst2": "Train on official train; validation is the only public labelled holdout. Official test labels are hidden (-1).", | |
| "race_middle": "Train on official middle/train; select using middle/validation; evaluate once on middle/test."}, | |
| "normalization": "Exact input strings retained; sentiment labels are 0=negative,1=positive; RACE A/B/C/D mapped to integer 0/1/2/3; no examples generated or reassigned."} | |
| manifest_path = ROOT / "dataset_manifest.json" | |
| manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") | |
| print(f"Manifest: {manifest_path}", flush=True) | |
| if __name__ == "__main__": | |
| main() | |