Spaces:
Sleeping
title: VidyaBot Gradio
emoji: ๐
colorFrom: yellow
colorTo: green
sdk: docker
app_port: 7860
VidyaBot Gradio Edition โ Offline AI Study Partner
Offline-first, cost-optimized AI tutor for rural Indian students powered by local Ollama inference and an advanced 5-Stage Context Pruning pipeline.
๐๏ธ Build Small 2026 Merit Badges
We have successfully earned all 5 merit badges for the Build Small 2026 hackathon:
- ๐ Off the Grid โ No cloud APIs used; runs fully offline with local Ollama/FastAPI backend
- ๐ฆ Llama Champion โ Runs via standard llama.cpp runtime embedded in local Ollama instance
- ๐จ Off-Brand โ Completely custom Gradio frontend with Indian flag aesthetics and responsive layouts
- ๐ Field Notes โ Complete 2,000-word engineering retro published at
docs/field_notes.md - ๐ฏ Well-Tuned โ Mistral 7B fine-tuned on 103 student Q&A pairs via Modal A10G GPU (LoRA/QLoRA)
๐ฏ Model: Fine-Tuned Mistral 7B (mistral-vidyabot)
VidyaBot uses Mistral 7B Instruct fine-tuned on student Q&A pairs from NCERT Class 10 curriculum. The fine-tuned model is served 100% offline via Ollama (llama.cpp runtime), maintaining the Off the Grid badge while improving answer quality.
Fine-Tuning Details
| Detail | Value |
|---|---|
| Base model | mistralai/Mistral-7B-Instruct-v0.1 |
| Training data | 103 hand-crafted + synthetic NCERT Q&A pairs |
| Method | QLoRA (4-bit quantization + LoRA adapters) |
| LoRA config | r=8, alpha=16, targets: q/v/k/o_proj |
| Hardware | Modal A10G GPU (24GB VRAM) |
| Training time | ~1โ2 hours |
| Estimated cost | ~$3โ5 from $250 Modal credits |
| Inference | GGUF Q4_K_M via Ollama (CPU-only, ~4GB RAM) |
| Ollama model name | mistral-vidyabot |
Why Fine-Tune on Educational Q&A?
Base mistral:latest is a strong general-purpose model, but fine-tuning on NCERT-aligned Q&A pairs produces:
- โ More structured answers โ consistent 2-4 sentence format
- โ Better NCERT terminology โ uses the exact textbook language students recognise
- โ Curriculum-aware responses โ references chapter context and exam-relevant concepts
- โ Bilingual support โ trained on Hindi-language Q&A pairs
Fine-Tuning Pipeline
Student Q&A Data (103 pairs)
โ
[Modal A10G GPU]
QLoRA: Mistral-7B-Instruct + LoRA adapters (r=8)
3 epochs, DataCollatorForLanguageModeling
โ Merge LoRA into base (merge_and_unload)
โ Save full merged model โ Modal Volume
โ
[local: modal_convert_gguf.py]
Convert HF safetensors โ GGUF (llama.cpp)
Q4_K_M quantization (~4GB)
โ
[Ollama]
ollama create mistral-vidyabot -f Modelfile
โ Offline inference at 4-8 tokens/sec (CPU)
Reproduce the Fine-Tuning
# Step 1: Generate dataset (needs Ollama running with mistral:latest)
python data/finetuning/generate_synthetic_qa.py
# Step 2: Submit to Modal (needs modal account + credits)
modal run modal_finetune.py
# Step 3: Download + convert to GGUF + register in Ollama
python modal_convert_gguf.py
# Step 4: Test the fine-tuned model
ollama run mistral-vidyabot "What is photosynthesis?"
๐ฏ Problem Statement
Over 200 million Indian students use textbooks from national and state boards (NCERT, CBSE, SSLC, etc.), but face:
- Limited or unstable internet connectivity in small towns and villages
- High cost of cloud APIs ($0.77+ per question using naive RAG baselines)
- Language barriers (need for Hindi, Kannada, Telugu, Tamil, Marathi, etc.)
- Need for absolute hardware resilience (must run on older 8GB-16GB RAM CPU laptops)
VidyaBot solves this by wrapping a local quantized LLM with a 5-Stage Context Pruning pipeline that achieves 88.2% input token reduction, allowing CPU inference to run in less than 2 seconds with $0.00 API costs.
๐๏ธ Architecture Diagram
STUDENT QUERY
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGE 0: Curriculum Router โ
โ - Eliminates 70% chapters โ
โ - Zero cost | Latency <1ms โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGE 1: BM25 Filter โ
โ - Keyword pre-filtering โ
โ - Top-30 candidate chunks โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGE 2: Cross-Encoder โ
โ - ms-marco-MiniLM-L-6-v2 โ
โ - Joint scoring | Top-5 โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGE 3: Token Budget โ
โ - Hard 512-token context capโ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ STAGE 4: Sentence Pruner โ
โ - Similarity-based trimming โ
โ - 30-50% text reduction โ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OLLAMA LOCAL INFERENCE (CPU) โ
โ - Model: mistral-vidyabot โ
โ - Cost: $0.00 | TTFT: <2s โ
โโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
STUDENT ANSWER
๐พ Tech Stack
| Layer | Technology | Why |
|---|---|---|
| Frontend | Gradio (Blocks UI) | Premium Indian themed interface with streaming and dashboards |
| Backend | Python 3.11 + FastAPI | Lightweight asynchronous API server |
| Inference Engine | Ollama (llama.cpp runtime) |
Fast local inference on consumer CPU hardware |
| Embeddings | sentence-transformers (all-MiniLM-L6-v2) |
384D, CPU-only, 22MB model |
| Reranker | Cross-Encoder (ms-marco-MiniLM-L-6-v2) |
80MB model, joint scoring for 15-25% more precision |
| PDF Processing | pdfplumber + PyMuPDF | Robust layout-aware textbook text extraction |
| Vector Search | FAISS (IndexFlatIP) |
Sub-millisecond local semantic search |
| Database | SQLite | Single .db file for student metadata and caching |
| Translation | deep-translator | Multi-language support (free tier) |
๐ Project Structure
vidyabot/
โโโ backend/
โ โโโ main.py # FastAPI entry point & routers
โ โโโ config.py # Settings & env loading
โ โโโ database.py # SQLite schema & DTOs
โ โ
โ โโโ ingestion/
โ โ โโโ pdf_parser.py # PDF -> structured text
โ โ โโโ chunker.py # Semantic chunking
โ โ โโโ embedder.py # MiniLM embeddings generator
โ โ
โ โโโ retrieval/
โ โ โโโ bm25_index.py # Stage 1: BM25 indexer
โ โ โโโ vector_store.py # Stage 2: FAISS vector store
โ โ โโโ reranker.py # Stage 2: Cross-Encoder reranker
โ โ โโโ sentence_pruner.py # Stage 4: Sentence trimmer
โ โ โโโ context_pruner.py # 5-stage orchestrator (CORE)
โ โ
โ โโโ llm/
โ โ โโโ ollama_client.py # Local Ollama client (offline)
โ โ โโโ prompt_builder.py # Prompt formatting
โ โ
โ โโโ cache/
โ โโโ semantic_cache.py # FAISS-based query cache
โ
โโโ docs/
โ โโโ field_notes.md # 2000-word engineering retrospective
โ โโโ social_post.md # Social media post drafts
โ
โโโ data/ # Local databases and PDF storage
โโโ gradio_app.py # Gradio blocks application layout
โโโ app.py # Unified Gradio + FastAPI launcher
โโโ space_requirements.txt # HF Space requirements file
โโโ README.md # This file
๐ Quick Start (Running Offline)
1. Pre-requisites
- Python 3.11+
- Ollama installed on your machine.
- Download the local target model:
ollama serve ollama pull llama3.2:latest
2. Clone & Setup
git clone https://github.com/shankarsai000/Paradox-vidyabot.git
cd Paradox-vidyabot
# Create and activate virtual environment
python -m venv venv
venv\Scripts\activate # Unix: source venv/bin/activate
# Install dependencies
pip install -r backend/requirements.txt
3. Configure Env
Create a .env file in the root directory:
LLM_BACKEND=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=mistral-vidyabot
4. Start Unified Application
$env:PYTHONPATH="."
python app.py
*Gradio interface will launch at http://localhost:7860. FastAPI routes will run at /api.*
โ
Ready to use! Ask questions about your textbooks.
---
## ๐ API Reference
### Ingestion
**POST /api/ingest** โ Upload & process PDF
```bash
curl -F "file=@textbook.pdf" \
-F "board=CBSE" \
-F "subject=Biology" \
-F "grade=10" \
-F "title=Biology Class 10" \
http://localhost:8000/api/ingest
Response:
{
"status": "success",
"textbook_id": 1,
"total_chunks": 442,
"processing_time_seconds": 28
}
GET /api/textbooks โ List available textbooks
{
"textbooks": [
{
"id": 1,
"title": "Biology Class 10",
"board": "CBSE",
"subject": "Biology",
"grade": "10",
"total_pages": 256,
"total_chunks": 442
}
]
}
Query & LLM
POST /api/query โ Answer a question
curl -X POST http://localhost:8000/api/query \
-H "Content-Type: application/json" \
-d '{
"question": "What is photosynthesis?",
"textbook_id": 1,
"language": "english",
"mode": "answer"
}'
Response:
{
"answer": "Photosynthesis is the process by which plants...",
"tokens_used": 387,
"baseline_tokens": 2000,
"tokens_saved": 1613,
"cost_usd": 0.000097,
"cost_saved_usd": 0.000403,
"cache_hit": false,
"pruning_ratio": 0.807,
"time_ms": 1250,
"source_pages": "45,46"
}
Analytics
GET /api/stats โ Cumulative cost dashboard
{
"total_queries": 1547,
"cache_hits": 621,
"cache_hit_rate": 0.401,
"total_tokens_used": 598818,
"total_baseline_tokens": 3094000,
"total_tokens_saved": 2495182,
"total_cost_usd": 0.1497,
"baseline_cost_usd": 0.7735,
"total_savings_usd": 0.6238,
"savings_percentage": 80.7,
"avg_tokens_per_query": 387,
"textbooks_ingested": 3
}
๐ How Cost Savings Work
Baseline (Full Textbook to LLM)
- Input: Entire chapter (~2000 tokens)
- Cost: 2000 tokens ร ($0.25/1M) = $0.0005/query
- Per 1000 queries: $0.50
VidyaBot (Pruned Context)
- Input: Relevant chunks only (~400 tokens)
- Stages:
- BM25 filter: top-30 chunks (0ms, free)
- Semantic rerank: top-10 chunks (5ms, local MiniLM)
- Token budget: top-3 chunks (0ms, local logic)
- Cost: 400 tokens ร ($0.25/1M) = $0.0001/query
- Per 1000 queries: $0.10
Result
Savings = $0.50 - $0.10 = $0.40 per 1000 queries
Percentage = (0.40 / 0.50) ร 100 = 80% reduction
At scale: Serving 100,000 students each asking 10 questions = $20,000 saved vs cloud alternatives.
๐งช Running Tests
# Install pytest
pip install pytest
# Run all tests
pytest tests/ -v
# Run specific test file
pytest tests/test_pruning.py -v
# Run with coverage
pytest tests/ --cov=backend
Test Coverage
- โ PDF parsing & chunking
- โ 3-stage pruning pipeline
- โ Semantic cache deduplication
- โ Edge cases (empty inputs, long texts, etc.)
๐ Languages Supported
VidyaBot works with Indian languages via deep-translator:
- English (default)
- เคนเคฟเคเคฆเฅ (Hindi)
- เฒเฒจเณเฒจเฒก (Kannada)
- เฐคเฑเฐฒเฑเฐเฑ (Telugu)
- เฎคเฎฎเฎฟเฎดเฏ (Tamil)
- เคฎเคฐเคพเค เฅ (Marathi)
- เฆฌเฆพเฆเฆฒเฆพ (Bengali)
How it works:
- Student asks in their language
- Question translated to English (free Google Translate)
- Answer fetched from English textbook
- Answer translated back to student's language
๐ Security & Privacy
โ All data stays local:
- SQLite DB stored locally (
./data/vidyabot.db) - No user data sent to VidyaBot servers
- Only LLM prompt + context sent to Anthropic
โ Offline-first:
- Service worker caches app shell
- Can answer repeat questions offline
- No tracking or analytics
โ API key protection:
- Never exposed in browser
- Backend-only communication with Anthropic
๐ Adding New Textbooks
Via Web UI
- Navigate to "๐ค Upload" tab
- Select PDF file
- Fill in metadata
- Click "Upload & Process"
- Done! (Takes ~30 seconds per 300-page book)
Via CLI
python -c "
from backend.ingestion.pdf_parser import PDFParser
from backend.ingestion.chunker import Chunker
from backend.ingestion.embedder import Embedder
parser = PDFParser('path/to/book.pdf')
pages = parser.parse()
chunker = Chunker()
chunks = chunker.chunk_by_section(pages, textbook_id=1)
embedder = Embedder()
embedder.embed_chunks([c.content for c in chunks])
"
๐ ๏ธ Deployment
Local Development
To run the unified application (Gradio fronted + FastAPI backend):
$env:PYTHONPATH="."
python app.py
๐ Troubleshooting
| Issue | Solution |
|---|---|
| "Ollama connection refused" | Make sure the Ollama desktop application is open or ollama serve is running. |
| "Ollama model not found" | Run ollama pull llama3.2:latest (or model name specified in .env). |
| "No textbooks loaded" | Navigate to the "Upload Textbook" tab in the UI or use the API ingest route. |
| "Slow first query" | First query compiles indexes (~10-20s). Subsequent queries are extremely fast. |
| "PDF upload fails" | Ensure the uploaded PDF is a digital text-based document (not scanned images). |
| "Out of memory" | Quantized models (3B/7B) run safely inside 8GB RAM. Ensure other heavy applications are closed. |
๐ Acceptance Criteria โ
- โ
POST /api/ingest returns
total_chunks > 0in <60 seconds - โ
POST /api/query returns answer with
tokens_used < 600 - โ tokens_saved consistently >1000 (proving ~80% reduction)
- โ
Second identical query returns
cache_hit: truewithtokens_used: 0 - โ Frontend loads, shows textbook selector, displays answer + savings badge
- โ GET /api/stats shows cumulative savings
- โ
All tests pass (
pytest tests/ -v)
๐ License
MIT License โ Free for educational use.
๐ Contributing
Contributions welcome! Focus areas:
- Additional Indian languages
- Mobile app (React Native)
- Handwriting recognition for math
- Teacher dashboard
- Offline video integration
Made with โค๏ธ for education access across rural India.
"Not all children have access to tutors, but they should have access to knowledge."