Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

artefact
A saved file a release needs, such as the model, the code that prepares its inputs or the exact package versions.
batch
A run that scores many rows at once on a schedule and writes the results to a table.
canary
A release shown to a small random slice of traffic first, so a bad model reaches few users.
drift
A change in the inputs a model sees, or in the link between those inputs and the outcome it predicts.
evaluation gate
A check before release that stops a model when its measured quality falls below a set bar.
feature contract
An agreed promise about one input column — its type, range, missing values, uniqueness, freshness and owner — checked as data arrives.
incident
An event that degrades a service beyond its agreed level and needs a coordinated response.
inference contract
The agreed inputs, outputs and error cases for a model's prediction service, written down and tested.
latency budget
The time a request may spend in the model path, after network and rendering are subtracted from what users will tolerate.
model card
A short document describing what a model is for, how it was trained, its limits and who owns it.
monitoring
Watching inputs, outputs, service health and later outcomes so a change is noticed before users report it.
rollback
Returning to the last known good version, using a saved copy and a command that has been rehearsed.
serving
Running a model to answer requests in production, either one at a time or in scheduled groups.
training-serving skew
When an input is computed one way for model fitting and another way at request time, so the model reads different data.

MLOps from the ground up

CI for models

CI for a model is more than unit tests: data checks, a training smoke test, an evaluation gate and an artefact that can be deployed.

Part 7 of 10

Intermediate17 min readBack to Courses

What CI must catch

Broken code, broken data, a training run that no longer converges, a metric below the floor, a slice that regressed, an artefact that cannot load. Each is a different test with a different runtime. A pipeline that only runs the unit tests catches the first and ships the rest.

The order matters. Cheap checks run first: lint, types, schema and a tiny training smoke test. Expensive checks run later: the full evaluation, the slice report and the artefact build. A failure early should stop the pipeline before it spends twenty minutes on a model that cannot import.

The test pyramid still applies, with one extra layer. Unit tests cover transformations; integration tests cover the pipeline from raw row to prediction; evaluation tests cover the model’s behaviour on a fixture; and a deployment test loads the artefact the way production will. Each layer should be fast enough to run on every change, or it will be skipped.

Fixtures and seeds

Keep a tiny golden dataset in the repository. Train on it with a fixed seed and assert that two runs agree. A smoke test that takes seconds catches the import error, the shape bug and the non-determinism that a full training run would hide for an hour.

Determinism is a testable property, not a hope. Fix the seed, the data order and the library flags that control threading. If the result still moves, the test has found a real source of irreproducibility, which is exactly what it is for.

A fixture should be small, readable and adversarial. Include the missing value, the unseen category and the row that used to crash the parser. A fixture made only of happy rows tests the plumbing and none of the behaviour that incidents are made of.

A parametrised metric test

import pytest

@pytest.mark.parametrize("threshold", [0.3, 0.5, 0.7])
def test_recall_floor(threshold):
    predictions = model.predict(fixture, threshold=threshold)
    assert recall(labels, predictions) >= 0.6

A gate that says no

Run the report and find every failed gate. Then lower the recall floor to 0.58 and confirm the model is still blocked by the latency and slice checks.

Output
Click "Run" to execute your code

Evaluation gates

A gate is a threshold with an owner. Compare against the current production model on the same split, not against last week’s number. Gate on the headline metric and on the slices that matter; a model that improves the mean and breaks a segment is not a release.

The gate should also cover cost and latency. A model that is two points better and three times slower may be a worse product. Put the budget in the pipeline next to the accuracy, so the trade is visible before the release rather than after the incident.

Gates need a margin. If the candidate is within noise of production, a strict “must be better” rule blocks every release and a loose one ships regressions. Set the margin from the variance you measured across seeds, and treat a result inside the margin as a tie rather than a win. A gate that has never blocked a release is either perfectly calibrated or not being read.

Keep the golden fixture small enough to read. A test dataset nobody can inspect is a test whose failures nobody can explain.

From CI to CD

The pipeline builds the artefact once, tags it with the commit and the data snapshot, and promotes the same artefact through staging and production. The release decision is a gate, not a rebuild. If staging and production build separately, the thing you tested is not the thing you shipped.

Continuous delivery for a model also needs a rollback path, a canary and a monitoring check after promotion. Those belong in the same pipeline, not in a runbook that is opened only when something is already wrong.

Retain the artefacts and the reports. Disk is cheaper than an investigation, and the ability to reload the model from three releases ago is what makes a rollback a pointer change. Prune on a schedule, not on a hunch, and keep the last known good bundle forever. Keep the evaluation report next to the artefact; a metric without its report is a rumour.

Train twice, compare

Run the smoke test, then change EPOCHS and confirm the fingerprint changes. A smoke test that never fails is not testing anything.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

What should run first in a model CI pipeline?