ML experiment tracking. Local, lightweight, framework-agnostic.
blackboxml logs your training runs as structured JSON. No accounts, no servers. It works with PyTorch, Keras, scikit-learn, or any Python training loop.
pip install blackboxml
pip install blackboxml[keras] #(opt) TensorFlow supportRequires Python 3.10+.
from blackboxml import track, MetricStore
@track(name="resnet_cifar10", tags=["pytorch", "cifar10"])
def train():
metrics = MetricStore()
for epoch in range(10):
metrics.reset()
for batch in dataloader:
loss, acc = train_step(batch)
metrics.update({"loss": loss, "acc": acc}, n=len(batch))
yield metrics.compute()
train()from blackboxml import Run
with Run(name="resnet_cifar10", tags=["pytorch"]) as run:
for epoch in range(10):
run.log({"loss": train_one_epoch(), "epoch": epoch})from blackboxml.callback import BlackBoxCallback
model.fit(x_train, y_train, epochs=10,
callbacks=[BlackBoxCallback(name="lstm_nlp", tags=["keras"])])from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from blackboxml import Run
with Run(name="rf_search", tags=["sklearn"]) as run:
for n in [50, 100, 200]:
scores = cross_val_score(RandomForestClassifier(n_estimators=n), X, y, cv=5)
run.log({"n_estimators": n, "accuracy": scores.mean()})$ bbml runs
NAME DATE DURATION STEPS TAGS
----------------------------------------------------------------
resnet_cifar10 2026-03-10 14:22:01 13m 46s 10 pytorch, cifar10
lstm_nlp 2026-03-10 11:05:33 4m 12s 5 keras
$ bbml show resnet_cifar10
$ bbml clean
Each run saves to blackboxml_logs/<name>_<timestamp>/run.json:
{
"name": "resnet_cifar10",
"tags": ["pytorch", "cifar10"],
"environment": {
"git_commit": "a3f91bc",
"git_dirty": false,
"python": "3.11.2",
"torch": "2.3.0",
"hostname": "lab-gpu-01"
},
"start": "2026-03-10T14:22:01",
"end": "2026-03-10T14:35:47",
"duration_seconds": 826,
"steps": [
{"loss": 0.842, "acc": 0.65},
{"loss": 0.671, "acc": 0.78}
]
}Git commit, Python version, framework versions, and hostname are captured automatically.
from blackboxml import visualise_run
visualise_run("blackboxml_logs/resnet_cifar10_20260310_142201/run.json")
visualise_run("blackboxml_logs/resnet_cifar10_20260310_142201/run.json",
save_path="plots/", show=False)Full docs at blackboxml.readthedocs.io, covering usage for all frameworks, API reference, CLI commands, run schema, and visualisation.
| Version | Date | What changed |
|---|---|---|
| 0.1.0 | Apr 2025 | Initial release, Keras auto-logging, visualise_metrics |
| 0.2.0 | Jul 2025 | Type hints, logging module, error handling |
| 0.5.0 | Mar 2026 | Framework-agnostic rewrite, @track, Run, MetricStore, bbml CLI |
| 0.5.1 | Apr 2026 | Migrated repo to sxa-lab, updated license classifier, added PyPI metadata |
| 0.5.2 | Apr 2026 | Documentation update, ReadTheDocs, updated package authorship |
See Contributing Guidelines to get started. Bug reports, feature requests, and pull requests are welcome.
Maintained by SxA Lab