Skip to content

Anuroop128/GradeOPS

Repository files navigation

GradeOPS

An AI-powered grading portal that turns scanned exam papers into rubric-scored, plagiarism-checked results — with a human in the loop.

Vision-LLM OCR pulls handwritten answers off PDFs, a LangGraph agent scores them against your rubric with Gemini, semantic similarity flags suspicious overlap, and anything below the auto-approve threshold lands in a TA review queue. A React dashboard ties it all together.


How it works

PDF scans  ──▶  OCR (Qwen2-VL)  ──▶  LangGraph agent  ──▶  Review router  ──▶  TA / auto-approved
                                     │
                                     ├─ grade        (Gemini 2.0 Flash, per-criterion)
                                     ├─ confidence   (heuristic signals)
                                     └─ plagiarism   (bge-small embeddings)

The OCR pipeline does adaptive preprocessing and a two-pass spatial layout detection — it asks the vision model for answer-region bounding boxes first, so multi-question pages get cropped per question instead of being read as one blob.

The grading agent runs as a LangGraph state machine: validate → grade → confidence → plagiarism → route → result. Each criterion gets its own awarded score and justification. The router sorts results into three tiers:

Tier Confidence Goes to
auto_approved ≥ 0.85 Skipped — accepted as-is
normal 0.60 – 0.85 TA review queue
priority < 0.60, or plagiarism flag, or score 0 Top of the TA queue

Features

  • OCR — Qwen2-VL with adaptive preprocessing, auto-detect multi-question pages, batched SSE streaming
  • AI grading — Gemini 2.0 Flash with per-criterion scores and natural-language justifications
  • Plagiarismbge-small-en-v1.5 cosine similarity, two severity levels (suspicious, high)
  • Cohort analytics — DBSCAN clustering surfaces consensus answers and outliers per question
  • Review workflow — priority-sorted TA queue, single-key approve / override, full audit trail
  • Live progress — Server-Sent Events for both batch OCR and batch grading

Tech stack

Backend FastAPI · LangGraph · Gemini 2.0 Flash · Qwen2-VL · sentence-transformers · scikit-learn · SQLite Frontend React 19 · Vite · Tailwind v4 · React Router


Quick start

Prerequisites: Python 3.12, Node 18+, a Google API key with Gemini access. RAM: 8 GB if you use the 2B OCR model, 32 GB+ for the default 7B.

# Backend
cd backend
cp .env.example .env                  # set GOOGLE_API_KEY, QWEN_MODEL_SIZE=2b for laptops
pip install -r ../requirements.txt
python run_api_server.py              # http://localhost:8000  (docs at /docs)

# Frontend (new terminal)
cd frontend
npm install
npm run dev                           # http://localhost:3000

The OCR model loads in the background, so the server is reachable immediately — GET /health reports ocr_qwen_vl: not_loaded until it's ready.


Project structure

GradeOPS/
├── backend/
│   └── gradeops/
│       ├── agents/      LangGraph nodes, prompts, state
│       ├── analytics/   DBSCAN cohort clustering
│       ├── api/         FastAPI routes
│       ├── batch/       Bulk processing + CSV/Excel export
│       ├── grading/     Rubric engine, schemas, confidence calculator
│       ├── llm/         Gemini client + grader adapter
│       ├── ocr/         Qwen-VL model, preprocessor, pipeline
│       ├── plagiarism/  Embedding cache + detector
│       └── storage/     SQLite repository
├── frontend/src/pages/  Dashboard · RubricBuilder · GradingStage · PlagiarismHub
└── frontend_design/     Original Stitch design references

Configuration

backend/.env:

Variable Default Notes
GOOGLE_API_KEY Required for grading
QWEN_MODEL_SIZE 7b Use 2b on laptops
GRADEOPS_DB gradeops.db SQLite file path
GRADEOPS_MEDIA_DIR media/ Where extracted answer crops are saved
FRONTEND_URL http://localhost:3000 CORS origin

API

Full interactive docs at http://localhost:8000/docs. The endpoints you'll use most:

Method Endpoint Purpose
POST /api/grade Grade one submission
POST /api/grade/batch/stream/start Start a streaming batch — SSE on /api/grade/batch/stream/{job_id}
POST /api/ocr/extract/batch/start Start streaming OCR — SSE on /api/ocr/jobs/{id}/stream
GET /api/review/queue TA queue, priority-sorted
POST /api/review/{result_id}/decision Approve or override
POST /api/analytics/cohort Cluster answers for a question
GET /api/dashboard/stats Aggregate counts for the home page

Rubric CRUD lives at /api/rubrics; plagiarism at /api/plagiarism/check and /api/plagiarism/exam/{exam_id}.


Frontend

Route What it does
/dashboard Bulk upload, exam stats, project list, activity feed
/rubric Build a rubric with a live Gemini-graded preview
/grading Split-pane TA review — Enter approve · O override · F flag
/plagiarism Similarity clusters + side-by-side comparison

Testing

cd backend && python run_all_tests.py     # or: pytest tests/

Suites cover the grading agent, confidence calculator, plagiarism detector, batch processor, LangGraph orchestration, API endpoints, and the OCR → grading integration path.


Status

Done — OCR pipeline · LangGraph grading agent · three-tier routing · semantic plagiarism · cohort clustering · SQLite persistence · streaming batch jobs · TA review workflow · all four frontend pages.

Not yet — Authentication / multi-user · Docker / production deployment · email notifications · Postgres backend · frontend integration tests.


Hardware

The OCR model is the only heavy component. Pick 2b in .env if your machine has under ~32 GB RAM — the 7B model will OOM.

Model CPU-only RAM GPU VRAM
Qwen2-VL-7B-Instruct (default) 32 GB 16 GB
Qwen2-VL-2B-Instruct 8 GB 6 GB

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages