Spaces:
Sleeping
Sleeping
File size: 7,115 Bytes
1e3caac 2e552e9 1e3caac 2e552e9 1e3caac 2e552e9 c966ef1 2e552e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | ---
title: PneumoOps
emoji: π«
colorFrom: blue
colorTo: indigo
sdk: docker
app_port: 7860
pinned: true
license: mit
short_description: MLOps A/B testing & drift monitoring
---
# π« PneumoOps
**Continuous MLOps Pipeline with A/B Testing & Data Drift Monitoring for 14-Class Thoracic Disease Detection**
[](https://github.com/Prakhar54-byte/PneumoOps/actions)
[](https://www.python.org/)
[](#)
---
## What This Is
PneumoOps is a production-style MLOps system for **multi-label chest X-ray classification**. It demonstrates real-world deployment challenges:
- **A/B Testing** β every inference request is randomly routed to either *Model A (PyTorch)* or *Model B (ONNX)*, letting you measure real-world latency differences between serving backends.
- **Data Drift Monitoring** β statistical pixel-distribution comparison (KS-test) against the training baseline. When distribution shifts, the system flags `DRIFT_DETECTED` β the trigger for automated retraining in production.
- **Prometheus Observability** β request counters, latency histograms, per-disease prediction rates, and drift alert counters are all scraped at `/metrics`.
- **Dockerized Deployment** β the entire stack runs in containers, deployable to Hugging Face Spaces via a single `git push`.
---
## Architecture
```
Train (ChestMNIST + MobileNetV3-small)
β
βββββββββββ΄βββββββββββ
Model A (.pth) Model B (.onnx)
PyTorch serving ONNX Runtime serving
βββββββββββ¬βββββββββββ
β
βββββββββββββ΄ββββββββββββ
β FastAPI Backend β
β ββ A/B Router (60/40) β
β ββ Drift Monitor (KS) β
β ββ Prometheus /metricsβ
β ββ /health /history β
βββββββββββββ¬ββββββββββββ
β
βββββββββββ΄βββββββββββ
β Gradio UI β
β Top-3 predictions β
β Model arm used β
β Latency (ms) β
β Drift alert badge β
βββββββββββββββββββββββ
```
---
## Dataset & Model
| Property | Value |
|---|---|
| Dataset | [ChestMNIST](https://medmnist.com/) β 14-class multi-label chest X-ray |
| Classes | Atelectasis, Cardiomegaly, Effusion, Infiltration, Mass, Nodule, Pneumonia, Pneumothorax, Consolidation, Edema, Emphysema, Fibrosis, Pleural Thickening, Hernia |
| Model A | MobileNetV3-small (PyTorch `.pth`) |
| Model B | MobileNetV3-small (ONNX Runtime `.onnx`) |
| Training | 5 epochs, AdamW, BCEWithLogitsLoss, per-class threshold tuning |
| Macro AUROC | 0.686 (5-epoch, 5k samples β improves with full dataset) |
---
## Project Structure
```
pneumo_ops/
βββ backend/
β βββ main.py # FastAPI: A/B routing, drift monitor, Prometheus
βββ frontend/
β βββ app.py # Gradio UI: top-3 chart, drift badge, latency
βββ scripts/
β βββ train_chestmnist.py # Training: ChestMNIST β MobileNetV3 β ONNX export
βββ models/
β βββ chestmnist_mobilenetv3/
β βββ mobilenetv3_chestmnist.pth # Model A (PyTorch)
β βββ mobilenetv3_chestmnist.onnx # Model B (ONNX)
β βββ training_metrics.json
β βββ baseline_stats.json # Pixel stats for drift reference
βββ model_utils.py # CalibratedModel + temperature scaling util
βββ Dockerfile # Single-container build
βββ docker-compose.yml # backend + frontend services
βββ requirements.txt
βββ .github/workflows/
βββ deploy.yml # CI (lint/import check) + HF Spaces deploy
```
---
## Quick Start
### 1. Install
```bash
git clone https://github.com/Prakhar54-byte/PneumoOps
cd pneumo_ops
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
```
### 2. Train the model
```bash
# Quick run (5k samples, ~1 min on GPU)
python3 scripts/train_chestmnist.py --epochs 5 --batch-size 32 --max-train-samples 5000
# Full dataset
python3 scripts/train_chestmnist.py --epochs 15 --batch-size 64
```
Outputs saved to `models/chestmnist_mobilenetv3/`:
- `mobilenetv3_chestmnist.pth` β PyTorch checkpoint
- `mobilenetv3_chestmnist.onnx` β ONNX export
- `training_metrics.json` β AUROC, AUPRC, F1, thresholds
- `baseline_stats.json` β pixel reference for drift detection
### 3. Run the backend
```bash
PNEUMOOPS_PROFILE=chestmnist python3 -m uvicorn backend.main:app --port 7860
```
Key endpoints:
| Endpoint | Description |
|---|---|
| `POST /predict` | Run inference (A/B routed) |
| `GET /health` | System status + model metadata |
| `GET /metrics` | Prometheus scrape endpoint |
| `GET /history` | Last 20 requests |
| `GET /metrics/class-rates` | Per-class prediction rates |
| `GET /metrics/calibration` | AUROC / AUPRC / Brier per class |
### 4. Run the UI
```bash
BACKEND_PREDICT_URL=http://127.0.0.1:7860/predict python3 frontend/app.py
```
### 5. Docker (full stack)
```bash
docker compose up --build
# Backend β http://localhost:7860
# Frontend β http://localhost:7861
```
---
## Deployment β Hugging Face Spaces
### Manual push
```bash
# Add HF remote
git remote add space https://huggingface.co/spaces/Prakhar54-byte/PneumoOps
# Push (Spaces will build the Docker image automatically)
git push space main
```
### Automated (GitHub Actions)
Set these repository secrets on GitHub:
| Secret | Description |
|---|---|
| `HF_TOKEN` | Hugging Face access token (write permission) |
| `HF_SPACE_REPO` | e.g. `your-username/pneumoops` |
| `HF_MODEL_REPO` | *(optional)* e.g. `your-username/pneumoops-models` |
Every push to `main` triggers CI checks then deploys to your Space automatically.
---
## Real-World MLOps Challenges Addressed
| Challenge | Solution |
|---|---|
| Model degradation over time | Drift Monitor (KS-test on pixel distribution) |
| Serving latency variance | A/B routing between PyTorch and ONNX, latency tracked per arm |
| Class imbalance (rare diseases) | Per-class threshold tuning on val set + AUPRC tracking |
| Missed diagnoses | Per-class recall monitored at `/metrics/class-rates` |
| Production observability | Prometheus metrics β latency histograms, per-disease counters, drift alerts |
| Automated retraining signals | `DRIFT_DETECTED` flag logged + exposed via Prometheus counter |
---
## Libraries
`PyTorch` Β· `ONNX Runtime` Β· `FastAPI` Β· `Gradio` Β· `Docker` Β· `Hugging Face Hub/Spaces` Β· `scikit-learn` Β· `Prometheus` Β· `MedMNIST` Β· `SciPy`
---
## License
MIT
|