|
|
|
|
|
|
|
|
|
|
|
|
|
|
| import glob
|
| import json
|
| import os
|
| import time
|
| import argparse
|
| import threading
|
| from concurrent.futures import ThreadPoolExecutor
|
|
|
| from humomni.core.streaming_driver import run_sample
|
|
|
|
|
| def make_policy_factory(name, config):
|
| """Return a zero-arg factory that builds a FRESH policy per sample (no state leak)."""
|
| if name == "silent":
|
| from humomni.phase1.policies import SilentPolicy
|
| return lambda: SilentPolicy()
|
| if name == "api":
|
| from humomni.phase1.policy_api import APIPolicy
|
| return lambda: APIPolicy(config=config)
|
| raise ValueError(f"unknown policy {name!r}")
|
|
|
|
|
| def _qid(d):
|
| with open(os.path.join(d, "question.json"), encoding="utf-8") as f:
|
| return json.load(f)["question_id"]
|
|
|
|
|
| def _done_qids(out):
|
| done = set()
|
| if os.path.exists(out):
|
| with open(out, encoding="utf-8") as f:
|
| for ln in f:
|
| ln = ln.strip()
|
| if ln:
|
| try:
|
| done.add(json.loads(ln)["question_id"])
|
| except Exception:
|
| pass
|
| return done
|
|
|
|
|
| def main(data_dir, out, policy_factory, limit=0, workers=1, resume=False):
|
| dirs = sorted(d for d in glob.glob(os.path.join(data_dir, "*")) if os.path.isdir(d))
|
| if limit:
|
| dirs = dirs[:limit]
|
| done = _done_qids(out) if resume else set()
|
| if not resume:
|
| open(out, "w", encoding="utf-8").close()
|
| todo = [d for d in dirs if _qid(d) not in done]
|
| print(f"{len(dirs)} samples | {len(done)} already done | {len(todo)} to run", flush=True)
|
|
|
| lock = threading.Lock()
|
| fails = []
|
| wfile = open(out, "a", encoding="utf-8")
|
|
|
| def process(d):
|
| for attempt in range(3):
|
| try:
|
| return run_sample(d, policy_factory())
|
| except Exception as e:
|
| if attempt == 2:
|
| fails.append((_qid(d), str(e)[:120]))
|
| return {"question_id": _qid(d), "model_response_list": []}
|
| time.sleep(0.5)
|
|
|
| def handle(d):
|
| rec = process(d)
|
| with lock:
|
| wfile.write(json.dumps(rec, ensure_ascii=False) + "\n")
|
| wfile.flush()
|
| return rec
|
|
|
| try:
|
| if workers > 1:
|
| with ThreadPoolExecutor(max_workers=workers) as ex:
|
| for n, _ in enumerate(ex.map(handle, todo), 1):
|
| if n % 50 == 0:
|
| print(f" ...{n}/{len(todo)}", flush=True)
|
| else:
|
| for n, d in enumerate(todo, 1):
|
| handle(d)
|
| if n % 50 == 0:
|
| print(f" ...{n}/{len(todo)}", flush=True)
|
| finally:
|
| wfile.close()
|
| print(f"wrote -> {out} (failed samples: {len(fails)})")
|
| for q, e in fails[:10]:
|
| print(" FAIL", q, e)
|
|
|
|
|
| if __name__ == "__main__":
|
| ap = argparse.ArgumentParser()
|
| ap.add_argument("--data_dir", default="data/phase1/data")
|
| ap.add_argument("--out", default="submission.jsonl")
|
| ap.add_argument("--policy", default="api", choices=["silent", "api"])
|
| ap.add_argument("--config", default="config.json", help="orchestrator config (gate/theta/dedup)")
|
| ap.add_argument("--limit", type=int, default=0, help="process only the first N samples (0=all; experiment.py uses it for fast Phase-2 evals)")
|
| ap.add_argument("--workers", type=int, default=1, help="parallel samples (independent, still causal)")
|
| ap.add_argument("--resume", action="store_true", help="skip question_ids already in --out")
|
| a = ap.parse_args()
|
| cfg = None
|
| if a.policy == "api" and os.path.exists(a.config):
|
| cfg = json.load(open(a.config, encoding="utf-8"))
|
|
|
| if a.policy == "api" and a.workers > 1:
|
|
|
|
|
|
|
| import humomni.phase1.vlm_client as vlm_client
|
| try:
|
| vlm_client._client_().chat.completions.create(
|
| model=vlm_client.MODEL, max_tokens=1,
|
| messages=[{"role": "user", "content": "ping"}])
|
| except Exception:
|
| pass
|
| if (cfg or {}).get("dedup", {}).get("use_llm"):
|
| import humomni.core.judges as judges
|
| try:
|
| judges.gemini("ping")
|
| except Exception:
|
| pass
|
| try:
|
| import humomni.core.emb_cache as emb_cache
|
| emb_cache.embed("ping")
|
| except Exception:
|
| pass
|
|
|
| main(a.data_dir, a.out, make_policy_factory(a.policy, cfg),
|
| limit=a.limit, workers=a.workers, resume=a.resume)
|
|
|