hydraflow 0.15.1__tar.gz → 0.16.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hydraflow-0.15.1 → hydraflow-0.16.1}/PKG-INFO +84 -75
- hydraflow-0.16.1/README.md +150 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part1-applications/main-decorator.md +30 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part3-analysis/run-class.md +27 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part3-analysis/run-collection.md +165 -9
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part3-analysis/updating-runs.md +23 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/practical-tutorials/advanced.md +27 -2
- {hydraflow-0.15.1 → hydraflow-0.16.1}/mkdocs.yaml +10 -9
- {hydraflow-0.15.1 → hydraflow-0.16.1}/pyproject.toml +1 -1
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/__init__.py +2 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/context.py +4 -4
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/io.py +6 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/main.py +24 -11
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/run.py +13 -3
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/run_collection.py +119 -12
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/run_info.py +16 -17
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/hydraflow.yaml +4 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/test_run.py +10 -0
- hydraflow-0.16.1/tests/core/main/test_update.py +18 -0
- hydraflow-0.16.1/tests/core/main/update.py +35 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/run/test_run.py +26 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/run/test_run_collection.py +31 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/run/test_run_info.py +0 -24
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/test_io.py +6 -0
- hydraflow-0.15.1/README.md +0 -141
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.devcontainer/devcontainer.json +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.devcontainer/postCreate.sh +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.devcontainer/starship.toml +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.gitattributes +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.github/workflows/ci.yaml +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.github/workflows/docs.yaml +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.github/workflows/publish.yaml +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/.gitignore +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/LICENSE +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/getting-started/concepts.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/getting-started/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/getting-started/installation.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part1-applications/configuration.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part1-applications/execution.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part1-applications/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part2-advanced/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part2-advanced/job-configuration.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part2-advanced/sweep-syntax.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/part3-analysis/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/practical-tutorials/analysis.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/practical-tutorials/applications.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/docs/practical-tutorials/index.md +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/examples/example.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/examples/hydraflow.yaml +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/examples/submit.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/cli.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/core/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/aio.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/conf.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/io.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/job.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/executor/parser.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/src/hydraflow/py.typed +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/app.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/conftest.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/submit.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/test_setup.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/test_show.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/cli/test_version.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/conftest.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/chdir.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/log_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/start_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/test_chdir.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/test_log_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/context/test_start_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/default.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/force_new_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/match_overrides.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/rerun_finished.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/skip_finished.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_default.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_force_new_run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_main.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_match_overrides.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_rerun_finished.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/main/test_skip_finished.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/run/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/core/run/run.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/__init__.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/conftest.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/echo.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/read.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_aio.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_args.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_conf.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_io.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_job.py +0 -0
- {hydraflow-0.15.1 → hydraflow-0.16.1}/tests/executor/test_parser.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: hydraflow
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.16.1
|
4
4
|
Summary: HydraFlow seamlessly integrates Hydra and MLflow to streamline ML experiment management, combining Hydra's configuration management with MLflow's tracking capabilities.
|
5
5
|
Project-URL: Documentation, https://daizutabi.github.io/hydraflow/
|
6
6
|
Project-URL: Source, https://github.com/daizutabi/hydraflow
|
@@ -51,7 +51,7 @@ Requires-Dist: ruff>=0.11
|
|
51
51
|
Requires-Dist: typer>=0.15
|
52
52
|
Description-Content-Type: text/markdown
|
53
53
|
|
54
|
-
#
|
54
|
+
# HydraFlow
|
55
55
|
|
56
56
|
[![PyPI Version][pypi-v-image]][pypi-v-link]
|
57
57
|
[![Build Status][GHAction-image]][GHAction-link]
|
@@ -60,6 +60,7 @@ Description-Content-Type: text/markdown
|
|
60
60
|
[![Python Version][python-v-image]][python-v-link]
|
61
61
|
|
62
62
|
<!-- Badges -->
|
63
|
+
|
63
64
|
[pypi-v-image]: https://img.shields.io/pypi/v/hydraflow.svg
|
64
65
|
[pypi-v-link]: https://pypi.org/project/hydraflow/
|
65
66
|
[GHAction-image]: https://github.com/daizutabi/hydraflow/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
|
@@ -73,117 +74,125 @@ Description-Content-Type: text/markdown
|
|
73
74
|
|
74
75
|
## Overview
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
HydraFlow seamlessly integrates [Hydra](https://hydra.cc/) and [MLflow](https://mlflow.org/) to streamline machine learning experiment workflows. By combining Hydra's powerful configuration management with MLflow's robust experiment tracking, HydraFlow provides a comprehensive solution for defining, executing, and analyzing machine learning experiments.
|
78
|
+
|
79
|
+
## Design Principles
|
80
|
+
|
81
|
+
HydraFlow is built on the following design principles:
|
82
|
+
|
83
|
+
1. **Type Safety** - Utilizing Python dataclasses for configuration type checking and IDE support
|
84
|
+
2. **Reproducibility** - Automatically tracking all experiment configurations for fully reproducible experiments
|
85
|
+
3. **Analysis Capabilities** - Providing powerful APIs for easily analyzing experiment results
|
86
|
+
4. **Workflow Integration** - Creating a cohesive workflow by integrating Hydra's configuration management with MLflow's experiment tracking
|
82
87
|
|
83
88
|
## Key Features
|
84
89
|
|
85
|
-
- **Configuration Management
|
86
|
-
|
87
|
-
- **
|
88
|
-
|
89
|
-
- **
|
90
|
-
|
91
|
-
- **Seamless Integration**: Easily integrate Hydra and MLflow in your machine learning
|
92
|
-
projects with minimal setup.
|
93
|
-
- **Rich CLI Interface**: Command-line tools for managing experiments and viewing results.
|
94
|
-
- **Cross-Platform Support**: Works consistently across different operating systems.
|
90
|
+
- **Type-safe Configuration Management** - Define experiment parameters using Python dataclasses with full IDE support and validation
|
91
|
+
- **Seamless Hydra-MLflow Integration** - Automatically register configurations with Hydra and track experiments with MLflow
|
92
|
+
- **Advanced Parameter Sweeps** - Define complex parameter spaces using extended sweep syntax for numerical ranges, combinations, and SI prefixes
|
93
|
+
- **Workflow Automation** - Create reusable experiment workflows with YAML-based job definitions
|
94
|
+
- **Powerful Analysis Tools** - Filter, group, and analyze experiment results with type-aware APIs
|
95
|
+
- **Custom Implementation Support** - Extend experiment analysis with domain-specific functionality
|
95
96
|
|
96
97
|
## Installation
|
97
98
|
|
98
|
-
You can install Hydraflow via pip:
|
99
|
-
|
100
99
|
```bash
|
101
100
|
pip install hydraflow
|
102
101
|
```
|
103
102
|
|
104
103
|
**Requirements:** Python 3.13+
|
105
104
|
|
106
|
-
## Quick
|
107
|
-
|
108
|
-
Here is a simple example to get you started with Hydraflow:
|
105
|
+
## Quick Example
|
109
106
|
|
110
107
|
```python
|
111
|
-
from __future__ import annotations
|
112
|
-
|
113
108
|
from dataclasses import dataclass
|
114
|
-
from
|
115
|
-
|
109
|
+
from mlflow.entities import Run
|
116
110
|
import hydraflow
|
117
|
-
import mlflow
|
118
111
|
|
119
|
-
|
120
|
-
|
112
|
+
@dataclass
|
113
|
+
class Config:
|
114
|
+
width: int = 1024
|
115
|
+
height: int = 768
|
121
116
|
|
117
|
+
@hydraflow.main(Config)
|
118
|
+
def app(run: Run, cfg: Config) -> None:
|
119
|
+
# Your experiment code here
|
120
|
+
print(f"Running with width={cfg.width}, height={cfg.height}")
|
121
|
+
|
122
|
+
# Log metrics
|
123
|
+
hydraflow.log_metric("area", cfg.width * cfg.height)
|
122
124
|
|
125
|
+
if __name__ == "__main__":
|
126
|
+
app()
|
127
|
+
```
|
128
|
+
|
129
|
+
Execute a parameter sweep with:
|
130
|
+
|
131
|
+
```bash
|
132
|
+
python app.py -m width=800,1200 height=600,900
|
133
|
+
```
|
134
|
+
|
135
|
+
## Core Components
|
136
|
+
|
137
|
+
HydraFlow consists of the following key components:
|
138
|
+
|
139
|
+
### Configuration Management
|
140
|
+
|
141
|
+
Define type-safe configurations using Python dataclasses:
|
142
|
+
|
143
|
+
```python
|
123
144
|
@dataclass
|
124
145
|
class Config:
|
125
|
-
"""Configuration for the ML training experiment."""
|
126
|
-
# Training hyperparameters
|
127
146
|
learning_rate: float = 0.001
|
128
147
|
batch_size: int = 32
|
129
148
|
epochs: int = 10
|
149
|
+
```
|
130
150
|
|
131
|
-
|
132
|
-
hidden_size: int = 128
|
133
|
-
dropout: float = 0.1
|
134
|
-
|
135
|
-
# Dataset parameters
|
136
|
-
train_size: float = 0.8
|
137
|
-
random_seed: int = 42
|
151
|
+
### Main Decorator
|
138
152
|
|
153
|
+
The `@hydraflow.main` decorator integrates Hydra and MLflow:
|
139
154
|
|
155
|
+
```python
|
140
156
|
@hydraflow.main(Config)
|
141
|
-
def
|
142
|
-
|
143
|
-
|
144
|
-
This example demonstrates how to:
|
157
|
+
def train(run: Run, cfg: Config) -> None:
|
158
|
+
# Your experiment code
|
159
|
+
```
|
145
160
|
|
146
|
-
|
147
|
-
2. Use Hydraflow to integrate with MLflow
|
148
|
-
3. Track metrics and parameters automatically
|
161
|
+
### Workflow Automation
|
149
162
|
|
150
|
-
|
151
|
-
run: MLflow run for the experiment corresponding to the Hydra app.
|
152
|
-
This `Run` instance is automatically created by Hydraflow.
|
153
|
-
cfg: Configuration for the experiment's run.
|
154
|
-
This `Config` instance is originally defined by Hydra, and then
|
155
|
-
automatically passed to the app by Hydraflow.
|
156
|
-
"""
|
157
|
-
# Training loop
|
158
|
-
for epoch in range(cfg.epochs):
|
159
|
-
# Simulate training and validation
|
160
|
-
train_loss = 1.0 / (epoch + 1)
|
161
|
-
val_loss = 1.1 / (epoch + 1)
|
163
|
+
Define reusable experiment workflows in YAML:
|
162
164
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
165
|
+
```yaml
|
166
|
+
jobs:
|
167
|
+
train_models:
|
168
|
+
run: python train.py
|
169
|
+
sets:
|
170
|
+
- each: model=small,medium,large
|
171
|
+
all: learning_rate=0.001,0.01,0.1
|
172
|
+
```
|
168
173
|
|
169
|
-
|
174
|
+
### Analysis Tools
|
170
175
|
|
176
|
+
Analyze experiment results with powerful APIs:
|
171
177
|
|
172
|
-
|
173
|
-
|
174
|
-
```
|
178
|
+
```python
|
179
|
+
from hydraflow import Run, iter_run_dirs
|
175
180
|
|
176
|
-
|
181
|
+
# Load runs
|
182
|
+
runs = Run.load(iter_run_dirs("mlruns"))
|
177
183
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
- Type-safe configuration with dataclasses
|
184
|
+
# Filter and analyze
|
185
|
+
best_runs = runs.filter(model_type="transformer").to_frame("learning_rate", "accuracy")
|
186
|
+
```
|
182
187
|
|
183
188
|
## Documentation
|
184
189
|
|
185
|
-
For detailed documentation,
|
186
|
-
|
190
|
+
For detailed documentation, visit our [documentation site](https://daizutabi.github.io/hydraflow/):
|
191
|
+
|
192
|
+
- [Getting Started](https://daizutabi.github.io/hydraflow/getting-started/) - Installation and core concepts
|
193
|
+
- [Practical Tutorials](https://daizutabi.github.io/hydraflow/practical-tutorials/) - Learn through hands-on examples
|
194
|
+
- [User Guide](https://daizutabi.github.io/hydraflow/part1-applications/) - Detailed documentation of HydraFlow's capabilities
|
195
|
+
- [API Reference](https://daizutabi.github.io/hydraflow/api/hydraflow/) - Complete API documentation
|
187
196
|
|
188
197
|
## Contributing
|
189
198
|
|
@@ -191,4 +200,4 @@ We welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) f
|
|
191
200
|
|
192
201
|
## License
|
193
202
|
|
194
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
203
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# HydraFlow
|
2
|
+
|
3
|
+
[![PyPI Version][pypi-v-image]][pypi-v-link]
|
4
|
+
[![Build Status][GHAction-image]][GHAction-link]
|
5
|
+
[![Coverage Status][codecov-image]][codecov-link]
|
6
|
+
[![Documentation Status][docs-image]][docs-link]
|
7
|
+
[![Python Version][python-v-image]][python-v-link]
|
8
|
+
|
9
|
+
<!-- Badges -->
|
10
|
+
|
11
|
+
[pypi-v-image]: https://img.shields.io/pypi/v/hydraflow.svg
|
12
|
+
[pypi-v-link]: https://pypi.org/project/hydraflow/
|
13
|
+
[GHAction-image]: https://github.com/daizutabi/hydraflow/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
|
14
|
+
[GHAction-link]: https://github.com/daizutabi/hydraflow/actions?query=event%3Apush+branch%3Amain
|
15
|
+
[codecov-image]: https://codecov.io/github/daizutabi/hydraflow/coverage.svg?branch=main
|
16
|
+
[codecov-link]: https://codecov.io/github/daizutabi/hydraflow?branch=main
|
17
|
+
[docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
|
18
|
+
[docs-link]: https://daizutabi.github.io/hydraflow/
|
19
|
+
[python-v-image]: https://img.shields.io/pypi/pyversions/hydraflow.svg
|
20
|
+
[python-v-link]: https://pypi.org/project/hydraflow
|
21
|
+
|
22
|
+
## Overview
|
23
|
+
|
24
|
+
HydraFlow seamlessly integrates [Hydra](https://hydra.cc/) and [MLflow](https://mlflow.org/) to streamline machine learning experiment workflows. By combining Hydra's powerful configuration management with MLflow's robust experiment tracking, HydraFlow provides a comprehensive solution for defining, executing, and analyzing machine learning experiments.
|
25
|
+
|
26
|
+
## Design Principles
|
27
|
+
|
28
|
+
HydraFlow is built on the following design principles:
|
29
|
+
|
30
|
+
1. **Type Safety** - Utilizing Python dataclasses for configuration type checking and IDE support
|
31
|
+
2. **Reproducibility** - Automatically tracking all experiment configurations for fully reproducible experiments
|
32
|
+
3. **Analysis Capabilities** - Providing powerful APIs for easily analyzing experiment results
|
33
|
+
4. **Workflow Integration** - Creating a cohesive workflow by integrating Hydra's configuration management with MLflow's experiment tracking
|
34
|
+
|
35
|
+
## Key Features
|
36
|
+
|
37
|
+
- **Type-safe Configuration Management** - Define experiment parameters using Python dataclasses with full IDE support and validation
|
38
|
+
- **Seamless Hydra-MLflow Integration** - Automatically register configurations with Hydra and track experiments with MLflow
|
39
|
+
- **Advanced Parameter Sweeps** - Define complex parameter spaces using extended sweep syntax for numerical ranges, combinations, and SI prefixes
|
40
|
+
- **Workflow Automation** - Create reusable experiment workflows with YAML-based job definitions
|
41
|
+
- **Powerful Analysis Tools** - Filter, group, and analyze experiment results with type-aware APIs
|
42
|
+
- **Custom Implementation Support** - Extend experiment analysis with domain-specific functionality
|
43
|
+
|
44
|
+
## Installation
|
45
|
+
|
46
|
+
```bash
|
47
|
+
pip install hydraflow
|
48
|
+
```
|
49
|
+
|
50
|
+
**Requirements:** Python 3.13+
|
51
|
+
|
52
|
+
## Quick Example
|
53
|
+
|
54
|
+
```python
|
55
|
+
from dataclasses import dataclass
|
56
|
+
from mlflow.entities import Run
|
57
|
+
import hydraflow
|
58
|
+
|
59
|
+
@dataclass
|
60
|
+
class Config:
|
61
|
+
width: int = 1024
|
62
|
+
height: int = 768
|
63
|
+
|
64
|
+
@hydraflow.main(Config)
|
65
|
+
def app(run: Run, cfg: Config) -> None:
|
66
|
+
# Your experiment code here
|
67
|
+
print(f"Running with width={cfg.width}, height={cfg.height}")
|
68
|
+
|
69
|
+
# Log metrics
|
70
|
+
hydraflow.log_metric("area", cfg.width * cfg.height)
|
71
|
+
|
72
|
+
if __name__ == "__main__":
|
73
|
+
app()
|
74
|
+
```
|
75
|
+
|
76
|
+
Execute a parameter sweep with:
|
77
|
+
|
78
|
+
```bash
|
79
|
+
python app.py -m width=800,1200 height=600,900
|
80
|
+
```
|
81
|
+
|
82
|
+
## Core Components
|
83
|
+
|
84
|
+
HydraFlow consists of the following key components:
|
85
|
+
|
86
|
+
### Configuration Management
|
87
|
+
|
88
|
+
Define type-safe configurations using Python dataclasses:
|
89
|
+
|
90
|
+
```python
|
91
|
+
@dataclass
|
92
|
+
class Config:
|
93
|
+
learning_rate: float = 0.001
|
94
|
+
batch_size: int = 32
|
95
|
+
epochs: int = 10
|
96
|
+
```
|
97
|
+
|
98
|
+
### Main Decorator
|
99
|
+
|
100
|
+
The `@hydraflow.main` decorator integrates Hydra and MLflow:
|
101
|
+
|
102
|
+
```python
|
103
|
+
@hydraflow.main(Config)
|
104
|
+
def train(run: Run, cfg: Config) -> None:
|
105
|
+
# Your experiment code
|
106
|
+
```
|
107
|
+
|
108
|
+
### Workflow Automation
|
109
|
+
|
110
|
+
Define reusable experiment workflows in YAML:
|
111
|
+
|
112
|
+
```yaml
|
113
|
+
jobs:
|
114
|
+
train_models:
|
115
|
+
run: python train.py
|
116
|
+
sets:
|
117
|
+
- each: model=small,medium,large
|
118
|
+
all: learning_rate=0.001,0.01,0.1
|
119
|
+
```
|
120
|
+
|
121
|
+
### Analysis Tools
|
122
|
+
|
123
|
+
Analyze experiment results with powerful APIs:
|
124
|
+
|
125
|
+
```python
|
126
|
+
from hydraflow import Run, iter_run_dirs
|
127
|
+
|
128
|
+
# Load runs
|
129
|
+
runs = Run.load(iter_run_dirs("mlruns"))
|
130
|
+
|
131
|
+
# Filter and analyze
|
132
|
+
best_runs = runs.filter(model_type="transformer").to_frame("learning_rate", "accuracy")
|
133
|
+
```
|
134
|
+
|
135
|
+
## Documentation
|
136
|
+
|
137
|
+
For detailed documentation, visit our [documentation site](https://daizutabi.github.io/hydraflow/):
|
138
|
+
|
139
|
+
- [Getting Started](https://daizutabi.github.io/hydraflow/getting-started/) - Installation and core concepts
|
140
|
+
- [Practical Tutorials](https://daizutabi.github.io/hydraflow/practical-tutorials/) - Learn through hands-on examples
|
141
|
+
- [User Guide](https://daizutabi.github.io/hydraflow/part1-applications/) - Detailed documentation of HydraFlow's capabilities
|
142
|
+
- [API Reference](https://daizutabi.github.io/hydraflow/api/hydraflow/) - Complete API documentation
|
143
|
+
|
144
|
+
## Contributing
|
145
|
+
|
146
|
+
We welcome contributions! Please see our [contributing guide](CONTRIBUTING.md) for details.
|
147
|
+
|
148
|
+
## License
|
149
|
+
|
150
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
@@ -242,6 +242,36 @@ This option is particularly useful when:
|
|
242
242
|
- You're iterating on experiments with command-line variations
|
243
243
|
- Your configuration contains volatile or automatically generated values
|
244
244
|
|
245
|
+
### Dynamic Configuration Updates (`update`)
|
246
|
+
|
247
|
+
Modify or enhance the configuration after it has been loaded by Hydra
|
248
|
+
but before the run starts:
|
249
|
+
|
250
|
+
```python
|
251
|
+
def update_config(cfg: Config) -> Config:
|
252
|
+
# Calculate derived values or add runtime information
|
253
|
+
if cfg.width > 0 and cfg.height > 0:
|
254
|
+
cfg.area = cfg.width * cfg.height
|
255
|
+
return cfg
|
256
|
+
|
257
|
+
@hydraflow.main(Config, update=update_config)
|
258
|
+
def train(run: Run, cfg: Config) -> None:
|
259
|
+
# Configuration has been updated with calculated area
|
260
|
+
print(f"Area: {cfg.area}")
|
261
|
+
```
|
262
|
+
|
263
|
+
This option is powerful when you need to:
|
264
|
+
|
265
|
+
- Calculate derived parameters based on existing configuration values
|
266
|
+
- Apply conditional logic to adjust parameters based on their relationships
|
267
|
+
- Ensure consistency between related parameters
|
268
|
+
- Adapt configurations to the current environment (e.g., hardware capabilities)
|
269
|
+
|
270
|
+
The `update` function should accept a configuration object and
|
271
|
+
return the same object (or None).
|
272
|
+
Any changes made to the configuration will be saved to the run's configuration file,
|
273
|
+
ensuring that the stored configuration accurately reflects all updates.
|
274
|
+
|
245
275
|
## Best Practices
|
246
276
|
|
247
277
|
1. **Keep Configuration Classes Focused**: Break down complex configurations
|
@@ -56,9 +56,22 @@ learning_rate = run.get("learning_rate")
|
|
56
56
|
# Nested access with dot notation
|
57
57
|
model_type = run.get("model.type")
|
58
58
|
|
59
|
+
# Alternatively, use double underscore notation for nested access
|
60
|
+
model_type = run.get("model__type") # Equivalent to "model.type"
|
61
|
+
|
59
62
|
# Access implementation attributes or run info
|
60
63
|
metric_value = run.get("accuracy") # From impl or cfg
|
61
64
|
run_id = run.get("run_id") # From RunInfo
|
65
|
+
|
66
|
+
# Provide a default value if the key doesn't exist
|
67
|
+
batch_size = run.get("batch_size", 32)
|
68
|
+
|
69
|
+
# Use a callable as default to dynamically generate values based on the run
|
70
|
+
# This is useful for derived parameters or conditional defaults
|
71
|
+
lr = run.get("learning_rate", default=lambda r: r.get("base_lr", 0.01) / 10)
|
72
|
+
|
73
|
+
# Complex default logic based on other parameters
|
74
|
+
steps = run.get("steps", default=lambda r: r.get("epochs", 10) * r.get("steps_per_epoch", 100))
|
62
75
|
```
|
63
76
|
|
64
77
|
The `get` method searches for values in the following order:
|
@@ -69,6 +82,20 @@ The `get` method searches for values in the following order:
|
|
69
82
|
|
70
83
|
This provides a unified access interface regardless of where the data is stored.
|
71
84
|
|
85
|
+
The double underscore notation (`__`) is automatically converted to dot notation (`.`) internally,
|
86
|
+
making it useful for nested parameter access, especially when using keyword arguments in methods
|
87
|
+
that don't allow dots in parameter names.
|
88
|
+
|
89
|
+
When providing a default value, you can use either a static value or a callable function.
|
90
|
+
If you provide a callable, it will receive the Run instance as an argument, allowing you to
|
91
|
+
create context-dependent default values that can access other run parameters or properties.
|
92
|
+
This is particularly useful for:
|
93
|
+
|
94
|
+
- Creating derived parameters that don't exist in the original configuration
|
95
|
+
- Handling schema evolution across different experiment iterations
|
96
|
+
- Providing fallbacks that depend on other configuration values
|
97
|
+
- Implementing conditional logic for parameter defaults
|
98
|
+
|
72
99
|
## Type-Safe Configuration Access
|
73
100
|
|
74
101
|
For better IDE integration and type checking, you can specify the configuration
|