Spaces:
Sleeping
Sleeping
metadata
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
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 β 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
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
# 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 checkpointmobilenetv3_chestmnist.onnxβ ONNX exporttraining_metrics.jsonβ AUROC, AUPRC, F1, thresholdsbaseline_stats.jsonβ pixel reference for drift detection
3. Run the backend
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
BACKEND_PREDICT_URL=http://127.0.0.1:7860/predict python3 frontend/app.py
5. Docker (full stack)
docker compose up --build
# Backend β http://localhost:7860
# Frontend β http://localhost:7861
Deployment β Hugging Face Spaces
Manual push
# 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