BRAG / README.md
Angshul's picture
Upload 8 files
1a3c3b3 verified
|
Raw History Blame Contribute Delete
5.03 kB
---
title: BRAG - Bayesian RAG
emoji: 🎯
colorFrom: indigo
colorTo: blue
sdk: gradio
sdk_version: 6.31.0
python_version: "3.11"
app_file: app.py
pinned: false
short_description: Closed-form Bayesian orchestration for RAG
---
# BRAG — Bayesian RAG
BRAG orchestrates retrieval-augmented question answering as a partially observable decision problem
solved in closed form. The orchestrator makes **no LLM calls**. Each decision is a few arithmetic
operations on conjugate (Beta) posteriors and takes microseconds. Only the actions call the LLM.
**Actions**
- `R1`: read the top-k BM25 passages and return an answer or NONE, plus a follow-up search query.
- `R2`: retrieve with the follow-up query, then read the old and new passages (the second hop).
- `CB`: take *m* parallel closed-book samples, which count as **one** vote (their mode). The vote's
reliability depends on how many of the samples agree.
**Posterior** (per-query reliabilities integrated out):
`log w_i = Σ_t [lnB(a_t+n_ti, b_t+N_t−n_ti) − lnB(a_t, b_t+N_t)] − n_i ln η`, with residual `−ln η`.
**Control**
- Choose `a* = argmax_a D_a / c_a`, where `D_a = q_a(ρ_a − (1−ρ_a)η) ln(ρ_a / ((1−ρ_a)η))` is the
KL information rate of action *a*.
- Stop when `P_err · D_a* / c_a* ≤ λ`.
**Hyperpriors**
- The reliabilities `ρ`, the answerability rates `q`, the agreement-level reliabilities `κ_g` and the
distractor concentration `η` are population-level.
- They are calibrated on labelled data and frozen; they are not self-trained.
- The shipped calibration (`data/calibration.json`) was fit with Claude Haiku as the LLM. When you use
another model, calibrate first with the `/calibrate` endpoint.
## Benchmark (300 test questions, Claude Haiku, BM25 over HippoRAG corpora)
| Method | Acc | F1 | LLM calls | Tokens |
|---|---|---|---|---|
| Closed-book | 0.270 | 0.275 | 1.00 | 69 |
| Vanilla RAG (1 hop) | 0.387 | 0.377 | 1.66 | 591 |
| IRCoT / self-ask style (always 2 hops) | 0.553 | 0.548 | 2.38 | 1561 |
| Adaptive / CRAG-style (hop if needed) | 0.550 | 0.529 | 2.05 | 1221 |
| **BRAG, λ = 0.05** | **0.567** | 0.545 | 3.26 | 1622 |
- Against the best baseline, the accuracy gain is +1.3 to +1.7 points. Paired-bootstrap 95% confidence
intervals include zero, so the gain is **not statistically significant**.
- The orchestrator's overhead is about 13 µs per decision.
- The deployed code reproduces the benchmark exactly: replayed on the cached LLM outputs it gives the
same accuracy and call count.
## Programmatic use
```python
from gradio_client import Client
c = Client("Angshul/BRAG")
answer, report = c.predict(
question="Friedrich Ratzel coined the phrase Lebensraum; which political movement made it notorious?",
corpus="HotpotQA", # HotpotQA | 2WikiMultihopQA | MuSiQue
documents="", # or your own passages: one per line, or a JSON list
lam=0.05, # cost of one LLM call in units of answer error
model="Qwen/Qwen2.5-7B-Instruct", # HF model id, or an OpenAI-compatible endpoint URL
hf_token="", # your own token, or empty to use the Space secret
provider="auto",
calibration="", # JSON returned by /calibrate for this model
api_name="/brag")
```
`report` contains, for every step:
- the posterior over candidate answers;
- the information rate of each action;
- the action taken and what it observed;
- the time the policy took.
It also contains the total LLM calls, tokens and wall-clock time.
To calibrate for a new model or corpus:
```python
cal = c.predict(labelled_json='[{"question": "...", "gold": ["..."]}, ...]', # 30+ questions
corpus="HotpotQA", documents="", model="<model>", hf_token="", provider="auto",
api_name="/calibrate")
```
REST:
```
POST /gradio_api/call/brag {"data": [question, corpus, documents, lam, model, hf_token, provider, calibration]}
GET /gradio_api/call/brag/<event_id>
```
## Scaling
- **The policy is not the bottleneck.** It is stateless per request and needs no GPU. Throughput is
bounded by the LLM provider's rate limits and by the Space's single replica.
- **Concurrency.** The Space queues requests and runs `BRAG_CONCURRENCY` of them at once (default 16).
Each request's closed-book samples run in parallel.
- **Callers can bring their own quota.** Pass `hf_token` so each caller is billed for their own
inference.
- **Higher throughput:**
- Point `model` at a dedicated, autoscaling Inference Endpoint, or at a vLLM or TGI server.
- Duplicate the Space.
- Import `brag.py` directly. It is a single dependency-light module:
`BRAG(llm).run(question, Corpus(passages))`.
## Setup
1. Add a Space secret `HF_TOKEN`, with permission to call Inference Providers.
2. Optionally set the variables `BRAG_MODEL` and `BRAG_CONCURRENCY`.
## Data
The corpora are from the HippoRAG reproduction set (OSU-NLP-Group/HippoRAG):
- HotpotQA (CC BY-SA 4.0)
- 2WikiMultihopQA (Apache-2.0)
- MuSiQue (CC BY 4.0)