rapidfireai 0.10.3rc1__py3-none-any.whl → 0.11.1rc1__py3-none-any.whl
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.
Potentially problematic release.
This version of rapidfireai might be problematic. Click here for more details.
- rapidfireai/automl/grid_search.py +4 -5
- rapidfireai/automl/model_config.py +41 -37
- rapidfireai/automl/random_search.py +21 -33
- rapidfireai/backend/controller.py +54 -148
- rapidfireai/backend/worker.py +14 -3
- rapidfireai/cli.py +148 -136
- rapidfireai/experiment.py +22 -11
- rapidfireai/frontend/build/asset-manifest.json +3 -3
- rapidfireai/frontend/build/index.html +1 -1
- rapidfireai/frontend/build/static/js/{main.e7d3b759.js → main.58393d31.js} +3 -3
- rapidfireai/frontend/build/static/js/{main.e7d3b759.js.map → main.58393d31.js.map} +1 -1
- rapidfireai/ml/callbacks.py +10 -24
- rapidfireai/ml/trainer.py +37 -81
- rapidfireai/utils/constants.py +3 -1
- rapidfireai/utils/interactive_controller.py +40 -61
- rapidfireai/utils/logging.py +1 -2
- rapidfireai/utils/mlflow_manager.py +1 -0
- rapidfireai/utils/ping.py +4 -2
- rapidfireai/version.py +2 -2
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/METADATA +1 -1
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/RECORD +26 -26
- /rapidfireai/frontend/build/static/js/{main.e7d3b759.js.LICENSE.txt → main.58393d31.js.LICENSE.txt} +0 -0
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/WHEEL +0 -0
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/entry_points.txt +0 -0
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/licenses/LICENSE +0 -0
- {rapidfireai-0.10.3rc1.dist-info → rapidfireai-0.11.1rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"""Grid search implementation for AutoML training configurations."""
|
|
2
2
|
|
|
3
3
|
from itertools import product
|
|
4
|
-
from typing import Any
|
|
5
|
-
from typing import List as ListType
|
|
4
|
+
from typing import Any
|
|
6
5
|
|
|
7
6
|
from rapidfireai.automl.base import AutoMLAlgorithm
|
|
8
7
|
from rapidfireai.automl.datatypes import List
|
|
@@ -15,7 +14,7 @@ def recursive_expand_gridsearch(item: Any):
|
|
|
15
14
|
keys = list(item.keys())
|
|
16
15
|
value_lists = [list(recursive_expand_gridsearch(item[k])) for k in keys]
|
|
17
16
|
for values in product(*value_lists):
|
|
18
|
-
yield dict(zip(keys, values))
|
|
17
|
+
yield dict(zip(keys, values, strict=False))
|
|
19
18
|
elif isinstance(item, List):
|
|
20
19
|
for value in item.values:
|
|
21
20
|
yield from recursive_expand_gridsearch(value)
|
|
@@ -26,7 +25,7 @@ def recursive_expand_gridsearch(item: Any):
|
|
|
26
25
|
class RFGridSearch(AutoMLAlgorithm):
|
|
27
26
|
"""Grid search algorithm that generates all hyperparameter combinations."""
|
|
28
27
|
|
|
29
|
-
def get_runs(self, seed: int) ->
|
|
28
|
+
def get_runs(self, seed: int) -> list[dict[str, Any]]:
|
|
30
29
|
"""Generate all possible hyperparameter combinations for grid search."""
|
|
31
30
|
if not isinstance(seed, int) or seed < 0:
|
|
32
31
|
raise AutoMLException("seed must be a non-negative integer")
|
|
@@ -122,4 +121,4 @@ class RFGridSearch(AutoMLAlgorithm):
|
|
|
122
121
|
return runs
|
|
123
122
|
|
|
124
123
|
except Exception as e:
|
|
125
|
-
raise AutoMLException(f"Error generating runs: {e}") from e
|
|
124
|
+
raise AutoMLException(f"Error generating runs: {e}") from e
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"""Model configuration for AutoML training."""
|
|
2
2
|
|
|
3
|
-
import inspect
|
|
4
3
|
import copy
|
|
4
|
+
import inspect
|
|
5
|
+
from collections.abc import Callable
|
|
5
6
|
from dataclasses import dataclass
|
|
6
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, get_type_hints
|
|
7
8
|
|
|
8
9
|
from peft import LoraConfig
|
|
9
10
|
from trl import DPOConfig, GRPOConfig, SFTConfig
|
|
10
11
|
|
|
11
12
|
from rapidfireai.automl.datatypes import List, Range
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
|
|
15
|
+
def _create_rf_class(base_class: type, class_name: str):
|
|
14
16
|
"""Creating a RF class that dynamically inherits all constructor parameters and supports singleton, list, and Range values."""
|
|
15
17
|
if not inspect.isclass(base_class):
|
|
16
18
|
raise ValueError(f"base_class must be a class, got {type(base_class)}")
|
|
@@ -28,45 +30,47 @@ def _create_rf_class(base_class: Type, class_name: str):
|
|
|
28
30
|
def __init__(self, **kwargs):
|
|
29
31
|
self._user_params = copy.deepcopy(kwargs)
|
|
30
32
|
self._constructor_params = constructor_params
|
|
31
|
-
self._initializing = True
|
|
32
|
-
|
|
33
|
+
self._initializing = True
|
|
34
|
+
|
|
33
35
|
parent_kwargs = {}
|
|
34
36
|
for key, value in kwargs.items():
|
|
35
37
|
if not isinstance(value, (List, Range)):
|
|
36
38
|
parent_kwargs[key] = value
|
|
37
|
-
|
|
39
|
+
|
|
38
40
|
base_class.__init__(self, **parent_kwargs)
|
|
39
|
-
|
|
40
|
-
self._initializing = False
|
|
41
|
+
|
|
42
|
+
self._initializing = False
|
|
43
|
+
|
|
41
44
|
def copy_config(self):
|
|
42
45
|
"""Create a deep copy of the configuration."""
|
|
43
|
-
copied_params = copy.deepcopy(self._user_params)
|
|
46
|
+
copied_params = copy.deepcopy(self._user_params)
|
|
44
47
|
new_instance = self.__class__(**copied_params)
|
|
45
|
-
|
|
48
|
+
|
|
46
49
|
return new_instance
|
|
47
|
-
|
|
50
|
+
|
|
48
51
|
def __setattr__(self, name, value):
|
|
49
52
|
"""Override setattr to update _user_params when constructor parameters are modified."""
|
|
50
|
-
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
|
|
54
|
+
if (
|
|
55
|
+
hasattr(self, "_constructor_params")
|
|
56
|
+
and name in self._constructor_params
|
|
57
|
+
and hasattr(self, "_user_params")
|
|
58
|
+
and name in self._user_params
|
|
59
|
+
and not getattr(self, "_initializing", True)
|
|
60
|
+
): # Don't update during init
|
|
56
61
|
self._user_params[name] = value
|
|
57
|
-
|
|
62
|
+
|
|
58
63
|
base_class.__setattr__(self, name, value)
|
|
59
|
-
|
|
60
64
|
|
|
61
65
|
return type(
|
|
62
66
|
class_name,
|
|
63
67
|
(base_class,),
|
|
64
68
|
{
|
|
65
|
-
"__doc__": f"RF version of {base_class.__name__}",
|
|
66
|
-
"__annotations__": new_type_hints,
|
|
69
|
+
"__doc__": f"RF version of {base_class.__name__}",
|
|
70
|
+
"__annotations__": new_type_hints,
|
|
67
71
|
"__init__": __init__,
|
|
68
72
|
"copy": copy_config,
|
|
69
|
-
"__setattr__": __setattr__
|
|
73
|
+
"__setattr__": __setattr__,
|
|
70
74
|
},
|
|
71
75
|
)
|
|
72
76
|
|
|
@@ -83,20 +87,20 @@ class RFModelConfig:
|
|
|
83
87
|
"""Model configuration for AutoML training."""
|
|
84
88
|
|
|
85
89
|
model_name: str = None
|
|
86
|
-
tokenizer:
|
|
87
|
-
tokenizer_kwargs:
|
|
88
|
-
formatting_func:
|
|
89
|
-
compute_metrics:
|
|
90
|
-
peft_config:
|
|
91
|
-
training_args:
|
|
92
|
-
model_type:
|
|
93
|
-
model_kwargs:
|
|
94
|
-
ref_model_name:
|
|
95
|
-
ref_model_type:
|
|
96
|
-
ref_model_kwargs:
|
|
97
|
-
reward_funcs:
|
|
98
|
-
generation_config:
|
|
99
|
-
|
|
100
|
-
def copy(self)
|
|
90
|
+
tokenizer: str | None = None
|
|
91
|
+
tokenizer_kwargs: dict[str, Any] | None = None
|
|
92
|
+
formatting_func: Callable | List | None = None
|
|
93
|
+
compute_metrics: Callable | List | None = None
|
|
94
|
+
peft_config: RFLoraConfig | List | None = None
|
|
95
|
+
training_args: RFSFTConfig | RFDPOConfig | RFGRPOConfig | None = None
|
|
96
|
+
model_type: str | None = "causal_lm"
|
|
97
|
+
model_kwargs: dict[str, Any] | None = None
|
|
98
|
+
ref_model_name: str | None = None
|
|
99
|
+
ref_model_type: str | None = None
|
|
100
|
+
ref_model_kwargs: dict[str, Any] | None = None
|
|
101
|
+
reward_funcs: str | List | Callable | Any | None = None
|
|
102
|
+
generation_config: dict[str, Any] | None = None
|
|
103
|
+
|
|
104
|
+
def copy(self): # FIXME: Handle similar to create_rf_class
|
|
101
105
|
"""Create a deep copy of the RFModelConfig."""
|
|
102
106
|
return copy.deepcopy(self)
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"""Random search implementation for AutoML hyperparameter optimization."""
|
|
2
2
|
|
|
3
3
|
import random
|
|
4
|
-
import
|
|
5
|
-
from itertools import product
|
|
6
|
-
from typing import Any, Dict
|
|
7
|
-
from typing import List as ListType
|
|
4
|
+
from typing import Any
|
|
8
5
|
|
|
9
6
|
from rapidfireai.automl.base import AutoMLAlgorithm
|
|
10
7
|
from rapidfireai.automl.datatypes import List, Range
|
|
@@ -15,38 +12,36 @@ from rapidfireai.utils.serialize import encode_payload
|
|
|
15
12
|
def recursive_expand_randomsearch(item: Any):
|
|
16
13
|
if isinstance(item, dict):
|
|
17
14
|
return {k: recursive_expand_randomsearch(v) for k, v in item.items()}
|
|
18
|
-
elif isinstance(item, List):
|
|
19
|
-
return item.sample()
|
|
20
|
-
elif isinstance(item, Range):
|
|
15
|
+
elif isinstance(item, List) or isinstance(item, Range):
|
|
21
16
|
return item.sample()
|
|
22
17
|
else:
|
|
23
18
|
return item
|
|
24
19
|
|
|
20
|
+
|
|
25
21
|
class RFRandomSearch(AutoMLAlgorithm):
|
|
26
22
|
"""Random search algorithm that samples num_runs hyperparameter combinations."""
|
|
27
23
|
|
|
28
|
-
def get_runs(self, seed: int=42) ->
|
|
24
|
+
def get_runs(self, seed: int = 42) -> list[dict[str, Any]]:
|
|
29
25
|
"""Generate num_runs random hyperparameter combinations."""
|
|
30
26
|
if seed is not None and (not isinstance(seed, int) or seed < 0):
|
|
31
27
|
raise AutoMLException("seed must be a non-negative integer")
|
|
32
|
-
|
|
28
|
+
|
|
33
29
|
if not isinstance(self.num_runs, int) or self.num_runs <= 0:
|
|
34
30
|
raise AutoMLException("num_runs must be a positive integer")
|
|
35
31
|
|
|
36
|
-
|
|
37
32
|
random.seed(seed)
|
|
38
|
-
|
|
33
|
+
|
|
39
34
|
try:
|
|
40
35
|
runs = []
|
|
41
36
|
seen_configs = set()
|
|
42
|
-
max_attempts = self.num_runs * 10
|
|
37
|
+
max_attempts = self.num_runs * 10
|
|
43
38
|
attempts = 0
|
|
44
|
-
|
|
39
|
+
|
|
45
40
|
while len(runs) < self.num_runs and attempts < max_attempts:
|
|
46
41
|
attempts += 1
|
|
47
42
|
|
|
48
43
|
config = List(self.configs).sample()
|
|
49
|
-
|
|
44
|
+
|
|
50
45
|
if config.peft_config is None:
|
|
51
46
|
selected_peft_config = None
|
|
52
47
|
elif isinstance(config.peft_config, list):
|
|
@@ -57,32 +52,26 @@ class RFRandomSearch(AutoMLAlgorithm):
|
|
|
57
52
|
selected_peft_config = config.peft_config
|
|
58
53
|
|
|
59
54
|
peft_params = (
|
|
60
|
-
{}
|
|
55
|
+
{}
|
|
56
|
+
if selected_peft_config is None
|
|
61
57
|
else recursive_expand_randomsearch(selected_peft_config._user_params)
|
|
62
58
|
)
|
|
63
59
|
|
|
64
|
-
|
|
65
60
|
# Sample other parameters
|
|
66
61
|
training_params = (
|
|
67
|
-
{}
|
|
62
|
+
{}
|
|
63
|
+
if config.training_args is None
|
|
68
64
|
else recursive_expand_randomsearch(config.training_args._user_params)
|
|
69
65
|
)
|
|
70
|
-
|
|
71
|
-
model_kwargs = (
|
|
72
|
-
|
|
73
|
-
else recursive_expand_randomsearch(config.model_kwargs)
|
|
74
|
-
)
|
|
75
|
-
|
|
66
|
+
|
|
67
|
+
model_kwargs = {} if config.model_kwargs is None else recursive_expand_randomsearch(config.model_kwargs)
|
|
68
|
+
|
|
76
69
|
ref_model_kwargs = (
|
|
77
|
-
{} if config.ref_model_kwargs is None
|
|
78
|
-
else recursive_expand_randomsearch(config.ref_model_kwargs)
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
reward_funcs = (
|
|
82
|
-
{} if config.reward_funcs is None
|
|
83
|
-
else recursive_expand_randomsearch(config.reward_funcs)
|
|
70
|
+
{} if config.ref_model_kwargs is None else recursive_expand_randomsearch(config.ref_model_kwargs)
|
|
84
71
|
)
|
|
85
72
|
|
|
73
|
+
reward_funcs = {} if config.reward_funcs is None else recursive_expand_randomsearch(config.reward_funcs)
|
|
74
|
+
|
|
86
75
|
# FIXME: avoid hardcoding the excluded attributes
|
|
87
76
|
excluded_attrs = {
|
|
88
77
|
"model_name",
|
|
@@ -101,8 +90,7 @@ class RFRandomSearch(AutoMLAlgorithm):
|
|
|
101
90
|
k: v for k, v in config.__dict__.items() if k not in excluded_attrs and v is not None
|
|
102
91
|
}
|
|
103
92
|
additional_kwargs_sampled = (
|
|
104
|
-
{} if not additional_kwargs
|
|
105
|
-
else recursive_expand_randomsearch(additional_kwargs)
|
|
93
|
+
{} if not additional_kwargs else recursive_expand_randomsearch(additional_kwargs)
|
|
106
94
|
)
|
|
107
95
|
|
|
108
96
|
leaf = {
|
|
@@ -123,7 +111,7 @@ class RFRandomSearch(AutoMLAlgorithm):
|
|
|
123
111
|
"model_type": config.ref_model_type,
|
|
124
112
|
"model_kwargs": ref_model_kwargs,
|
|
125
113
|
}
|
|
126
|
-
#FIXME: correct ref args
|
|
114
|
+
# FIXME: correct ref args
|
|
127
115
|
elif self.trainer_type == "GRPO":
|
|
128
116
|
leaf["reward_funcs"] = reward_funcs
|
|
129
117
|
|