Skip to content
C.W.K.
Stream
Lesson 03 of 05 · published

Pipeline Artifact

~26 min · artifact, serialization, deployment

Level 0Scout
0 XP0/48 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

The deployable unit is not one model file

An estimator alone does not know how raw fields become its matrix. Package the complete prediction path and an explicit input-output contract so a clean serving environment can score representative raw rows without notebook state or reconstructed glue.

Bundle pipeline and schema

Include fitted feature selection, encoders, imputers, scalers, and estimator in required order. Record names, types, units, required fields, categories, null behavior, feature order, class meanings, and output shape.

Preserve the lineage needed to reproduce a result

Record artifact version and checksum, code revision, environment and library versions, data snapshot, training time, parameters, calibration mapping, threshold, and the validation evidence that selected them. Publish binary and metadata as one immutable release.

Joblib is convenient but environment-bound

joblib is common for scikit-learn, but pickle-compatible files can execute code when loaded and may depend on library versions. Never load them from an untrusted source; verify provenance and checksum and use a pinned compatible runtime.

ONNX can bridge serving runtimes

ONNX supports cross-language execution for compatible operators, but conversion is not proof of equivalence. Run numerical parity fixtures across representative and edge-case inputs and document unsupported transformations.

Keep native booster formats too

LightGBM, XGBoost, and CatBoost provide stable native formats that preserve library-specific behavior and are easier to inspect than a generic Python pickle. Save feature order, class order, and best iteration alongside them.

Round-trip the saved artifact in a fresh process

Load the exact released bytes and score golden fixtures covering normal rows, missing values, unseen categories, and invalid input. Compare with pre-save predictions within tolerance, then test cold start, memory, concurrency, and corrupted-artifact failure behavior.

Promote and roll back immutable releases

Expose active artifact identity and attach it to prediction logs so outcomes can be joined later. Keep the previous known-good release and rehearse rollback. If a metric cannot be traced to the exact bytes that produced it, the artifact contract is incomplete.

Code

Save the pipeline plus its metadata·python
import json, joblib, hashlib, datetime

joblib.dump(pipe, "artifacts/churn_v1.joblib")
metadata = {
    "version": "churn_v1",
    "trained_at": datetime.datetime.utcnow().isoformat(),
    "git_commit": git_sha,
    "data_hash": hashlib.md5(open("data/processed/train.parquet", "rb").read()).hexdigest(),
    "features": list(X_train.columns),
    "threshold": 0.42,
    "pr_auc_train": float(pr_auc_train),
}
with open("artifacts/churn_v1.json", "w") as f:
    json.dump(metadata, f, indent=2)
Load and validate before serving·python
import joblib, json
import pandas as pd

pipe = joblib.load("artifacts/churn_v1.joblib")
meta = json.load(open("artifacts/churn_v1.json"))

def predict(raw_row: dict) -> dict:
    X = pd.DataFrame([raw_row])
    missing = set(meta["features"]) - set(X.columns)
    assert not missing, f"missing features: {missing}"
    p = pipe.predict_proba(X[meta["features"]])[0, 1]
    return {"prob": float(p), "label": int(p >= meta["threshold"]), "version": meta["version"]}

External links

Exercise

Save your trained pipeline as a joblib artifact plus a metadata JSON. From a fresh shell, write a 20-line script that loads both and serves predictions for a raw row. Verify the prediction matches the training notebook.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.