Spaces:
Sleeping
Sleeping
Download app/benchmark.py from Conradf/nullmap-api: direct link, hf CLI and curl.
- Browser
- Download file 5 kB
-
https://huggingface.co/spaces/Conradf/nullmap-api/resolve/main/app/benchmark.py
- Command line
-
hf download hf://spaces/Conradf/nullmap-api/app/benchmark.py
-
curl -L -o benchmark.py https://huggingface.co/spaces/Conradf/nullmap-api/resolve/main/app/benchmark.py
5 kB
| """Paired compression accuracy and real cold/warm cost measurements. | |
| python -m app.benchmark compression --input data/normalized.jsonl --limit 20 | |
| python -m app.benchmark search --idea 'Does vitamin D reduce depression?' | |
| """ | |
| import argparse | |
| import asyncio | |
| import json | |
| from pathlib import Path | |
| from time import perf_counter | |
| import httpx | |
| from app.config import Settings, settings | |
| from app.ingest.__main__ import read_jsonl | |
| from app.llm import LLMService, Usage | |
| FIELDS = ("n", "estimate", "ci_low", "ci_high", "p_value", "effect_type", "outcome") | |
| async def compression_benchmark(path: Path, limit: int) -> dict: | |
| config = Settings(**settings.model_dump()) | |
| config.compression_enabled = True | |
| config.compression_validated = True # Experiment only; never changes live configuration. | |
| if not config.ttc_api_key or not config.openai_api_key: | |
| raise ValueError("OpenAI and TTC keys are required for the paired benchmark") | |
| llm = LLMService(config) | |
| rows = [] | |
| try: | |
| for study in read_jsonl(path): | |
| if len(rows) >= limit: | |
| break | |
| if ( | |
| not study.get("abstract") | |
| or study.get("is_review") | |
| or study.get("source") != "openalex" | |
| ): | |
| continue | |
| pair = {"id": study["id"]} | |
| for compressed in (False, True): | |
| usage = Usage() | |
| label = "compressed" if compressed else "original" | |
| started = perf_counter() | |
| try: | |
| result = await llm.extract(study, usage, compression=compressed) | |
| pair[label] = { | |
| "verified": True, | |
| "facts": {key: result.get(key) for key in FIELDS}, | |
| } | |
| except Exception as exc: | |
| pair[label] = {"verified": False, "failure": type(exc).__name__, "facts": {}} | |
| pair[label]["usage"] = usage.summary([study["abstract"]], config) | |
| pair[label]["wallMs"] = round((perf_counter() - started) * 1000) | |
| pair["exactFactAgreement"] = pair["original"]["facts"] == pair["compressed"]["facts"] | |
| rows.append(pair) | |
| finally: | |
| await llm.close() | |
| passed = sum( | |
| r["original"]["verified"] and r["compressed"]["verified"] and r["exactFactAgreement"] | |
| for r in rows | |
| ) | |
| return { | |
| "kind": "paired_compression", | |
| "studies": len(rows), | |
| "verifiedExactAgreements": passed, | |
| "agreementRate": passed / len(rows) if rows else None, | |
| "enableRecommended": bool(rows) and passed == len(rows) and config.ttc_input_price > 0, | |
| "limitation": "Agreement with uncompressed model extraction is not human-validated clinical accuracy. Review every difference and include actual TTC pricing before enabling compression.", | |
| "rows": rows, | |
| } | |
| async def search_benchmark(idea: str, url: str) -> dict: | |
| rows = [] | |
| async with httpx.AsyncClient(timeout=300) as client: | |
| for label in ("first", "repeat"): | |
| started = perf_counter() | |
| response = await client.post( | |
| f"{url.rstrip('/')}/search", json={"idea": idea, "sesoi": 0.2} | |
| ) | |
| response.raise_for_status() | |
| result = response.json() | |
| rows.append( | |
| { | |
| "run": label, | |
| "wallMs": round((perf_counter() - started) * 1000), | |
| "matched": result["totalScanned"], | |
| "retrieval": result["retrieval"], | |
| "costs": result["costs"], | |
| "warnings": result["warnings"], | |
| } | |
| ) | |
| return { | |
| "kind": "measured_repeated_search", | |
| "idea": idea, | |
| "runs": rows, | |
| "note": "The first run is cold only for documents not previously extracted. Inspect cache hits.", | |
| } | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| sub = parser.add_subparsers(dest="command", required=True) | |
| compression = sub.add_parser("compression") | |
| compression.add_argument("--input", type=Path, required=True) | |
| compression.add_argument("--limit", type=int, default=20) | |
| search = sub.add_parser("search") | |
| search.add_argument("--idea", required=True) | |
| search.add_argument("--url", default="http://127.0.0.1:8000") | |
| for command in (compression, search): | |
| command.add_argument("--output", type=Path, required=True) | |
| args = parser.parse_args() | |
| if getattr(args, "limit", 1) <= 0: | |
| parser.error("--limit must be positive") | |
| result = asyncio.run( | |
| compression_benchmark(args.input, args.limit) | |
| if args.command == "compression" | |
| else search_benchmark(args.idea, args.url) | |
| ) | |
| args.output.parent.mkdir(parents=True, exist_ok=True) | |
| args.output.write_text(json.dumps(result, indent=2)) | |
| print(f"Benchmark written to {args.output}") | |
| if __name__ == "__main__": | |
| main() | |