# End-to-End ML Engineering: CI/CD, Docker, MLflow, FastAPI * I designed and implemented a full-stack machine learning system for computer vision, integrating CI/CD pipelines, Docker containerization, MLflow experiment tracking, and FastAPI service deployment. The project demonstrates reproducible workflows, automated testing, and scalable deployment — transforming ML models into production-ready services. * I don’t just build models — I build systems that make models usable, reproducible, and deployable. * This project shows I can take a model from research to production, with all the engineering rigor clients need. # :key: Highlights ✅ CI/CD: Automated testing and release pipelines with GitHub Actions. ✅ Docker: Lean runtime images + dev tooling split for reproducibility. ✅ MLflow: Experiment tracking, artifact logging, and reproducible runs. ✅ FastAPI: REST API exposing inference endpoints with Swagger docs. ✅ Testing Suite: Unit, integration, and registry consistency checks. # :desktop_computer: Visuals to Include Architecture diagram (Mermaid or exported PNG). Screenshot of Swagger UI (/docs). MLflow dashboard screenshot (metrics/artifacts). CI/CD pipeline run screenshot (GitHub Actions green check). These visuals make the project tangible for non-technical clients. # :rocket: Quickstart ```bash= # 1. Prepare dataset (VOC → YOLO-seg) make data # 2. Start Docker services (app + MLflow) make up make mlflow-up # 3. Run inference with MLflow tracking make track-infer # 4. Benchmark performance make bench # 5. Log dataset snapshot into MLflow make snapshot ``` * Browse MLflow UI at http://localhost:5000 for metrics, configs, and artifacts. * Push to main → CI automatically bumps patch version, tags repo, and publishes release artifacts (wheel + Docker image). # :file_folder: Folder Structure Root ├── configs/ # YAML configs for data, inference, and models │ ├──data.yaml # Dataset splits + class list │ ├──inference.yaml # Runtime + postprocess settings │ └──model.yaml # Default model definition ├── docker/ # Dockerfiles + compose configs │ ├──app.Dockerfile # Application container │ ├──mlflow.Dockerfile # MLflow tracking server │ └──compose.yaml # Docker Compose services ├── models/ │ ├──artifacts/ # Trained weights organized by model + version │ └──yolo-ultra/1.0.0/best.pt │ └──registry.json # Local model registry (semantic versioned) ├── scripts/ # Utility scripts │ ├──prepare_data.py # Convert raw VOC → YOLO-seg format │ ├── benchmark_inference.py # Benchmark latency/throughput/IoU │ ├── train.py # Training wrapper if needed │ └──demo.sh # End-to-end demo workflow ├── src/ │ └──ydd/ # Core library │ ├── models/ # Model adapters (YOLOUltralytics, etc.) │ ├── pipeline/ # Inference runner │ └──tracking/ # MLflow client ├── Makefile # Common commands (data, bench, track-infer, snapshot) └──README.md # Documentation ## :heavy_plus_sign: Adding a New Model ### Place weights Put your trained weights in: ```bash models/artifacts/<model-name>/<version>/best.pt ``` Example: ```python models/artifacts/yolo-large/1.0.0/best.pt ``` ### Update registry Add an entry in models/registry.json: ```json "yolo-large": { "1.0.0": { "weights_path": "models/artifacts/yolo-large/1.0.0/best.pt", "format": "pt", "task": "segment", "classes": ["good","LID","Silver_Line","Scratch","internal","background"], "notes": "YOLOv8l baseline trained on oscillator defects", "input_size": [640, 640], "conf_threshold": 0.25, "iou_threshold": 0.45 } } ``` ### Update configs Edit configs/model.yaml to include the new model: ```json models: - name: "yolo-ultra" version: "1.0.0" type: "ultralytics" weights_path: "models/artifacts/yolo-ultra/1.0.0/best.pt" ... - name: "yolo-large" version: "1.0.0" type: "ultralytics" weights_path: "models/artifacts/yolo-large/1.0.0/best.pt" ... ``` ## :label: Releasing a New Version to GitHub ### Bump version Use CLI or Makefile: ```bash make bump-patch # 1.0.0 → 1.0.1 make bump-minor # 1.0.0 → 1.1.0 make bump-major # 1.0.0 → 2.0.0 ``` This updates both models/registry.json and configs/model.yaml. ### Push to GitHub Commit and push changes: ```bash= git add models/registry.json configs/model.yaml git commit -m "feat: bump YOLO Ultra to 1.0.1" git push origin main ``` ### CI/CD automation #### GitHub Actions will * Run tests + lint. * Bump patch version automatically on successful builds. * Tag repo (vX.Y.Z). * Publish GitHub Release with artifacts (wheel + Docker tarball). ## :whale: Deploying with Docker ### Build images ```bash= docker compose -f docker/compose.yaml build ``` ### Start services ```bash= docker compose -f docker/compose.yaml up -d ``` This launches: * App container (inference pipeline). * MLflow server (metrics + artifacts at http://localhost:5000). ### Run inference ```bash= make track-infer ``` Logs metrics, predictions, configs, and dataset snapshots into MLflow. ### Stop service ```bash= docker compose -f docker/compose.yaml down ``` ```mermaid flowchart TD A["User Input Images"] --> B["YOLO Adapter"] B --> C["Inference Runner"] C --> D["Postprocessing"] D --> E["Outputs (JSON, Visuals, Metrics)"] E --> F["MLflow Tracking"] ``` ```mermaid sequenceDiagram participant U as User participant I as Input Images participant M as Model Adapter (YOLOUltralytics) participant R as Inference Runner participant P as Postprocessing participant O as Outputs participant L as MLflow Tracking U->>I: Provide test/val images I->>M: Load model weights (best.pt) M->>R: Run predictions R->>P: Apply thresholds (conf, IoU) P->>O: Format masks, generate JSON + visuals O->>L: Log metrics, configs, dataset snapshot, artifacts L-->>U: Results available in MLflow UI ```