Model Deployment & MLOps — basics
for placement interviews · goal: be able to say "yes, here's exactly how I deployed it" and back it up
01 Model serialization
saving a trained model to disk so it can be loaded later without retraining
- pickle — python's built-in object serializer. works for almost any python object (sklearn models, custom classes)
- joblib — built for objects with big numpy arrays (like sklearn models). faster + smaller files than pickle for these
- rule of thumb interviewers like: "sklearn → joblib, anything generic/custom → pickle, deep learning → framework-native (torch.save / model.save for keras)"
gotchas to mention
- pickle files are not secure — never unpickle untrusted files (arbitrary code exec risk)
- version mismatch — model pickled with sklearn 1.3 may break on 1.5. pin your library versions
- not cross-language — a python pickle can't be loaded in Java/Go directly
quick code
joblib.dump(model, "model.pkl")
model = joblib.load("model.pkl")
- same idea with
pickle.dump() / pickle.load()
02 Wrapping the model as a REST API
the model file alone is useless — an app needs a way to send input, get a prediction back. that's the API's job
client sends JSON
→
API loads model once at startup
→
preprocess input
→
model.predict()
→
return JSON response
Flask
simple, minimal, huge community. no built-in input validation — you check types yourself. sync by default.
FastAPI (preferred today)
built-in request validation via pydantic, auto-generates Swagger docs at /docs, native async support → better for real-world serving
# app.py
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
app = FastAPI()
model = joblib.load("model.pkl") # loaded ONCE at startup, not per request
class InputData(BaseModel):
feature1: float
feature2: float
@app.post("/predict")
def predict(data: InputData):
x = [[data.feature1, data.feature2]]
prediction = model.predict(x)
return {"prediction": prediction.tolist()[0]}
# run: uvicorn app:app --reload --port 8000
interview line: "I load the model once at app startup, not inside the endpoint — reloading per request kills latency."
03 Docker — why, not syntax
the problem it solves: "works on my machine"
- a container packages code + model file + exact library versions + OS-level deps into one image
- that image runs identically on your laptop, a teammate's laptop, or a cloud server — no "but I have numpy 1.21 and prod has 1.26" bugs
- lightweight vs a VM — containers share the host OS kernel, so they start in seconds and use way less resources
- makes the app portable: build once, ship the image anywhere (AWS, GCP, on-prem)
Dockerfile (recipe)
→
docker build → image
→
docker run → container
→
same behavior everywhere
interview line: "Docker isn't about the model itself — it's about guaranteeing the serving environment is reproducible."
04 CI/CD pipeline for ML
same spirit as software CI/CD, but with data + model versions added to the mix
push code
→
run tests / lint
→
build docker image
→
(re)train / validate model
→
check metrics vs threshold
→
deploy if it passes
- CI (continuous integration): every code change is auto-tested — unit tests on preprocessing code, API tests, model sanity checks (e.g. accuracy above a floor)
- CD (continuous deployment): if checks pass, the new docker image is automatically pushed to staging/production
- ML-specific twist: also version datasets and models (tools like DVC / MLflow get mentioned here) so you can trace "which data + code produced this exact model"
- common toolchain to name-drop: GitHub Actions / Jenkins for the pipeline, MLflow for experiment + model tracking
05 Model monitoring & drift
deploying isn't the finish line — a model's accuracy decays silently over time in production
data drift
the input distribution changes. e.g. a fraud model trained on pre-pandemic spending patterns sees very different transaction patterns post-pandemic. features shift even though the relationship to the label hasn't.
concept drift
the relationship between input and output changes. e.g. what counted as "spam" 5 years ago looks different today — same features, different meaning/label mapping.
- why it matters: a model that was 92% accurate at launch can quietly drop to 70% with nobody noticing — until it shows up as a business problem
- what's monitored in practice: prediction distribution, input feature distribution, latency, error rates, and — where ground truth arrives later (e.g. did the loan actually default) — real accuracy over time
- typical response: alert → investigate → retrain on fresh data → redeploy through the same CI/CD pipeline
interview line: "monitoring is what turns deployment from a one-time event into a loop — retrain, redeploy, remonitor."
06 Cloud deployment — conceptual view
you don't need deep config knowledge — just the shape of what managed ML platforms give you
AWS SageMaker
train, host, and monitor models without managing servers yourself. gives you a hosted endpoint URL you call for predictions, plus built-in autoscaling and a model registry.
GCP Vertex AI
google's equivalent — unifies training, a model registry, one-click deployment to an endpoint, and drift/monitoring dashboards out of the box.
- the core idea both share: you upload your docker image / model artifact → the platform handles scaling, load balancing, uptime → you just hit an endpoint
- this replaces "I manually run a Flask server on an EC2 box" with something that autoscales and is production-hardened
if they ask: "have you deployed a model?"
answer with the real pipeline, not just "yes":
trained & saved model with joblib → wrapped it in a FastAPI /predict endpoint → containerized it with Docker so the environment is reproducible → pushed through a simple CI/CD pipeline (tests → build → deploy) → for production, would put it behind a managed endpoint like SageMaker/Vertex AI → and set up basic monitoring to catch drift so it doesn't silently degrade.
saying this flow out loud, even for a small side project, beats vague theory every time.