In this guide
Your model hits 92% in the notebook. Then the demo needs it running on a server, the data changes next month, and nobody — including you — can reproduce that 92% anymore. The gap between "model works in a notebook" and "system works in the real world" is what MLOps covers: the practices and tooling for deploying, monitoring, and maintaining ML systems.
This guide is MLOps distilled to what a student project actually needs: reproducible training, packaged deployment, basic monitoring, and a retraining story. Not the enterprise platform — the 20% that prevents 80% of project failures.
What MLOps actually is (beyond the buzzword)
MLOps = the engineering discipline of running ML systems reliably. Concretely, it answers four questions:
- Can you reproduce that result? (Versioned code, data, parameters, environment.)
- Can you deploy the model? (Packaged artifact, serving infrastructure.)
- Do you know when it breaks? (Monitoring predictions and inputs in production.)
- Can you update it? (Retraining pipeline when data or the world changes.)
A student project needs a credible answer to all four — scaled down, not skipped.
Note: MLOps is not a tool you install. It is a set of habits plus a few tools. A project with git, a requirements file, MLflow, and a Docker container has more MLOps than most enterprise slide decks.
Pillar 1: reproducibility
Everything downstream depends on this. The checklist:
- Training code in git (not just a notebook — a runnable script)
- Dependencies pinned (
pip freeze > requirements.txt) - Random seeds fixed and logged
- Dataset versioned (folder versions + a changelog README at minimum)
- Hyperparameters in a config file, logged per run
- Experiments tracked (MLflow)
The test: hand your repo to a teammate with a fresh machine. If they cannot reproduce your headline number by following the README, you are not done.
Pillar 2: packaging and deployment
A model file is not a deployable unit. The deployable unit is model + preprocessing + dependencies + API, packaged together. For student projects, that means a Docker container serving predictions over HTTP:
project/
├── app.py # FastAPI: loads model, exposes /predict
├── model.onnx # the artifact (see the ONNX guide)
├── requirements.txt # pinned dependencies
├── Dockerfile # reproducible environment
└── README.md # how to build and run
A minimal serving endpoint:
from fastapi import FastAPI
import onnxruntime as ort
app = FastAPI()
sess = ort.InferenceSession("model.onnx")
@app.post("/predict")
async def predict(payload: dict):
x = preprocess(payload["input"]) # SAME preprocessing as training
out = sess.run(None, {"input": x})[0]
return {"prediction": postprocess(out)}
The line that kills most deployments is the preprocessing one: training-serving skew — the deployed pipeline preprocesses inputs differently than training did (different resize, different normalization, different tokenizer settings). The fix is structural: one shared preprocessing function imported by both training and serving code. Never two copies.
For packaging details, see Docker for student projects and deploying ML models.
Pillar 3: monitoring (the one everyone skips)
Deployed models fail silently. Accuracy does not announce its own decay. Monitor what you can:
| What to monitor | How (student-scale) | What it catches |
|---|---|---|
| Prediction distribution | Log predictions; plot class ratios daily | Data drift, upstream breakage |
| Input statistics | Log feature means/ranges | Sensor changes, format changes |
| Confidence scores | Track average confidence | Model encountering unfamiliar inputs |
| Latency | Log inference time per request | Performance regression |
| Error rate | Count exceptions and low-confidence fallbacks | Outright breakage |
You do not need a monitoring platform: log predictions and inputs to a file or tiny database, and review a weekly summary (even a script that emails you histograms). The habit matters more than the tooling.
Data drift deserves emphasis: the world changes (new camera, new season, new user behavior) and the model's training distribution stops matching reality. Monitoring input statistics is how you notice before users do.
Pillar 4: retraining story
Every project report should answer: "what happens when the model needs updating?" Your answer needs three parts:
- Trigger: what tells you retraining is needed? (Monitoring alert, calendar schedule, new labeled data arriving.)
- Pipeline: one command that retrains on current data and produces a versioned artifact. (
python train.py --data data/v3→model-v3.onnx, logged in MLflow.) - Rollout: how the new model replaces the old one. At student scale: keep the previous artifact, deploy the new one, compare on a validation set, roll back if worse. Even this simple discipline beats "overwrite model.pkl and hope."
You do not need automated retraining pipelines. You need a retraining procedure that a human can run reliably.
CI for ML: the lightweight version
Continuous integration for ML projects means automated checks on every code change:
- Unit tests for preprocessing and postprocessing functions (the skew-prone code).
- A smoke test that loads the model artifact and runs one prediction — catches broken artifacts immediately.
- A data validation check on new datasets (expected columns, value ranges, no empty files).
- A tiny training smoke test (one epoch on a data subset) to catch broken training code before a full run.
GitHub Actions runs all of this free for student repos. The smoke test alone — "does the model load and predict" — catches an embarrassing fraction of demo-day failures.
The minimal MLOps stack for a final-year project
| Need | Tool | Effort |
|---|---|---|
| Version control | git + GitHub | You already have this |
| Experiment tracking | MLflow | An afternoon |
| Packaging | Docker | A day to learn properly |
| Serving | FastAPI + ONNX Runtime | An afternoon |
| CI smoke tests | GitHub Actions | An afternoon |
| Monitoring | Structured logging + weekly review script | An afternoon |
Roughly one focused week takes a notebook project to a defensible, deployable system. That week is the difference between "I trained a model" and "I built an ML system" — and examiners notice.
Common mistakes
- Notebooks as the deployment artifact. Notebooks are for exploration; deployment runs scripts and containers.
- Training-serving skew. Two copies of preprocessing that drift apart. One shared function, imported by both.
- No rollback plan. The new model is worse and the old file is overwritten. Version every artifact.
- Monitoring nothing. The model degrades for weeks; nobody knows.
- Over-engineering. Kubernetes, feature stores, and Kubeflow for a class project is resume-driven development. Docker + FastAPI + logs is enough.
- Secrets in the repo. API keys committed to git. Use environment variables; check git history before submitting.
Where to go from here
Build the foundations first: MLflow experiment tracking, Docker for student projects, and ONNX model conversion. For the serving layer, the ML deployment guide goes deeper. When your system serves predictions to users, A/B testing ML models covers safe rollout comparisons. More production-ML topics in the AI & Machine Learning branch hub.