Ruvadev commited on
Commit
926dffd
·
verified ·
1 Parent(s): b7ed367

Delete raven/budget.py

Browse files
Files changed (1) hide show
  1. raven/budget.py +0 -176
raven/budget.py DELETED
@@ -1,176 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import copy
4
- import json
5
- import math
6
- from pathlib import Path
7
-
8
- import yaml
9
-
10
- from .benchmark import benchmark_foundation
11
- from .config import load_config
12
- from .utils import read_jsonl
13
-
14
-
15
- def _counts(rows: list[dict]) -> dict:
16
- out = {"train_real": 0, "train_ai": 0, "val": 0, "test": 0}
17
- for r in rows:
18
- split = str(r.get("split", "train"))
19
- if split == "train":
20
- out["train_ai" if int(r.get("label", 0)) == 1 else "train_real"] += 1
21
- elif split == "val":
22
- out["val"] += 1
23
- elif split == "test":
24
- out["test"] += 1
25
- return out
26
-
27
-
28
- def _estimate(cfg: dict, counts: dict, ips: float) -> dict:
29
- fc = cfg["foundation"]
30
- rc = cfg["real_specialists"]
31
- tc = cfg["training"]
32
- cap = int(fc.get("train_cap_per_class", 0))
33
- tr0 = counts["train_real"] if cap <= 0 else min(counts["train_real"], cap)
34
- tr1 = counts["train_ai"] if cap <= 0 else min(counts["train_ai"], cap)
35
- eval_n = counts["val"] + counts["test"]
36
- base_n = tr0 + tr1 + eval_n
37
- aug_per_class = int(fc.get("augment_max_per_class", 0))
38
- aug_n = 0
39
- if not bool(fc.get("reuse_semantic_for_augmented_views", True)):
40
- aug_n = min(tr0, aug_per_class) + min(tr1, aug_per_class)
41
- foundation_n = base_n + aug_n
42
- foundation_h = foundation_n / max(ips, 1e-6) / 3600.0
43
-
44
-
45
- runtime = str(fc.get("_planned_runtime", "unknown"))
46
- overhead = {"directml": 1.65, "openvino": 1.80, "torch": 2.15}.get(runtime, 1.90)
47
- cache_h = foundation_h * overhead
48
-
49
- specialist_limit = int(rc.get("max_real_images", 0))
50
- specialist_n = counts["train_real"] if specialist_limit <= 0 else min(counts["train_real"], specialist_limit)
51
- specialist_epochs = int(rc.get("epochs", 12))
52
- specialist_h = 0.05 + specialist_n * (0.030 + 0.0015 * specialist_epochs) / 3600.0
53
-
54
-
55
- members = int(tc.get("ensemble_members", 5))
56
- epochs = int(tc.get("epochs", 60))
57
- refine = int(tc.get("hard_refine_epochs", 6))
58
- selected_train = tr0 + tr1
59
- fusion_h = 0.04 + (selected_train / 10000.0) * members * (epochs + refine) * 0.0018
60
- calibration_h = 0.08
61
- total = cache_h + specialist_h + fusion_h + calibration_h
62
- return {
63
- "selected_train_real": tr0,
64
- "selected_train_ai": tr1,
65
- "eval_images": eval_n,
66
- "foundation_passes": foundation_n,
67
- "foundation_hours_raw": foundation_h,
68
- "cache_hours_est": cache_h,
69
- "specialist_hours_est": specialist_h,
70
- "fusion_hours_est": fusion_h,
71
- "calibration_hours_est": calibration_h,
72
- "total_hours_est": total,
73
- }
74
-
75
-
76
- def plan_budget(
77
- manifest: str,
78
- base_config: str,
79
- out_config: str,
80
- target_hours: float = 4.5,
81
- min_hours: float = 3.0,
82
- max_hours: float = 6.0,
83
- accelerator: str = "auto",
84
- loops: int = 4,
85
- ) -> dict:
86
- rows = read_jsonl(manifest)
87
- counts = _counts(rows)
88
- cfg = copy.deepcopy(load_config(base_config))
89
- bench = benchmark_foundation(cfg, accelerator, loops)
90
- ips = float(bench["foundation_images_per_second"])
91
- runtime = str(bench["selected_runtime"])
92
- fc, rc, tc = cfg["foundation"], cfg["real_specialists"], cfg["training"]
93
- fc["_planned_runtime"] = runtime
94
-
95
-
96
- tc["ensemble_members"] = 5
97
- tc["epochs"] = 60
98
- tc["early_stop_patience"] = 7
99
- tc["hard_refine_epochs"] = 6
100
- tc["hard_refine_lr_multiplier"] = 0.22
101
- tc["hard_replay_boost"] = 4.0
102
- tc["contrastive_weight"] = 0.028
103
- tc["branch_dropout"] = 0.12
104
- tc["source_dropout_per_member"] = 1
105
- rc["epochs"] = 12
106
- rc["early_stop_patience"] = 3
107
-
108
- rc["max_real_images"] = int(counts["train_real"])
109
- fc["reuse_semantic_for_augmented_views"] = True
110
- fc["augment_max_per_class"] = 6000
111
- fc["train_coreset"] = True
112
- fc["train_cap_per_class"] = 0
113
-
114
-
115
- target = min(max(float(target_hours), float(min_hours)), float(max_hours))
116
- runtime_factor = {"directml": 1.65, "openvino": 1.80, "torch": 2.15}.get(runtime, 1.90)
117
- foundation_budget_h = target * 0.62
118
- affordable_total = int(foundation_budget_h * 3600.0 * ips / runtime_factor)
119
- eval_n = counts["val"] + counts["test"]
120
- train_budget = max(2000, affordable_total - eval_n)
121
-
122
-
123
- fc["train_cap_per_class"] = 0
124
-
125
- est = _estimate(cfg, counts, ips)
126
-
127
-
128
- if fc["train_cap_per_class"] == 0 and est["total_hours_est"] < min(target * 0.78, max_hours - 0.5):
129
- remaining_h = max(0.0, target - est["total_hours_est"])
130
- extra_passes = int(remaining_h * 3600.0 * ips / runtime_factor * 0.72)
131
- per_cls_extra = min(counts["train_real"], counts["train_ai"], max(0, extra_passes // 2))
132
- if per_cls_extra >= 500:
133
- fc["reuse_semantic_for_augmented_views"] = False
134
- fc["augment_max_per_class"] = int(min(6000, per_cls_extra))
135
- est = _estimate(cfg, counts, ips)
136
-
137
-
138
- if est["total_hours_est"] > max_hours:
139
- fc["reuse_semantic_for_augmented_views"] = True
140
- fc["augment_max_per_class"] = 0
141
- tc["epochs"] = min(int(tc.get("epochs",60)), 50)
142
- tc["hard_refine_epochs"] = min(int(tc.get("hard_refine_epochs",6)), 4)
143
- fc["train_cap_per_class"] = 0
144
- rc["max_real_images"] = int(counts["train_real"])
145
- est = _estimate(cfg, counts, ips)
146
-
147
- cfg["project"]["version"] = "5.1-full-data-debiased"
148
- cfg["budget"] = {
149
- "target_hours": target,
150
- "minimum_hours": float(min_hours),
151
- "maximum_hours": float(max_hours),
152
- "benchmark_runtime": runtime,
153
- "foundation_images_per_second": ips,
154
- "planner_note": "Estimate is hardware-measured but still approximate; disk/image decode speed can shift wall time.",
155
- }
156
- fc.pop("_planned_runtime", None)
157
- out = Path(out_config)
158
- out.parent.mkdir(parents=True, exist_ok=True)
159
- out.write_text(yaml.safe_dump(cfg, allow_unicode=True, sort_keys=False), encoding="utf-8")
160
- result = {
161
- "counts": counts,
162
- "benchmark": bench,
163
- "selected": {
164
- "train_cap_per_class": int(fc.get("train_cap_per_class", 0)),
165
- "reuse_semantic_for_augmented_views": bool(fc.get("reuse_semantic_for_augmented_views", True)),
166
- "augment_max_per_class": int(fc.get("augment_max_per_class", 0)),
167
- "real_specialist_max": int(rc.get("max_real_images", 0)),
168
- "ensemble_members": int(tc.get("ensemble_members", 5)),
169
- "hard_refine_epochs": int(tc.get("hard_refine_epochs", 0)),
170
- "all_original_train_images": True,
171
- },
172
- "estimate": est,
173
- "output_config": str(out),
174
- }
175
- Path(str(out) + ".plan.json").write_text(json.dumps(result, indent=2, ensure_ascii=False), encoding="utf-8")
176
- return result