File size: 9,516 Bytes
404da58 d574299 404da58 d574299 404da58 83bdf33 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 d42c9fb d574299 404da58 d42c9fb 404da58 d574299 404da58 d574299 d42c9fb d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 d574299 404da58 81deeef c90fd11 81deeef 404da58 d574299 404da58 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | # EmpathRAG
<div align="center">
**Emotion-Aware Retrieval-Augmented Generation with Safety Guardrails for Student Mental Health**
[](https://python.org)
[](https://pytorch.org)
[](LICENSE)
[]()
[](https://umd.edu)
*MSML641 Β· Applied Machine Learning Β· University of Maryland Β· Spring 2025*
</div>
---
Standard RAG systems treat every message identically as a neutral information request. A student in crisis and a student asking for study tips go through the same retrieval pipeline, with no emotional awareness and no safety gate.
**EmpathRAG fixes this.** It is a 5-stage NLP pipeline that classifies a student's emotional state *before* retrieval, rewrites queries based on that state, and intercepts crisis-level messages with a trained NLI classifier before the language model is ever invoked.
---
## Pipeline
```
Student Message
β
ββββΆ [1] Emotion Classifier RoBERTa + LoRA (CPU)
β distress Β· anxiety Β· frustration Β· neutral Β· hopeful
β
ββββΆ [2] Safety Guardrail DeBERTa-v3 NLI (CPU)
β β If crisis β return 988 lifeline Β· STOP Β· generator never runs
β
ββββΆ [3] Query Router Deterministic templates + session tracker
β Rewrites query with emotion context Β· tracks 6 trajectory states
β
ββββΆ [4] FAISS Retrieval all-mpnet-base-v2 Β· 1,674,369 vectors
β Emotion-match re-ranking Β· SQLite metadata sidecar
β
ββββΆ [5] Mistral 7B Generator Q4_K_M GGUF Β· 28/33 GPU layers
Sliding 3-turn memory Β· 2-paragraph empathetic response
```
---
## Results
| Metric | Value | Target | |
|---|---|---|---|
| RoBERTa Emotion F1 (weighted) | **0.7127** | > 0.55 | β
|
| DeBERTa Crisis Recall (held-out NLI test set, 23K samples) | **0.9629** | > 0.80 | β
|
| DeBERTa Crisis Recall (30 adversarial probes, 6 categories) | **0.75** | β | β
|
| DeBERTa Crisis Precision | **0.7951** | > 0.65 | β
|
| BERTScore F1 | **0.8266** | > 0.72 | β
|
| Wilcoxon p-value (Full vs BM25) | **3.62e-08** | < 0.05 | β
|
| Euphemistic recall β NLI vs keyword | **100% vs 20%** | β | π |
### Ablation β Emotion Alignment Score (3-condition)
| Condition | Retrieval | Emotion Conditioning | Score |
|---|---|---|---|
| A β BM25 baseline | Sparse | None | 0.30 |
| C β Dense RAG | FAISS semantic | None | 0.50 |
| D β **Full EmpathRAG** | FAISS + emotion | Query rewrite + re-rank | **0.88** |
> Emotion conditioning contributes **+0.38** over pure dense retrieval (CβD). Wilcoxon signed-rank: p = 3.62e-08.
> **Note:** Condition B (DPR two-tower baseline) was descoped β deprioritised to increase adversarial probe depth. A ColBERT-scale index would be required for DPR to offer meaningful gains over FAISS flat-L2 at 1.67M vectors.
---
## Key Finding
The NLI-framed safety guardrail outperforms a keyword filter across every adversarial probe category that matters:
| Probe Category | EmpathRAG (NLI) | Keyword Filter |
|---|---|---|
| Direct crisis language | 100% | 80% |
| Euphemistic / indirect | **100%** | 20% |
| Negation bypass | **100%** | 60% |
| Bait-and-switch | 40% | 20% |
Keyword filters miss indirect phrasing. NLI understands semantic entailment. This is the core research finding.
---
## Demo
> π **Demo recording in progress** β Loom walkthrough coming soon.
The Gradio demo shows:
- Real-time emotion timeline with trajectory detection across turns
- Safety guardrail panel with Integrated Gradients token attribution highlights
- Multi-turn conversation memory (sliding 3-turn window)
- Session ID for human evaluation correlation
To run locally (requires models β see [Setup](#setup)):
```bash
python demo/app.py
```
---
## VRAM Budget (RTX 3060, 6 GB)
| Component | Device | VRAM |
|---|---|---|
| RoBERTa + DeBERTa | CPU | 0 MB |
| Sentence Transformer | GPU (encode only) | 440 MB |
| Mistral 7B Q4_K_M | GPU resident | 3,870 MB |
| KV cache + compute | GPU | ~630 MB |
| **Total peak** | | **~4,940 MB** β
|
---
## Repo Structure
```
Empath-RAG/
βββ src/
β βββ pipeline/
β β βββ pipeline.py # 5-stage orchestrator Β· conversation memory
β β βββ query_router.py # Emotion-conditioned query rewriting
β β βββ session_tracker.py # Trajectory detection (6 states)
β βββ models/
β β βββ guardrail_ig.py # DeBERTa NLI + Integrated Gradients
β β βββ annotate_corpus.py # Corpus emotion annotation (Colab A100)
β βββ data/
β βββ preprocess.py # GoEmotions 27β5 label collapse
β βββ build_faiss_index.py # FAISS IVFFlat builder
β βββ build_nli_pairs.py # NLI training pair construction
βββ demo/
β βββ app.py # Gradio demo Β· emotion timeline Β· crisis panel
βββ eval/
β βββ run_ablation.py # Conditions A / C / D
β βββ run_bertscore.py # BERTScore F1
β βββ run_wilcoxon.py # Wilcoxon signed-rank test
β βββ run_adversarial.py # NLI vs keyword filter Β· 30 probes
β βββ test_prompts.json # 50 prompts Β· 10 per emotion class
β βββ adversarial_probes.json # 30 probes Β· 6 categories Γ 5
βββ notebooks/
β βββ colab_emotion_classifier.ipynb # RoBERTa + LoRA Β· A100
β βββ colab_deberta_guardrail.ipynb # DeBERTa NLI Β· A100 Β· bf16
βββ data/
βββ MANIFEST.md # Dataset download instructions
```
---
## Setup
**Requirements:** Python 3.12 Β· CUDA 12.1 Β· 6 GB VRAM Β· 16 GB RAM Β· ~15 GB disk
> β οΈ Install order is critical β do not skip steps.
```bash
# 1. Clone
git clone https://github.com/MukulRay1603/Empath-RAG.git
cd Empath-RAG
python -m venv venv
venv\Scripts\activate # Windows
# 2. PyTorch with CUDA β install FIRST
pip install torch==2.5.1+cu121 --index-url https://download.pytorch.org/whl/cu121
# 3. llama-cpp-python CUDA wheel β install SECOND
pip install "llama_cpp_python==0.3.4" --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121
# 4. Everything else
pip install -r requirements.txt
# 5. Force correct numpy (faiss requires < 2.0)
pip install "numpy==1.26.4" --force-reinstall
```
**Model downloads** β see [`data/MANIFEST.md`](data/MANIFEST.md) for dataset download instructions.
Mistral 7B GGUF β download `mistral-7b-instruct-v0.2.Q4_K_M.gguf` from [TheBloke/Mistral-7B-Instruct-v0.2-GGUF](https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF) β place at `models/generator/mistral-7b-instruct-v0.2.Q4_K_M.gguf`
---
## Datasets
| Dataset | Role | License |
|---|---|---|
| [GoEmotions](https://huggingface.co/datasets/google-research-datasets/go_emotions) | Emotion classifier training | Apache 2.0 |
| [Reddit Mental Health](https://zenodo.org/records/3941387) | FAISS retrieval corpus | CC BY 4.0 |
| [Suicide Detection](https://www.kaggle.com/datasets/nikhileswarkomati/suicide-watch) | Guardrail NLI training | Public |
| [Empathetic Dialogues](https://huggingface.co/datasets/facebook/empathetic_dialogues) | BERTScore gold references | CC BY-NC 4.0 |
---
## Evaluation Status
| Task | Status |
|---|---|
| Emotion Classifier (RoBERTa F1 = 0.7127) | β
Complete |
| Safety Guardrail (DeBERTa recall = 0.9629) | β
Complete |
| BERTScore Evaluation (F1 = 0.8266) | β
Complete |
| Wilcoxon Test (p = 3.62e-08) | β
Complete |
| Adversarial Probe Evaluation (30 probes) | β
Complete |
| Human Evaluation (8β10 raters) | π In Progress |
| Loom Demo Recording | π In Progress |
---
## Known Limitations
- **Bait-and-switch probes:** Positive openers cause the guardrail to misclassify follow-up crisis content (40% recall). Most dangerous documented failure mode.
- **Domain transfer false positives:** Academic hyperbole ("this thesis is killing me") fires the guardrail at high confidence β trained on r/SuicideWatch, never saw graduate student language.
- **Generator quality:** Mistral 7B Q4_K_M produces adequate but not optimal empathetic responses. Architecture supports drop-in model replacement.
- **Faithfulness gap:** No automated faithfulness metric deployed β RAGAS and DeepEval both produced degenerate scores with a small model judge. BERTScore reported instead.
---
## v2 Safety Direction
EmpathRAG Core is being hardened as a guarded conversational RAG research system,
not a production counseling replacement. The Core plan prioritizes fail-closed
safety loading, multi-level triage, private-by-default demo behavior, curated
resource retrieval, and stronger safety evaluation. Start with
[`docs/README.md`](docs/README.md) and
[`docs/planning/MASTER_CHECKLIST.md`](docs/planning/MASTER_CHECKLIST.md).
---
## License
MIT License β see [`LICENSE`](LICENSE) for details.
Dataset licenses vary β see Datasets table above. Mistral 7B: Apache 2.0.
|