Assignment 3 — FAST-NUCES | NLP Course 2026 | Dr. Zohair Ahmed
Team: Ayesha Shabbir · Hifza Hussain · Saad bin Amir
This project reproduces and extends OPEN-RAG — an adaptive retrieval-augmented generation framework that teaches a language model to decide when to retrieve external knowledge rather than always retrieving or never retrieving.
The model (shayekh/openrag_llama2_7b_8x135m) is a LLaMA-2-7B fine-tuned with a Mixture-of-Experts adapter. At inference time it produces a retrieval probability P(retrieve). If P(retrieve) ≥ threshold γ, the model fetches external passages; otherwise it answers from parametric memory.
Assignment 2 reproduced the baseline on 2WikiMultihopQA.
Assignment 3 (this repo) adds:
| Dataset | Paper EM | Our EM | Notes |
|---|---|---|---|
| 2WikiMultihopQA (A2 baseline) | 43.6% | 48.5% | Exceeds paper by +4.9% |
| HotpotQA (A3 new dataset) | 63.3% | 54.0% | 85% of paper EM; gap due to sample size + 4-bit quant |
| Threshold γ | Exact Match |
|---|---|
| 0.3 (retrieve more) | 52.0% ← best |
| 0.5 (default) | 48.5% |
| 0.7 (retrieve less) | 48.0% |
Finding: For multi-hop questions a lower threshold (more aggressive retrieval) consistently helps. The model's default threshold of 0.5 is conservative for this task.
| Stratum | Condition | n | EM |
|---|---|---|---|
| High-confidence Retrieve | P > 0.7 | 63 (62.4%) | 54.0% |
| Ambiguous | 0.3 ≤ P ≤ 0.7 | 24 (23.8%) | 41.7% |
| High-confidence Skip | P < 0.3 | 14 (13.9%) | 35.7% |
Samples where the model is confident about retrieving achieve substantially higher EM (54% vs 36%), validating the adaptive retrieval design.
project-root/
├── README.md
├── requirements.txt
├── train.py ← evaluation runner (calls OPEN-RAG repo scripts)
├── inference.py ← single-question inference CLI
├── config.yaml ← all experiment parameters
│
├── data/
│ └── sample_data.csv ← 7 representative QA samples with metadata
│
├── notebooks/
│ └── 01_inference_demo.ipynb ← live Gradio demo (run on Colab)
│
├── src/
│ ├── model.py ← model loading utilities
│ ├── dataset.py ← dataset loading helpers
│ └── utils.py ← EM metric, threshold sweep, confidence analysis
│
├── results/
│ ├── baseline_metrics.json ← 2WikiMultihopQA baseline (A2)
│ ├── improved_metrics.json ← HotpotQA + threshold sweep (A3)
│ └── training_log.csv ← all experiment runs in one table
│
└── checkpoints/
└── README.md ← model weights are on HuggingFace (see below)
git clone <this-repo-url>
cd <this-repo>
git clone https://github.com/ShayekhBinIslam/openrag.git
pip install -r requirements.txt
GPU required. The model needs ~4–5 GB VRAM in 4-bit mode. We ran all experiments on a Google Colab A100.
No local weights are stored. The model downloads automatically from HuggingFace on first use:
Model: shayekh/openrag_llama2_7b_8x135m
URL : https://huggingface.co/shayekh/openrag_llama2_7b_8x135m
# Baseline (2WikiMultihopQA, threshold=0.5)
python train.py --task 2wikimultihopqa --threshold 0.5 --max_samples 101
# HotpotQA
python train.py --task hotpotqa --threshold 0.5 --max_samples 100
# Threshold sweep
python train.py --task 2wikimultihopqa --threshold 0.3 --max_samples 100
python train.py --task 2wikimultihopqa --threshold 0.7 --max_samples 100
python inference.py --question "Were Scott Derrickson and Ed Wood of the same nationality?"
# Interactive mode
python inference.py --interactive
Open notebooks/01_inference_demo.ipynb in Google Colab and run all cells. The notebook launches a Gradio interface with pre-computed results and real inference capability.
Motivation: The default threshold γ=0.5 is a single flat value applied to all questions. Our analysis shows that the model's retrieval confidence distribution varies across question types and datasets.
Method: Instead of a fixed threshold, we propose selecting γ based on the variance of P(retrieve) across a validation set:
Evidence from our experiments:
Assignment 3 — FAST-NUCES | NLP Course 2026 | Dr. Zohair Ahmed
Team: Ayesha Shabbir · Hifza Hussain · Saad bin Amir
This project reproduces and extends OPEN-RAG — an adaptive retrieval-augmented generation framework that teaches a language model to decide when to retrieve external knowledge rather than always retrieving or never retrieving.
The model (shayekh/openrag_llama2_7b_8x135m) is a LLaMA-2-7B fine-tuned with a Mixture-of-Experts adapter. At inference time it produces a retrieval probability P(retrieve). If P(retrieve) ≥ threshold γ, the model fetches external passages; otherwise it answers from parametric memory.
Assignment 2 reproduced the baseline on 2WikiMultihopQA.
Assignment 3 (this repo) adds:
| Dataset | Paper EM | Our EM | Notes |
|---|---|---|---|
| 2WikiMultihopQA (A2 baseline) | 43.6% | 48.5% | Exceeds paper by +4.9% |
| HotpotQA (A3 new dataset) | 63.3% | 54.0% | 85% of paper EM; gap due to sample size + 4-bit quant |
| Threshold γ | Exact Match |
|---|---|
| 0.3 (retrieve more) | 52.0% ← best |
| 0.5 (default) | 48.5% |
| 0.7 (retrieve less) | 48.0% |
Finding: For multi-hop questions a lower threshold (more aggressive retrieval) consistently helps. The model's default threshold of 0.5 is conservative for this task.
| Stratum | Condition | n | EM |
|---|---|---|---|
| High-confidence Retrieve | P > 0.7 | 63 (62.4%) | 54.0% |
| Ambiguous | 0.3 ≤ P ≤ 0.7 | 24 (23.8%) | 41.7% |
| High-confidence Skip | P < 0.3 | 14 (13.9%) | 35.7% |
Samples where the model is confident about retrieving achieve substantially higher EM (54% vs 36%), validating the adaptive retrieval design.
project-root/
├── README.md
├── requirements.txt
├── train.py ← evaluation runner (calls OPEN-RAG repo scripts)
├── inference.py ← single-question inference CLI
├── config.yaml ← all experiment parameters
│
├── data/
│ └── sample_data.csv ← 7 representative QA samples with metadata
│
├── notebooks/
│ └── 01_inference_demo.ipynb ← live Gradio demo (run on Colab)
│
├── src/
│ ├── model.py ← model loading utilities
│ ├── dataset.py ← dataset loading helpers
│ └── utils.py ← EM metric, threshold sweep, confidence analysis
│
├── results/
│ ├── baseline_metrics.json ← 2WikiMultihopQA baseline (A2)
│ ├── improved_metrics.json ← HotpotQA + threshold sweep (A3)
│ └── training_log.csv ← all experiment runs in one table
│
└── checkpoints/
└── README.md ← model weights are on HuggingFace (see below)
git clone <this-repo-url>
cd <this-repo>
git clone https://github.com/ShayekhBinIslam/openrag.git
pip install -r requirements.txt
GPU required. The model needs ~4–5 GB VRAM in 4-bit mode. We ran all experiments on a Google Colab A100.
No local weights are stored. The model downloads automatically from HuggingFace on first use:
Model: shayekh/openrag_llama2_7b_8x135m
URL : https://huggingface.co/shayekh/openrag_llama2_7b_8x135m
# Baseline (2WikiMultihopQA, threshold=0.5)
python train.py --task 2wikimultihopqa --threshold 0.5 --max_samples 101
# HotpotQA
python train.py --task hotpotqa --threshold 0.5 --max_samples 100
# Threshold sweep
python train.py --task 2wikimultihopqa --threshold 0.3 --max_samples 100
python train.py --task 2wikimultihopqa --threshold 0.7 --max_samples 100
python inference.py --question "Were Scott Derrickson and Ed Wood of the same nationality?"
# Interactive mode
python inference.py --interactive
Open notebooks/01_inference_demo.ipynb in Google Colab and run all cells. The notebook launches a Gradio interface with pre-computed results and real inference capability.
Motivation: The default threshold γ=0.5 is a single flat value applied to all questions. Our analysis shows that the model's retrieval confidence distribution varies across question types and datasets.
Method: Instead of a fixed threshold, we propose selecting γ based on the variance of P(retrieve) across a validation set:
Evidence from our experiments: