SmartHire-AI / README.md
Vishu2006's picture
Fix: resolve merge conflict, add HF Spaces YAML metadata
bb780c0
|
Raw
History Blame Contribute Delete
12.3 kB
---
title: SmartHire AI
emoji: 🎯
colorFrom: indigo
colorTo: purple
sdk: docker
pinned: false
license: mit
short_description: Transformer-based resume and job description matching API
---
# πŸ€– SmartHire AI: Transformer-Based Resume & Job Matching System
[![Python](https://img.shields.io/badge/Python-3.9%2B-3776ab?style=flat-square&logo=python)](https://python.org)
[![PyTorch](https://img.shields.io/badge/PyTorch-2.0%2B-ee4c2c?style=flat-square&logo=pytorch)](https://pytorch.org)
[![HuggingFace](https://img.shields.io/badge/HuggingFace-Transformers-FFD21E?style=flat-square&logo=huggingface)](https://huggingface.co)
[![Streamlit](https://img.shields.io/badge/Streamlit-1.28%2B-FF4B4B?style=flat-square&logo=streamlit)](https://streamlit.io)
[![FastAPI](https://img.shields.io/badge/FastAPI-0.104%2B-009688?style=flat-square&logo=fastapi)](https://fastapi.tiangolo.com)
[![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)](LICENSE)
> **ATS-inspired AI recruitment system** that matches candidate resumes with job descriptions using fine-tuned Sentence Transformer embeddings and cosine semantic similarity β€” going far beyond simple keyword matching.
---
## πŸ“Œ Project Overview
SmartHire AI is a **production-style HRTech application** that demonstrates:
- **Transformer-based NLP** using `all-MiniLM-L6-v2` (fine-tuned on 127 resume–JD pairs across 41 job roles)
- **Semantic understanding** via mean-pooled sentence embeddings
- **Cosine similarity scoring** β€” context-aware, not keyword-matching
- **Candidate ranking** from multiple simultaneous resume uploads
- **Skill gap analysis** with critical missing skill detection (300+ skill vocabulary)
- **Persistent vector index** (ChromaDB/NumPy) for instant sub-100ms resume search
- **REST API** (FastAPI) for frontend integration
- **Interactive recruiter dashboard** built with Streamlit + Plotly
---
## πŸ“Š Fine-Tuning Results
| Metric | Value |
|--------|-------|
| Pearson r | **0.9733** |
| Spearman ρ | **0.9604** |
| Strong Match Accuracy | **98%** |
| Partial Match Accuracy | **47%** |
| Mismatch Accuracy | **100%** |
| Overall 3-tier Accuracy | **81.25%** |
| Fine-tuning Gain | **+9.4%** |
> Fine-tuned on 127 pairs across 41 job roles: 43 Strong (34%), 40 Partial (31%), 44 Mismatch (35%)
---
## πŸ—οΈ Project Structure
```
SmartHireAI/
β”‚
β”œβ”€β”€ app/
β”‚ └── streamlit_app.py # Full Streamlit dashboard (dark mode, port 8501)
β”‚
β”œβ”€β”€ api/
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ main.py # FastAPI REST API server (port 8000)
β”‚ └── README.md # Full API endpoint documentation
β”‚
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ parser.py # PDF, DOCX, TXT resume parser
β”‚ β”œβ”€β”€ preprocess.py # Text cleaning & normalization pipeline
β”‚ β”œβ”€β”€ model.py # Sentence Transformer embedding model
β”‚ β”œβ”€β”€ similarity.py # Cosine similarity & calibrated scoring
β”‚ β”œβ”€β”€ skills.py # Skill extraction & gap analysis (300+ skills)
β”‚ β”œβ”€β”€ ranking.py # Candidate ranking & export
β”‚ └── vector_store.py # ChromaDB/NumPy persistent vector index
β”‚
β”œβ”€β”€ train/
β”‚ └── training_data.json # 127 labeled resume–JD pairs (41 job roles)
β”‚
β”œβ”€β”€ datasets/
β”‚ β”œβ”€β”€ sample_jd.txt
β”‚ β”œβ”€β”€ candidate_alice.txt
β”‚ β”œβ”€β”€ candidate_bob.txt
β”‚ β”œβ”€β”€ candidate_carol.txt
β”‚ └── candidate_david.txt
β”‚
β”œβ”€β”€ finetune.py # Fine-tuning script (CosineSimilarityLoss, 6 epochs)
β”œβ”€β”€ evaluate.py # Evaluation (Pearson r, Spearman ρ, 3-tier accuracy)
β”œβ”€β”€ diagnose.py # Calibration diagnostics
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ RUN_APP.bat # Windows: launch Streamlit UI
β”œβ”€β”€ RUN_API.bat # Windows: launch FastAPI server
β”œβ”€β”€ SETUP_AND_RUN.bat # Windows: first-time setup
└── main.py # CLI entry point
```
---
## ⚑ Quick Start
### 1. Clone the Repository
```bash
git clone https://github.com/Vishu200672/SmartHire-AI.git
cd SmartHire-AI
```
### 2. Create a Virtual Environment
```bash
python -m venv venv
source venv/bin/activate # Linux / macOS
# .\venv\Scripts\activate # Windows
```
### 3. Install Dependencies
```bash
pip install -r requirements.txt
```
> ⚠️ First run downloads the embedding model (~90 MB). Subsequent runs use the HuggingFace cache.
### 4. Run the Streamlit Dashboard
```bash
streamlit run app/streamlit_app.py
# β†’ http://localhost:8501
```
### 5. Run the REST API
```bash
uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload
# β†’ http://localhost:8000
# β†’ http://localhost:8000/docs (interactive Swagger UI)
```
> Both servers can run simultaneously β€” they share the same `src/` model.
### 6. Run the CLI Demo
```bash
python main.py --demo
# Or with your own files:
python main.py --resume resume.pdf --jd job_description.txt
```
---
## 🌐 REST API
SmartHire AI includes a full **FastAPI REST API** for integrating the matching engine into any frontend (React, Next.js, Vue, Node.js, etc.).
### Base URL
```
http://localhost:8000
```
### Interactive Docs
```
http://localhost:8000/docs ← Swagger UI (try all endpoints in browser)
http://localhost:8000/redoc ← Redoc
```
### Key Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/health` | Health check |
| GET | `/model/info` | Loaded model metadata |
| **POST** | **`/match`** | **Match resumes vs JD β€” main endpoint** |
| POST | `/skills` | Skills-only analysis |
| POST | `/index/build` | Build persistent vector index |
| POST | `/index/search` | Instant search against index (<100ms) |
| GET | `/index/info` | Index stats |
| GET | `/index/candidates` | List indexed resumes |
| POST | `/index/add` | Add single resume to index |
| DELETE | `/index/clear` | Clear index |
| POST | `/parse` | Parse file β†’ raw text |
| POST | `/embed` | Get embedding vector for any text |
### Example β€” Match Resumes (JavaScript)
```javascript
const form = new FormData();
form.append("resumes", resumeFile1);
form.append("resumes", resumeFile2);
form.append("jd_text", "Looking for Python ML Engineer with PyTorch...");
form.append("similarity_weight", "0.7");
const res = await fetch("http://localhost:8000/match", {
method: "POST",
body: form,
});
const data = await res.json();
// data.candidates β†’ ranked list with scores, skills, recommendations
```
### Example Response
```json
{
"status": "success",
"duration_sec": 1.23,
"total_candidates": 2,
"summary": {
"average_score": 72.5,
"highest_score": 85.0,
"highly_recommended": 1,
"recommended": 1
},
"candidates": [
{
"rank": 1,
"name": "John_Doe",
"score_pct": 85.0,
"semantic_similarity": 91.2,
"skill_coverage_pct": 75.0,
"recommendation": "Highly Recommended",
"matching_skills": ["python", "pytorch", "docker"],
"missing_skills": ["kubernetes"],
"critical_missing": [],
"ai_insight": "Strong contextual alignment with the JD..."
}
]
}
```
See [`api/README.md`](api/README.md) for full endpoint documentation.
---
## πŸ–₯️ Streamlit Dashboard Features
| Tab | Features |
|-----|----------|
| **Upload & Analyze** | Upload PDF/DOCX/TXT resumes, paste or upload JD, run pipeline |
| **Match Results** | Score distribution bar chart, scatter plot, per-candidate cards |
| **Skill Gap Analysis** | Matching/missing/critical skill chips, skill matrix chart |
| **Candidate Ranking** | Leaderboard table, gauge chart for top candidate, CSV export |
| **Vector Index** | Build/search persistent resume index, instant JD search |
---
## πŸ—„οΈ Vector Index
SmartHire AI includes a **persistent vector index** that pre-encodes resumes so JD search is instant:
```
Normal flow: Upload resumes β†’ encode each (~0.06s each) β†’ compare β†’ results
Vector index: Index resumes once β†’ search any JD β†’ results in <100ms
```
**Backends supported:**
- **ChromaDB** (recommended) β€” `pip install chromadb`
- **NumPy flat-file** (automatic fallback) β€” no extra install needed
**Usage via API:**
```bash
# Index resumes once
curl -X POST http://localhost:8000/index/build \
-F "resumes=@resume1.pdf" -F "resumes=@resume2.docx"
# Search instantly for any JD
curl -X POST http://localhost:8000/index/search \
-F "jd_text=Python ML Engineer with PyTorch experience" \
-F "top_k=5"
```
---
## 🧠 How It Works
### Architecture Pipeline
```
Resume (PDF/DOCX/TXT)
β”‚
β–Ό
[parser.py] Extract raw text
β”‚
β–Ό
[preprocess.py] Normalize β†’ clean β†’ chunk (400 tokens, 50 overlap)
β”‚
β–Ό
[model.py] Tokenize β†’ forward pass β†’ mean pooling β†’ L2 normalize β†’ embedding
β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β–Ό β–Ό
[similarity.py] [skills.py]
Cosine similarity vs JD Skill extraction (300+ vocab)
Calibrated score 0–100% Gap analysis (matching/missing/critical)
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό
[ranking.py]
Composite score = 70% semantic + 30% skill
Sort β†’ Recommendation tier β†’ AI insight
```
### Composite Ranking Score
```
Final Score = (Semantic Similarity Γ— 0.70) + (Skill Coverage Γ— 0.30)
```
Weights are configurable via API parameter or Streamlit sidebar slider.
---
## 🎯 Recommendation Tiers
| Score | Recommendation | Action |
|-------|---------------|--------|
| **β‰₯ 60%** | 🟒 Highly Recommended | Fast-track to interview |
| **38–60%** | πŸ”΅ Recommended | Schedule screening call |
| **18–38%** | 🟠 Consider | Review manually |
| **< 18%** | πŸ”΄ Not Recommended | Archive |
---
## πŸ› οΈ Tech Stack
| Component | Technology |
|-----------|-----------|
| Core Model | Fine-tuned `all-MiniLM-L6-v2` (Sentence Transformers) |
| DL Framework | PyTorch 2.0+ |
| NLP Library | Hugging Face Transformers + Sentence-Transformers |
| REST API | FastAPI + Uvicorn |
| Vector Store | ChromaDB / NumPy |
| Web App | Streamlit |
| Charts | Plotly |
| PDF Parsing | pdfplumber + PyPDF2 |
| DOCX Parsing | python-docx |
| Data | Pandas, NumPy |
---
## πŸš€ Performance Benchmarks
| Operation | Time (CPU) |
|-----------|-----------|
| Model load (first time) | ~5–10s |
| Encode 1 resume | ~0.06s |
| Encode 60 resumes | ~4–5s |
| Vector index search | **<100ms** |
| Skill gap analysis | <0.01s per candidate |
---
## πŸ“ Module Documentation
Each module is fully documented with:
- Google-style docstrings
- Python type hints throughout
- `logging` at every pipeline step
- Meaningful error messages
---
## 🀝 Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/your-feature`)
3. Commit changes (`git commit -m "Add: your feature"`)
4. Push to branch (`git push origin feature/your-feature`)
5. Open a Pull Request
---
## πŸ“„ License
This project is licensed under the **MIT License** β€” see [LICENSE](LICENSE) for details.
---
## πŸ™ Acknowledgements
- [Hugging Face](https://huggingface.co) for Transformers and `all-MiniLM-L6-v2`
- [Sentence Transformers](https://www.sbert.net) for the fine-tuning framework
- [FastAPI](https://fastapi.tiangolo.com) for the API framework
- [Streamlit](https://streamlit.io) for the dashboard framework
- [Plotly](https://plotly.com) for interactive charts
- [ChromaDB](https://www.trychroma.com) for the vector store
---
## πŸ“¬ Contact
Built as a portfolio project demonstrating Transformer-based NLP, semantic search, fine-tuning, REST API design, and production ML engineering practices.
**GitHub**: [github.com/Vishu200672/SmartHire-AI](https://github.com/Vishu200672/SmartHire-AI)
**HF Space**: [huggingface.co/spaces/Vishu2006/SmartHire-AI](https://huggingface.co/spaces/Vishu2006/SmartHire-AI)