What a Model Version Actually Contains
Why weights alone are not a deployable model, the full set of artefacts that must move together, and the coupling failures that occur when one of them is versioned separately.
A model version that contains only weights is a version of one component of a system whose behaviour depends on several. When the others change independently, the deployed behaviour changes without the model version changing, and every downstream assumption about what version 7 does becomes unreliable.
The bundle
Weights, in a specified format, with the framework version that can load them.
Architecture or graph definition, whether as code, a serialised graph, or an exported format. Weights without the architecture that consumes them are a tensor archive.
Preprocessing. Tokeniser, vocabulary, scalers, encoders and their fitted state. This is the component most often versioned separately and the one whose drift causes the most confusing failures, because a mismatched tokeniser produces plausible output rather than an error.
Postprocessing. Decision thresholds, label mappings, calibration parameters. A classifier's threshold is part of its behaviour, and moving it changes the model's decisions without touching a weight.
Signature. Input and output schema with types and shapes, so a caller can be validated against the model rather than discovering a mismatch at runtime.
Metadata. Training run reference, evaluation results, intended use, known limitations, and the dependencies needed to serve it.
For an LLM-based system the bundle extends further: the prompt template, the tool definitions, the retrieval configuration and the generation parameters are all part of what determines behaviour, and versioning the model without them is versioning the least frequently changed component.
Why the bundle must move as a unit
The reason is a coupling argument. Preprocessing, weights and postprocessing were fitted together on one data distribution; each is only correct in the presence of the others. Deploying a new tokeniser with old weights, or new weights with an old threshold, produces a system that was never evaluated.
The failure is silent in both directions. A mismatched scaler produces inputs in the wrong range and outputs that are wrong rather than absent. A stale threshold produces a well-calibrated model making badly calibrated decisions. Neither raises an exception, and both are found by monitoring the output distribution rather than by any deployment check.
When it breaks
Serialisation formats carry code. Pickled Python objects execute on load, which makes them both a security risk and a compatibility hazard, since the class definitions must be importable at the same paths. Formats that are pure data, or that specify their own execution semantics, avoid both problems and constrain what can be expressed.
Large models make bundling awkward. A hundred-gigabyte checkpoint is not something to copy per deployment. Content-addressed storage with references, so a bundle names its weights rather than containing them, is the practical arrangement, and it requires the weights to be genuinely immutable at that address.
Prompt and configuration changes bypass the version. A team versions the model carefully and edits the system prompt in a configuration file. Behaviour changes, the version does not, and the change is not attributable. Treating every input to behaviour as part of the version is the fix and requires deciding that a prompt edit is a release.
Framework upgrades break old versions. A model saved two years ago may not load in the current library. Long-term availability means either keeping the loading environment as a container image or exporting to a stable interchange format at save time, and the second is cheaper if done from the start.
12 flashcards for this concept
Click a card to reveal the answer.