ruslanmv's picture
Deploy MoC-RAG benchmark leaderboard
9f51f50 verified
Raw
History Blame Contribute Delete
3.65 kB
"""MoC-RAG Benchmark leaderboard — Gradio Space.
Self-contained: reads the bundled result artifacts in ``results/<embedder>/`` and
renders (1) the single-split leaderboard and (2) the robustness-by-query-type
table that is the headline of the benchmark. No dataset access or token needed.
"""
import json
from pathlib import Path
import gradio as gr
import pandas as pd
RESULTS = Path(__file__).parent / "results"
EMBEDDERS = [p.name for p in sorted(RESULTS.iterdir()) if p.is_dir()]
LEADERBOARD_COLS = [
("recall_at_k", "Recall@K"), ("precision_at_k", "Prec@K"), ("mrr", "MRR"),
("ndcg_at_k", "nDCG@K"), ("hard_distractors", "HardDistr↓"),
("tokens", "Tokens↓"), ("useful_context_ratio", "UsefulRatio↑"),
("context_efficiency", "CtxEff↑"), ("routing_accuracy", "RouteAcc"),
("groundedness", "Ground"),
]
def _pct(v):
return "-" if v is None else (f"{v:.0%}" if isinstance(v, float) and v <= 1 else v)
def leaderboard(embedder: str) -> pd.DataFrame:
rep = json.loads((RESULTS / embedder / "results.json").read_text())
rows = []
for name in rep["order"]:
m = rep["results"][name]
row = {"Method": name}
for key, label in LEADERBOARD_COLS:
v = m.get(key)
row[label] = _pct(v) if key in (
"recall_at_k", "precision_at_k", "useful_context_ratio",
"routing_accuracy", "groundedness") else (v if v is not None else "-")
rows.append(row)
return pd.DataFrame(rows)
def robustness(embedder: str) -> pd.DataFrame:
rep = json.loads((RESULTS / embedder / "variants.json").read_text())
cats = rep["categories"]
rows = []
for name in rep["order"]:
r = rep["results"][name]
row = {"Method": name}
for c in cats:
row[f"R@K {c}"] = _pct(r[c].get("recall_at_k"))
for c in cats:
row[f"HardDistr {c}"] = r[c].get("hard_distractors")
first = r[cats[0]].get("recall_at_k", 0.0)
last = r[cats[-1]].get("recall_at_k", 0.0)
row["Δ kw→adv"] = f"{last - first:+.0%}"
rows.append(row)
return pd.DataFrame(rows)
INTRO = """
# 🧭 MoC-RAG Benchmark Leaderboard
Does **routed, typed context** (Mixture-of-Contexts RAG) beat **flat RAG** for
agentic memory? This leaderboard reports retrieval, context-efficiency, routing,
and robustness metrics for BM25 / dense / hybrid / metadata-filtered / reranked
RAG and MoC-RAG (`top_experts ∈ {1,2,3,all}`).
**Headline (sentence-transformers):** BM25 collapses on adversarial queries
(−36% vs keyword), while MoC-RAG holds and **overtakes BM25 by ~+15 points on the
adversarial split**, carrying roughly half the hard distractors of dense RAG at
95–100% routing accuracy.
Dataset: [`ruslanmv/moc-rag-benchmark`](https://huggingface.co/datasets/ruslanmv/moc-rag-benchmark).
"""
def build():
with gr.Blocks(title="MoC-RAG Benchmark Leaderboard") as demo:
gr.Markdown(INTRO)
emb = gr.Dropdown(EMBEDDERS, value=("st" if "st" in EMBEDDERS else EMBEDDERS[0]),
label="Embedder")
gr.Markdown("## Robustness by query type (the key result)")
rob = gr.Dataframe(value=robustness("st" if "st" in EMBEDDERS else EMBEDDERS[0]),
interactive=False)
gr.Markdown("## Single-split leaderboard")
lead = gr.Dataframe(value=leaderboard("st" if "st" in EMBEDDERS else EMBEDDERS[0]),
interactive=False)
emb.change(robustness, emb, rob)
emb.change(leaderboard, emb, lead)
return demo
if __name__ == "__main__":
build().launch()