hydraflow 0.3.5__tar.gz → 0.4.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {hydraflow-0.3.5 → hydraflow-0.4.0}/PKG-INFO +1 -1
- {hydraflow-0.3.5 → hydraflow-0.4.0}/pyproject.toml +1 -1
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/__init__.py +2 -1
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/config.py +11 -2
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/run_collection.py +18 -7
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/utils.py +1 -1
- hydraflow-0.4.0/tests/integ/app.py +54 -0
- hydraflow-0.4.0/tests/scripts/__init__.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_run_collection.py +2 -2
- {hydraflow-0.3.5 → hydraflow-0.4.0}/.devcontainer/devcontainer.json +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/.devcontainer/postCreate.sh +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/.devcontainer/starship.toml +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/.gitattributes +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/.gitignore +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/LICENSE +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/README.md +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/apps/quickstart.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/mkdocs.yml +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/asyncio.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/context.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/mlflow.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/param.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/progress.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/py.typed +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/run_data.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/src/hydraflow/run_info.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/__init__.py +0 -0
- {hydraflow-0.3.5/tests/scripts → hydraflow-0.4.0/tests/integ}/__init__.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/scripts/app.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/scripts/progress.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/scripts/watch.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_app.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_asyncio.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_config.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_context.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_log_run.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_mlflow.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_param.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_progress.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_run_data.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_run_info.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_version.py +0 -0
- {hydraflow-0.3.5 → hydraflow-0.4.0}/tests/test_watch.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: hydraflow
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.0
|
4
4
|
Summary: Hydraflow integrates Hydra and MLflow to manage and track machine learning experiments.
|
5
5
|
Project-URL: Documentation, https://github.com/daizutabi/hydraflow
|
6
6
|
Project-URL: Source, https://github.com/daizutabi/hydraflow
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Integrate Hydra and MLflow to manage and track machine learning experiments."""
|
2
2
|
|
3
|
-
from .config import select_config
|
3
|
+
from .config import select_config, select_overrides
|
4
4
|
from .context import chdir_artifact, chdir_hydra_output, log_run, start_run, watch
|
5
5
|
from .mlflow import list_runs, search_runs, set_experiment
|
6
6
|
from .progress import multi_tasks_progress, parallel_progress
|
@@ -28,6 +28,7 @@ __all__ = [
|
|
28
28
|
"parallel_progress",
|
29
29
|
"search_runs",
|
30
30
|
"select_config",
|
31
|
+
"select_overrides",
|
31
32
|
"set_experiment",
|
32
33
|
"start_run",
|
33
34
|
"watch",
|
@@ -6,6 +6,8 @@ from typing import TYPE_CHECKING
|
|
6
6
|
|
7
7
|
from omegaconf import DictConfig, ListConfig, OmegaConf
|
8
8
|
|
9
|
+
from hydraflow.utils import get_overrides
|
10
|
+
|
9
11
|
if TYPE_CHECKING:
|
10
12
|
from collections.abc import Iterator
|
11
13
|
from typing import Any
|
@@ -116,9 +118,9 @@ def select_config(config: object, names: list[str]) -> dict[str, Any]:
|
|
116
118
|
|
117
119
|
"""
|
118
120
|
if not isinstance(config, DictConfig):
|
119
|
-
|
121
|
+
config = OmegaConf.structured(config)
|
120
122
|
|
121
|
-
return {name: _get(
|
123
|
+
return {name: _get(config, name) for name in names} # type: ignore
|
122
124
|
|
123
125
|
|
124
126
|
def _get(config: DictConfig, name: str) -> Any:
|
@@ -128,3 +130,10 @@ def _get(config: DictConfig, name: str) -> Any:
|
|
128
130
|
|
129
131
|
prefix, name = name.split(".", 1)
|
130
132
|
return _get(config.get(prefix), name)
|
133
|
+
|
134
|
+
|
135
|
+
def select_overrides(config: object) -> dict[str, Any]:
|
136
|
+
"""Select the given overrides from the configuration object."""
|
137
|
+
overrides = get_overrides()
|
138
|
+
names = [override.split("=")[0].strip() for override in overrides]
|
139
|
+
return select_config(config, names)
|
@@ -26,7 +26,7 @@ from typing import TYPE_CHECKING, Any, Concatenate, ParamSpec, TypeVar, overload
|
|
26
26
|
from mlflow.entities import RunStatus
|
27
27
|
|
28
28
|
import hydraflow.param
|
29
|
-
from hydraflow.config import iter_params
|
29
|
+
from hydraflow.config import iter_params, select_config, select_overrides
|
30
30
|
from hydraflow.run_data import RunCollectionData
|
31
31
|
from hydraflow.run_info import RunCollectionInfo
|
32
32
|
from hydraflow.utils import load_config
|
@@ -603,7 +603,7 @@ class RunCollection:
|
|
603
603
|
def _param_matches(run: Run, key: str, value: Any) -> bool:
|
604
604
|
params = run.data.params
|
605
605
|
if key not in params:
|
606
|
-
return
|
606
|
+
return False
|
607
607
|
|
608
608
|
param = params[key]
|
609
609
|
if param == "None":
|
@@ -616,6 +616,8 @@ def filter_runs(
|
|
616
616
|
runs: list[Run],
|
617
617
|
config: object | None = None,
|
618
618
|
*,
|
619
|
+
override: bool = False,
|
620
|
+
select: list[str] | None = None,
|
619
621
|
status: str | list[str] | int | list[int] | None = None,
|
620
622
|
**kwargs,
|
621
623
|
) -> list[Run]:
|
@@ -636,17 +638,26 @@ def filter_runs(
|
|
636
638
|
|
637
639
|
Args:
|
638
640
|
runs (list[Run]): The list of runs to filter.
|
639
|
-
config (object | None): The configuration object to filter the
|
640
|
-
This can be any object that provides key-value pairs through
|
641
|
-
`iter_params` function.
|
642
|
-
|
643
|
-
the
|
641
|
+
config (object | None, optional): The configuration object to filter the
|
642
|
+
runs. This can be any object that provides key-value pairs through
|
643
|
+
the `iter_params` function. Defaults to None.
|
644
|
+
override (bool, optional): If True, filter the runs based on
|
645
|
+
the overrides. Defaults to False.
|
646
|
+
select (list[str] | None, optional): The list of parameters to select.
|
647
|
+
Defaults to None.
|
648
|
+
status (str | list[str] | RunStatus | list[RunStatus] | None, optional): The
|
649
|
+
status of the runs to filter. Defaults to None.
|
644
650
|
**kwargs: Additional key-value pairs to filter the runs.
|
645
651
|
|
646
652
|
Returns:
|
647
653
|
A list of runs that match the specified configuration and key-value pairs.
|
648
654
|
|
649
655
|
"""
|
656
|
+
if override:
|
657
|
+
config = select_overrides(config)
|
658
|
+
elif select:
|
659
|
+
config = select_config(config, select)
|
660
|
+
|
650
661
|
for key, value in chain(iter_params(config), kwargs.items()):
|
651
662
|
runs = [run for run in runs if _param_matches(run, key, value)]
|
652
663
|
if not runs:
|
@@ -90,7 +90,7 @@ def load_config(run: Run) -> DictConfig:
|
|
90
90
|
|
91
91
|
def get_overrides() -> list[str]:
|
92
92
|
"""Retrieve the overrides for the current run."""
|
93
|
-
return HydraConfig.get().overrides.task
|
93
|
+
return list(HydraConfig.get().overrides.task) # ListConifg -> list
|
94
94
|
|
95
95
|
|
96
96
|
def load_overrides(run: Run) -> list[str]:
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import logging
|
4
|
+
from dataclasses import dataclass, field
|
5
|
+
|
6
|
+
import hydra
|
7
|
+
from hydra.core.config_store import ConfigStore
|
8
|
+
|
9
|
+
import hydraflow
|
10
|
+
|
11
|
+
log = logging.getLogger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class B:
|
16
|
+
z: float = 0.0
|
17
|
+
|
18
|
+
|
19
|
+
@dataclass
|
20
|
+
class A:
|
21
|
+
y: str = "y"
|
22
|
+
b: B = field(default_factory=B)
|
23
|
+
|
24
|
+
|
25
|
+
@dataclass
|
26
|
+
class Config:
|
27
|
+
x: int = 0
|
28
|
+
y: int = 0
|
29
|
+
a: A = field(default_factory=A)
|
30
|
+
|
31
|
+
|
32
|
+
cs = ConfigStore.instance()
|
33
|
+
cs.store(name="config", node=Config)
|
34
|
+
|
35
|
+
|
36
|
+
@hydra.main(version_base=None, config_name="config")
|
37
|
+
def app(cfg: Config):
|
38
|
+
hydraflow.set_experiment()
|
39
|
+
rc = hydraflow.list_runs()
|
40
|
+
log.info(rc)
|
41
|
+
log.info(hydraflow.select_overrides(cfg))
|
42
|
+
log.info(rc.filter(cfg, override=True))
|
43
|
+
log.info(rc.filter(cfg, select=["x"]))
|
44
|
+
log.info(rc.try_find_last(cfg, override=True))
|
45
|
+
log.info(rc.try_find_last(cfg, select=["x"]))
|
46
|
+
log.info(rc.filter(cfg))
|
47
|
+
|
48
|
+
cfg.y = 2 * cfg.x
|
49
|
+
with hydraflow.start_run(cfg):
|
50
|
+
pass
|
51
|
+
|
52
|
+
|
53
|
+
if __name__ == "__main__":
|
54
|
+
app()
|
File without changes
|
@@ -101,9 +101,9 @@ def test_filter_invalid_param(run_list: list[Run]):
|
|
101
101
|
from hydraflow.run_collection import filter_runs
|
102
102
|
|
103
103
|
x = filter_runs(run_list, {"invalid": 0})
|
104
|
-
assert len(x) ==
|
104
|
+
assert len(x) == 0
|
105
105
|
x = filter_runs(run_list, ["invalid=0"])
|
106
|
-
assert len(x) ==
|
106
|
+
assert len(x) == 0
|
107
107
|
|
108
108
|
|
109
109
|
def test_filter_status(run_list: list[Run]):
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|