Spaces:
Running on Zero
Running on Zero
| #!/usr/bin/env python3 | |
| """Generate the upgraded ControlAI SFT v2 dataset with Chain of Thought (CoT), textbook cases, and STEM replay.""" | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| import sys | |
| from collections import Counter | |
| from pathlib import Path | |
| PROJECT_ROOT = Path(__file__).resolve().parents[1] | |
| if str(PROJECT_ROOT) not in sys.path: | |
| sys.path.insert(0, str(PROJECT_ROOT)) | |
| from controlai_data.generators import ( | |
| generate_advanced_v1, | |
| generate_classical_optimal_v1, | |
| generate_code_v1, | |
| generate_extended_v1, | |
| generate_linear_v1, | |
| generate_safety_behavior_v1, | |
| ) | |
| from scripts.build_stem_replay_dataset import build_all_stem_records | |
| from scripts.build_textbook_sft_dataset import build_all_textbook_records | |
| BENCHMARK_FAMILIES = { | |
| "iid_scalar_jump_mean_square_test", | |
| "kharitonov_cubic_interval_stability", | |
| "matlab_exact_zoh_state_space", | |
| "minimum_norm_redundant_control_allocation", | |
| "scalar_affine_nonlinear_dynamic_inversion", | |
| "scalar_control_barrier_safety_filter", | |
| } | |
| VALID_FAMILIES = { | |
| "box_constrained_scalar_mpc_horizon2", | |
| "discrete_cycle_consensus_step_size", | |
| "finite_horizon_scalar_lqr_recursion", | |
| "noise_free_arx_least_squares", | |
| "relative_degree_and_zero_dynamics", | |
| "scalar_kalman_time_update", | |
| "textbook_inverted_pendulum_design", | |
| "stem_rlc_circuit_transient", | |
| } | |
| def stable_fraction(value: str) -> float: | |
| raw = hashlib.sha256(value.encode("utf-8")).digest()[:8] | |
| return int.from_bytes(raw, "big") / 2**64 | |
| def write_jsonl(path: Path, rows: list[dict]) -> None: | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| with path.open("w", encoding="utf-8") as stream: | |
| for row in rows: | |
| stream.write(json.dumps(row, ensure_ascii=False) + "\n") | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--count-per-family", type=int, default=50) | |
| parser.add_argument("--seed", type=int, default=20260817) | |
| parser.add_argument( | |
| "--output-dir", type=Path, default=Path("data/training/sft_v2") | |
| ) | |
| args = parser.parse_args() | |
| records: list[dict] = [] | |
| # 1. Synthetic control generators with rich CoT | |
| records.extend(generate_linear_v1(args.count_per_family, args.seed)) | |
| records.extend(generate_classical_optimal_v1(args.count_per_family, args.seed + 10_000)) | |
| records.extend(generate_advanced_v1(args.count_per_family, args.seed + 20_000)) | |
| records.extend(generate_code_v1(args.count_per_family, args.seed + 30_000)) | |
| records.extend(generate_extended_v1(args.count_per_family, args.seed + 40_000)) | |
| records.extend(generate_safety_behavior_v1(args.count_per_family, args.seed + 50_000)) | |
| # 2. Textbook case studies with CoT and verified code | |
| records.extend(build_all_textbook_records(args.count_per_family, args.seed + 60_000)) | |
| # 3. Base STEM replay derivations | |
| records.extend(build_all_stem_records(args.count_per_family, args.seed + 70_000)) | |
| families = sorted({row["metadata"]["family"] for row in records}) | |
| missing_split_families = (BENCHMARK_FAMILIES | VALID_FAMILIES) - set(families) | |
| if missing_split_families: | |
| raise ValueError(f"Configured split families are missing: {sorted(missing_split_families)}") | |
| train = [ | |
| row for row in records | |
| if row["metadata"]["family"] not in (BENCHMARK_FAMILIES | VALID_FAMILIES) | |
| ] | |
| valid = [ | |
| row for row in records if row["metadata"]["family"] in VALID_FAMILIES | |
| ] | |
| benchmark_candidates = [ | |
| row for row in records if row["metadata"]["family"] in BENCHMARK_FAMILIES | |
| ] | |
| train.sort(key=lambda row: stable_fraction(f"train:{row['metadata']['id']}")) | |
| valid.sort(key=lambda row: stable_fraction(f"valid:{row['metadata']['id']}")) | |
| benchmark_candidates.sort(key=lambda row: stable_fraction(f"bench:{row['metadata']['id']}")) | |
| write_jsonl(args.output_dir / "train.jsonl", train) | |
| write_jsonl(args.output_dir / "valid.jsonl", valid) | |
| write_jsonl(args.output_dir / "benchmark_candidates.jsonl", benchmark_candidates) | |
| domains = Counter(row["metadata"]["domain"] for row in records) | |
| summary = { | |
| "schema_version": 2, | |
| "status": "ready_for_training", | |
| "total_records": len(records), | |
| "total_families": len(families), | |
| "train_records": len(train), | |
| "valid_records": len(valid), | |
| "train_families": sorted(set(families) - BENCHMARK_FAMILIES - VALID_FAMILIES), | |
| "valid_families": sorted(VALID_FAMILIES), | |
| "benchmark_candidate_records": len(benchmark_candidates), | |
| "benchmark_families": sorted(BENCHMARK_FAMILIES), | |
| "domains": dict(sorted(domains.items())), | |
| } | |
| (args.output_dir / "summary.json").write_text( | |
| json.dumps(summary, indent=2) + "\n", encoding="utf-8" | |
| ) | |
| print(json.dumps(summary, indent=2)) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |