LMFuser 0.0.1__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.
- lmfuser/__init__.py +0 -0
- lmfuser/model_loader.py +33 -0
- lmfuser/optimizers.py +162 -0
- lmfuser/runners/__init__.py +1 -0
- lmfuser/runners/ddp_runner.py +619 -0
- lmfuser/runners/runner.py +40 -0
- lmfuser/schedulers.py +210 -0
- lmfuser/task.py +287 -0
- lmfuser/utils.py +249 -0
- lmfuser-0.0.1.dist-info/METADATA +30 -0
- lmfuser-0.0.1.dist-info/RECORD +13 -0
- lmfuser-0.0.1.dist-info/WHEEL +4 -0
- lmfuser-0.0.1.dist-info/licenses/LICENSE +21 -0
lmfuser/schedulers.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from functools import partial
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
from torch.optim.lr_scheduler import LambdaLR, LRScheduler
|
|
5
|
+
from torch.optim import Optimizer
|
|
6
|
+
|
|
7
|
+
from hyperargs import Conf, IntArg, FloatArg, OptionArg, monitor_on, add_dependency
|
|
8
|
+
|
|
9
|
+
def _get_linear_schedule_with_warmup_lr_lambda(
|
|
10
|
+
current_step: int,
|
|
11
|
+
*,
|
|
12
|
+
num_warmup_steps: int,
|
|
13
|
+
num_training_steps: int
|
|
14
|
+
):
|
|
15
|
+
if current_step < num_warmup_steps:
|
|
16
|
+
return float(current_step) / float(max(1, num_warmup_steps))
|
|
17
|
+
return max(
|
|
18
|
+
0.0,
|
|
19
|
+
float(num_training_steps - current_step) / float(
|
|
20
|
+
max(1, num_training_steps - num_warmup_steps))
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
def get_linear_schedule_with_warmup(
|
|
24
|
+
optimizer: Optimizer,
|
|
25
|
+
num_warmup_steps: int,
|
|
26
|
+
num_training_steps: int,
|
|
27
|
+
last_epoch=-1
|
|
28
|
+
) -> LRScheduler:
|
|
29
|
+
"""
|
|
30
|
+
Create a schedule with a learning rate that decreases linearly from the initial lr set in the optimizer to 0, after
|
|
31
|
+
a warmup period during which it increases linearly from 0 to the initial lr set in the optimizer.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
optimizer ([`~torch.optim.Optimizer`]):
|
|
35
|
+
The optimizer for which to schedule the learning rate.
|
|
36
|
+
num_warmup_steps (`int`):
|
|
37
|
+
The number of steps for the warmup phase.
|
|
38
|
+
num_training_steps (`int`):
|
|
39
|
+
The total number of training steps.
|
|
40
|
+
last_epoch (`int`, *optional*, defaults to -1):
|
|
41
|
+
The index of the last epoch when resuming training.
|
|
42
|
+
|
|
43
|
+
Return:
|
|
44
|
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
lr_lambda = partial(
|
|
48
|
+
_get_linear_schedule_with_warmup_lr_lambda,
|
|
49
|
+
num_warmup_steps=num_warmup_steps,
|
|
50
|
+
num_training_steps=num_training_steps,
|
|
51
|
+
)
|
|
52
|
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
|
53
|
+
|
|
54
|
+
def _get_constant_schedule_with_warmup_lr_lambda(
|
|
55
|
+
current_step: int,
|
|
56
|
+
*,
|
|
57
|
+
num_warmup_steps: int
|
|
58
|
+
):
|
|
59
|
+
if current_step < num_warmup_steps:
|
|
60
|
+
return float(current_step) / float(max(1.0, num_warmup_steps))
|
|
61
|
+
return 1.0
|
|
62
|
+
|
|
63
|
+
def get_constant_schedule_with_warmup(
|
|
64
|
+
optimizer: Optimizer,
|
|
65
|
+
num_warmup_steps: int,
|
|
66
|
+
last_epoch: int = -1
|
|
67
|
+
) -> LRScheduler:
|
|
68
|
+
"""
|
|
69
|
+
Create a schedule with a constant learning rate preceded by a warmup period during which the learning rate
|
|
70
|
+
increases linearly between 0 and the initial lr set in the optimizer.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
optimizer ([`~torch.optim.Optimizer`]):
|
|
74
|
+
The optimizer for which to schedule the learning rate.
|
|
75
|
+
num_warmup_steps (`int`):
|
|
76
|
+
The number of steps for the warmup phase.
|
|
77
|
+
last_epoch (`int`, *optional*, defaults to -1):
|
|
78
|
+
The index of the last epoch when resuming training.
|
|
79
|
+
|
|
80
|
+
Return:
|
|
81
|
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
lr_lambda = partial(_get_constant_schedule_with_warmup_lr_lambda, num_warmup_steps=num_warmup_steps)
|
|
85
|
+
return LambdaLR(optimizer, lr_lambda, last_epoch=last_epoch)
|
|
86
|
+
|
|
87
|
+
def _get_cosine_schedule_with_warmup_lr_lambda(
|
|
88
|
+
current_step: int, *, num_warmup_steps: int, num_training_steps: int, num_cycles: float
|
|
89
|
+
):
|
|
90
|
+
if current_step < num_warmup_steps:
|
|
91
|
+
return float(current_step) / float(max(1, num_warmup_steps))
|
|
92
|
+
progress = float(current_step - num_warmup_steps) / float(max(1, num_training_steps - num_warmup_steps))
|
|
93
|
+
return max(0.0, 0.5 * (1.0 + math.cos(math.pi * float(num_cycles) * 2.0 * progress)))
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def get_cosine_schedule_with_warmup(
|
|
97
|
+
optimizer: Optimizer, num_warmup_steps: int, num_training_steps: int, num_cycles: float = 0.5, last_epoch: int = -1
|
|
98
|
+
) -> LRScheduler:
|
|
99
|
+
"""
|
|
100
|
+
Create a schedule with a learning rate that decreases following the values of the cosine function between the
|
|
101
|
+
initial lr set in the optimizer to 0, after a warmup period during which it increases linearly between 0 and the
|
|
102
|
+
initial lr set in the optimizer.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
optimizer ([`~torch.optim.Optimizer`]):
|
|
106
|
+
The optimizer for which to schedule the learning rate.
|
|
107
|
+
num_warmup_steps (`int`):
|
|
108
|
+
The number of steps for the warmup phase.
|
|
109
|
+
num_training_steps (`int`):
|
|
110
|
+
The total number of training steps.
|
|
111
|
+
num_cycles (`float`, *optional*, defaults to 0.5):
|
|
112
|
+
The number of waves in the cosine schedule (the defaults is to just decrease from the max value to 0
|
|
113
|
+
following a half-cosine).
|
|
114
|
+
last_epoch (`int`, *optional*, defaults to -1):
|
|
115
|
+
The index of the last epoch when resuming training.
|
|
116
|
+
|
|
117
|
+
Return:
|
|
118
|
+
`torch.optim.lr_scheduler.LambdaLR` with the appropriate schedule.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
lr_lambda = partial(
|
|
122
|
+
_get_cosine_schedule_with_warmup_lr_lambda,
|
|
123
|
+
num_warmup_steps=num_warmup_steps,
|
|
124
|
+
num_training_steps=num_training_steps,
|
|
125
|
+
num_cycles=num_cycles,
|
|
126
|
+
)
|
|
127
|
+
return LambdaLR(optimizer, lr_lambda, last_epoch)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class LRSchedulerConfigBase(Conf):
|
|
131
|
+
|
|
132
|
+
def init_lr_scheduler(self, optimizer: Optimizer, **kwargs) -> LRScheduler:
|
|
133
|
+
raise NotImplementedError(
|
|
134
|
+
'Please Implement this method in child classes!'
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class ConstantScheduleWithWarmupConfig(LRSchedulerConfigBase):
|
|
139
|
+
|
|
140
|
+
num_warmup_steps= IntArg(0, min_value=0)
|
|
141
|
+
last_epoch= IntArg(-1, min_value=-1)
|
|
142
|
+
|
|
143
|
+
def init_lr_scheduler(self, optimizer: Optimizer, **kwargs) -> LRScheduler:
|
|
144
|
+
return get_constant_schedule_with_warmup(
|
|
145
|
+
optimizer=optimizer,
|
|
146
|
+
num_warmup_steps=self.num_warmup_steps.value(), # type: ignore
|
|
147
|
+
last_epoch=self.last_epoch.value() # type: ignore
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class LienarScheduleWithWarmup(LRSchedulerConfigBase):
|
|
152
|
+
|
|
153
|
+
num_warmup_steps= IntArg(0, min_value=0)
|
|
154
|
+
num_training_steps= IntArg(10000, min_value=1)
|
|
155
|
+
last_epoch= IntArg(-1, min_value=-1)
|
|
156
|
+
|
|
157
|
+
def init_lr_scheduler(self, optimizer: Optimizer, **kwargs) -> LRScheduler:
|
|
158
|
+
return get_linear_schedule_with_warmup(
|
|
159
|
+
optimizer=optimizer,
|
|
160
|
+
num_warmup_steps=self.num_warmup_steps.value(), # type: ignore
|
|
161
|
+
num_training_steps=self.num_training_steps.value(), # type: ignore
|
|
162
|
+
last_epoch=self.last_epoch.value() # type: ignore
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class CosineScheduleWithWarmu(LRSchedulerConfigBase):
|
|
167
|
+
|
|
168
|
+
num_warmup_steps= IntArg(0, min_value=0)
|
|
169
|
+
num_training_steps= IntArg(10000, min_value=1)
|
|
170
|
+
num_cycles= FloatArg(0.5, min_value=0.0, max_value=1.0)
|
|
171
|
+
last_epoch= IntArg(-1, min_value=-1)
|
|
172
|
+
|
|
173
|
+
def init_lr_scheduler(self, optimizer: Optimizer, **kwargs) -> LRScheduler:
|
|
174
|
+
return get_cosine_schedule_with_warmup(
|
|
175
|
+
optimizer=optimizer,
|
|
176
|
+
num_warmup_steps=self.num_warmup_steps.value(), # type: ignore
|
|
177
|
+
num_training_steps=self.num_training_steps.value(), # type: ignore
|
|
178
|
+
num_cycles=self.num_cycles.value(), # type: ignore
|
|
179
|
+
last_epoch=self.last_epoch.value() # type: ignore
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@add_dependency('type', 'scheduler')
|
|
184
|
+
class LRSchedulerConfig(LRSchedulerConfigBase):
|
|
185
|
+
|
|
186
|
+
type = OptionArg(
|
|
187
|
+
options=[
|
|
188
|
+
'constant_schedule_with_warmup',
|
|
189
|
+
'linear_schedule_with_warmup',
|
|
190
|
+
'cosine_schedule_with_warmup'
|
|
191
|
+
],
|
|
192
|
+
default='constant_schedule_with_warmup',
|
|
193
|
+
)
|
|
194
|
+
scheduler = ConstantScheduleWithWarmupConfig()
|
|
195
|
+
|
|
196
|
+
def init_lr_scheduler(self, optimizer: Optimizer, **kwargs) -> LRScheduler:
|
|
197
|
+
return self.scheduler.init_lr_scheduler(optimizer, **kwargs)
|
|
198
|
+
|
|
199
|
+
@monitor_on('type')
|
|
200
|
+
def set_scheduler(self) -> None:
|
|
201
|
+
if self.type.value() == 'constant_schedule_with_warmup' and not isinstance(self.scheduler, ConstantScheduleWithWarmupConfig):
|
|
202
|
+
self.scheduler = ConstantScheduleWithWarmupConfig()
|
|
203
|
+
elif self.type.value() == 'linear_schedule_with_warmup' and not isinstance(self.scheduler, LienarScheduleWithWarmup):
|
|
204
|
+
self.scheduler = LienarScheduleWithWarmup()
|
|
205
|
+
elif self.type.value() == 'cosine_schedule_with_warmup' and not isinstance(self.scheduler, CosineScheduleWithWarmu):
|
|
206
|
+
self.scheduler = CosineScheduleWithWarmu()
|
|
207
|
+
|
|
208
|
+
if __name__ == '__main__':
|
|
209
|
+
conf = LRSchedulerConfig.parse_command_line()
|
|
210
|
+
print(conf)
|
lmfuser/task.py
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import TypeVar, Any, Callable
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
|
|
5
|
+
import torch
|
|
6
|
+
from torch import nn
|
|
7
|
+
from lmfuser_data.interfaces import Batch, Row
|
|
8
|
+
from lmfuser_data.scanners import Scanner
|
|
9
|
+
from lmfuser_data import DataLoader
|
|
10
|
+
from lmfuser_data.interfaces import SubclassTracer
|
|
11
|
+
from hyperargs import Conf, StrArg, FloatArg, IntArg, OptionArg, add_dependency, monitor_on
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def scanner_type_list() -> list[str]:
|
|
15
|
+
return list(Scanner.all_subclass_names())
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@add_dependency('num_train_data_path', 'train_data_path_list')
|
|
19
|
+
@add_dependency('num_train_data_path', 'train_data_weights')
|
|
20
|
+
class TaskBase(Conf, SubclassTracer):
|
|
21
|
+
num_train_data_path = IntArg(1, min_value=0)
|
|
22
|
+
train_data_path_list = [StrArg('Enther the path to the data file.')]
|
|
23
|
+
train_data_weights = [FloatArg(1.0, min_value=0.0, max_value=1.0)]
|
|
24
|
+
|
|
25
|
+
num_eval_data_path = IntArg(1, min_value=0)
|
|
26
|
+
eval_data_path_list = [StrArg('Enther the path to the data file.')]
|
|
27
|
+
eval_data_weights = [FloatArg(1.0, min_value=0.0, max_value=1.0)]
|
|
28
|
+
|
|
29
|
+
scanner_type = OptionArg(default='C4Scanner', option_fn=scanner_type_list)
|
|
30
|
+
|
|
31
|
+
_train_dataloader: DataLoader | None = None
|
|
32
|
+
_eval_dataloader: DataLoader | None = None
|
|
33
|
+
|
|
34
|
+
@monitor_on('num_train_data_path')
|
|
35
|
+
def set_train_path_list(self) -> None:
|
|
36
|
+
num = self.num_train_data_path.value()
|
|
37
|
+
assert isinstance(num, int)
|
|
38
|
+
if len(self.train_data_path_list) > num:
|
|
39
|
+
self.train_data_path_list = self.train_data_path_list[:num]
|
|
40
|
+
self.train_data_weights = self.train_data_weights[:num]
|
|
41
|
+
elif len(self.train_data_path_list) < num:
|
|
42
|
+
self.train_data_path_list += [StrArg('Enther the path to the data file.')] * (num - len(self.train_data_path_list))
|
|
43
|
+
self.train_data_weights += [FloatArg(1.0, min_value=0.0, max_value=1.0)] * (num - len(self.train_data_weights))
|
|
44
|
+
|
|
45
|
+
@monitor_on('num_eval_data_path')
|
|
46
|
+
def set_eval_path_list(self) -> None:
|
|
47
|
+
num = self.num_eval_data_path.value()
|
|
48
|
+
assert isinstance(num, int)
|
|
49
|
+
if len(self.eval_data_path_list) > num:
|
|
50
|
+
self.eval_data_path_list = self.eval_data_path_list[:num]
|
|
51
|
+
self.eval_data_weights = self.eval_data_weights[:num]
|
|
52
|
+
elif len(self.eval_data_path_list) < num:
|
|
53
|
+
self.eval_data_path_list += [StrArg('Enther the path to the data file.')] * (num - len(self.train_data_path_list))
|
|
54
|
+
self.eval_data_weights += [FloatArg(1.0, min_value=0.0, max_value=1.0)] * (num - len(self.train_data_weights))
|
|
55
|
+
|
|
56
|
+
def _get_train_dataloader(
|
|
57
|
+
self,
|
|
58
|
+
batch_size: int,
|
|
59
|
+
seed: int,
|
|
60
|
+
shuffle: bool,
|
|
61
|
+
prefetch_factor: int,
|
|
62
|
+
ignore_error: bool,
|
|
63
|
+
qps: float | None,
|
|
64
|
+
instruct_timeout: float,
|
|
65
|
+
worker_timeout: float,
|
|
66
|
+
num_workers: int,
|
|
67
|
+
rank: int,
|
|
68
|
+
world_size: int
|
|
69
|
+
) -> DataLoader | None:
|
|
70
|
+
if self.num_train_data_path.value() == 0:
|
|
71
|
+
return None
|
|
72
|
+
if self._train_dataloader is not None:
|
|
73
|
+
return self._train_dataloader
|
|
74
|
+
path_list = [p.value() for p in self.train_data_path_list]
|
|
75
|
+
weight_list = [w.value() for w in self.train_data_weights]
|
|
76
|
+
scanner_type = self.scanner_type.value()
|
|
77
|
+
assert scanner_type is not None, 'scanner_type is None'
|
|
78
|
+
|
|
79
|
+
self._train_dataloader = DataLoader(
|
|
80
|
+
batch_size=batch_size,
|
|
81
|
+
path_list=path_list, # type: ignore
|
|
82
|
+
distributor_weights=weight_list, # type: ignore
|
|
83
|
+
scanner_type=Scanner.get_subclass(scanner_type),
|
|
84
|
+
seed=seed,
|
|
85
|
+
shuffle=shuffle,
|
|
86
|
+
pre_fetch_factor=prefetch_factor,
|
|
87
|
+
ignore_error=ignore_error,
|
|
88
|
+
qps=qps,
|
|
89
|
+
instruct_timeout=instruct_timeout,
|
|
90
|
+
worker_timeout=worker_timeout,
|
|
91
|
+
num_workers=num_workers,
|
|
92
|
+
map_fn=self.get_row_processor(),
|
|
93
|
+
flow_fn=self.get_flow_processor(),
|
|
94
|
+
batch_map_fn=self.get_batch_processor(),
|
|
95
|
+
rank_idx=rank,
|
|
96
|
+
num_ranks=world_size,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return self._train_dataloader
|
|
100
|
+
|
|
101
|
+
def _get_eval_dataloader(
|
|
102
|
+
self,
|
|
103
|
+
batch_size: int,
|
|
104
|
+
seed: int,
|
|
105
|
+
shuffle: bool,
|
|
106
|
+
prefetch_factor: int,
|
|
107
|
+
ignore_error: bool,
|
|
108
|
+
qps: float | None,
|
|
109
|
+
instruct_timeout: float,
|
|
110
|
+
worker_timeout: float,
|
|
111
|
+
num_workers: int,
|
|
112
|
+
rank: int,
|
|
113
|
+
world_size: int
|
|
114
|
+
) -> DataLoader | None:
|
|
115
|
+
if self.num_eval_data_path.value() == 0:
|
|
116
|
+
return None
|
|
117
|
+
if self._eval_dataloader is not None:
|
|
118
|
+
return self._eval_dataloader
|
|
119
|
+
path_list = [p.value() for p in self.eval_data_path_list]
|
|
120
|
+
weight_list = [w.value() for w in self.eval_data_weights]
|
|
121
|
+
scanner_type = self.scanner_type.value()
|
|
122
|
+
assert scanner_type is not None, 'scanner_type is None'
|
|
123
|
+
self._eval_dataloader = DataLoader(
|
|
124
|
+
batch_size=batch_size,
|
|
125
|
+
path_list=path_list, # type: ignore
|
|
126
|
+
distributor_weights=weight_list, # type: ignore
|
|
127
|
+
scanner_type=Scanner.get_subclass(scanner_type),
|
|
128
|
+
seed=seed,
|
|
129
|
+
shuffle=shuffle,
|
|
130
|
+
pre_fetch_factor=prefetch_factor,
|
|
131
|
+
ignore_error=ignore_error,
|
|
132
|
+
qps=qps,
|
|
133
|
+
instruct_timeout=instruct_timeout,
|
|
134
|
+
worker_timeout=worker_timeout,
|
|
135
|
+
num_workers=num_workers,
|
|
136
|
+
map_fn=self.get_row_processor(),
|
|
137
|
+
flow_fn=self.get_flow_processor(),
|
|
138
|
+
batch_map_fn=self.get_batch_processor(),
|
|
139
|
+
rank_idx=rank,
|
|
140
|
+
num_ranks=world_size,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return self._eval_dataloader
|
|
144
|
+
|
|
145
|
+
def train_step(
|
|
146
|
+
self, model: nn.Module,
|
|
147
|
+
batch: Batch,
|
|
148
|
+
step: int,
|
|
149
|
+
device: Any,
|
|
150
|
+
acc_step: int,
|
|
151
|
+
**kwargs: Any
|
|
152
|
+
) -> Batch | torch.Tensor:
|
|
153
|
+
raise NotImplementedError('Please implement this method in child class')
|
|
154
|
+
|
|
155
|
+
def eval_step(
|
|
156
|
+
self,
|
|
157
|
+
model: nn.Module,
|
|
158
|
+
batch: Batch,
|
|
159
|
+
step: int,
|
|
160
|
+
device: Any,
|
|
161
|
+
**kwargs: Any
|
|
162
|
+
) -> dict[str, list[Any]]:
|
|
163
|
+
raise NotImplementedError('Please implement this method in child class')
|
|
164
|
+
|
|
165
|
+
def cal_dev_metric(self, eval_outputs: dict[str, list[Any]]) -> dict[str, Any]:
|
|
166
|
+
raise NotImplementedError('Please implement this method in child class')
|
|
167
|
+
|
|
168
|
+
def get_row_processor(self) -> Callable[[Row], Row] | None:
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
def get_flow_processor(self) -> Callable[[Iterable[Row]], Iterable[Row]] | None:
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
def get_batch_processor(self) -> Callable[[Batch], Batch] | None:
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class Task(TaskBase):
|
|
179
|
+
pass
|
|
180
|
+
|
|
181
|
+
def task_list() -> list[str]:
|
|
182
|
+
return list(TaskBase.all_subclass_names())
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@add_dependency('conf', 'task_name')
|
|
186
|
+
class TaskSelector(Conf):
|
|
187
|
+
task_name = OptionArg(default='Task', option_fn=task_list)
|
|
188
|
+
conf: TaskBase = Task()
|
|
189
|
+
|
|
190
|
+
@monitor_on('task_name')
|
|
191
|
+
def change_conf(self) -> None:
|
|
192
|
+
name = self.task_name.value()
|
|
193
|
+
if name is None:
|
|
194
|
+
self.conf = Task()
|
|
195
|
+
|
|
196
|
+
elif name != self.conf.__class__.__name__:
|
|
197
|
+
self.conf = TaskBase.all_subclass_map()[name]()
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@add_dependency('num_tasks', 'tasks')
|
|
201
|
+
class Tasks(Conf):
|
|
202
|
+
num_tasks = IntArg(1, min_value=1)
|
|
203
|
+
tasks = [TaskSelector()]
|
|
204
|
+
task_weights = [FloatArg(1.0, min_value=0.0, max_value=1.0)]
|
|
205
|
+
|
|
206
|
+
@monitor_on('num_tasks')
|
|
207
|
+
def change_task_list(self) -> None:
|
|
208
|
+
num = self.num_tasks.value()
|
|
209
|
+
assert num is not None, 'num_tasks is None'
|
|
210
|
+
|
|
211
|
+
if len(self.tasks) > num:
|
|
212
|
+
self.tasks = self.tasks[:num]
|
|
213
|
+
self.task_weight = self.task_weight[:num]
|
|
214
|
+
elif len(self.tasks) < num:
|
|
215
|
+
self.tasks += [TaskSelector() for _ in range(num - len(self.tasks))]
|
|
216
|
+
self.task_weight += [
|
|
217
|
+
FloatArg(1.0, min_value=0.0, max_value=1.0) for _ in range(num - len(self.task_weight))
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
def get_train_dataloaders(
|
|
221
|
+
self,
|
|
222
|
+
batch_size: int,
|
|
223
|
+
seed: int,
|
|
224
|
+
shuffle: bool,
|
|
225
|
+
prefetch_factor: int,
|
|
226
|
+
ignore_error: bool,
|
|
227
|
+
qps: float | None,
|
|
228
|
+
instruct_timeout: float,
|
|
229
|
+
worker_timeout: float,
|
|
230
|
+
num_workers: int,
|
|
231
|
+
rank: int,
|
|
232
|
+
world_size: int
|
|
233
|
+
) -> list[DataLoader | None]:
|
|
234
|
+
return [
|
|
235
|
+
task.conf._get_train_dataloader(
|
|
236
|
+
batch_size=batch_size,
|
|
237
|
+
seed=seed,
|
|
238
|
+
shuffle=shuffle,
|
|
239
|
+
prefetch_factor=prefetch_factor,
|
|
240
|
+
ignore_error=ignore_error,
|
|
241
|
+
qps=qps,
|
|
242
|
+
instruct_timeout=instruct_timeout,
|
|
243
|
+
worker_timeout=worker_timeout,
|
|
244
|
+
num_workers=num_workers,
|
|
245
|
+
rank=rank,
|
|
246
|
+
world_size=world_size,
|
|
247
|
+
)
|
|
248
|
+
for task in self.tasks
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
def get_eval_dataloaders(
|
|
252
|
+
self,
|
|
253
|
+
batch_size: int,
|
|
254
|
+
seed: int,
|
|
255
|
+
shuffle: bool,
|
|
256
|
+
prefetch_factor: int,
|
|
257
|
+
ignore_error: bool,
|
|
258
|
+
qps: float | None,
|
|
259
|
+
instruct_timeout: float,
|
|
260
|
+
worker_timeout: float,
|
|
261
|
+
num_workers: int,
|
|
262
|
+
rank: int,
|
|
263
|
+
world_size: int
|
|
264
|
+
) -> list[DataLoader | None]:
|
|
265
|
+
return [
|
|
266
|
+
task.conf._get_eval_dataloader(
|
|
267
|
+
batch_size=batch_size,
|
|
268
|
+
seed=seed,
|
|
269
|
+
shuffle=shuffle,
|
|
270
|
+
prefetch_factor=prefetch_factor,
|
|
271
|
+
ignore_error=ignore_error,
|
|
272
|
+
qps=qps,
|
|
273
|
+
instruct_timeout=instruct_timeout,
|
|
274
|
+
worker_timeout=worker_timeout,
|
|
275
|
+
num_workers=num_workers,
|
|
276
|
+
rank=rank,
|
|
277
|
+
world_size=world_size,
|
|
278
|
+
)
|
|
279
|
+
for task in self.tasks
|
|
280
|
+
]
|
|
281
|
+
|
|
282
|
+
if __name__ == '__main__':
|
|
283
|
+
class TaskTemp(Task):
|
|
284
|
+
pass
|
|
285
|
+
|
|
286
|
+
conf = Tasks.parse_command_line()
|
|
287
|
+
print(conf)
|