SPB Git

spb/wp27_uqo

Public
3.6 KB · 69 lines python
1"""`ma` command line: run one config, run a design, analyze, estimate budget."""2from __future__ import annotations34import argparse5import json6import sys7from pathlib import Path8910def main(argv=None) -> None:11    ap = argparse.ArgumentParser(prog="ma")12    sub = ap.add_subparsers(dest="cmd", required=True)13    r = sub.add_parser("run", help="run one configuration")14    r.add_argument("config"); r.add_argument("--seed", type=int); r.add_argument("--out"); r.add_argument("--set", nargs="*", default=[])15    r.add_argument("--cache"); r.add_argument("--progress", action="store_true")16    d = sub.add_parser("design", help="run a design file (cells x seeds)")17    d.add_argument("design"); d.add_argument("--workers", type=int, default=4); d.add_argument("--cache"); d.add_argument("--cells", nargs="*")18    d.add_argument("--max-seeds", type=int); d.add_argument("--root", default="results/runs")19    b = sub.add_parser("budget", help="estimate API calls and USD for a design")20    b.add_argument("design"); b.add_argument("--tokens-in", type=int, default=800); b.add_argument("--tokens-out", type=int, default=250)21    args = ap.parse_args(argv)22    from dotenv import load_dotenv23    load_dotenv(Path(".env"), override=False)24    if args.cmd == "run":25        from .experiments.config import RunConfig26        from .experiments.runner import run_config27        from .metrics.outcomes import run_outcomes28        ov = {}29        for kv in args.set:30            k, v = kv.split("=", 1)31            ov[k] = json.loads(v) if v[:1] in "[{\"0123456789-tfn" and v not in ("true", "false") else v32            if v in ("true", "false"):33                ov[k] = v == "true"34        cfg = RunConfig.from_yaml(args.config, **ov)35        if args.seed is not None:36            cfg = cfg.with_overrides(seed=args.seed)37        res = run_config(cfg, out_dir=args.out, cache_path=args.cache, progress=args.progress)38        oc = run_outcomes(res)39        print(json.dumps({k: (round(v, 4) if isinstance(v, float) else v) for k, v in oc.items()}, indent=1, default=str))40    elif args.cmd == "design":41        from .experiments.design import run_design42        df = run_design(args.design, args.root, args.workers, args.cache, args.cells, args.max_seeds)43        print(df.groupby("name")[[c for c in ("msd_log", "spread_bp", "n_bubbles", "llm_usd") if c in df]].mean().round(4))44    elif args.cmd == "budget":45        from .experiments.design import cell_config, expand_cells, load_design, seeds_of46        design = load_design(args.design)47        total_calls, total_usd = 0, 0.048        for c in expand_cells(design):49            for s in seeds_of(design):50                cfg = cell_config(design, c, s, Path(args.design).parent)51                p = cfg.population52                n_llm = int(round(p.llm_share * p.n_traders))53                n_dec = (cfg.n_ticks - cfg.warmup // 2) // p.llm.decision_interval54                if p.llm.decision_cap:55                    n_dec = min(n_dec, p.llm.decision_cap)56                calls = n_llm * n_dec57                usd = 0.058                for prov, share in p.llm.provider_mix.items():59                    model = p.llm.models.get(prov, "")60                    pr = p.llm.price_assumptions.get(model, {"input": 0, "output": 0})61                    usd += calls * share * (args.tokens_in * pr["input"] + args.tokens_out * pr["output"]) / 1e662                total_calls += calls63                total_usd += usd64        print(f"design {design['name']}: {total_calls} LLM calls, est. ${total_usd:.2f} at {args.tokens_in} in / {args.tokens_out} out tokens per call")656667if __name__ == "__main__":68    main(sys.argv[1:])69
Files · main
Menu

Theme