mllogs
Local experiment tracking and model registry for machine learning.
Why mllogs?
mllogs is built for developers who want structured experiment tracking without running a separate tracking server or external service. It provides a simple local workflow for tracking experiments, runs, parameters, metrics, artifacts, and model versions using SQLite and the filesystem.
Use it when your training code has outgrown ad hoc dictionaries, folders, and filenames, but you do not need the infrastructure of a larger ML platform.
Contents
Installation
pip install mllogs
Quickstart
Track multiple model configurations and compare their results.
from mllogs import MLLogs
from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
# Prepare data
X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Create experiment
mll = MLLogs()
experiment = mll.create_experiment("ridge-tuning")
best_mse = float("inf")
best_model_ref = None
# Track different configurations
for alpha in [0.1, 1.0, 10.0]:
mll.start_run(experiment.name)
model = Ridge(alpha=alpha)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
mse = mean_squared_error(y_test, predictions)
mll.log_param("alpha", alpha)
mll.log_metric("mse", mse)
mll.save_artifact("predictions", predictions, "npy")
model_ref = mll.save_artifact("model", model, "joblib")
mll.complete_run()
if mse < best_mse:
best_mse = mse
best_model_ref = model_ref
Each configuration creates a separate run within the same experiment, preserving its parameters, metrics, and trained model.
Usage
Query experiments and runs
Retrieve experiments and inspect previously recorded runs.
mll.query.list_experiments()
runs = mll.query.list_runs(experiment.name)
run = runs[0]
mll.query.get_run(run.id)
mll.query.get_params(run.id)
mll.query.get_metrics(run.id)
mll.query.get_tags(run.id)
Load saved artifacts
Load a previously trained model from its associated run.
mll.query.list_artifacts(run.id)
predictions = mll.query.load_artifact(run.id, "predictions")
model = mll.query.load_artifact(run.id, "model")
Supported artifact formats
mllogs supports saving and loading artifacts in the following formats:
| Format | Common use cases |
|---|---|
JSON (.json) |
Dictionaries, configurations, metadata |
CSV (.csv) |
Predictions, tabular data |
Parquet (.parquet) |
DataFrames, larger datasets |
Pickle (.pkl) |
Serialized Python objects, models |
NumPy (.npy) |
Arrays, embeddings |
Joblib (.joblib) |
Trained models, Python objects |
Specify the format when saving an artifact:
mll.save_artifact("predictions", predictions, "npy")
mll.save_artifact("model", model, "joblib")
Artifacts are associated with individual runs and can be loaded via mll.query.load_artifact().
Note: Only load Pickle or Joblib from trusted sources, since deserialization can execute arbitrary code.
Register and version models
Register the best-performing model and create its first version.
mll.registry.create_version("diabetes-ridge", best_model_ref)
create_version automatically registers the model if it does not already exist. Subsequent versions can reference new model artifacts without overwriting previous versions.
Retrieve the latest or a specific model version:
latest = mll.registry.get_latest_version("diabetes-ridge")
version = mll.registry.get_version(
model_name="diabetes-ridge",
version=1,
)
Assign model aliases
Assign a stable alias such as champion to a model version.
mll.registry.set_alias(version, "champion")
Aliases can be reassinged as new model versions are created, allowing application code to refer to a role such as champion instead of a fixed number.
Retrieve an alias or resolve it to its associated model version:
alias = mll.registry.get_alias("diabetes-ridge", "champion")
champion = mll.registry.get_version_by_alias("diabetes-ridge", "champion")
Aliases are scoped to individual registered models, so different models can independently use aliases such as champion, staging, or candidate.
Load registered models
Load a registered model directly without manually retrieving its version or associated artifact.
By default, load_model() loads the latest version:
model = mll.registry.load_model("diabetes-ridge")
Load a specific version:
model = mll.registry.load_model("diabetes-ridge", version=1)
Or load a model by its alias:
model = mll.registry.load_model("diabetes-ridge", alias="champion")
load_model() resolves the requested model version, retrieves its associated artifact, and returns the deserialized Python object.
The version and alias arguments are mutually exclusive. If neither is provided, the latest version is loaded.
Configure local storage
By default, mllogs stores its SQLite database and artifacts in the .mllogs directory.
Specify a custom storage directory when initializing MLLogs:
mll = MLLogs(storage_dir="./experiments")
The database and artifacts will be stored together:
experiments/
mllogs.db
artifacts/
Features
- Create experiments to organize related machine learning runs
- Start, complete, and fail runs
- Log parameters, metrics, and tags
- Persist run metadata to a local SQLite database
- Save and load artifacts in multiple formats using local file storage
- Query experiments, runs, and logged data
- Register models and create versioned references to persisted model artifacts
- Assign and reassign aliases to model versions
- Load registered models by latest version, specific version, or alias
- Configure the local storage directory
Development
Install from source with development dependencies:
pip install -e ".[dev]"
Run the test suite:
pytest
License
MIT
Metadata
Release files for mllogs 0.10.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mllogs-0.10.0.tar.gz | 16.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mllogs-0.10.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.9 kB
Release files / mllogs-0.10.0.tar.gz
| Download URL | mllogs-0.10.0.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
829315b6f259dd0bd4252bdeffe3f2538c310ce9329e443b3e5abc878f30d0aa
|
|
BLAKE2b-256 checksum How to use checksums |
4da8497263b9b0f4c2a2821c2a86134b9d3ec7bbb45d283fd966920200afe86c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / mllogs-0.10.0-py3-none-any.whl
| Download URL | mllogs-0.10.0-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a6fd72b891a703bc60fd97d5a3c69b901afaaf426c40e5e3f8e89a38f7ddbd05
|
|
BLAKE2b-256 checksum How to use checksums |
4ac102aa49199e2c19c1544c3612365176a6f2be5320f61a52de81db00525693
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log