bharatrag 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bharatrag-0.1.0/LICENSE +21 -0
- bharatrag-0.1.0/PKG-INFO +251 -0
- bharatrag-0.1.0/README.md +231 -0
- bharatrag-0.1.0/bharatrag/__init__.py +77 -0
- bharatrag-0.1.0/bharatrag/embeddings/__init__.py +0 -0
- bharatrag-0.1.0/bharatrag/embeddings/indic_embeddings.py +110 -0
- bharatrag-0.1.0/bharatrag/metrics/__init__.py +0 -0
- bharatrag-0.1.0/bharatrag/metrics/answer_relevance.py +39 -0
- bharatrag-0.1.0/bharatrag/metrics/context_relevance.py +42 -0
- bharatrag-0.1.0/bharatrag/metrics/groundedness.py +62 -0
- bharatrag-0.1.0/bharatrag/utils/__init__.py +0 -0
- bharatrag-0.1.0/bharatrag/utils/helpers.py +75 -0
- bharatrag-0.1.0/bharatrag.egg-info/PKG-INFO +251 -0
- bharatrag-0.1.0/bharatrag.egg-info/SOURCES.txt +18 -0
- bharatrag-0.1.0/bharatrag.egg-info/dependency_links.txt +1 -0
- bharatrag-0.1.0/bharatrag.egg-info/requires.txt +7 -0
- bharatrag-0.1.0/bharatrag.egg-info/top_level.txt +1 -0
- bharatrag-0.1.0/pyproject.toml +34 -0
- bharatrag-0.1.0/setup.cfg +4 -0
- bharatrag-0.1.0/tests/test_metrics.py +216 -0
bharatrag-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pradnyagundu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bharatrag-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bharatrag
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: RAG evaluation library for Indian languages (Hindi, Marathi)
|
|
5
|
+
Author-email: Pradnya Gundu <gundupradnya@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/pradnyagundu/bharatrag
|
|
8
|
+
Project-URL: Repository, https://github.com/pradnyagundu/bharatrag
|
|
9
|
+
Keywords: RAG,evaluation,Hindi,Marathi,Indic,NLP,LLM
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: sentence-transformers>=2.2.0
|
|
14
|
+
Requires-Dist: numpy>=1.24.0
|
|
15
|
+
Requires-Dist: scikit-learn>=1.2.0
|
|
16
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# bharatrag
|
|
22
|
+
Open-source RAG evaluation library for Indian languages (Hindi, Marathi). pip install bharatrag
|
|
23
|
+
# BharatRAG 🇮🇳
|
|
24
|
+
|
|
25
|
+
**RAG Evaluation Library for Indian Languages**
|
|
26
|
+
|
|
27
|
+
[](https://www.python.org/downloads/)
|
|
28
|
+
[](https://opensource.org/licenses/MIT)
|
|
29
|
+
[](https://github.com/pradnyagundu/bharatrag)
|
|
30
|
+
|
|
31
|
+
BharatRAG is the first open-source RAG evaluation library built specifically for **Indian languages (Hindi and Marathi)**.
|
|
32
|
+
|
|
33
|
+
Existing tools like RAGAS are built and tested on English data. BharatRAG fills the gap — giving developers a reliable way to measure RAG quality in Indic languages.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## The Problem
|
|
38
|
+
|
|
39
|
+
RAG (Retrieval Augmented Generation) systems are being deployed across India for:
|
|
40
|
+
- Government scheme chatbots (PM Kisan, Ayushman Bharat)
|
|
41
|
+
- Health information systems in regional languages
|
|
42
|
+
- EdTech platforms for vernacular learners
|
|
43
|
+
- Banking and insurance customer support
|
|
44
|
+
|
|
45
|
+
But there is **no standard way to evaluate** whether these systems are actually working correctly in Hindi, Marathi, or other Indian languages.
|
|
46
|
+
|
|
47
|
+
RAGAS — the most popular RAG evaluation tool — uses English-first embedding models that produce unreliable scores for Indic text.
|
|
48
|
+
|
|
49
|
+
**BharatRAG solves this.**
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## What it measures
|
|
54
|
+
|
|
55
|
+
BharatRAG computes the **RAG Triad** in Hindi and Marathi:
|
|
56
|
+
|
|
57
|
+
| Metric | Question it answers |
|
|
58
|
+
|---|---|
|
|
59
|
+
| **Context Relevance** | Did we retrieve the right documents? |
|
|
60
|
+
| **Groundedness** | Is the answer based on the context, or hallucinated? |
|
|
61
|
+
| **Answer Relevance** | Does the answer actually address the question? |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Benchmark Results
|
|
66
|
+
|
|
67
|
+
BharatRAG evaluated on 20 Hindi + Marathi QA pairs across government schemes, health, and agriculture domains:
|
|
68
|
+
|
|
69
|
+
| Metric | Hindi ✅ Correct | Hindi ❌ Hallucinated | Marathi ✅ Correct | Marathi ❌ Hallucinated |
|
|
70
|
+
|---|---|---|---|---|
|
|
71
|
+
| Context Relevance | 0.4793 | 0.4793 | 0.4327 | 0.4327 |
|
|
72
|
+
| Groundedness | 0.9167 | 0.7000 | 0.9667 | 0.2000 |
|
|
73
|
+
| Answer Relevance | 0.6221 | 0.5417 | 0.5072 | 0.2959 |
|
|
74
|
+
| **Overall** | **0.6727** | **0.5737** | **0.6355** | **0.3095** |
|
|
75
|
+
|
|
76
|
+
BharatRAG correctly scores hallucinated answers **lower** than correct answers in both languages.
|
|
77
|
+
Marathi hallucination detection shows a **2x difference** in overall score (0.6355 vs 0.3095).
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install bharatrag
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Quick Start
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from bharatrag import evaluate
|
|
93
|
+
|
|
94
|
+
results = evaluate(
|
|
95
|
+
questions=["पीएम किसान योजना में कितने रुपये मिलते हैं?"],
|
|
96
|
+
contexts=[[
|
|
97
|
+
"पीएम किसान सम्मान निधि योजना के तहत किसानों को",
|
|
98
|
+
"प्रति वर्ष 6000 रुपये तीन किश्तों में मिलते हैं।"
|
|
99
|
+
]],
|
|
100
|
+
answers=["पीएम किसान योजना में किसानों को 6000 रुपये मिलते हैं।"],
|
|
101
|
+
language="hindi"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
print(results)
|
|
105
|
+
# {
|
|
106
|
+
# 'context_relevance': 0.72,
|
|
107
|
+
# 'groundedness': 1.0,
|
|
108
|
+
# 'answer_relevance': 0.66,
|
|
109
|
+
# 'overall': 0.79,
|
|
110
|
+
# 'language': 'hindi',
|
|
111
|
+
# 'num_questions': 1
|
|
112
|
+
# }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Marathi support
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
results = evaluate(
|
|
119
|
+
questions=["पीएम किसान योजनेत किती रुपये मिळतात?"],
|
|
120
|
+
contexts=[[
|
|
121
|
+
"पीएम किसान सन्मान निधी योजनेंतर्गत शेतकऱ्यांना",
|
|
122
|
+
"दरवर्षी 6000 रुपये तीन हप्त्यांमध्ये मिळतात."
|
|
123
|
+
]],
|
|
124
|
+
answers=["पीएम किसान योजनेत 6000 रुपये मिळतात."],
|
|
125
|
+
language="marathi"
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Individual metrics
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from bharatrag.metrics.context_relevance import ContextRelevance
|
|
133
|
+
from bharatrag.metrics.groundedness import Groundedness
|
|
134
|
+
from bharatrag.metrics.answer_relevance import AnswerRelevance
|
|
135
|
+
|
|
136
|
+
cr = ContextRelevance(language="hindi")
|
|
137
|
+
score = cr.score(
|
|
138
|
+
question="भारत की राजधानी क्या है?",
|
|
139
|
+
contexts=["भारत की राजधानी नई दिल्ली है।"]
|
|
140
|
+
)
|
|
141
|
+
print(score) # 0.61
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Supported Languages
|
|
147
|
+
|
|
148
|
+
| Language | Model Used |
|
|
149
|
+
|---|---|
|
|
150
|
+
| Hindi | `sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2` |
|
|
151
|
+
| Marathi | `l3cube-pune/marathi-sentence-bert-nli` |
|
|
152
|
+
| English | `sentence-transformers/all-MiniLM-L6-v2` |
|
|
153
|
+
|
|
154
|
+
More languages coming soon — Tamil, Bengali, Gujarati.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Benchmark Dataset
|
|
159
|
+
|
|
160
|
+
BharatRAG ships with a hand-curated benchmark dataset of **20 Hindi + Marathi QA pairs** across:
|
|
161
|
+
- Government schemes (PM Kisan, Ayushman Bharat, Jan Dhan, Ujjwala)
|
|
162
|
+
- Health (diabetes, sanitation)
|
|
163
|
+
- Agriculture (wheat sowing, crop insurance)
|
|
164
|
+
- Education (Mid Day Meal, Beti Bachao)
|
|
165
|
+
|
|
166
|
+
Each example includes a correct answer and a hallucinated answer for evaluation testing.
|
|
167
|
+
|
|
168
|
+
Dataset location: `data/benchmark.json`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Project Structure
|
|
173
|
+
|
|
174
|
+
bharatrag/
|
|
175
|
+
├── bharatrag/
|
|
176
|
+
│ ├── init.py # evaluate() function
|
|
177
|
+
│ ├── embeddings/
|
|
178
|
+
│ │ └── indic_embeddings.py # Indic embedding models
|
|
179
|
+
│ └── metrics/
|
|
180
|
+
│ ├── context_relevance.py # Metric 1
|
|
181
|
+
│ ├── groundedness.py # Metric 2
|
|
182
|
+
│ └── answer_relevance.py # Metric 3
|
|
183
|
+
├── data/
|
|
184
|
+
│ └── benchmark.json # 20 Hindi+Marathi QA pairs
|
|
185
|
+
├── tests/
|
|
186
|
+
│ └── test_metrics.py # 21 pytest tests
|
|
187
|
+
└── examples/
|
|
188
|
+
└── run_benchmark.py # Benchmark runner
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Running Tests
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pip install pytest
|
|
196
|
+
pytest tests/ -v
|
|
197
|
+
# 21 passed ✅
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Why BharatRAG?
|
|
203
|
+
|
|
204
|
+
| Feature | RAGAS | BharatRAG |
|
|
205
|
+
|---|---|---|
|
|
206
|
+
| English RAG evaluation | ✅ | ✅ |
|
|
207
|
+
| Hindi RAG evaluation | ❌ Unreliable | ✅ |
|
|
208
|
+
| Marathi RAG evaluation | ❌ Not supported | ✅ |
|
|
209
|
+
| Indic benchmark dataset | ❌ | ✅ |
|
|
210
|
+
| Free, no API key needed | ✅ | ✅ |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Roadmap
|
|
215
|
+
|
|
216
|
+
- [x] Hindi support
|
|
217
|
+
- [x] Marathi support
|
|
218
|
+
- [x] 20-example benchmark dataset
|
|
219
|
+
- [ ] Tamil support
|
|
220
|
+
- [ ] Bengali support
|
|
221
|
+
- [ ] 100-example benchmark dataset
|
|
222
|
+
- [ ] LangChain integration
|
|
223
|
+
- [ ] LlamaIndex integration
|
|
224
|
+
- [ ] HuggingFace Spaces demo
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Author
|
|
229
|
+
|
|
230
|
+
**Pradnya Gundu**
|
|
231
|
+
B.E. Artificial Intelligence & Data Science, APCOER Pune
|
|
232
|
+
|
|
233
|
+
- GitHub: [@pradnyagundu](https://github.com/pradnyagundu)
|
|
234
|
+
- LinkedIn: [pradnya-gundu](https://linkedin.com/in/pradnya-gundu-b28737249)
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
MIT License — free to use, modify, and distribute.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Contributing
|
|
245
|
+
|
|
246
|
+
Contributions welcome! Especially:
|
|
247
|
+
- New Indian language support
|
|
248
|
+
- More benchmark QA pairs
|
|
249
|
+
- Integration with LangChain/LlamaIndex
|
|
250
|
+
|
|
251
|
+
Open an issue or submit a PR on GitHub.
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# bharatrag
|
|
2
|
+
Open-source RAG evaluation library for Indian languages (Hindi, Marathi). pip install bharatrag
|
|
3
|
+
# BharatRAG 🇮🇳
|
|
4
|
+
|
|
5
|
+
**RAG Evaluation Library for Indian Languages**
|
|
6
|
+
|
|
7
|
+
[](https://www.python.org/downloads/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://github.com/pradnyagundu/bharatrag)
|
|
10
|
+
|
|
11
|
+
BharatRAG is the first open-source RAG evaluation library built specifically for **Indian languages (Hindi and Marathi)**.
|
|
12
|
+
|
|
13
|
+
Existing tools like RAGAS are built and tested on English data. BharatRAG fills the gap — giving developers a reliable way to measure RAG quality in Indic languages.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## The Problem
|
|
18
|
+
|
|
19
|
+
RAG (Retrieval Augmented Generation) systems are being deployed across India for:
|
|
20
|
+
- Government scheme chatbots (PM Kisan, Ayushman Bharat)
|
|
21
|
+
- Health information systems in regional languages
|
|
22
|
+
- EdTech platforms for vernacular learners
|
|
23
|
+
- Banking and insurance customer support
|
|
24
|
+
|
|
25
|
+
But there is **no standard way to evaluate** whether these systems are actually working correctly in Hindi, Marathi, or other Indian languages.
|
|
26
|
+
|
|
27
|
+
RAGAS — the most popular RAG evaluation tool — uses English-first embedding models that produce unreliable scores for Indic text.
|
|
28
|
+
|
|
29
|
+
**BharatRAG solves this.**
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## What it measures
|
|
34
|
+
|
|
35
|
+
BharatRAG computes the **RAG Triad** in Hindi and Marathi:
|
|
36
|
+
|
|
37
|
+
| Metric | Question it answers |
|
|
38
|
+
|---|---|
|
|
39
|
+
| **Context Relevance** | Did we retrieve the right documents? |
|
|
40
|
+
| **Groundedness** | Is the answer based on the context, or hallucinated? |
|
|
41
|
+
| **Answer Relevance** | Does the answer actually address the question? |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Benchmark Results
|
|
46
|
+
|
|
47
|
+
BharatRAG evaluated on 20 Hindi + Marathi QA pairs across government schemes, health, and agriculture domains:
|
|
48
|
+
|
|
49
|
+
| Metric | Hindi ✅ Correct | Hindi ❌ Hallucinated | Marathi ✅ Correct | Marathi ❌ Hallucinated |
|
|
50
|
+
|---|---|---|---|---|
|
|
51
|
+
| Context Relevance | 0.4793 | 0.4793 | 0.4327 | 0.4327 |
|
|
52
|
+
| Groundedness | 0.9167 | 0.7000 | 0.9667 | 0.2000 |
|
|
53
|
+
| Answer Relevance | 0.6221 | 0.5417 | 0.5072 | 0.2959 |
|
|
54
|
+
| **Overall** | **0.6727** | **0.5737** | **0.6355** | **0.3095** |
|
|
55
|
+
|
|
56
|
+
BharatRAG correctly scores hallucinated answers **lower** than correct answers in both languages.
|
|
57
|
+
Marathi hallucination detection shows a **2x difference** in overall score (0.6355 vs 0.3095).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install bharatrag
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Quick Start
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from bharatrag import evaluate
|
|
73
|
+
|
|
74
|
+
results = evaluate(
|
|
75
|
+
questions=["पीएम किसान योजना में कितने रुपये मिलते हैं?"],
|
|
76
|
+
contexts=[[
|
|
77
|
+
"पीएम किसान सम्मान निधि योजना के तहत किसानों को",
|
|
78
|
+
"प्रति वर्ष 6000 रुपये तीन किश्तों में मिलते हैं।"
|
|
79
|
+
]],
|
|
80
|
+
answers=["पीएम किसान योजना में किसानों को 6000 रुपये मिलते हैं।"],
|
|
81
|
+
language="hindi"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
print(results)
|
|
85
|
+
# {
|
|
86
|
+
# 'context_relevance': 0.72,
|
|
87
|
+
# 'groundedness': 1.0,
|
|
88
|
+
# 'answer_relevance': 0.66,
|
|
89
|
+
# 'overall': 0.79,
|
|
90
|
+
# 'language': 'hindi',
|
|
91
|
+
# 'num_questions': 1
|
|
92
|
+
# }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Marathi support
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
results = evaluate(
|
|
99
|
+
questions=["पीएम किसान योजनेत किती रुपये मिळतात?"],
|
|
100
|
+
contexts=[[
|
|
101
|
+
"पीएम किसान सन्मान निधी योजनेंतर्गत शेतकऱ्यांना",
|
|
102
|
+
"दरवर्षी 6000 रुपये तीन हप्त्यांमध्ये मिळतात."
|
|
103
|
+
]],
|
|
104
|
+
answers=["पीएम किसान योजनेत 6000 रुपये मिळतात."],
|
|
105
|
+
language="marathi"
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Individual metrics
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from bharatrag.metrics.context_relevance import ContextRelevance
|
|
113
|
+
from bharatrag.metrics.groundedness import Groundedness
|
|
114
|
+
from bharatrag.metrics.answer_relevance import AnswerRelevance
|
|
115
|
+
|
|
116
|
+
cr = ContextRelevance(language="hindi")
|
|
117
|
+
score = cr.score(
|
|
118
|
+
question="भारत की राजधानी क्या है?",
|
|
119
|
+
contexts=["भारत की राजधानी नई दिल्ली है।"]
|
|
120
|
+
)
|
|
121
|
+
print(score) # 0.61
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Supported Languages
|
|
127
|
+
|
|
128
|
+
| Language | Model Used |
|
|
129
|
+
|---|---|
|
|
130
|
+
| Hindi | `sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2` |
|
|
131
|
+
| Marathi | `l3cube-pune/marathi-sentence-bert-nli` |
|
|
132
|
+
| English | `sentence-transformers/all-MiniLM-L6-v2` |
|
|
133
|
+
|
|
134
|
+
More languages coming soon — Tamil, Bengali, Gujarati.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Benchmark Dataset
|
|
139
|
+
|
|
140
|
+
BharatRAG ships with a hand-curated benchmark dataset of **20 Hindi + Marathi QA pairs** across:
|
|
141
|
+
- Government schemes (PM Kisan, Ayushman Bharat, Jan Dhan, Ujjwala)
|
|
142
|
+
- Health (diabetes, sanitation)
|
|
143
|
+
- Agriculture (wheat sowing, crop insurance)
|
|
144
|
+
- Education (Mid Day Meal, Beti Bachao)
|
|
145
|
+
|
|
146
|
+
Each example includes a correct answer and a hallucinated answer for evaluation testing.
|
|
147
|
+
|
|
148
|
+
Dataset location: `data/benchmark.json`
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Project Structure
|
|
153
|
+
|
|
154
|
+
bharatrag/
|
|
155
|
+
├── bharatrag/
|
|
156
|
+
│ ├── init.py # evaluate() function
|
|
157
|
+
│ ├── embeddings/
|
|
158
|
+
│ │ └── indic_embeddings.py # Indic embedding models
|
|
159
|
+
│ └── metrics/
|
|
160
|
+
│ ├── context_relevance.py # Metric 1
|
|
161
|
+
│ ├── groundedness.py # Metric 2
|
|
162
|
+
│ └── answer_relevance.py # Metric 3
|
|
163
|
+
├── data/
|
|
164
|
+
│ └── benchmark.json # 20 Hindi+Marathi QA pairs
|
|
165
|
+
├── tests/
|
|
166
|
+
│ └── test_metrics.py # 21 pytest tests
|
|
167
|
+
└── examples/
|
|
168
|
+
└── run_benchmark.py # Benchmark runner
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Running Tests
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
pip install pytest
|
|
176
|
+
pytest tests/ -v
|
|
177
|
+
# 21 passed ✅
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Why BharatRAG?
|
|
183
|
+
|
|
184
|
+
| Feature | RAGAS | BharatRAG |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| English RAG evaluation | ✅ | ✅ |
|
|
187
|
+
| Hindi RAG evaluation | ❌ Unreliable | ✅ |
|
|
188
|
+
| Marathi RAG evaluation | ❌ Not supported | ✅ |
|
|
189
|
+
| Indic benchmark dataset | ❌ | ✅ |
|
|
190
|
+
| Free, no API key needed | ✅ | ✅ |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Roadmap
|
|
195
|
+
|
|
196
|
+
- [x] Hindi support
|
|
197
|
+
- [x] Marathi support
|
|
198
|
+
- [x] 20-example benchmark dataset
|
|
199
|
+
- [ ] Tamil support
|
|
200
|
+
- [ ] Bengali support
|
|
201
|
+
- [ ] 100-example benchmark dataset
|
|
202
|
+
- [ ] LangChain integration
|
|
203
|
+
- [ ] LlamaIndex integration
|
|
204
|
+
- [ ] HuggingFace Spaces demo
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Author
|
|
209
|
+
|
|
210
|
+
**Pradnya Gundu**
|
|
211
|
+
B.E. Artificial Intelligence & Data Science, APCOER Pune
|
|
212
|
+
|
|
213
|
+
- GitHub: [@pradnyagundu](https://github.com/pradnyagundu)
|
|
214
|
+
- LinkedIn: [pradnya-gundu](https://linkedin.com/in/pradnya-gundu-b28737249)
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT License — free to use, modify, and distribute.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Contributing
|
|
225
|
+
|
|
226
|
+
Contributions welcome! Especially:
|
|
227
|
+
- New Indian language support
|
|
228
|
+
- More benchmark QA pairs
|
|
229
|
+
- Integration with LangChain/LlamaIndex
|
|
230
|
+
|
|
231
|
+
Open an issue or submit a PR on GitHub.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BharatRAG — RAG Evaluation Library for Indian Languages
|
|
3
|
+
Author: Pradnya Gundu
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from bharatrag.embeddings.indic_embeddings import IndicEmbedder
|
|
7
|
+
from bharatrag.metrics.context_relevance import ContextRelevance
|
|
8
|
+
from bharatrag.metrics.groundedness import Groundedness
|
|
9
|
+
from bharatrag.metrics.answer_relevance import AnswerRelevance
|
|
10
|
+
|
|
11
|
+
__version__ = "0.1.0"
|
|
12
|
+
__author__ = "Pradnya Gundu"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def evaluate(questions, contexts, answers, language="hindi"):
|
|
16
|
+
"""
|
|
17
|
+
Evaluate a RAG system on Indian language data.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
questions: list of questions (in Hindi/Marathi)
|
|
21
|
+
contexts: list of lists — retrieved context chunks per question
|
|
22
|
+
answers: list of generated answers
|
|
23
|
+
language: "hindi" or "marathi" (default: "hindi")
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
dict with scores for each metric
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> from bharatrag import evaluate
|
|
30
|
+
>>> results = evaluate(
|
|
31
|
+
... questions=["भारत की राजधानी क्या है?"],
|
|
32
|
+
... contexts=[["भारत की राजधानी नई दिल्ली है।"]],
|
|
33
|
+
... answers=["भारत की राजधानी नई दिल्ली है।"],
|
|
34
|
+
... language="hindi"
|
|
35
|
+
... )
|
|
36
|
+
>>> print(results)
|
|
37
|
+
"""
|
|
38
|
+
print(f"\nLoading embedding model for {language}...")
|
|
39
|
+
|
|
40
|
+
# Load embedder ONCE and share across all 3 metrics
|
|
41
|
+
embedder = IndicEmbedder(language=language)
|
|
42
|
+
|
|
43
|
+
# Pass the same embedder to all metrics — no reloading
|
|
44
|
+
cr = ContextRelevance(language=language, embedder=embedder)
|
|
45
|
+
gr = Groundedness(language=language, embedder=embedder)
|
|
46
|
+
ar = AnswerRelevance(language=language, embedder=embedder)
|
|
47
|
+
|
|
48
|
+
print(f"Evaluating {len(questions)} question(s) in {language}...")
|
|
49
|
+
|
|
50
|
+
cr_scores = []
|
|
51
|
+
gr_scores = []
|
|
52
|
+
ar_scores = []
|
|
53
|
+
|
|
54
|
+
for i, (question, context, answer) in enumerate(
|
|
55
|
+
zip(questions, contexts, answers)
|
|
56
|
+
):
|
|
57
|
+
print(f" Scoring question {i+1}/{len(questions)}...")
|
|
58
|
+
cr_scores.append(cr.score(question, context))
|
|
59
|
+
gr_scores.append(gr.score(answer, context))
|
|
60
|
+
ar_scores.append(ar.score(question, answer))
|
|
61
|
+
|
|
62
|
+
results = {
|
|
63
|
+
"context_relevance": round(sum(cr_scores) / len(cr_scores), 4),
|
|
64
|
+
"groundedness": round(sum(gr_scores) / len(gr_scores), 4),
|
|
65
|
+
"answer_relevance": round(sum(ar_scores) / len(ar_scores), 4),
|
|
66
|
+
"language": language,
|
|
67
|
+
"num_questions": len(questions),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
results["overall"] = round(
|
|
71
|
+
(results["context_relevance"] +
|
|
72
|
+
results["groundedness"] +
|
|
73
|
+
results["answer_relevance"]) / 3,
|
|
74
|
+
4
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
return results
|
|
File without changes
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Indic Embeddings — loads multilingual embedding models
|
|
3
|
+
that actually understand Hindi and Marathi.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from sentence_transformers import SentenceTransformer
|
|
7
|
+
import numpy as np
|
|
8
|
+
from sklearn.metrics.pairwise import cosine_similarity
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Best free models for Indian languages
|
|
12
|
+
INDIC_MODELS = {
|
|
13
|
+
"hindi": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
|
14
|
+
"marathi": "l3cube-pune/marathi-sentence-bert-nli",
|
|
15
|
+
"english": "sentence-transformers/all-MiniLM-L6-v2",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IndicEmbedder:
|
|
20
|
+
"""
|
|
21
|
+
Loads the right embedding model for a given Indian language
|
|
22
|
+
and computes sentence embeddings + similarity scores.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
>>> embedder = IndicEmbedder(language="hindi")
|
|
26
|
+
>>> score = embedder.similarity(
|
|
27
|
+
... "भारत की राजधानी क्या है?",
|
|
28
|
+
... "भारत की राजधानी नई दिल्ली है।"
|
|
29
|
+
... )
|
|
30
|
+
>>> print(score) # 0.91
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, language: str = "hindi"):
|
|
34
|
+
"""
|
|
35
|
+
Args:
|
|
36
|
+
language: "hindi", "marathi", or "english"
|
|
37
|
+
"""
|
|
38
|
+
if language not in INDIC_MODELS:
|
|
39
|
+
raise ValueError(
|
|
40
|
+
f"Language '{language}' not supported. "
|
|
41
|
+
f"Choose from: {list(INDIC_MODELS.keys())}"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
self.language = language
|
|
45
|
+
self.model_name = INDIC_MODELS[language]
|
|
46
|
+
|
|
47
|
+
print(f"Loading embedding model for {language}: {self.model_name}")
|
|
48
|
+
self.model = SentenceTransformer(self.model_name)
|
|
49
|
+
print("Model loaded successfully!")
|
|
50
|
+
|
|
51
|
+
def embed(self, text: str) -> np.ndarray:
|
|
52
|
+
"""
|
|
53
|
+
Convert a single text string into a vector (embedding).
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
text: input string in Hindi/Marathi/English
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
numpy array of shape (embedding_dim,)
|
|
60
|
+
"""
|
|
61
|
+
return self.model.encode(text, convert_to_numpy=True)
|
|
62
|
+
|
|
63
|
+
def embed_batch(self, texts: list) -> np.ndarray:
|
|
64
|
+
"""
|
|
65
|
+
Convert a list of texts into embeddings all at once.
|
|
66
|
+
Faster than calling embed() in a loop.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
texts: list of strings
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
numpy array of shape (len(texts), embedding_dim)
|
|
73
|
+
"""
|
|
74
|
+
return self.model.encode(texts, convert_to_numpy=True)
|
|
75
|
+
|
|
76
|
+
def similarity(self, text1: str, text2: str) -> float:
|
|
77
|
+
"""
|
|
78
|
+
Compute similarity between two texts.
|
|
79
|
+
Returns a score between 0 and 1.
|
|
80
|
+
1.0 = identical meaning, 0.0 = completely unrelated.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
text1: first string
|
|
84
|
+
text2: second string
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
float between 0 and 1
|
|
88
|
+
"""
|
|
89
|
+
emb1 = self.embed(text1).reshape(1, -1)
|
|
90
|
+
emb2 = self.embed(text2).reshape(1, -1)
|
|
91
|
+
score = cosine_similarity(emb1, emb2)[0][0]
|
|
92
|
+
# Clip to [0, 1] — cosine can return tiny negatives
|
|
93
|
+
return float(np.clip(score, 0.0, 1.0))
|
|
94
|
+
|
|
95
|
+
def similarity_one_to_many(self, query: str, candidates: list) -> list:
|
|
96
|
+
"""
|
|
97
|
+
Compare one query against many candidate texts.
|
|
98
|
+
Used in Context Relevance: compare question vs all chunks.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
query: the question
|
|
102
|
+
candidates: list of context chunks
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
list of similarity scores, one per candidate
|
|
106
|
+
"""
|
|
107
|
+
query_emb = self.embed(query).reshape(1, -1)
|
|
108
|
+
candidate_embs = self.embed_batch(candidates)
|
|
109
|
+
scores = cosine_similarity(query_emb, candidate_embs)[0]
|
|
110
|
+
return [float(np.clip(s, 0.0, 1.0)) for s in scores]
|
|
File without changes
|