Pranil Bankar
Deploy Application
4d67ec7
|
Raw History Blame Contribute Delete
14 kB
# NEET Biology Question & Answer Generation System β€” Project Report
## 1. Project Objective
Build an **end-to-end AI-powered Question Answering system** for NEET Biology that:
1. Ingests NCERT Class 11 & 12 Biology textbooks (PDFs)
2. Chunks, embeds, and stores them in a **vector database**
3. Uses a **Retrieval-Augmented Generation (RAG)** pipeline to answer student questions grounded in NCERT content
4. Fine-tunes a **BERT classifier** to predict which chapter a question belongs to β€” enabling targeted retrieval and routing
5. Exposes the pipeline via a **FastAPI backend** (planned)
The system is designed for NEET exam preparation, where every answer must be traceable back to specific NCERT textbook content.
---
## 2. High-Level Architecture
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ USER QUESTION β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ BERT Chapter Classifier β”‚ ← Classification/ (fine-tuned bert-base-uncased)
β”‚ Predicts: chapter_id β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ chapter filter (planned integration)
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ RAG Pipeline (rag/) │────▢│ Supabase + pgvector β”‚
β”‚ 1. Embed question β”‚ β”‚ Table: ncert_knowledge_ β”‚
β”‚ 2. Retrieve top-k chunks│◀────│ chunks β”‚
β”‚ 3. Build prompt β”‚ β”‚ RPC: match_ncert_chunks() β”‚
β”‚ 4. Generate answer (LLM)β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ 5. Justify + Verify β”‚
β”‚ 6. Confidence score β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FastAPI Backend (TBD) β”‚ ← /qa endpoint, /ingest, /health
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
## 3. Complete Tech Stack
| Layer | Technology | Purpose |
|---|---|---|
| **Language** | Python 3.10+ | Core runtime |
| **PDF Extraction** | PyMuPDF 1.23.8 | Extract text from NCERT PDFs |
| **Chunking** | Custom ([clean_pdf_to_json.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/clean_pdf_to_json.py)) | Section-aware chunking with metadata |
| **Embedding Model** | `BAAI/bge-small-en-v1.5` (384-dim) | Local embedding generation via `sentence-transformers` |
| **Vector Database** | Supabase + pgvector | Cloud-hosted PostgreSQL with vector similarity search |
| **Vector Index** | HNSW (via pgvector) | Fast approximate nearest-neighbor search |
| **LLM Provider** | Groq API | Free, fast inference (llama-3.3-70b-versatile) |
| **Classification** | HuggingFace `bert-base-uncased` | Fine-tuned for chapter prediction |
| **Training Framework** | HuggingFace `Trainer` + PyTorch | BERT fine-tuning with early stopping |
| **Backend (planned)** | FastAPI + Uvicorn | REST API serving |
| **Data Validation** | Pydantic | Request/response schemas |
| **Environment** | python-dotenv | Secrets management via [.env](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/.env) |
| **Dependencies** | pip + [requirements.txt](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/requirements.txt) | All versions pinned for reproducibility |
---
## 4. Repository Structure
```
Question_AndAnswerGeneration/
β”œβ”€β”€ .env # (gitignored) API keys
β”œβ”€β”€ .gitignore # .venv, .env, __pycache__, *.pyc
β”œβ”€β”€ requirements.txt # All dependencies pinned
β”œβ”€β”€ taxonomy_full.txt # Complete NCERT syllabus taxonomy
β”‚
β”œβ”€β”€ pdf_to_embedding/ # 🟒 PHASE 1: Data Pipeline
β”‚ β”œβ”€β”€ .env / .env.example # Supabase + Groq credentials
β”‚ β”œβ”€β”€ clean_pdf_to_json.py # PDF β†’ section-aware JSON chunks
β”‚ β”œβ”€β”€ embed_and_upload.py # JSON β†’ embeddings β†’ Supabase upsert
β”‚ β”œβ”€β”€ supabase_schema.sql # Table + RPC + HNSW index DDL
β”‚ └── json_ouput/ # Intermediate JSON files
β”‚ β”œβ”€β”€ 11th Ncert output/ # 19 files (Kebo101–Kebo119)
β”‚ └── 12th Ncert Output/ # 13 files (Lebo101–Lebo113)
β”‚
β”œβ”€β”€ rag/ # 🟒 PHASE 2: RAG Pipeline
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ retriever.py # Embed question β†’ Supabase RPC β†’ top-k chunks
β”‚ β”œβ”€β”€ prompt_builder.py # Build answer/justification/verifier prompts
β”‚ β”œβ”€β”€ generator.py # Groq LLM calls (answer + justify + verify)
β”‚ β”œβ”€β”€ confidence.py # Confidence scorer (retrieval + verification)
β”‚ └── pipeline.py # Orchestrator with smoke test (--debug flag)
β”‚
└── Classification/ # 🟑 PHASE 3: BERT Classifier (scaffold ready)
β”œβ”€β”€ __init__.py
β”œβ”€β”€ config.json # All hyperparameters (model, lr, epochs, etc.)
β”œβ”€β”€ dataset.py # PyTorch Dataset + label_map builder
β”œβ”€β”€ train.py # Full HuggingFace Trainer script
β”œβ”€β”€ predict.py # ClassifierPredictor inference wrapper
└── data/
β”œβ”€β”€ sample_questions.json # Placeholder labeled data (3 examples)
└── label_map.json # (auto-generated) chapter_id β†’ chapter_name
```
---
## 5. What Is Completed βœ…
### Phase 1 β€” Data Ingestion Pipeline βœ…
| Component | File | Status |
|---|---|---|
| PDF text extraction | [clean_pdf_to_json.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/clean_pdf_to_json.py) | βœ… Complete |
| Section-aware chunking with metadata | [clean_pdf_to_json.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/clean_pdf_to_json.py) | βœ… Complete |
| Supabase schema + RPC + HNSW index | [supabase_schema.sql](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/supabase_schema.sql) | βœ… Deployed |
| Embedding generation (BGE-small) | [embed_and_upload.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/embed_and_upload.py) | βœ… Complete |
| Batch upsert to Supabase | [embed_and_upload.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/embed_and_upload.py) | βœ… Complete |
| All 32 NCERT chapters processed | `json_ouput/` | βœ… 19 (Class 11) + 13 (Class 12) |
**Data stats:** 32 JSON files β†’ **~696 chunks** with metadata (chapter, section, section_title, chunk_text, embedding vector).
### Phase 2 β€” RAG Pipeline βœ…
| Component | File | What It Does |
|---|---|---|
| Retriever | [retriever.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/rag/retriever.py) | Embeds query β†’ calls `match_ncert_chunks` RPC β†’ returns top-k relevant chunks |
| Prompt Builder | [prompt_builder.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/rag/prompt_builder.py) | Constructs 3 prompt types: answer, justification, verifier |
| Generator | [generator.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/rag/generator.py) | Calls Groq API for answer generation, step-by-step justification, and YES/NO faithfulness verification |
| Confidence Scorer | [confidence.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/rag/confidence.py) | Combines retrieval similarity + verifier output into a 0-1 confidence score |
| Pipeline Orchestrator | [pipeline.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/rag/pipeline.py) | End-to-end flow: question β†’ retrieve β†’ generate β†’ justify β†’ verify β†’ confidence. Includes `--debug` smoke test |
**RAG design highlights:**
- **Multi-stage pipeline**: Retrieve β†’ Answer β†’ Justify β†’ Verify β†’ Confidence
- **Singleton pattern** for Supabase client, embedding model, and Groq client (no repeated initialization)
- **Similarity threshold** of 0.1 (tuned lower to avoid false negatives with limited data)
- **Groq model**: `llama-3.3-70b-versatile` β€” fast, free tier, high quality
### Phase 3 β€” BERT Classification Layer 🟑 (Scaffold Complete)
| Component | File | Status |
|---|---|---|
| Config | [config.json](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/Classification/config.json) | βœ… All hyperparameters defined |
| Dataset class | [dataset.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/Classification/dataset.py) | βœ… Tokenizer + label_map builder |
| Training script | [train.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/Classification/train.py) | βœ… Full Trainer with early stopping, F1 metric |
| Inference wrapper | [predict.py](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/Classification/predict.py) | βœ… [ClassifierPredictor](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/Classification/predict.py#26-109) with top-k + confidence |
| Labeled training data | `data/` | πŸ”΄ Only 3 sample examples β€” needs real NEET questions |
**Classifier config:**
```json
{
"model_name": "bert-base-uncased",
"max_length": 128,
"num_labels": 16,
"batch_size": 16,
"learning_rate": 2e-5,
"num_epochs": 10,
"warmup_ratio": 0.1,
"eval_strategy": "epoch",
"metric_for_best_model": "f1",
"early_stopping_patience": 2
}
```
---
## 6. NCERT Dataset Summary
| Class | Chapters | Files | Total Chunks | Unique Sections |
|---|---|---|---|---|
| 11th | 19 (Ch 1–19) | Kebo101–Kebo119 | ~263 | ~200+ |
| 12th | 12 (Ch 2–13) + 1 front matter | Lebo101–Lebo113 | ~433 | ~150+ |
| **Total** | **32** | **32 JSON files** | **~696** | **~350+** |
> **Note:** Class 12 Chapter 1 (Reproduction in Organisms) is missing β€” [Lebo101.json](file:///d:/Users/Pranil/Github%20Repos/Question_AndAnswerGeneration/pdf_to_embedding/json_ouput/12th%20Ncert%20Output/Lebo101.json) contains only front matter. Needs re-processing.
---
## 7. Environment Variables
```env
SUPABASE_URL=https://xxxxx.supabase.co
SUPABASE_KEY=eyJhbG... # Service Role Key
GROQ_API_KEY=gsk_... # Free tier API key
GROQ_MODEL=llama-3.3-70b-versatile # Default LLM
EMBEDDING_MODEL=BAAI/bge-small-en-v1.5 # 384-dim local embeddings
```
---
## 8. What Remains β€” Roadmap πŸ”œ
### Immediate (Next Steps)
| # | Task | Priority | Effort |
|---|---|---|---|
| 1 | **Collect & label NEET questions** β†’ map each to chapter_id | πŸ”΄ Critical | Medium |
| 2 | **Run BERT training** (`python -m Classification.train`) | πŸ”΄ Critical | Low (code ready) |
| 3 | **Evaluate classifier** β€” target >85% F1 on held-out set | πŸ”΄ Critical | Low |
| 4 | **Fix Lebo101.json** β€” re-process Ch 1 Reproduction in Organisms PDF | 🟑 Medium | Low |
### Short-Term (Integration)
| # | Task | Priority |
|---|---|---|
| 5 | **Integrate classifier into RAG** β€” use predicted chapter to filter retrieval (pre-filter Supabase query by chapter metadata) | πŸ”΄ Critical |
| 6 | **Build FastAPI backend** β€” `/qa` endpoint wrapping `pipeline.run()`, `/health`, `/ingest` | 🟑 Medium |
| 7 | **Add syllabus_taxonomy.json** β€” structured JSON of all chapters/sections for the classifier and frontend | 🟑 Medium |
### Medium-Term (Production Readiness)
| # | Task | Priority |
|---|---|---|
| 8 | Add unit + integration tests for RAG pipeline and classifier | 🟑 Medium |
| 9 | Build frontend UI (React / Streamlit) for question input + answer display | 🟒 Nice-to-have |
| 10 | Add question generation capability (generate practice MCQs from NCERT content) | 🟒 Future |
| 11 | Deploy to cloud (Render / Railway / Docker) | 🟒 Future |
---
## 9. Key Design Decisions
| Decision | Rationale |
|---|---|
| **BGE-small-en-v1.5** over larger models | 384-dim is fast and good enough for NCERT-level text; runs locally without GPU |
| **Supabase + pgvector** over Pinecone/Weaviate | Free tier, PostgreSQL ecosystem, full SQL alongside vectors |
| **Groq API** over OpenAI/Anthropic | Free tier with fast inference; `llama-3.3-70b` is competitive quality |
| **bert-base-uncased** for classification | Lightweight, well-studied for text classification; fine-tunes on a single GPU |
| **Section-aware chunking** | Each chunk carries chapter/section metadata β†’ enables filtered retrieval |
| **Multi-stage RAG** (answer β†’ justify β†’ verify) | Reduces hallucination by adding a verification layer before presenting answers |
| **Singleton pattern** for clients | Avoids expensive re-initialization of embedding model, Supabase client, Groq client |
---
## 10. How to Run (Quick Reference)
```bash
# 1. Activate virtual environment
.\.venv\Scripts\activate
# 2. Process a new PDF
python pdf_to_embedding/clean_pdf_to_json.py --input "path/to/chapter.pdf"
# 3. Upload embeddings to Supabase
python pdf_to_embedding/embed_and_upload.py
# 4. Test RAG pipeline (smoke test)
python -m rag.pipeline --debug
# 5. Train BERT classifier (when data is ready)
python -m Classification.train
# 6. Test classifier predictions
python -m Classification.predict
```