Packaging and Serialising Model Artefacts
What actually needs to be saved when a trained model is moved from a research notebook into production — far more than just the learned weights — and the common ways a saved model quietly stops matching what was trained.
Prerequisites: Immutable Training-Set Snapshots
Training finishes, the model looks good, and someone saves it with a single line of code — model.save("model.pkl") — and moves on. Weeks later, the production system loads that file and produces predictions that don't match what the research notebook showed. Usually the model's weights were saved correctly; what's missing is everything around the weights that turns a bag of numbers back into a working prediction pipeline.
The idea: a model is more than its weights
The learned parameters — the numbers a neural network or gradient-boosted tree adjusted during training — are necessary but nowhere near sufficient to reproduce a prediction. A usable model artefact also needs: the exact preprocessing applied to raw features (a scaler's fitted mean and standard deviation, a category-to-integer mapping learned from training data — not recomputed fresh at inference); the exact list and order of expected input features; the library version trained with (a model saved by one library version can misbehave in another); and metadata identifying the training-data snapshot and code version that produced it.
Miss any one of these and the model can load without error and still produce wrong answers — silently, because nothing crashes. A scaler refit on today's data instead of loaded from training time will center features around today's mean instead of the training mean, shifting every prediction in a way that looks like reasonable output rather than an obvious bug.
Worked example: a silent packaging bug
A model was trained on features standardized with a scaler fit on the training set, where feature had mean 50 and standard deviation 10. The team saves the weights but not the fitted scaler, reasoning "we'll just refit one in production." Months later, feature 's live distribution has drifted to mean 65, and production code refits a new scaler on live data, standardizing around 65 instead of 50.
A raw input of 70 gets standardized to using the training scaler the model actually learned from, but to using the wrongly refit one. The model receives 0.5 where it expects something like 2.0 — a completely different input from its point of view — producing a degraded prediction with no error anywhere, because standardization "succeeded," just against the wrong reference statistics.
Treat that curve as illustrating how quickly small preprocessing mismatches compound: a modest shift in the assumed mean or scale doesn't produce a proportionally modest prediction error — it can distort the input the model sees enough to move predictions well outside the model's trained range.
What this means in practice
The safe default is packaging fitted preprocessing objects together with model weights in a single artefact — a scaler, an encoder, and a model saved as one versioned bundle, rather than separate pieces an engineer has to keep in sync by hand. Recording the library version and data-snapshot reference alongside it turns "why doesn't this match the notebook" from a multi-day investigation into a quick metadata check.
A production-ready model artefact bundles the learned weights together with every piece of fitted preprocessing (scalers, encoders, expected feature order) and version metadata — saving weights alone and reconstructing the rest by hand is exactly how a model quietly stops matching what was trained, without ever raising an error.
Refitting a preprocessing step (a scaler, an encoder) fresh in production instead of loading the exact one fitted during training is a common and completely silent bug — the pipeline runs without error, but the model receives inputs standardized against the wrong reference statistics, producing degraded predictions that look like ordinary model drift rather than a packaging mistake.
Related concepts
Practice in interviews
Further reading
- PyTorch documentation, Saving and Loading Models
- scikit-learn documentation, Model persistence