Fitted Model Persistence
Every built-in fitted recommender exposes the same self-contained API:
from compresso_recsys.models import EASE
model = EASE().fit(interactions, item_ids=item_ids)
model.save("artifacts/ease.ckpt")
restored = EASE.load("artifacts/ease.ckpt")
The loaded object is fitted and ready to predict. Checkpoints contain the model configuration, learned state, and the vocabulary, mappings, or candidate catalog needed to interpret its prediction columns. Loading defaults to CPU regardless of the device used during training:
on_cpu = ELSATrainer.load("artifacts/elsa.ckpt")
on_gpu = ELSATrainer.load("artifacts/elsa.ckpt", device="cuda")
A device-backed recommender can also be moved after loading. to updates the
model, its runtime configuration, optional optimizer tensors, and any
device-specific caches, and returns the same recommender:
restored = SimpleGPTTrainer.load("artifacts/gpt.ckpt")
restored.to("cuda")
NumPy-only recommenders such as EASE have no device-backed state and reject
to rather than implying that their computation moved.
Calling load through a different model class, reading an unsupported format
version, or saving an unfitted model raises rather than guessing.
Embedding Models in Data Checkpoints
A model may remain a standalone checkpoint or travel inside an existing data
checkpoint. The convenience methods preserve the same model format under
models/<name>.zip while hiding the outer archive’s temporary workspace:
rnn.save_to_checkpoint(
"artifacts/ml20m/recsys_checkpoint.zip",
"gru",
)
restored = SimpleRNNTrainer.load_from_checkpoint(
"artifacts/ml20m/recsys_checkpoint.zip",
"gru",
device="cuda",
)
name is an extension-free identifier; the example creates
models/gru.zip. Saving the same model type under that name replaces it, but
using an existing name for another model type raises. The outer manifest records
the embedded path, model type, and whether optimizer state is included. The data
checkpoint must already exist, preventing a misspelled path from silently
creating a model-only outer archive.
Embedding is convenient for a self-contained experiment artifact, while a standalone model avoids rewriting a potentially large data checkpoint on every save. Both forms use the same inner model archive and the same device and optimizer options.
Stable Item IDs
Fitted item identities are part of the model checkpoint, so the production interface is unchanged after loading:
before = model.recommend([["item-14", "item-87"]], k=20)
restored = EASE.load("artifacts/ease.ckpt")
after = restored.recommend([["item-14", "item-87"]], k=20)
Checkpoint item IDs use an explicit pickle-free encoding for strings, integers,
finite floats, and booleans. A fixed-catalog model fitted without item_ids
uses positional integer IDs. Cold-start checkpoints preserve both the fitted
source vocabulary and the current mutable candidate catalog.
Optimizer State
Optimizer state is excluded by default because prediction does not need it. A trainer can include and restore it explicitly:
model.save("artifacts/elsa-with-optimizer.ckpt", include_optimizer=True)
restored = ELSATrainer.load(
"artifacts/elsa-with-optimizer.ckpt",
load_optimizer=True,
)
This preserves optimizer continuity for training APIs that can use it. It does
not promise exact training resumption: scheduler, random-number-generator,
data-order, and partial-epoch state are not stored. A model without an optimizer
rejects include_optimizer=True.
Checkpoint Format
Model checkpoints are atomic, versioned ZIP files, separate from dataset
checkpoints. The framework owns their manifest and layout. Configurations and
IDs use explicit JSON-safe encodings, NumPy arrays load with
allow_pickle=False, candidate metadata uses Parquet, sparse matrices use
SciPy .npz, and Torch state is loaded with weights_only=True.
The public reader and writer helpers give third-party model implementations the same typed storage operations without requiring them to invent a manifest or archive convention.
- class compresso_recsys.ModelCheckpointWriter(path, *, model_type, optimizer_included=False)[source]
Build one model checkpoint while owning its manifest and ZIP layout.
- Parameters:
path (str | Path)
model_type (str)
optimizer_included (bool)
- write_json(relpath, value)[source]
Write dataclasses and JSON-safe values without non-finite numbers.
- Return type:
None- Parameters:
relpath (str | Path)
value (Any)
- write_numpy(relpath, value)[source]
Write a non-object NumPy array with pickle disabled.
- Return type:
None- Parameters:
relpath (str | Path)
value (ndarray)
- write_sparse(relpath, value)[source]
Write a CSR matrix in SciPy’s compressed NPZ representation.
- Return type:
None- Parameters:
relpath (str | Path)
value (csr_matrix)
- write_features(relpath, value)[source]
Write dense or CSR features and return their storage discriminator.
- Return type:
str- Parameters:
relpath (str | Path)
value (csr_matrix | ndarray)
- write_dataframe(relpath, value)[source]
Write candidate metadata as Parquet without an index.
- Return type:
None- Parameters:
relpath (str | Path)
value (DataFrame)
- class compresso_recsys.ModelCheckpointReader(path, *, expected_model_type)[source]
Validate and read one fitted-recommender checkpoint.
- Parameters:
path (str | Path)
expected_model_type (str)
- property optimizer_included: bool
Whether the checkpoint manifest advertises optimizer state.
- read_json(relpath)[source]
Read a JSON object.
- Return type:
dict[str,Any]- Parameters:
relpath (str | Path)
- read_json_value(relpath)[source]
Read any JSON value.
- Return type:
Any- Parameters:
relpath (str | Path)
- read_numpy(relpath)[source]
Read a NumPy array with pickle disabled.
- Return type:
ndarray- Parameters:
relpath (str | Path)
- read_sparse(relpath)[source]
Read a SciPy sparse matrix and canonicalize it to CSR.
- Return type:
csr_matrix- Parameters:
relpath (str | Path)
- read_features(relpath, *, storage)[source]
Read features according to a writer-provided storage discriminator.
- Return type:
csr_matrix|ndarray- Parameters:
relpath (str | Path)
storage (str)
- read_dataframe(relpath)[source]
Read Parquet metadata.
- Return type:
DataFrame- Parameters:
relpath (str | Path)
Compiled Torch wrappers and runtime caches are not serialized. Torch models are
stored through their eager state_dict and loaded uncompiled. A direct
nn.Module recommender can use the inherited Torch behavior after declaring
how its JSON configuration reconstructs the module; wrappers add only the
tokenizer, catalog, or other state outside that module.
Extending Persistence
A model base subclass declares a stable checkpoint_type and implements
_from_checkpoint_config so loading can reconstruct its fitted shape. A
dataclass stored as self.cfg supplies the default JSON configuration. For a
recommender that is itself an nn.Module, those pieces are sufficient for
configuration and learned weights; the inherited implementation saves and
strictly reloads its state_dict.
Trainer wrappers return their nested module from _checkpoint_module.
Non-Torch learned state belongs in _save_checkpoint_state and
_load_checkpoint_state, using ModelCheckpointWriter and
ModelCheckpointReader. A trainer that supports optional optimizer
restoration also implements _build_checkpoint_optimizer. Derived caches and
other runtime-only state are rebuilt in _finish_checkpoint_load.
Warm Catalog Adapters
compresso_recsys.models.WarmCatalogAdapter is a projection onto a
particular evaluation-stage catalog rather than learned model state. Save its
nested fitted model and rebuild the adapter from the dataset checkpoint:
model.save("artifacts/rnn.ckpt")
restored = SimpleRNNTrainer.load("artifacts/rnn.ckpt")
restored = WarmCatalogAdapter(
restored,
train_item_ids=split["train_item_ids"],
catalog_item_ids=split["test_item_ids"],
)