Easily run experiment permutations with multi-processing and caching.
Project description
Labtech makes it easy to define multi-step experiment pipelines and run them with maximal parallelism and result caching:
- Defining tasks is simple; write a class with a single
run()method and parameters as dataclass-style attributes. - Flexible experiment configuration; simply create task objects for all of your parameter permutations.
- Handles pipelines of tasks; any task parameter that is itself a task will be executed first and make its result available to its dependent task(s).
- Implicit parallelism; Labtech resolves task dependencies and runs tasks in sub-processes with as much parallelism as possible.
- Implicit caching and loading of task results; configurable and extensible options for how and where task results are cached.
- Integration with mlflow; Automatically log task runs to mlflow with all of their parameters.
- Easily scale to a multi-machine cluster; Built-in support for running tasks across an easy-to-setup Ray cluster.
To learn more about how Labtech can speed up your experiments, check out the Kiwi Pycon presentation:
Installation
pip install labtech
Usage
from time import sleep
import labtech
# Decorate your task class with @labtech.task:
@labtech.task
class Experiment:
# Each Experiment task instance will take `base` and `power` parameters:
base: int
power: int
def run(self) -> int:
# Define the task's run() method to return the result of the experiment:
labtech.logger.info(f'Raising {self.base} to the power of {self.power}')
sleep(1)
return self.base ** self.power
def main():
# Configure Experiment parameter permutations
experiments = [
Experiment(
base=base,
power=power,
)
for base in range(5)
for power in range(5)
]
# Configure a Lab to run the experiments:
lab = labtech.Lab(
# Specify a directory to cache results in (running the experiments a second
# time will just load results from the cache!):
storage='demo_lab',
# Control the degree of parallelism:
max_workers=5,
)
# Run the experiments!
results = lab.run_tasks(experiments)
print([results[experiment] for experiment in experiments])
if __name__ == '__main__':
main()
Labtech can also produce graphical progress bars in Jupyter notebooks:
Tasks parameters can be any of the following types:
- Simple scalar types:
str,bool,float,int,None - Collections of any of these types:
list,tuple,dict,Enum - Task types: A task parameter is a "nested task" that will be executed before its parent so that it may make use of the nested result.
Here's an example of defining a single long-running task to produce a result for a large number of dependent tasks:
from time import sleep
import labtech
@labtech.task
class SlowTask:
base: int
def run(self) -> int:
sleep(5)
return self.base ** 2
@labtech.task
class DependentTask:
slow_task: SlowTask
multiplier: int
def run(self) -> int:
return self.multiplier * self.slow_task.result
def main():
some_slow_task = SlowTask(base=42)
dependent_tasks = [
DependentTask(
slow_task=some_slow_task,
multiplier=multiplier,
)
for multiplier in range(10)
]
lab = labtech.Lab(storage='demo_lab')
results = lab.run_tasks(dependent_tasks)
print([results[task] for task in dependent_tasks])
if __name__ == '__main__':
main()
Labtech can even generate a Mermaid diagram to visualise your tasks:
from labtech.diagram import display_task_diagram
some_slow_task = SlowTask(base=42)
dependent_tasks = [
DependentTask(
slow_task=some_slow_task,
multiplier=multiplier,
)
for multiplier in range(10)
]
display_task_diagram(dependent_tasks)
classDiagram
direction BT
class DependentTask
DependentTask : SlowTask slow_task
DependentTask : int multiplier
DependentTask : run() int
class SlowTask
SlowTask : int base
SlowTask : run() int
DependentTask <-- SlowTask: slow_task
To learn more, dive into the following resources:
- The labtech tutorial (as an interactive notebook)
- Cookbook of common patterns (as an interactive notebook)
- API reference for Labs and Tasks
- More options for cache formats and storage providers
- Option for customising task execution backends
- Diagramming tools
- Distributing across multiple machines
- More examples
Mypy Plugin
For mypy type-checking of classes decorated
with labtech.task, simply enable the labtech mypy plugin in your
mypy.ini file:
[mypy]
plugins = labtech.mypy_plugin
Contributing
- Install uv dependencies with
make deps - Run linting, mypy, and tests with
make check - Documentation:
- Run local server:
make docs-serve - Build docs:
make docs-build - Deploy docs to GitHub Pages:
make docs-github - Docstring style follows the Google style guide
- Run local server:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file labtech-1.0.0.tar.gz.
File metadata
- Download URL: labtech-1.0.0.tar.gz
- Upload date:
- Size: 222.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.28
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cf7fe450087af39200769f7642fa80320f0eacefafb126d5ea8c5b2cd9c02a8
|
|
| MD5 |
e07fa8c31ab19aaec942d8e9f6e061df
|
|
| BLAKE2b-256 |
a5cc8d6c73399b42a64d0576e9de82cdc7673b80fbce83b88d3eea04d397ffc8
|
File details
Details for the file labtech-1.0.0-py3-none-any.whl.
File metadata
- Download URL: labtech-1.0.0-py3-none-any.whl
- Upload date:
- Size: 63.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.28
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8555c298c34dd82438f05505d510cd66b3eb2270f751db0f8c2c38599029df2d
|
|
| MD5 |
ea7b22d82a1f353361e316c8f8051ae0
|
|
| BLAKE2b-256 |
90639ecce82d640068c7638457dea14f334a72c5ea899fc6763a89de10ab0254
|