A simple & elegant experiment tracking framework that integrates persistence logic & best practices directly into Python
Jupyter Notebook
541
321 commits
updated Jan 14, 2025
mandala eliminates the effort and code overhead of ML experiment tracking (and
beyond) with two generic tools:
@op decorator:
|
A quick demo of running computations in mandala and simultaneously updating a view of the corresponding ComputationFrame and the dataframe extracted from it (code can
be found here):
https://github.com/amakelov/mandala/assets/1467702/85185599-10fb-479e-bf02-442873732906
pip install pymandala
or
pip install git+https://github.com/amakelov/mandala
ComputationFrames:
ComputationFrame data structure and its applicationsmandala's dependency tracking systemCompared to popular tools like W&B, MLFlow or Comet, mandala:
list, dict) can be made
transparent to the storage system, so that individual elements are stored
and tracked separately and can be reused across collections and calls.ComputationFrame data structure, a powerful & simple way to
represent, query and manipulate complex saved computations.@op call from the current
state of the codebase and the inputs to the call.@op cache invalidated?@op, e.g. f, it searches for a past call
to f on inputs with the same contents (as determined by a hash function) where the dependencies accessed by this call (including f
itself) have versions compatible with their current state.mandala uses slightly modified joblib hashing to compute a
content hash for Python objects. This is practical for many use cases, but
not perfect, as discussed in the limitations section.@ops, and what happens if I do?@op you've been using, then want to
extend its functionality in a way that doesn't invalidate the past results.
The recommended way is to add a new argument a, and provide a default
value for it wrapped with NewArgDefault(x). When a value equal to x is
passed for this argument, the storage falls back on calls before@ops and changes to them. See the
documentation.mandala is in alpha, and the API is subject to change.mandala's core is a few kLoCs and only depends on pandas and joblib.ComputationFrames, you should have dot installed
on the system level, and/or the Python graphviz library installed.ComputationFrames by function versions.
Moreover, many of the error messages are not informative enough and/or don't
suggest solutions.mandala. Changes to such "invisible" dependencies may remain
unnoticed by the storage system, leading you to believe that certain results
are up to date when they are not.Overall
@ops@ops and their inputs/outputsMemoization
@op execution via e.g. dask or rayComputation frames
expand_... methodsVersioning
Performance
ComputationFrame operationsAspirationally, mandala is about much more than ML experiment tracking. The
main goal is to make persistence logic & best practices a natural extension of Python.
Once this is achieved, the purely "computational" code you must write anyway
doubles as a storage interface. It's hard to think of a simpler and more
reliable way to manage computational artifacts.
What we want from our storage are ways to
The key observation is that execution traces can already answer ~all of these questions.
mandala combines ideas from, and shares similarities with, many technologies.
Here are some useful points of comparison:
provenance library is quite
similar to the memoization part of mandala, but lacks the querying and
dependency tracking features.joblib.Memory
and
functools.lru_cache.
mandala uses joblib serialization and hashing under the hood.incpy is a project that integrates
memoization with the python interpreter itself.funsies is a
memoization-based distributed workflow executor that uses an analogous notion
of hashing to mandala to keep track of which computations have already been done. It
works on the level of scripts (not functions), and lacks queriability and
versioning.koji is a design for an incremental
computation data processing framework that unifies over different resource
types (files or services). It also uses an analogous notion of hashing to
keep track of computations.Refs in the variable. Foreign key
constraints relate the functions' columns to the variables, and various joins
over the tables express various notions of joint computational history of
variables.@ops, are special cases of queries over graph
databases. The internal representation of the Storage is also closer to
a graph database than a relational one.git repository" that shares only the most basic
features with git: it is a
content-addressable
tree, where each edge tracks a diff from the content at one endpoint to that
at the other. Additional metadata indicates equivalence classes of
semantically equivalent contents.mandala is similar to semver in that it allows you to
make backward-compatible changes to the interface and logic of dependencies.
It is different in that versions are still labeled by content, instead of by
"non-canonical" numbers.156 followers · starred Jul 2023
108 followers · starred Apr 2025
129 followers · starred Nov 2023
127 followers · starred Nov 2023
A simple & elegant experiment tracking framework that integrates persistence logic & best practices directly into Python
Jupyter Notebook
541
321 commits
updated Jan 14, 2025
mandala eliminates the effort and code overhead of ML experiment tracking (and
beyond) with two generic tools:
@op decorator:
|
A quick demo of running computations in mandala and simultaneously updating a view of the corresponding ComputationFrame and the dataframe extracted from it (code can
be found here):
https://github.com/amakelov/mandala/assets/1467702/85185599-10fb-479e-bf02-442873732906
pip install pymandala
or
pip install git+https://github.com/amakelov/mandala
ComputationFrames:
ComputationFrame data structure and its applicationsmandala's dependency tracking systemCompared to popular tools like W&B, MLFlow or Comet, mandala:
list, dict) can be made
transparent to the storage system, so that individual elements are stored
and tracked separately and can be reused across collections and calls.ComputationFrame data structure, a powerful & simple way to
represent, query and manipulate complex saved computations.@op call from the current
state of the codebase and the inputs to the call.@op cache invalidated?@op, e.g. f, it searches for a past call
to f on inputs with the same contents (as determined by a hash function) where the dependencies accessed by this call (including f
itself) have versions compatible with their current state.mandala uses slightly modified joblib hashing to compute a
content hash for Python objects. This is practical for many use cases, but
not perfect, as discussed in the limitations section.@ops, and what happens if I do?@op you've been using, then want to
extend its functionality in a way that doesn't invalidate the past results.
The recommended way is to add a new argument a, and provide a default
value for it wrapped with NewArgDefault(x). When a value equal to x is
passed for this argument, the storage falls back on calls before@ops and changes to them. See the
documentation.mandala is in alpha, and the API is subject to change.mandala's core is a few kLoCs and only depends on pandas and joblib.ComputationFrames, you should have dot installed
on the system level, and/or the Python graphviz library installed.ComputationFrames by function versions.
Moreover, many of the error messages are not informative enough and/or don't
suggest solutions.mandala. Changes to such "invisible" dependencies may remain
unnoticed by the storage system, leading you to believe that certain results
are up to date when they are not.Overall
@ops@ops and their inputs/outputsMemoization
@op execution via e.g. dask or rayComputation frames
expand_... methodsVersioning
Performance
ComputationFrame operationsAspirationally, mandala is about much more than ML experiment tracking. The
main goal is to make persistence logic & best practices a natural extension of Python.
Once this is achieved, the purely "computational" code you must write anyway
doubles as a storage interface. It's hard to think of a simpler and more
reliable way to manage computational artifacts.
What we want from our storage are ways to
The key observation is that execution traces can already answer ~all of these questions.
mandala combines ideas from, and shares similarities with, many technologies.
Here are some useful points of comparison:
provenance library is quite
similar to the memoization part of mandala, but lacks the querying and
dependency tracking features.joblib.Memory
and
functools.lru_cache.
mandala uses joblib serialization and hashing under the hood.incpy is a project that integrates
memoization with the python interpreter itself.funsies is a
memoization-based distributed workflow executor that uses an analogous notion
of hashing to mandala to keep track of which computations have already been done. It
works on the level of scripts (not functions), and lacks queriability and
versioning.koji is a design for an incremental
computation data processing framework that unifies over different resource
types (files or services). It also uses an analogous notion of hashing to
keep track of computations.Refs in the variable. Foreign key
constraints relate the functions' columns to the variables, and various joins
over the tables express various notions of joint computational history of
variables.@ops, are special cases of queries over graph
databases. The internal representation of the Storage is also closer to
a graph database than a relational one.git repository" that shares only the most basic
features with git: it is a
content-addressable
tree, where each edge tracks a diff from the content at one endpoint to that
at the other. Additional metadata indicates equivalence classes of
semantically equivalent contents.mandala is similar to semver in that it allows you to
make backward-compatible changes to the interface and logic of dependencies.
It is different in that versions are still labeled by content, instead of by
"non-canonical" numbers.156 followers · starred Jul 2023
108 followers · starred Apr 2025
129 followers · starred Nov 2023
127 followers · starred Nov 2023