Buckets:
| """cwm3/weak/run_gpt.py — thin wrapper over cwm2/annotation_package/run_annotation.py for the cwm3 budget (budget.yaml). | |
| Adds the gpt-5 family (the only models visible on the 2026-09-10 key) to the package's model/price tables at import time | |
| (the shipped package itself is not modified), points the ledger at cwm3/weak/budget_ledger.sqlite and enforces the $100 cap. | |
| Usage: python cwm3/weak/run_gpt.py --model gpt-5 --pass observe_prefix --preset standard --detail high --clips <id> --mode sync --cap-usd 1 | |
| """ | |
| import os, sys | |
| from pathlib import Path | |
| CWM3 = Path(__file__).resolve().parents[1] | |
| PKG = CWM3.parent / "cwm2" / "annotation_package" | |
| sys.path.insert(0, str(PKG)) | |
| os.environ.setdefault("CWM2_ALLOW_PAID_API", "1") # authorised by cwm3/budget.yaml (user, 2026-09-10) | |
| os.environ.setdefault("OPENAI_API_KEY_FILE", os.path.expanduser("~/.openai_api_key")) | |
| import pkg_common as pc # noqa: E402 | |
| # OpenAI list prices (USD / 1M tokens) for the gpt-5 family as of the 2025-08 launch; batch = 50 %. Snapshot recorded here; | |
| # the ledger stores the true `usage` so reconciliation catches any drift. | |
| pc.PRICING["gpt-5"] = {"standard": {"input": 1.25, "cached_input": 0.125, "output": 10.0}, | |
| "batch": {"input": 0.625, "cached_input": 0.0625, "output": 5.0}} | |
| pc.PRICING["gpt-5-mini"] = {"standard": {"input": 0.25, "cached_input": 0.025, "output": 2.0}, | |
| "batch": {"input": 0.125, "cached_input": 0.0125, "output": 1.0}} | |
| pc.MODELS = tuple(pc.MODELS) + ("gpt-5", "gpt-5-mini") | |
| pc.LEDGER_PATH = CWM3 / "weak" / "budget_ledger.sqlite" | |
| HARD_CAP = 100.0 | |
| import run_annotation as ra # noqa: E402 | |
| if "--ledger" not in sys.argv: | |
| sys.argv += ["--ledger", str(pc.LEDGER_PATH)] | |
| # ---- 2026-09-12 hard rule (roadmap §B3 / owner): TEST (and VAL) clips never leave the machine. Every clip resolved for a paid call must belong to a | |
| # TRAIN-split device (cwm2/private/clip_map_full.json dongle -> s3 anchors split, the split_of rule of score_clean568); anything else aborts before | |
| # any request is built. `--clips all` is resolved through the same check. | |
| CLIP_MAP = CWM3.parent / "cwm2" / "private" / "clip_map_full.json" | |
| S3_ANCHORS = CWM3.parent / "s3_can_baseline" / "results" / "anchors.parquet" | |
| CLIP_MAP_PILOT = CWM3.parent / "cwm2" / "private" / "clip_map.json" # 187-clip pilot manifest; its ids are NOT in clip_map_full.json | |
| def _split_of_dongle(d, known): | |
| """split_of rule of s12_wm/build_targets_s12.py:40-44 (= build_pilot_manifest.py / score_clean568.py): s3 known map, else md5 bucket.""" | |
| import hashlib | |
| if d in known: | |
| return known[d] | |
| h = int(hashlib.md5(d.encode()).hexdigest(), 16) % 100 | |
| return "train" if h < 60 else ("val" if h < 70 else "test") | |
| def _split_of_clips(clip_ids): | |
| import json | |
| import pandas as pd | |
| cm = json.load(open(CLIP_MAP)) | |
| cmp = json.load(open(CLIP_MAP_PILOT)) if CLIP_MAP_PILOT.is_file() else {} # 2026-09-13: pilot clips resolve through their own private map | |
| a3 = pd.read_parquet(S3_ANCHORS, columns=["dongle", "split"]).drop_duplicates("dongle") | |
| known = dict(zip(a3.dongle, a3.split)) | |
| out = {} | |
| for c in clip_ids: | |
| d = cm.get(c, {}).get("dongle") or cmp.get(c, {}).get("dongle") | |
| out[c] = _split_of_dongle(d, known) if d else "unknown" # no dongle -> "unknown" -> refused by assert_train_only | |
| return out | |
| def assert_train_only(clips_arg, limit=None): | |
| ids = pc.resolve_clips(clips_arg, limit, require_frames=False) | |
| sp = _split_of_clips(ids) | |
| bad = {c: s for c, s in sp.items() if s != "train"} | |
| if bad: | |
| ex = ", ".join(f"{c}:{s}" for c, s in list(bad.items())[:5]) | |
| raise SystemExit(f"run_gpt.py REFUSED: {len(bad)} of {len(ids)} clips are not on TRAIN-split devices (test / val clips never leave the machine): {ex}" | |
| + (" ..." if len(bad) > 5 else "")) | |
| return ids | |
| if __name__ == "__main__": | |
| _argv = sys.argv[1:] | |
| _clips = _argv[_argv.index("--clips") + 1] if "--clips" in _argv else "all" | |
| _limit = int(_argv[_argv.index("--limit") + 1]) if "--limit" in _argv else None | |
| assert_train_only(_clips, _limit) | |
| sys.exit(ra.main()) | |
Xet Storage Details
- Size:
- 4.29 kB
- Xet hash:
- 1d2907947e8ae2ffcd5de0c1d50fd05ac121206eff8a4efe945ebafae573b900
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.