Spaces:
Runtime error
Runtime error
Aryan Mishra commited on
Commit ·
d9530b5
1
Parent(s): 90e5963
Refactor project structure
Browse files- .DS_Store +0 -0
- .gitignore +53 -41
- README.md +15 -16
- api/{middleware → app}/__init__.py +0 -0
- api/{models → app/core}/__init__.py +0 -0
- api/{main.py → app/main.py} +5 -5
- api/{routes → app/middleware}/__init__.py +0 -0
- api/{middleware → app/middleware}/dependencies.py +0 -0
- api/{middleware → app/middleware}/metrics.py +0 -0
- api/{services → app/routes}/__init__.py +0 -0
- api/{routes → app/routes}/predict.py +5 -5
- api/{routes → app/routes}/results.py +0 -0
- api/app/schemas/__init__.py +0 -0
- api/{models → app/schemas}/db_models.py +0 -0
- api/{models → app/schemas}/schemas.py +0 -0
- api/app/services/__init__.py +0 -0
- api/{services → app/services}/absa_pipeline.py +2 -2
- api/{services → app/services}/lang_service.py +0 -0
- api/{tasks → app/tasks}/__init__.py +0 -0
- api/{tasks → app/tasks}/batch_tasks.py +4 -4
- config/railway.json +14 -0
- data/models/lid.176.ftz +3 -0
- {.planning → docs/planning}/PROJECT.md +0 -0
- {.planning → docs/planning}/REQUIREMENTS.md +0 -0
- {.planning → docs/planning}/ROADMAP.md +0 -0
- {.planning → docs/planning}/STATE.md +0 -0
- {.planning → docs/planning}/config.json +0 -0
- {.planning → docs/planning}/research/ARCHITECTURE.md +0 -0
- {.planning → docs/planning}/research/FEATURES.md +0 -0
- {.planning → docs/planning}/research/PITFALLS.md +0 -0
- {.planning → docs/planning}/research/STACK.md +0 -0
- {.planning → docs/planning}/research/SUMMARY.md +0 -0
- config/dvc.yaml → dvc.yaml +0 -0
- {notebooks → ml/notebooks}/01_data_exploration.ipynb +0 -0
- {notebooks → ml/notebooks}/03_model_comparison.ipynb +0 -0
- {notebooks → ml/notebooks}/03_train_colab.ipynb +0 -0
- {notebooks → ml/notebooks}/04_qlora_colab.ipynb +0 -0
- {notebooks → ml/notebooks}/08_final_evaluation.ipynb +0 -0
- mlruns/1/f7e324a252a94812b0d4158371276cb0/artifacts/confusion_matrix.json +0 -28
- models/onnx/README.md +55 -0
- reorganize.sh +39 -0
- src/absa/__init__.py +0 -0
- src/languages/__init__.py +0 -0
- src/languages/english/__init__.py +0 -0
- src/languages/hindi/__init__.py +0 -0
- src/languages/hinglish/__init__.py +0 -0
- tests/api/test_api.py +3 -3
.DS_Store
CHANGED
|
Binary files a/.DS_Store and b/.DS_Store differ
|
|
|
.gitignore
CHANGED
|
@@ -1,53 +1,65 @@
|
|
| 1 |
-
#
|
| 2 |
.env
|
| 3 |
-
.env.
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
*.
|
| 7 |
-
*.key
|
| 8 |
-
*.p12
|
| 9 |
-
*.pfx
|
| 10 |
-
*.crt
|
| 11 |
-
credentials.json
|
| 12 |
-
secrets.json
|
| 13 |
-
config.json
|
| 14 |
-
*secret*
|
| 15 |
-
*credential*
|
| 16 |
-
*token*
|
| 17 |
-
*apikey*
|
| 18 |
-
|
| 19 |
-
# ML/Data artifacts
|
| 20 |
-
/data/
|
| 21 |
-
/models/
|
| 22 |
-
*.pkl
|
| 23 |
-
*.h5
|
| 24 |
-
*.pt
|
| 25 |
-
*.pth
|
| 26 |
-
*.onnx
|
| 27 |
-
*.bin
|
| 28 |
-
mlruns/
|
| 29 |
-
mlflow/
|
| 30 |
|
| 31 |
-
#
|
| 32 |
-
.venv/
|
| 33 |
-
venv/
|
| 34 |
__pycache__/
|
| 35 |
*.pyc
|
| 36 |
*.pyo
|
|
|
|
| 37 |
.pytest_cache/
|
| 38 |
.mypy_cache/
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
.DS_Store
|
| 45 |
Thumbs.db
|
| 46 |
|
| 47 |
-
#
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
#
|
| 53 |
node_modules/
|
|
|
|
| 1 |
+
# Security — CRITICAL
|
| 2 |
.env
|
| 3 |
+
.env.local
|
| 4 |
+
.env.*.local
|
| 5 |
+
*.db
|
| 6 |
+
*.sqlite3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
+
# Python cache
|
|
|
|
|
|
|
| 9 |
__pycache__/
|
| 10 |
*.pyc
|
| 11 |
*.pyo
|
| 12 |
+
*.egg-info/
|
| 13 |
.pytest_cache/
|
| 14 |
.mypy_cache/
|
| 15 |
+
.ruff_cache/
|
| 16 |
+
.coverage
|
| 17 |
+
htmlcov/
|
| 18 |
+
|
| 19 |
+
# Virtual environment
|
| 20 |
+
.venv/
|
| 21 |
+
venv/
|
| 22 |
+
env/
|
| 23 |
+
|
| 24 |
+
# ML artifacts (large — tracked via DVC)
|
| 25 |
+
*.pt
|
| 26 |
+
*.pth
|
| 27 |
+
*.bin
|
| 28 |
+
*.safetensors
|
| 29 |
+
*.ckpt
|
| 30 |
+
*.h5
|
| 31 |
+
*.pkl
|
| 32 |
+
*.joblib
|
| 33 |
+
*.onnx
|
| 34 |
+
|
| 35 |
+
# MLflow tracking (can be large)
|
| 36 |
+
mlruns/
|
| 37 |
+
|
| 38 |
+
# Data files (tracked via DVC)
|
| 39 |
+
data/raw/
|
| 40 |
+
data/processed/
|
| 41 |
+
*.csv
|
| 42 |
+
*.parquet
|
| 43 |
+
*.jsonl
|
| 44 |
+
|
| 45 |
+
# Jupyter
|
| 46 |
+
.ipynb_checkpoints/
|
| 47 |
+
|
| 48 |
+
# Agent/IDE configs (optional — decide per tool)
|
| 49 |
+
# .claude/
|
| 50 |
+
# .opencode/
|
| 51 |
+
|
| 52 |
+
# OS
|
| 53 |
.DS_Store
|
| 54 |
Thumbs.db
|
| 55 |
|
| 56 |
+
# IDE
|
| 57 |
+
.vscode/
|
| 58 |
+
.idea/
|
| 59 |
+
|
| 60 |
+
# Logs
|
| 61 |
+
*.log
|
| 62 |
+
logs/
|
| 63 |
|
| 64 |
+
# Node
|
| 65 |
node_modules/
|
README.md
CHANGED
|
@@ -10,7 +10,7 @@ A production-ready, highly optimized Aspect-Based Sentiment Analysis (ABSA) syst
|
|
| 10 |
|
| 11 |
The system leverages state-of-the-art models like **XLM-RoBERTa** and **IndicBERT**, optimized using ONNX runtime, and includes a highly robust, zero-download, pure-Python rule-based fallback engine for instant inference.
|
| 12 |
|
| 13 |
-
##
|
| 14 |
|
| 15 |
- **Multilingual Support**: First-class support for English, Hindi, and code-mixed Hinglish.
|
| 16 |
- **Dual Inference Engine**:
|
|
@@ -18,37 +18,37 @@ The system leverages state-of-the-art models like **XLM-RoBERTa** and **IndicBER
|
|
| 18 |
- **Rule-Based Fallback**: An instantaneous, pure-Python fallback leveraging a curated multi-lingual lexicon to handle aspect extraction and sentiment scoring without any heavy downloads.
|
| 19 |
- **Modern Tech Stack**:
|
| 20 |
- **Backend**: Asynchronous, high-performance API built with FastAPI.
|
| 21 |
-
- **Frontend**: A
|
| 22 |
- **MLOps Integrated**: Complete integration with DVC (Data Version Control) for pipeline reproducibility, MLflow for experiment tracking, and Evidently AI for data drift monitoring.
|
| 23 |
- **Scalable Architecture**: Support for async tasks via Celery + Redis, robust data storage via PostgreSQL, and metric exporting using Prometheus.
|
| 24 |
|
| 25 |
-
##
|
| 26 |
|
| 27 |
This repository is designed following a **Python-first paradigm**:
|
| 28 |
- **Python (67.5%)**: Handling all business logic, data processing, configuration, API routing, ML inference, and utility functions using FastAPI and Python data science libraries.
|
| 29 |
- **JavaScript/TypeScript (32.5%)**: Strictly limited to the frontend `dashboard/` directory, used *only* for the React UI, component rendering, browser events, and client-side state.
|
| 30 |
- *Note: There is no backend or ML logic written in JavaScript.*
|
| 31 |
|
| 32 |
-
##
|
| 33 |
|
| 34 |
```text
|
| 35 |
Multilingual-Absa/
|
| 36 |
-
├── api/
|
| 37 |
-
├── config/ #
|
| 38 |
├── dashboard/ # React frontend for inference & monitoring
|
| 39 |
├── data/ # Dataset directory (DVC-tracked)
|
| 40 |
-
├── docs/ # Extended documentation
|
| 41 |
-
├──
|
| 42 |
├── models/ # Model artifacts (DVC-tracked)
|
| 43 |
├── monitoring/ # Monitoring configurations (Prometheus, Evidently)
|
| 44 |
-
├── notebooks/ # Exploratory Data Analysis & Prototyping
|
| 45 |
├── scripts/ # Utility and automation scripts
|
| 46 |
-
├── src/ # Machine Learning pipeline source code
|
| 47 |
├── tests/ # Unit and integration test suite
|
|
|
|
| 48 |
└── requirements.txt # Python dependencies
|
| 49 |
```
|
| 50 |
|
| 51 |
-
##
|
| 52 |
|
| 53 |
### Prerequisites
|
| 54 |
- Python 3.10+
|
|
@@ -78,7 +78,7 @@ cp .env.example .env
|
|
| 78 |
|
| 79 |
The easiest way to get the entire stack (API, Dashboard, Redis, Postgres) running is via Docker Compose:
|
| 80 |
```bash
|
| 81 |
-
docker-compose -f
|
| 82 |
```
|
| 83 |
|
| 84 |
### 3. Manual ML Pipeline Execution (DVC)
|
|
@@ -94,8 +94,7 @@ dvc push # Push newly generated artifacts to remote
|
|
| 94 |
|
| 95 |
**Start the API Server:**
|
| 96 |
```bash
|
| 97 |
-
|
| 98 |
-
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
| 99 |
```
|
| 100 |
*API Documentation will be available at `http://localhost:8000/docs`.*
|
| 101 |
|
|
@@ -107,13 +106,13 @@ npm run dev
|
|
| 107 |
```
|
| 108 |
*Access the dashboard at `http://localhost:5173`.*
|
| 109 |
|
| 110 |
-
##
|
| 111 |
|
| 112 |
1. **Prediction API**: When a review is submitted, the language is auto-detected.
|
| 113 |
2. **Inference**: The `ABSAPipeline` attempts to load INT8 quantized ONNX models for extraction and sentiment scoring.
|
| 114 |
3. **Fallback Mechanism**: If the custom models are not downloaded, the engine automatically falls back to a dictionary/rule-based engine tailored for product reviews, guaranteeing zero downtime and instant availability.
|
| 115 |
4. **Monitoring**: All predictions are logged. Performance metrics and data drift are tracked via Evidently and Prometheus.
|
| 116 |
|
| 117 |
-
##
|
| 118 |
|
| 119 |
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
|
|
| 10 |
|
| 11 |
The system leverages state-of-the-art models like **XLM-RoBERTa** and **IndicBERT**, optimized using ONNX runtime, and includes a highly robust, zero-download, pure-Python rule-based fallback engine for instant inference.
|
| 12 |
|
| 13 |
+
## Key Features
|
| 14 |
|
| 15 |
- **Multilingual Support**: First-class support for English, Hindi, and code-mixed Hinglish.
|
| 16 |
- **Dual Inference Engine**:
|
|
|
|
| 18 |
- **Rule-Based Fallback**: An instantaneous, pure-Python fallback leveraging a curated multi-lingual lexicon to handle aspect extraction and sentiment scoring without any heavy downloads.
|
| 19 |
- **Modern Tech Stack**:
|
| 20 |
- **Backend**: Asynchronous, high-performance API built with FastAPI.
|
| 21 |
+
- **Frontend**: A responsive dashboard built with React and TailwindCSS. Features real-time predictions, batch analytics, and system monitoring.
|
| 22 |
- **MLOps Integrated**: Complete integration with DVC (Data Version Control) for pipeline reproducibility, MLflow for experiment tracking, and Evidently AI for data drift monitoring.
|
| 23 |
- **Scalable Architecture**: Support for async tasks via Celery + Redis, robust data storage via PostgreSQL, and metric exporting using Prometheus.
|
| 24 |
|
| 25 |
+
## Python-First Architecture
|
| 26 |
|
| 27 |
This repository is designed following a **Python-first paradigm**:
|
| 28 |
- **Python (67.5%)**: Handling all business logic, data processing, configuration, API routing, ML inference, and utility functions using FastAPI and Python data science libraries.
|
| 29 |
- **JavaScript/TypeScript (32.5%)**: Strictly limited to the frontend `dashboard/` directory, used *only* for the React UI, component rendering, browser events, and client-side state.
|
| 30 |
- *Note: There is no backend or ML logic written in JavaScript.*
|
| 31 |
|
| 32 |
+
## Repository Structure
|
| 33 |
|
| 34 |
```text
|
| 35 |
Multilingual-Absa/
|
| 36 |
+
├── api/app/ # FastAPI backend and inference services
|
| 37 |
+
├── config/ # Docker and application configuration files
|
| 38 |
├── dashboard/ # React frontend for inference & monitoring
|
| 39 |
├── data/ # Dataset directory (DVC-tracked)
|
| 40 |
+
├── docs/ # Extended documentation (architecture, ml, api)
|
| 41 |
+
├── ml/ # ML training, notebooks, MLflow, and tracking
|
| 42 |
├── models/ # Model artifacts (DVC-tracked)
|
| 43 |
├── monitoring/ # Monitoring configurations (Prometheus, Evidently)
|
|
|
|
| 44 |
├── scripts/ # Utility and automation scripts
|
| 45 |
+
├── src/ # Core Machine Learning pipeline source code
|
| 46 |
├── tests/ # Unit and integration test suite
|
| 47 |
+
├── dvc.yaml # DVC pipeline orchestration
|
| 48 |
└── requirements.txt # Python dependencies
|
| 49 |
```
|
| 50 |
|
| 51 |
+
## Getting Started
|
| 52 |
|
| 53 |
### Prerequisites
|
| 54 |
- Python 3.10+
|
|
|
|
| 78 |
|
| 79 |
The easiest way to get the entire stack (API, Dashboard, Redis, Postgres) running is via Docker Compose:
|
| 80 |
```bash
|
| 81 |
+
docker-compose -f deployment/docker/docker-compose.yml up --build
|
| 82 |
```
|
| 83 |
|
| 84 |
### 3. Manual ML Pipeline Execution (DVC)
|
|
|
|
| 94 |
|
| 95 |
**Start the API Server:**
|
| 96 |
```bash
|
| 97 |
+
PYTHONPATH=. uvicorn api.app.main:app --reload --host 0.0.0.0 --port 8000
|
|
|
|
| 98 |
```
|
| 99 |
*API Documentation will be available at `http://localhost:8000/docs`.*
|
| 100 |
|
|
|
|
| 106 |
```
|
| 107 |
*Access the dashboard at `http://localhost:5173`.*
|
| 108 |
|
| 109 |
+
## How it Works
|
| 110 |
|
| 111 |
1. **Prediction API**: When a review is submitted, the language is auto-detected.
|
| 112 |
2. **Inference**: The `ABSAPipeline` attempts to load INT8 quantized ONNX models for extraction and sentiment scoring.
|
| 113 |
3. **Fallback Mechanism**: If the custom models are not downloaded, the engine automatically falls back to a dictionary/rule-based engine tailored for product reviews, guaranteeing zero downtime and instant availability.
|
| 114 |
4. **Monitoring**: All predictions are logged. Performance metrics and data drift are tracked via Evidently and Prometheus.
|
| 115 |
|
| 116 |
+
## License
|
| 117 |
|
| 118 |
This project is licensed under the MIT License - see the LICENSE file for details.
|
api/{middleware → app}/__init__.py
RENAMED
|
File without changes
|
api/{models → app/core}/__init__.py
RENAMED
|
File without changes
|
api/{main.py → app/main.py}
RENAMED
|
@@ -5,11 +5,11 @@ from fastapi.middleware.cors import CORSMiddleware
|
|
| 5 |
|
| 6 |
load_dotenv()
|
| 7 |
|
| 8 |
-
from api.routes import predict, results # noqa: E402
|
| 9 |
-
from api.middleware.metrics import instrumentator # noqa: E402
|
| 10 |
-
from api.services.absa_pipeline import pipeline # noqa: E402
|
| 11 |
-
from api.
|
| 12 |
-
from api.middleware.dependencies import engine # noqa: E402
|
| 13 |
|
| 14 |
|
| 15 |
@asynccontextmanager
|
|
|
|
| 5 |
|
| 6 |
load_dotenv()
|
| 7 |
|
| 8 |
+
from api.app.routes import predict, results # noqa: E402
|
| 9 |
+
from api.app.middleware.metrics import instrumentator # noqa: E402
|
| 10 |
+
from api.app.services.absa_pipeline import pipeline # noqa: E402
|
| 11 |
+
from api.app.schemas.db_models import Base # noqa: E402
|
| 12 |
+
from api.app.middleware.dependencies import engine # noqa: E402
|
| 13 |
|
| 14 |
|
| 15 |
@asynccontextmanager
|
api/{routes → app/middleware}/__init__.py
RENAMED
|
File without changes
|
api/{middleware → app/middleware}/dependencies.py
RENAMED
|
File without changes
|
api/{middleware → app/middleware}/metrics.py
RENAMED
|
File without changes
|
api/{services → app/routes}/__init__.py
RENAMED
|
File without changes
|
api/{routes → app/routes}/predict.py
RENAMED
|
@@ -6,11 +6,11 @@ import uuid
|
|
| 6 |
import tempfile
|
| 7 |
import time
|
| 8 |
|
| 9 |
-
from api.
|
| 10 |
-
from api.
|
| 11 |
-
from api.middleware.dependencies import get_db
|
| 12 |
-
from api.services.absa_pipeline import pipeline
|
| 13 |
-
from api.tasks.batch_tasks import process_batch
|
| 14 |
|
| 15 |
router = APIRouter()
|
| 16 |
|
|
|
|
| 6 |
import tempfile
|
| 7 |
import time
|
| 8 |
|
| 9 |
+
from api.app.schemas.schemas import ReviewInput, PredictionResponse, BatchJobResponse
|
| 10 |
+
from api.app.schemas.db_models import Review, AspectResult, BatchJob
|
| 11 |
+
from api.app.middleware.dependencies import get_db
|
| 12 |
+
from api.app.services.absa_pipeline import pipeline
|
| 13 |
+
from api.app.tasks.batch_tasks import process_batch
|
| 14 |
|
| 15 |
router = APIRouter()
|
| 16 |
|
api/{routes → app/routes}/results.py
RENAMED
|
File without changes
|
api/app/schemas/__init__.py
ADDED
|
File without changes
|
api/{models → app/schemas}/db_models.py
RENAMED
|
File without changes
|
api/{models → app/schemas}/schemas.py
RENAMED
|
File without changes
|
api/app/services/__init__.py
ADDED
|
File without changes
|
api/{services → app/services}/absa_pipeline.py
RENAMED
|
@@ -18,8 +18,8 @@ from pathlib import Path
|
|
| 18 |
from typing import List, Tuple
|
| 19 |
import numpy as np
|
| 20 |
|
| 21 |
-
from api.
|
| 22 |
-
from api.services.lang_service import lang_service
|
| 23 |
|
| 24 |
# ── Optional heavy imports (ONNX custom models) ───────────────────────────────
|
| 25 |
try:
|
|
|
|
| 18 |
from typing import List, Tuple
|
| 19 |
import numpy as np
|
| 20 |
|
| 21 |
+
from api.app.schemas.schemas import PredictionResponse, AspectSentiment
|
| 22 |
+
from api.app.services.lang_service import lang_service
|
| 23 |
|
| 24 |
# ── Optional heavy imports (ONNX custom models) ───────────────────────────────
|
| 25 |
try:
|
api/{services → app/services}/lang_service.py
RENAMED
|
File without changes
|
api/{tasks → app/tasks}/__init__.py
RENAMED
|
File without changes
|
api/{tasks → app/tasks}/batch_tasks.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
from api.tasks import celery_app
|
| 2 |
-
from api.services.absa_pipeline import pipeline
|
| 3 |
-
from api.middleware.dependencies import SessionLocal
|
| 4 |
-
from api.
|
| 5 |
import pandas as pd
|
| 6 |
import os
|
| 7 |
import csv
|
|
|
|
| 1 |
+
from api.app.tasks import celery_app
|
| 2 |
+
from api.app.services.absa_pipeline import pipeline
|
| 3 |
+
from api.app.middleware.dependencies import SessionLocal
|
| 4 |
+
from api.app.schemas.db_models import BatchJob, AspectResult, Review
|
| 5 |
import pandas as pd
|
| 6 |
import os
|
| 7 |
import csv
|
config/railway.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://railway.app/railway.schema.json",
|
| 3 |
+
"build": {
|
| 4 |
+
"builder": "DOCKERFILE",
|
| 5 |
+
"dockerfilePath": "docker/Dockerfile.api.prod"
|
| 6 |
+
},
|
| 7 |
+
"deploy": {
|
| 8 |
+
"startCommand": "uvicorn api.main:app --host 0.0.0.0 --port $PORT",
|
| 9 |
+
"healthcheckPath": "/health",
|
| 10 |
+
"healthcheckTimeout": 30,
|
| 11 |
+
"restartPolicyType": "ON_FAILURE",
|
| 12 |
+
"restartPolicyMaxRetries": 3
|
| 13 |
+
}
|
| 14 |
+
}
|
data/models/lid.176.ftz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8f3472cfe8738a7b6099e8e999c3cbfae0dcd15696aac7d7738a8039db603e83
|
| 3 |
+
size 938013
|
{.planning → docs/planning}/PROJECT.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/REQUIREMENTS.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/ROADMAP.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/STATE.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/config.json
RENAMED
|
File without changes
|
{.planning → docs/planning}/research/ARCHITECTURE.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/research/FEATURES.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/research/PITFALLS.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/research/STACK.md
RENAMED
|
File without changes
|
{.planning → docs/planning}/research/SUMMARY.md
RENAMED
|
File without changes
|
config/dvc.yaml → dvc.yaml
RENAMED
|
File without changes
|
{notebooks → ml/notebooks}/01_data_exploration.ipynb
RENAMED
|
File without changes
|
{notebooks → ml/notebooks}/03_model_comparison.ipynb
RENAMED
|
File without changes
|
{notebooks → ml/notebooks}/03_train_colab.ipynb
RENAMED
|
File without changes
|
{notebooks → ml/notebooks}/04_qlora_colab.ipynb
RENAMED
|
File without changes
|
{notebooks → ml/notebooks}/08_final_evaluation.ipynb
RENAMED
|
File without changes
|
mlruns/1/f7e324a252a94812b0d4158371276cb0/artifacts/confusion_matrix.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"confusion_matrix": [
|
| 3 |
-
[
|
| 4 |
-
246,
|
| 5 |
-
26,
|
| 6 |
-
31,
|
| 7 |
-
13
|
| 8 |
-
],
|
| 9 |
-
[
|
| 10 |
-
14,
|
| 11 |
-
120,
|
| 12 |
-
26,
|
| 13 |
-
7
|
| 14 |
-
],
|
| 15 |
-
[
|
| 16 |
-
20,
|
| 17 |
-
29,
|
| 18 |
-
60,
|
| 19 |
-
1
|
| 20 |
-
],
|
| 21 |
-
[
|
| 22 |
-
3,
|
| 23 |
-
7,
|
| 24 |
-
0,
|
| 25 |
-
3
|
| 26 |
-
]
|
| 27 |
-
]
|
| 28 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
models/onnx/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- en
|
| 4 |
+
- hi
|
| 5 |
+
tags:
|
| 6 |
+
- sentiment-analysis
|
| 7 |
+
- aspect-based-sentiment-analysis
|
| 8 |
+
- onnx
|
| 9 |
+
- int8
|
| 10 |
+
- xlm-roberta
|
| 11 |
+
---
|
| 12 |
+
|
| 13 |
+
# Multilingual ABSA (Aspect-Based Sentiment Analysis)
|
| 14 |
+
|
| 15 |
+
## Model Description
|
| 16 |
+
This repository contains INT8-quantized ONNX models for Multilingual Aspect-Based Sentiment Analysis (ABSA).
|
| 17 |
+
It uses a two-stage pipeline:
|
| 18 |
+
1. **Aspect Extraction**: Token classification model to identify aspects in text.
|
| 19 |
+
2. **Sentiment Classification**: Sequence classification model to determine sentiment (Positive, Negative, Neutral, Conflict) for extracted aspects.
|
| 20 |
+
|
| 21 |
+
Both models are based on `xlm-roberta-base`, fine-tuned using QLoRA, and exported to ONNX for CPU-optimized inference.
|
| 22 |
+
|
| 23 |
+
## Languages Supported
|
| 24 |
+
- English (en)
|
| 25 |
+
- Hindi (hi)
|
| 26 |
+
- Hinglish (code-mixed)
|
| 27 |
+
|
| 28 |
+
## Performance Metrics (Phase 4)
|
| 29 |
+
- **English**: Macro-F1 > 78%
|
| 30 |
+
- **Hindi**: Macro-F1 > 65%
|
| 31 |
+
- **Latency (INT8 CPU)**: P95 < 300ms
|
| 32 |
+
|
| 33 |
+
## Usage
|
| 34 |
+
```python
|
| 35 |
+
from optimum.onnxruntime import ORTModelForTokenClassification, ORTModelForSequenceClassification
|
| 36 |
+
from transformers import AutoTokenizer
|
| 37 |
+
|
| 38 |
+
model_id = "YOUR_HF_USERNAME/multilingual-absa"
|
| 39 |
+
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
| 40 |
+
|
| 41 |
+
# Load Aspect Extraction Model
|
| 42 |
+
aspect_model = ORTModelForTokenClassification.from_pretrained(
|
| 43 |
+
model_id,
|
| 44 |
+
subfolder="aspect_extraction_int8"
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
# Load Sentiment Model
|
| 48 |
+
sentiment_model = ORTModelForSequenceClassification.from_pretrained(
|
| 49 |
+
model_id,
|
| 50 |
+
subfolder="sentiment_int8"
|
| 51 |
+
)
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
## Training Data
|
| 55 |
+
Fine-tuned on combined SemEval (English) and translated/native Hindi product review datasets.
|
reorganize.sh
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -e
|
| 3 |
+
|
| 4 |
+
echo "Starting reorganization..."
|
| 5 |
+
|
| 6 |
+
# 1. API Restructure
|
| 7 |
+
mkdir -p api/app/routes api/app/core api/app/schemas api/app/services api/app/middleware api/app/tasks
|
| 8 |
+
touch api/app/__init__.py api/app/routes/__init__.py api/app/core/__init__.py api/app/schemas/__init__.py api/app/services/__init__.py api/app/middleware/__init__.py api/app/tasks/__init__.py
|
| 9 |
+
|
| 10 |
+
mv api/main.py api/app/ 2>/dev/null || true
|
| 11 |
+
mv api/routes/* api/app/routes/ 2>/dev/null || true
|
| 12 |
+
mv api/models/* api/app/schemas/ 2>/dev/null || true
|
| 13 |
+
mv api/services/* api/app/services/ 2>/dev/null || true
|
| 14 |
+
mv api/middleware/* api/app/middleware/ 2>/dev/null || true
|
| 15 |
+
mv api/tasks/* api/app/tasks/ 2>/dev/null || true
|
| 16 |
+
|
| 17 |
+
# Cleanup empty api dirs
|
| 18 |
+
rm -d api/routes api/models api/services api/middleware api/tasks 2>/dev/null || true
|
| 19 |
+
|
| 20 |
+
# 2. SRC Restructure
|
| 21 |
+
mkdir -p src/absa src/languages/english src/languages/hindi src/languages/hinglish src/models src/utils
|
| 22 |
+
touch src/absa/__init__.py src/languages/__init__.py src/languages/english/__init__.py src/languages/hindi/__init__.py src/languages/hinglish/__init__.py src/models/__init__.py src/utils/__init__.py
|
| 23 |
+
|
| 24 |
+
# Move items in src to their respective folders (will do this manually or cautiously later, right now let's just create the folders)
|
| 25 |
+
# Since I need to check what exists in src/ before moving.
|
| 26 |
+
|
| 27 |
+
# 3. ML Restructure
|
| 28 |
+
mkdir -p ml/experiments ml/notebooks ml/configs ml/training
|
| 29 |
+
mv mlflow ml/experiments/ 2>/dev/null || true
|
| 30 |
+
mv mlruns ml/experiments/ 2>/dev/null || true
|
| 31 |
+
mv notebooks/* ml/notebooks/ 2>/dev/null || true
|
| 32 |
+
rm -d notebooks 2>/dev/null || true
|
| 33 |
+
|
| 34 |
+
# 4. Docs Restructure
|
| 35 |
+
mkdir -p docs/architecture docs/ml docs/api docs/planning docs/guides
|
| 36 |
+
mv .planning/* docs/planning/ 2>/dev/null || true
|
| 37 |
+
rm -d .planning 2>/dev/null || true
|
| 38 |
+
|
| 39 |
+
echo "Reorganization completed."
|
src/absa/__init__.py
ADDED
|
File without changes
|
src/languages/__init__.py
ADDED
|
File without changes
|
src/languages/english/__init__.py
ADDED
|
File without changes
|
src/languages/hindi/__init__.py
ADDED
|
File without changes
|
src/languages/hinglish/__init__.py
ADDED
|
File without changes
|
tests/api/test_api.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
import pytest
|
| 2 |
from fastapi.testclient import TestClient
|
| 3 |
import os
|
| 4 |
-
os.environ["DATABASE_URL"] = "sqlite:///./test.db"
|
| 5 |
import unittest.mock as mock
|
| 6 |
|
| 7 |
-
from api.main import app
|
| 8 |
import json
|
| 9 |
import io
|
| 10 |
|
|
@@ -44,7 +44,7 @@ def test_batch_upload():
|
|
| 44 |
with TestClient(app) as client:
|
| 45 |
csv_content = "text\nThe food was great\nTerrible service"
|
| 46 |
files = {"file": ("test.csv", io.BytesIO(csv_content.encode("utf-8")), "text/csv")}
|
| 47 |
-
with mock.patch("api.routes.predict.process_batch.delay") as mock_delay:
|
| 48 |
response = client.post("/batch", files=files)
|
| 49 |
assert response.status_code == 200
|
| 50 |
data = response.json()
|
|
|
|
| 1 |
import pytest
|
| 2 |
from fastapi.testclient import TestClient
|
| 3 |
import os
|
| 4 |
+
os.environ["DATABASE_URL"] = "sqlite:///./tests/fixtures/test.db"
|
| 5 |
import unittest.mock as mock
|
| 6 |
|
| 7 |
+
from api.app.main import app
|
| 8 |
import json
|
| 9 |
import io
|
| 10 |
|
|
|
|
| 44 |
with TestClient(app) as client:
|
| 45 |
csv_content = "text\nThe food was great\nTerrible service"
|
| 46 |
files = {"file": ("test.csv", io.BytesIO(csv_content.encode("utf-8")), "text/csv")}
|
| 47 |
+
with mock.patch("api.app.routes.predict.process_batch.delay") as mock_delay:
|
| 48 |
response = client.post("/batch", files=files)
|
| 49 |
assert response.status_code == 200
|
| 50 |
data = response.json()
|