Skip to content

API: Persistence

Fiducio saves a single torch.save payload containing format metadata, the Fiducio version, a stable calibrator id, the constructor configuration and the learned state. Loading resolves the id through an internal controlled registry and never imports an arbitrary module path stored in the file. By default files are read with weights_only=True and onto CPU.

Warning

Only load calibrator files from sources you trust. See the project security policy.

save_calibrator

save_calibrator(calibrator: Any, path: PathLike) -> None

Serialize calibrator to path.

Parameters:

Name Type Description Default
calibrator Any

A fitted (or at least constructed) :class:fiducio.Calibrator.

required
path PathLike

Destination file. The .pt extension is conventional.

required
Source code in src/fiducio/persistence.py
def save_calibrator(calibrator: Any, path: PathLike) -> None:
    """Serialize ``calibrator`` to ``path``.

    Parameters
    ----------
    calibrator:
        A fitted (or at least constructed) :class:`fiducio.Calibrator`.
    path:
        Destination file. The ``.pt`` extension is conventional.
    """
    if not getattr(calibrator, "calibrator_id", ""):
        raise ValueError(
            f"{type(calibrator).__name__} has no registered calibrator_id and "
            "cannot be saved"
        )
    directory = os.path.dirname(os.fspath(path))
    if directory:
        os.makedirs(directory, exist_ok=True)

    payload: dict[str, Any] = {
        "format": FORMAT_NAME,
        "format_version": FORMAT_VERSION,
        "fiducio_version": _fiducio_version(),
        "calibrator_id": calibrator.calibrator_id,
        "config": calibrator.get_config(),
        "num_classes": calibrator.num_classes,
        "fitted": calibrator.is_fitted,
        "state": _to_cpu(calibrator._get_state()),
    }
    torch.save(payload, os.fspath(path))

load_calibrator

load_calibrator(path: PathLike, map_location: MapLocation | None = 'cpu') -> Any

Load a calibrator previously written by :func:save_calibrator.

Parameters:

Name Type Description Default
path PathLike

File to load.

required
map_location MapLocation | None

Device for the loaded tensors and the reconstructed calibrator. Defaults to "cpu"; the device saved on the original calibrator is not forced. Pass "cuda" to load onto a GPU.

'cpu'
Notes

The payload is read exclusively with weights_only=True, which restricts deserialization to tensors and basic Python types. Only load files you trust.

Source code in src/fiducio/persistence.py
def load_calibrator(
    path: PathLike,
    map_location: MapLocation | None = "cpu",
) -> Any:
    """Load a calibrator previously written by :func:`save_calibrator`.

    Parameters
    ----------
    path:
        File to load.
    map_location:
        Device for the loaded tensors and the reconstructed calibrator. Defaults
        to ``"cpu"``; the device saved on the original calibrator is **not**
        forced. Pass ``"cuda"`` to load onto a GPU.

    Notes
    -----
    The payload is read exclusively with ``weights_only=True``, which restricts
    deserialization to tensors and basic Python types. Only load files you trust.
    """
    if not os.path.exists(path):
        raise FileNotFoundError(f"calibrator file not found: {path}")

    location: MapLocation = "cpu" if map_location is None else map_location
    payload = torch.load(os.fspath(path), map_location=location, weights_only=True)

    if not isinstance(payload, dict) or payload.get("format") != FORMAT_NAME:
        raise ValueError(f"{path} is not a Fiducio calibrator file")

    if type(payload.get("format_version")) is not int or payload["format_version"] != FORMAT_VERSION:
        raise ValueError("unsupported or missing Fiducio format_version")
    required = {"fiducio_version", "calibrator_id", "config", "num_classes", "fitted", "state"}
    if not required <= payload.keys():
        raise ValueError("missing required Fiducio payload fields")
    if not isinstance(payload["calibrator_id"], str) or not isinstance(payload["fiducio_version"], str):
        raise ValueError("invalid calibrator id or package version")
    if not isinstance(payload["config"], dict) or not isinstance(payload["state"], dict):
        raise ValueError("config and state must be dictionaries")
    fitted, classes = payload["fitted"], payload["num_classes"]
    if type(fitted) is not bool or (fitted and (type(classes) is not int or classes < 2)):
        raise ValueError("invalid fitted status or number of classes")
    if not fitted and classes is not None:
        raise ValueError("an unfitted calibrator must have num_classes=None")

    saved_version = payload.get("fiducio_version")
    saved_major, current_major = _major(saved_version), _major(_fiducio_version())
    if saved_major is not None and current_major is not None and saved_major != current_major:
        _logger.warning(
            "calibrator was saved with fiducio %s but the installed version is %s; "
            "loading may not be fully compatible",
            saved_version,
            _fiducio_version(),
        )

    calibrator_id = payload["calibrator_id"]
    cls = get_calibrator_class(calibrator_id)

    config = dict(payload["config"])
    if "device" in config:
        raise ValueError("saved config must not override map_location")
    device = torch.device(location) if isinstance(location, (str, torch.device)) else None
    try:
        calibrator = cls(device=device, **config)
    except (TypeError, ValueError, OverflowError) as exc:
        raise ValueError(f"invalid saved calibrator configuration: {exc}") from exc
    _validate_state(calibrator, payload["state"], classes, fitted)
    calibrator._num_classes = classes
    calibrator._set_state(payload["state"])
    calibrator._fitted = fitted
    return calibrator

registered_ids

registered_ids() -> list[str]

Return the sorted list of registered calibrator ids.

Source code in src/fiducio/registry.py
def registered_ids() -> list[str]:
    """Return the sorted list of registered calibrator ids."""
    return sorted(_REGISTRY)