kostyl-toolkit 0.1.37__py3-none-any.whl → 0.1.38__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.
Files changed (30) hide show
  1. kostyl/ml/base_uploader.py +17 -0
  2. kostyl/ml/configs/__init__.py +2 -2
  3. kostyl/ml/configs/mixins.py +50 -0
  4. kostyl/ml/{data_processing_utils.py → data_collator.py} +6 -3
  5. kostyl/ml/dist_utils.py +2 -4
  6. kostyl/ml/integrations/clearml/__init__.py +7 -0
  7. kostyl/ml/{registry_uploader.py → integrations/clearml/checkpoint_uploader.py} +3 -13
  8. kostyl/ml/{configs/base_model.py → integrations/clearml/config_mixin.py} +7 -63
  9. kostyl/ml/{clearml/pulling_utils.py → integrations/clearml/loading_utils.py} +32 -5
  10. kostyl/ml/integrations/lightning/__init__.py +14 -0
  11. kostyl/ml/{lightning → integrations/lightning}/callbacks/checkpoint.py +25 -40
  12. kostyl/ml/{lightning/extensions/custom_module.py → integrations/lightning/module.py} +2 -33
  13. kostyl/ml/schedulers/__init__.py +4 -4
  14. kostyl/ml/schedulers/{cosine_with_plateu.py → plateau.py} +59 -36
  15. {kostyl_toolkit-0.1.37.dist-info → kostyl_toolkit-0.1.38.dist-info}/METADATA +1 -1
  16. kostyl_toolkit-0.1.38.dist-info/RECORD +40 -0
  17. {kostyl_toolkit-0.1.37.dist-info → kostyl_toolkit-0.1.38.dist-info}/WHEEL +2 -2
  18. kostyl/ml/lightning/__init__.py +0 -5
  19. kostyl/ml/lightning/extensions/__init__.py +0 -5
  20. kostyl_toolkit-0.1.37.dist-info/RECORD +0 -38
  21. /kostyl/ml/{clearml → integrations}/__init__.py +0 -0
  22. /kostyl/ml/{clearml → integrations/clearml}/dataset_utils.py +0 -0
  23. /kostyl/ml/{clearml/logging_utils.py → integrations/clearml/version_utils.py} +0 -0
  24. /kostyl/ml/{lightning → integrations/lightning}/callbacks/__init__.py +0 -0
  25. /kostyl/ml/{lightning → integrations/lightning}/callbacks/early_stopping.py +0 -0
  26. /kostyl/ml/{lightning → integrations/lightning}/loggers/__init__.py +0 -0
  27. /kostyl/ml/{lightning → integrations/lightning}/loggers/tb_logger.py +0 -0
  28. /kostyl/ml/{metrics_formatting.py → integrations/lightning/metrics_formatting.py} +0 -0
  29. /kostyl/ml/{lightning/extensions/pretrained_model.py → integrations/lightning/mixins.py} +0 -0
  30. /kostyl/ml/{lightning → integrations/lightning}/utils.py +0 -0
@@ -0,0 +1,17 @@
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+ from pathlib import Path
4
+
5
+ from kostyl.utils.logging import setup_logger
6
+
7
+
8
+ logger = setup_logger()
9
+
10
+
11
+ class ModelCheckpointUploader(ABC):
12
+ """Abstract base class for uploading model checkpoints to a registry backend."""
13
+
14
+ @abstractmethod
15
+ def upload_checkpoint(self, path: str | Path) -> None:
16
+ """Upload the checkpoint located at the given path to the configured registry backend."""
17
+ raise NotImplementedError
@@ -1,8 +1,8 @@
1
- from .base_model import KostylBaseModel
2
1
  from .hyperparams import HyperparamsConfig
3
2
  from .hyperparams import Lr
4
3
  from .hyperparams import Optimizer
5
4
  from .hyperparams import WeightDecay
5
+ from .mixins import ConfigLoadingMixin
6
6
  from .training_settings import CheckpointConfig
7
7
  from .training_settings import DataConfig
8
8
  from .training_settings import DDPStrategyConfig
@@ -15,12 +15,12 @@ from .training_settings import TrainingSettings
15
15
 
16
16
  __all__ = [
17
17
  "CheckpointConfig",
18
+ "ConfigLoadingMixin",
18
19
  "DDPStrategyConfig",
19
20
  "DataConfig",
20
21
  "EarlyStoppingConfig",
21
22
  "FSDP1StrategyConfig",
22
23
  "HyperparamsConfig",
23
- "KostylBaseModel",
24
24
  "LightningTrainerParameters",
25
25
  "Lr",
26
26
  "Optimizer",
@@ -0,0 +1,50 @@
1
+ from pathlib import Path
2
+
3
+ from pydantic import BaseModel as PydanticBaseModel
4
+
5
+ from kostyl.utils.fs import load_config
6
+
7
+
8
+ class ConfigLoadingMixin[TConfig: PydanticBaseModel]:
9
+ """Mixin providing configuration loading functionality for Pydantic models."""
10
+
11
+ @classmethod
12
+ def from_file(
13
+ cls: type[TConfig], # pyright: ignore
14
+ path: str | Path,
15
+ ) -> TConfig:
16
+ """
17
+ Create an instance of the class from a configuration file.
18
+
19
+ Args:
20
+ cls_: The class type to instantiate.
21
+ path (str | Path): Path to the configuration file.
22
+
23
+ Returns:
24
+ An instance of the class created from the configuration file.
25
+
26
+ """
27
+ config = load_config(path)
28
+ instance = cls.model_validate(config)
29
+ return instance
30
+
31
+ @classmethod
32
+ def from_dict(
33
+ cls: type[TConfig], # pyright: ignore
34
+ state_dict: dict,
35
+ ) -> TConfig:
36
+ """
37
+ Creates an instance from a dictionary.
38
+
39
+ Args:
40
+ cls_: The class type to instantiate.
41
+ state_dict (dict): A dictionary representing the state of the
42
+ class that must be validated and used for initialization.
43
+
44
+ Returns:
45
+ An initialized instance of the class based on the
46
+ provided state dictionary.
47
+
48
+ """
49
+ instance = cls.model_validate(state_dict)
50
+ return instance
@@ -36,6 +36,7 @@ class BatchCollatorWithKeyAlignment:
36
36
  keys_mapping: A dictionary mapping original keys to new keys.
37
37
  keys_to_keep: A set of keys to retain as-is from the original items.
38
38
  max_length: If provided, truncates "input_ids" and "attention_mask" to this length.
39
+ Only 1D tensors/lists are supported.
39
40
 
40
41
  Raises:
41
42
  ValueError: If both `keys_mapping` and `keys_to_keep` are None.
@@ -59,14 +60,16 @@ class BatchCollatorWithKeyAlignment:
59
60
  def _truncate_data(self, key: str, value: Any) -> Any:
60
61
  match value:
61
62
  case torch.Tensor():
62
- if value.dim() > 2:
63
+ if value.dim() >= 2:
63
64
  raise ValueError(
64
- f"Expected value with dim <= 2 for key {key}, got {value.dim()}"
65
+ f"Expected tensor with dim < 2 for key {key}, got {value.dim()}. "
66
+ "Check your data or disable truncation with `max_length=None`."
65
67
  )
66
68
  case list():
67
69
  if isinstance(value[0], list):
68
70
  raise ValueError(
69
- f"Expected value with dim <= 2 for key {key}, got nested lists"
71
+ f"Expected value with dim <= 2 for key {key}, got nested lists. "
72
+ "Check your data or disable truncation with `max_length=None`."
70
73
  )
71
74
  value = value[: self.max_length]
72
75
  return value
kostyl/ml/dist_utils.py CHANGED
@@ -40,7 +40,7 @@ def log_dist(
40
40
 
41
41
  if not dist.is_initialized():
42
42
  module_logger.warning_once(
43
- "Distributed process group is not initialized; logging from all ranks."
43
+ "Distributed process group is not initialized. Logging from the current process only."
44
44
  )
45
45
  log_attr(msg)
46
46
  return
@@ -65,7 +65,6 @@ def log_dist(
65
65
  def scale_lrs_by_world_size(
66
66
  lrs: dict[str, float],
67
67
  group: dist.ProcessGroup | None = None,
68
- config_name: str = "",
69
68
  inv_scale: bool = False,
70
69
  verbose_level: Literal["only-zero-rank", "world"] | None = None,
71
70
  ) -> dict[str, float]:
@@ -79,7 +78,6 @@ def scale_lrs_by_world_size(
79
78
  lrs (dict[str, float]): A dictionary of learning rate names and their corresponding values to be scaled.
80
79
  group (dist.ProcessGroup | None): Optional process group used to determine
81
80
  the target world size. Defaults to the global process group.
82
- config_name (str): Human-readable identifier included in log messages.
83
81
  inv_scale (bool): If True, use the inverse square-root scale factor.
84
82
  verbose_level (Literal["only-zero-rank", "world"] | None): Verbosity level for logging scaled values.
85
83
  - "only-zero-rank": Log only from the main process (rank 0).
@@ -102,7 +100,7 @@ def scale_lrs_by_world_size(
102
100
  new_value = value * scale
103
101
  if verbose_level is not None:
104
102
  log_dist(
105
- f"New {config_name} lr {name.upper()}: {new_value}; OLD: {old_value}",
103
+ f"lr {name.upper()}: {new_value}; OLD: {old_value}",
106
104
  log_scope=verbose_level,
107
105
  group=group,
108
106
  )
@@ -0,0 +1,7 @@
1
+ try:
2
+ import clearml # noqa: F401
3
+ except ImportError as e:
4
+ raise ImportError(
5
+ "ClearML integration requires the 'clearml' package. "
6
+ "Please install it via 'pip install clearml'."
7
+ ) from e
@@ -1,5 +1,3 @@
1
- from abc import ABC
2
- from abc import abstractmethod
3
1
  from collections.abc import Callable
4
2
  from functools import partial
5
3
  from pathlib import Path
@@ -7,22 +5,14 @@ from typing import override
7
5
 
8
6
  from clearml import OutputModel
9
7
 
8
+ from kostyl.ml.base_uploader import ModelCheckpointUploader
10
9
  from kostyl.utils.logging import setup_logger
11
10
 
12
11
 
13
12
  logger = setup_logger()
14
13
 
15
14
 
16
- class RegistryUploaderCallback(ABC):
17
- """Abstract Lightning callback responsible for tracking and uploading the best-performing model checkpoint."""
18
-
19
- @abstractmethod
20
- def upload_checkpoint(self, path: str | Path) -> None:
21
- """Upload the checkpoint located at the given path to the configured registry backend."""
22
- raise NotImplementedError
23
-
24
-
25
- class ClearMLRegistryUploaderCallback(RegistryUploaderCallback):
15
+ class ClearMLCheckpointUploader(ModelCheckpointUploader):
26
16
  """PyTorch Lightning callback to upload the best model checkpoint to ClearML."""
27
17
 
28
18
  def __init__(
@@ -38,7 +28,7 @@ class ClearMLRegistryUploaderCallback(RegistryUploaderCallback):
38
28
  verbose: bool = True,
39
29
  ) -> None:
40
30
  """
41
- Initializes the ClearMLRegistryUploaderCallback.
31
+ Initializes the ClearMLRegistryUploader.
42
32
 
43
33
  Args:
44
34
  model_name: The name for the newly created model.
@@ -1,75 +1,25 @@
1
1
  from pathlib import Path
2
- from typing import Self
3
- from typing import TypeVar
4
2
 
5
3
  from caseconverter import pascalcase
6
4
  from caseconverter import snakecase
7
5
  from clearml import Task
8
- from pydantic import BaseModel as PydanticBaseModel
9
6
 
7
+ from kostyl.ml.configs import ConfigLoadingMixin
10
8
  from kostyl.utils.dict_manipulations import convert_to_flat_dict
11
9
  from kostyl.utils.dict_manipulations import flattened_dict_to_nested
12
10
  from kostyl.utils.fs import load_config
13
11
 
14
12
 
15
- TConfig = TypeVar("TConfig", bound=PydanticBaseModel)
16
-
17
-
18
- class BaseModelWithConfigLoading(PydanticBaseModel):
19
- """Pydantic class providing basic configuration loading functionality."""
20
-
21
- @classmethod
22
- def from_file(
23
- cls: type[Self], # pyright: ignore
24
- path: str | Path,
25
- ) -> Self:
26
- """
27
- Create an instance of the class from a configuration file.
28
-
29
- Args:
30
- cls_: The class type to instantiate.
31
- path (str | Path): Path to the configuration file.
32
-
33
- Returns:
34
- An instance of the class created from the configuration file.
35
-
36
- """
37
- config = load_config(path)
38
- instance = cls.model_validate(config)
39
- return instance
40
-
41
- @classmethod
42
- def from_dict(
43
- cls: type[Self], # pyright: ignore
44
- state_dict: dict,
45
- ) -> Self:
46
- """
47
- Creates an instance from a dictionary.
48
-
49
- Args:
50
- cls_: The class type to instantiate.
51
- state_dict (dict): A dictionary representing the state of the
52
- class that must be validated and used for initialization.
53
-
54
- Returns:
55
- An initialized instance of the class based on the
56
- provided state dictionary.
57
-
58
- """
59
- instance = cls.model_validate(state_dict)
60
- return instance
61
-
62
-
63
- class BaseModelWithClearmlSyncing(BaseModelWithConfigLoading):
64
- """Pydantic class providing ClearML configuration loading and syncing functionality."""
13
+ class BaseModelWithClearmlSyncing[TConfig: ConfigLoadingMixin]:
14
+ """Mixin providing ClearML task configuration syncing functionality for Pydantic models."""
65
15
 
66
16
  @classmethod
67
17
  def connect_as_file(
68
- cls: type[Self], # pyright: ignore
18
+ cls: type[TConfig], # pyright: ignore
69
19
  task: Task,
70
20
  path: str | Path,
71
21
  alias: str | None = None,
72
- ) -> Self:
22
+ ) -> TConfig:
73
23
  """
74
24
  Connects the configuration file to a ClearML task and creates an instance of the class from it.
75
25
 
@@ -104,11 +54,11 @@ class BaseModelWithClearmlSyncing(BaseModelWithConfigLoading):
104
54
 
105
55
  @classmethod
106
56
  def connect_as_dict(
107
- cls: type[Self], # pyright: ignore
57
+ cls: type[TConfig], # pyright: ignore
108
58
  task: Task,
109
59
  path: str | Path,
110
60
  alias: str | None = None,
111
- ) -> Self:
61
+ ) -> TConfig:
112
62
  """
113
63
  Connects configuration from a file as a dictionary to a ClearML task and creates an instance of the class.
114
64
 
@@ -135,9 +85,3 @@ class BaseModelWithClearmlSyncing(BaseModelWithConfigLoading):
135
85
 
136
86
  model = cls.from_dict(state_dict=config)
137
87
  return model
138
-
139
-
140
- class KostylBaseModel(BaseModelWithClearmlSyncing):
141
- """A Pydantic model class with basic configuration loading functionality."""
142
-
143
- pass
@@ -9,9 +9,26 @@ from transformers import AutoTokenizer
9
9
  from transformers import PreTrainedModel
10
10
  from transformers import PreTrainedTokenizerBase
11
11
 
12
- from kostyl.ml.lightning.extensions.pretrained_model import (
13
- LightningCheckpointLoaderMixin,
14
- )
12
+
13
+ try:
14
+ from kostyl.ml.integrations.lightning import (
15
+ LightningCheckpointLoaderMixin, # pyright: ignore[reportAssignmentType]
16
+ )
17
+
18
+ LIGHTING_MIXIN_AVAILABLE = True
19
+ except ImportError:
20
+
21
+ class LightningCheckpointLoaderMixin(PreTrainedModel): # noqa: D101
22
+ pass # type: ignore
23
+
24
+ @classmethod
25
+ def from_lightning_checkpoint(cls, *args: Any, **kwargs: Any) -> Any: # noqa: D103
26
+ raise ImportError(
27
+ "Loading from Lightning checkpoints requires lightning integration. "
28
+ "Please package install via 'pip install lightning' to enable this functionality."
29
+ )
30
+
31
+ LIGHTING_MIXIN_AVAILABLE = False
15
32
 
16
33
 
17
34
  def get_tokenizer_from_clearml(
@@ -89,13 +106,23 @@ def get_model_from_clearml[
89
106
  local_path = Path(input_model.get_local_copy(raise_on_error=True))
90
107
 
91
108
  if local_path.is_dir() and input_model._is_package():
109
+ if not issubclass(model, (PreTrainedModel, AutoModel)):
110
+ raise ValueError(
111
+ f"Model class {model.__name__} must be a subclass of PreTrainedModel or AutoModel for directory loads."
112
+ )
92
113
  model_instance = model.from_pretrained(local_path, **kwargs)
93
114
  elif local_path.suffix == ".ckpt":
115
+ if not LIGHTING_MIXIN_AVAILABLE:
116
+ raise ImportError(
117
+ "Loading from Lightning checkpoints requires lightning integration. "
118
+ "Please package install via 'pip install lightning' to enable this functionality."
119
+ )
94
120
  if not issubclass(model, LightningCheckpointLoaderMixin):
95
121
  raise ValueError(
96
- f"Model class {model.__name__} is not compatible with Lightning checkpoints."
122
+ f"Model class {model.__name__} is not compatible with Lightning checkpoints "
123
+ "(must inherit from LightningCheckpointLoaderMixin)."
97
124
  )
98
- model_instance = model.from_lightning_checkpoint(local_path, **kwargs)
125
+ model_instance = model.from_lightning_checkpoint(local_path, **kwargs) # type: ignore
99
126
  else:
100
127
  raise ValueError(
101
128
  f"Unsupported model format for path: {local_path}. "
@@ -0,0 +1,14 @@
1
+ try:
2
+ import lightning # noqa: F401
3
+ except ImportError as e:
4
+ raise ImportError(
5
+ "Lightning integration requires the 'lightning' package. "
6
+ "Please install it via 'pip install lightning'."
7
+ ) from e
8
+
9
+
10
+ from .mixins import LightningCheckpointLoaderMixin
11
+ from .module import KostylLightningModule
12
+
13
+
14
+ __all__ = ["KostylLightningModule", "LightningCheckpointLoaderMixin"]
@@ -9,17 +9,16 @@ import torch.distributed as dist
9
9
  from lightning.fabric.utilities.types import _PATH
10
10
  from lightning.pytorch.callbacks import ModelCheckpoint
11
11
 
12
+ from kostyl.ml.base_uploader import ModelCheckpointUploader
12
13
  from kostyl.ml.configs import CheckpointConfig
13
14
  from kostyl.ml.dist_utils import is_local_zero_rank
14
- from kostyl.ml.lightning import KostylLightningModule
15
- from kostyl.ml.registry_uploader import RegistryUploaderCallback
16
15
  from kostyl.utils import setup_logger
17
16
 
18
17
 
19
18
  logger = setup_logger("callbacks/checkpoint.py")
20
19
 
21
20
 
22
- class ModelCheckpointWithRegistryUploader(ModelCheckpoint):
21
+ class ModelCheckpointWithCheckpointUploader(ModelCheckpoint):
23
22
  r"""
24
23
  Save the model after every epoch by monitoring a quantity. Every logged metrics are passed to the
25
24
  :class:`~lightning.pytorch.loggers.logger.Logger` for the version it gets saved in the same directory as the
@@ -229,8 +228,8 @@ class ModelCheckpointWithRegistryUploader(ModelCheckpoint):
229
228
 
230
229
  def __init__( # noqa: D107
231
230
  self,
232
- registry_uploader_callback: RegistryUploaderCallback,
233
- uploading_mode: Literal["only-best", "every-checkpoint"] = "only-best",
231
+ checkpoint_uploader: ModelCheckpointUploader,
232
+ upload_strategy: Literal["only-best", "every-checkpoint"] = "only-best",
234
233
  dirpath: _PATH | None = None,
235
234
  filename: str | None = None,
236
235
  monitor: str | None = None,
@@ -247,9 +246,9 @@ class ModelCheckpointWithRegistryUploader(ModelCheckpoint):
247
246
  save_on_train_epoch_end: bool | None = None,
248
247
  enable_version_counter: bool = True,
249
248
  ) -> None:
250
- self.registry_uploader_callback = registry_uploader_callback
249
+ self.registry_uploader = checkpoint_uploader
251
250
  self.process_group: dist.ProcessGroup | None = None
252
- self.uploading_mode = uploading_mode
251
+ self.upload_strategy = upload_strategy
253
252
  super().__init__(
254
253
  dirpath=dirpath,
255
254
  filename=filename,
@@ -269,40 +268,26 @@ class ModelCheckpointWithRegistryUploader(ModelCheckpoint):
269
268
  )
270
269
  return
271
270
 
272
- @override
273
- def setup(
274
- self,
275
- trainer: pl.Trainer,
276
- pl_module: pl.LightningModule | KostylLightningModule,
277
- stage: str,
278
- ) -> None:
279
- super().setup(trainer, pl_module, stage)
280
- if isinstance(pl_module, KostylLightningModule):
281
- self.process_group = pl_module.get_process_group()
282
- return
283
-
284
271
  @override
285
272
  def _save_checkpoint(self, trainer: "pl.Trainer", filepath: str) -> None:
286
273
  super()._save_checkpoint(trainer, filepath)
287
- if dist.is_initialized():
288
- dist.barrier(group=self.process_group)
289
- if trainer.is_global_zero and self.registry_uploader_callback is not None:
290
- match self.uploading_mode:
274
+ if trainer.is_global_zero and self.registry_uploader is not None:
275
+ match self.upload_strategy:
291
276
  case "every-checkpoint":
292
- self.registry_uploader_callback.upload_checkpoint(filepath)
277
+ self.registry_uploader.upload_checkpoint(filepath)
293
278
  case "only-best":
294
279
  if filepath == self.best_model_path:
295
- self.registry_uploader_callback.upload_checkpoint(filepath)
280
+ self.registry_uploader.upload_checkpoint(filepath)
296
281
  return
297
282
 
298
283
 
299
284
  def setup_checkpoint_callback(
300
285
  dirpath: Path,
301
286
  ckpt_cfg: CheckpointConfig,
302
- registry_uploader_callback: RegistryUploaderCallback | None = None,
303
- uploading_strategy: Literal["only-best", "every-checkpoint"] | None = None,
287
+ checkpoint_uploader: ModelCheckpointUploader | None = None,
288
+ upload_strategy: Literal["only-best", "every-checkpoint"] | None = None,
304
289
  remove_folder_if_exists: bool = True,
305
- ) -> ModelCheckpointWithRegistryUploader | ModelCheckpoint:
290
+ ) -> ModelCheckpointWithCheckpointUploader | ModelCheckpoint:
306
291
  """
307
292
  Create and configure a checkpoint callback for model saving.
308
293
 
@@ -313,29 +298,29 @@ def setup_checkpoint_callback(
313
298
  Args:
314
299
  dirpath: Path to the directory for saving checkpoints.
315
300
  ckpt_cfg: Checkpoint configuration (filename, monitor, mode, save_top_k).
316
- registry_uploader_callback: Optional callback for uploading checkpoints to a remote registry.
317
- Must be specified together with uploading_strategy.
318
- uploading_strategy: Checkpoint upload mode:
301
+ checkpoint_uploader: Optional checkpoint uploader instance. If provided, enables
302
+ uploading of checkpoints to a remote registry.
303
+ upload_strategy: Checkpoint upload mode:
319
304
  - "only-best": only the best checkpoint is uploaded
320
305
  - "every-checkpoint": every saved checkpoint is uploaded
321
- Must be specified together with registry_uploader_callback.
306
+ Must be specified together with checkpoint_uploader.
322
307
  remove_folder_if_exists: If True, removes existing checkpoint directory before creating a new one.
323
308
 
324
309
  Returns:
325
- ModelCheckpointWithRegistryUploader if registry_uploader_callback is provided,
310
+ ModelCheckpointWithCheckpointUploader if checkpoint_uploader is provided,
326
311
  otherwise standard ModelCheckpoint.
327
312
 
328
313
  Raises:
329
- ValueError: If only one of registry_uploader_callback or uploading_mode is None.
314
+ ValueError: If only one of checkpoint_uploader or uploading_mode is None.
330
315
 
331
316
  Note:
332
317
  If the dirpath directory already exists, it will be removed and recreated
333
318
  (only on the main process in distributed training) if remove_folder_if_exists is True.
334
319
 
335
320
  """
336
- if (registry_uploader_callback is None) != (uploading_strategy is None):
321
+ if (checkpoint_uploader is None) != (upload_strategy is None):
337
322
  raise ValueError(
338
- "Both registry_uploader_callback and uploading_mode must be provided or neither."
323
+ "Both checkpoint_uploader and upload_strategy must be provided or neither."
339
324
  )
340
325
 
341
326
  if dirpath.exists():
@@ -348,8 +333,8 @@ def setup_checkpoint_callback(
348
333
  logger.info(f"Creating checkpoint directory {dirpath}.")
349
334
  dirpath.mkdir(parents=True, exist_ok=True)
350
335
 
351
- if (registry_uploader_callback is not None) and (uploading_strategy is not None):
352
- checkpoint_callback = ModelCheckpointWithRegistryUploader(
336
+ if (checkpoint_uploader is not None) and (upload_strategy is not None):
337
+ checkpoint_callback = ModelCheckpointWithCheckpointUploader(
353
338
  dirpath=dirpath,
354
339
  filename=ckpt_cfg.filename,
355
340
  save_top_k=ckpt_cfg.save_top_k,
@@ -357,8 +342,8 @@ def setup_checkpoint_callback(
357
342
  mode=ckpt_cfg.mode,
358
343
  verbose=True,
359
344
  save_weights_only=ckpt_cfg.save_weights_only,
360
- registry_uploader_callback=registry_uploader_callback,
361
- uploading_mode=uploading_strategy,
345
+ checkpoint_uploader=checkpoint_uploader,
346
+ upload_strategy=upload_strategy,
362
347
  )
363
348
  else:
364
349
  checkpoint_callback = ModelCheckpoint(
@@ -5,17 +5,15 @@ from typing import override
5
5
 
6
6
  import lightning as L
7
7
  import torch
8
- import torch.distributed as dist
9
8
  from lightning.pytorch.strategies import FSDPStrategy
10
9
  from torch import nn
11
- from torch.distributed import ProcessGroup
12
10
  from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
13
11
  from torchmetrics import Metric
14
12
  from torchmetrics import MetricCollection
15
13
  from transformers import PretrainedConfig
16
14
  from transformers import PreTrainedModel
17
15
 
18
- from kostyl.ml.metrics_formatting import apply_suffix
16
+ from kostyl.ml.integrations.lightning.metrics_formatting import apply_suffix
19
17
  from kostyl.ml.schedulers.base import BaseScheduler
20
18
  from kostyl.utils import setup_logger
21
19
 
@@ -26,32 +24,6 @@ module_logger = setup_logger(fmt="only_message")
26
24
  class KostylLightningModule(L.LightningModule):
27
25
  """Custom PyTorch Lightning Module with logging, checkpointing, and distributed training utilities."""
28
26
 
29
- def get_process_group(self) -> ProcessGroup | None:
30
- """
31
- Retrieves the data parallel process group for distributed training.
32
-
33
- This method checks if distributed processing is initialized. If a device mesh is provided,
34
- it extracts the data parallel mesh and returns its process group, unless the mesh size is 1,
35
- in which case it logs a warning and returns None. If no device mesh is provided, it returns
36
- the world process group.
37
-
38
- Returns:
39
- ProcessGroup | None: The data parallel process group if available and valid, otherwise None.
40
-
41
- """
42
- if not dist.is_initialized():
43
- return None
44
-
45
- if self.device_mesh is not None:
46
- dp_mesh = self.device_mesh["data_parallel"]
47
- if dp_mesh.size() == 1:
48
- module_logger.warning("Data parallel mesh size is 1, returning None")
49
- return None
50
- dp_pg = dp_mesh.get_group()
51
- else:
52
- dp_pg = dist.group.WORLD
53
- return dp_pg
54
-
55
27
  @property
56
28
  def model_instance(self) -> PreTrainedModel | nn.Module:
57
29
  """Returns the underlying model."""
@@ -60,10 +32,7 @@ class KostylLightningModule(L.LightningModule):
60
32
  @property
61
33
  def model_config(self) -> PretrainedConfig | None:
62
34
  """Returns the model configuration if available."""
63
- model = self.model_instance
64
- if hasattr(model, "config"):
65
- return model.config # type: ignore
66
- return None
35
+ raise NotImplementedError
67
36
 
68
37
  @property
69
38
  def grad_clip_val(self) -> float | None:
@@ -1,18 +1,18 @@
1
1
  from .composite import CompositeScheduler
2
2
  from .cosine import CosineParamScheduler
3
3
  from .cosine import CosineScheduler
4
- from .cosine_with_plateu import CosineWithPlateauParamScheduler
5
- from .cosine_with_plateu import CosineWithPlateuScheduler
6
4
  from .linear import LinearParamScheduler
7
5
  from .linear import LinearScheduler
6
+ from .plateau import PlateauWithAnnealingParamScheduler
7
+ from .plateau import PlateauWithAnnealingScheduler
8
8
 
9
9
 
10
10
  __all__ = [
11
11
  "CompositeScheduler",
12
12
  "CosineParamScheduler",
13
13
  "CosineScheduler",
14
- "CosineWithPlateauParamScheduler",
15
- "CosineWithPlateuScheduler",
16
14
  "LinearParamScheduler",
17
15
  "LinearScheduler",
16
+ "PlateauWithAnnealingParamScheduler",
17
+ "PlateauWithAnnealingScheduler",
18
18
  ]
@@ -1,4 +1,5 @@
1
1
  from typing import Any
2
+ from typing import Literal
2
3
  from typing import override
3
4
 
4
5
  import numpy as np
@@ -7,20 +8,25 @@ import torch
7
8
  from .base import BaseScheduler
8
9
 
9
10
 
10
- class _CosineWithPlateauSchedulerCore(BaseScheduler):
11
- """Core cosine with plateau scheduler logic."""
11
+ class _PlateauWithAnnealingCore(BaseScheduler):
12
+ """Core annealing with plateau scheduler logic."""
12
13
 
13
14
  def __init__(
14
15
  self,
15
16
  param_name: str,
16
17
  num_iters: int,
17
- base_value: float,
18
+ plateau_value: float,
18
19
  final_value: float,
19
20
  plateau_ratio: float,
20
21
  warmup_value: float | None = None,
21
22
  warmup_ratio: float | None = None,
22
23
  freeze_ratio: float | None = None,
24
+ annealing_type: Literal["cosine", "linear"] = "cosine",
23
25
  ) -> None:
26
+ if annealing_type not in ("cosine", "linear"):
27
+ raise ValueError(
28
+ f"Annealing type must be 'cosine' or 'linear', got {annealing_type}."
29
+ )
24
30
  if warmup_ratio is not None:
25
31
  if not (0 < warmup_ratio < 1):
26
32
  raise ValueError(f"Warmup ratio must be in (0, 1), got {warmup_ratio}.")
@@ -47,16 +53,17 @@ class _CosineWithPlateauSchedulerCore(BaseScheduler):
47
53
 
48
54
  self.param_name = param_name
49
55
  self.num_iters = num_iters
50
- self.base_value = base_value
56
+ self.plateau_value = plateau_value
51
57
  self.final_value = final_value
52
- self.cosine_annealing_ratio = 1 - pre_annealing_ratio
58
+ self.annealing_ratio = 1 - pre_annealing_ratio
53
59
  self.plateau_ratio = plateau_ratio
54
60
  self.warmup_ratio = warmup_ratio
55
61
  self.warmup_value = warmup_value
56
62
  self.freeze_ratio = freeze_ratio
63
+ self.annealing_type = annealing_type
57
64
 
58
65
  self.scheduled_values: np.ndarray = np.array([], dtype=np.float64)
59
- self.current_value_ = self.base_value
66
+ self.current_value_ = self.plateau_value
60
67
  return
61
68
 
62
69
  def _create_scheduler(self) -> None:
@@ -72,28 +79,41 @@ class _CosineWithPlateauSchedulerCore(BaseScheduler):
72
79
  if self.warmup_ratio is not None and self.warmup_value is not None:
73
80
  warmup_iters = int(self.num_iters * self.warmup_ratio)
74
81
  warmup_schedule = np.linspace(
75
- self.warmup_value, self.base_value, warmup_iters, dtype=np.float64
82
+ self.warmup_value, self.plateau_value, warmup_iters, dtype=np.float64
76
83
  )
77
84
  else:
78
85
  warmup_iters = 0
79
86
  warmup_schedule = np.array([], dtype=np.float64)
80
87
 
81
- # Create cosine annealing schedule
82
- if self.cosine_annealing_ratio > 0:
83
- cosine_annealing_iters = int(self.num_iters * self.cosine_annealing_ratio)
84
- iters = np.arange(cosine_annealing_iters)
85
- cosine_annealing_schedule = self.final_value + 0.5 * (
86
- self.base_value - self.final_value
87
- ) * (1 + np.cos(np.pi * iters / len(iters)))
88
+ # Create annealing schedule
89
+ if self.annealing_ratio > 0:
90
+ annealing_iters = int(self.num_iters * self.annealing_ratio)
91
+ match self.annealing_type:
92
+ case "cosine":
93
+ iters = np.arange(annealing_iters)
94
+ annealing_schedule = self.final_value + 0.5 * (
95
+ self.plateau_value - self.final_value
96
+ ) * (1 + np.cos(np.pi * iters / len(iters)))
97
+ case "linear":
98
+ annealing_schedule = np.linspace(
99
+ self.plateau_value,
100
+ self.final_value,
101
+ annealing_iters,
102
+ dtype=np.float64,
103
+ )
104
+ case _:
105
+ raise ValueError(
106
+ f"Unsupported annealing type: {self.annealing_type}"
107
+ )
88
108
  else:
89
- cosine_annealing_iters = 0
90
- cosine_annealing_schedule = np.array([], dtype=np.float64)
109
+ annealing_iters = 0
110
+ annealing_schedule = np.array([], dtype=np.float64)
91
111
 
92
- plateau_iters = (
93
- self.num_iters - warmup_iters - freeze_iters - cosine_annealing_iters
94
- )
112
+ plateau_iters = self.num_iters - warmup_iters - freeze_iters - annealing_iters
95
113
  if plateau_iters > 0:
96
- plateau_schedule = np.full(plateau_iters, self.base_value, dtype=np.float64)
114
+ plateau_schedule = np.full(
115
+ plateau_iters, self.plateau_value, dtype=np.float64
116
+ )
97
117
  else:
98
118
  plateau_schedule = np.array([], dtype=np.float64)
99
119
 
@@ -103,7 +123,7 @@ class _CosineWithPlateauSchedulerCore(BaseScheduler):
103
123
  freeze_schedule,
104
124
  warmup_schedule,
105
125
  plateau_schedule,
106
- cosine_annealing_schedule,
126
+ annealing_schedule,
107
127
  )
108
128
  )
109
129
  self._verify()
@@ -137,12 +157,12 @@ class _CosineWithPlateauSchedulerCore(BaseScheduler):
137
157
  return {self.param_name: self.current_value_}
138
158
 
139
159
 
140
- class CosineWithPlateuScheduler(_CosineWithPlateauSchedulerCore):
160
+ class PlateauWithAnnealingScheduler(_PlateauWithAnnealingCore):
141
161
  """
142
- Applies a cosine schedule with plateau to an optimizer param-group field.
162
+ Applies an annealing schedule with plateau to an optimizer param-group field.
143
163
 
144
- Schedule phases: freeze (0) → warmup → plateau (base_value) → cosine annealing to final_value.
145
- The plateau phase maintains the base_value before cosine annealing begins.
164
+ Schedule phases: freeze (0) → warmup → plateau (plateau_value) → annealing (cosine/linear) to final_value.
165
+ The plateau phase maintains the plateau_value before annealing begins.
146
166
  """
147
167
 
148
168
  def __init__(
@@ -150,30 +170,32 @@ class CosineWithPlateuScheduler(_CosineWithPlateauSchedulerCore):
150
170
  optimizer: torch.optim.Optimizer,
151
171
  param_group_field: str,
152
172
  num_iters: int,
153
- base_value: float,
173
+ plateau_value: float,
154
174
  final_value: float,
155
175
  plateau_ratio: float,
156
176
  warmup_value: float | None = None,
157
177
  warmup_ratio: float | None = None,
158
178
  freeze_ratio: float | None = None,
179
+ annealing_type: Literal["cosine", "linear"] = "cosine",
159
180
  multiplier_field: str | None = None,
160
181
  skip_if_zero: bool = False,
161
182
  apply_if_field: str | None = None,
162
183
  ignore_if_field: str | None = None,
163
184
  ) -> None:
164
185
  """
165
- Configure cosine scheduling for matching optimizer groups.
186
+ Configure annealing scheduling for matching optimizer groups.
166
187
 
167
188
  Args:
168
189
  optimizer: Optimizer whose param groups are updated in-place.
169
190
  param_group_field: Name of the field that receives the scheduled value.
170
191
  num_iters: Number of scheduler iterations before clamping at ``final_value``.
171
- base_value: Value maintained during plateau phase and used as cosine start.
172
- final_value: Value approached as iterations progress during cosine annealing.
173
- plateau_ratio: Fraction of iterations to maintain ``base_value`` before cosine annealing.
174
- warmup_ratio: Optional fraction of iterations to linearly ramp from ``warmup_value`` to ``base_value``.
192
+ plateau_value: Value maintained during plateau phase and used as annealing start.
193
+ final_value: Value approached as iterations progress during annealing.
194
+ plateau_ratio: Fraction of iterations to maintain ``plateau_value`` before annealing.
195
+ warmup_ratio: Optional fraction of iterations to linearly ramp from ``warmup_value`` to ``plateau_value``.
175
196
  warmup_value: Starting value for the warmup ramp.
176
197
  freeze_ratio: Optional fraction of iterations to keep the value frozen at zero at the beginning.
198
+ annealing_type: Type of annealing from plateau to final value ("cosine" or "linear").
177
199
  multiplier_field: Optional per-group multiplier applied to the scheduled value.
178
200
  skip_if_zero: Leave groups untouched when their target field equals zero.
179
201
  apply_if_field: Require this flag to be present in a param group before updating.
@@ -188,12 +210,13 @@ class CosineWithPlateuScheduler(_CosineWithPlateauSchedulerCore):
188
210
  super().__init__(
189
211
  param_name=param_group_field,
190
212
  num_iters=num_iters,
191
- base_value=base_value,
213
+ plateau_value=plateau_value,
192
214
  final_value=final_value,
193
215
  plateau_ratio=plateau_ratio,
194
216
  warmup_ratio=warmup_ratio,
195
217
  warmup_value=warmup_value,
196
218
  freeze_ratio=freeze_ratio,
219
+ annealing_type=annealing_type,
197
220
  )
198
221
  self.param_group_field = param_group_field
199
222
  return
@@ -242,12 +265,12 @@ class CosineWithPlateuScheduler(_CosineWithPlateauSchedulerCore):
242
265
  return
243
266
 
244
267
 
245
- class CosineWithPlateauParamScheduler(_CosineWithPlateauSchedulerCore):
268
+ class PlateauWithAnnealingParamScheduler(_PlateauWithAnnealingCore):
246
269
  """
247
- Standalone cosine scheduler with plateau for non-optimizer parameters.
270
+ Standalone annealing scheduler with plateau for non-optimizer parameters.
248
271
 
249
- Schedule phases: freeze (0) → warmup → plateau (base_value) → cosine annealing to final_value.
250
- The plateau phase maintains the base_value before cosine annealing begins.
272
+ Schedule phases: freeze (0) → warmup → plateau (plateau_value) → annealing (cosine/linear) to final_value.
273
+ The plateau phase maintains the plateau_value before annealing begins.
251
274
  """
252
275
 
253
276
  @override
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kostyl-toolkit
3
- Version: 0.1.37
3
+ Version: 0.1.38
4
4
  Summary: Kickass Orchestration System for Training, Yielding & Logging
5
5
  Requires-Dist: case-converter>=1.2.0
6
6
  Requires-Dist: loguru>=0.7.3
@@ -0,0 +1,40 @@
1
+ kostyl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ kostyl/ml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ kostyl/ml/base_uploader.py,sha256=KxHuohCcNK18kTVFBBqDu_IOQefluhSXOzwC56O66wc,484
4
+ kostyl/ml/configs/__init__.py,sha256=djYjLxA7riFcSibAKfWHns-BCESEPrqSz_ZY2rJO-cc,913
5
+ kostyl/ml/configs/hyperparams.py,sha256=lvtbvOFEoTBAJug7FR35xMQdPLgDQjRoP2fyDP-jD7E,3305
6
+ kostyl/ml/configs/mixins.py,sha256=xHHAoRoPbzP9ECFP9duzg6SzegHcoLI8Pr9NrLoWNHs,1411
7
+ kostyl/ml/configs/training_settings.py,sha256=wT9CHuLaKrLwonsc87Ee421EyFis_c9fqOgn9bSClm8,2747
8
+ kostyl/ml/data_collator.py,sha256=kxiaMDKwSKXGBtrF8yXxHcypf7t_6syU-NwO1LcX50k,4062
9
+ kostyl/ml/dist_utils.py,sha256=UFNMLEHc0A5F6KvTRG8GQPpRDwG4m5dvM__UvXNc2aQ,4526
10
+ kostyl/ml/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ kostyl/ml/integrations/clearml/__init__.py,sha256=3TBVI-3fE9ZzuvOLEohW9TOK0BZTLD5JiYalAVDkocc,217
12
+ kostyl/ml/integrations/clearml/checkpoint_uploader.py,sha256=PupFi7jKROsIddOz7X5DhV7nUNdDZg5kKaaLvzdCHlY,4012
13
+ kostyl/ml/integrations/clearml/config_mixin.py,sha256=70QRicU7etiDzLX-MplqVX8uFm5siuPrM8KbTOriZnQ,3308
14
+ kostyl/ml/integrations/clearml/dataset_utils.py,sha256=eij_sr2KDhm8GxEbVbK8aBjPsuVvLl9-PIGGaKVgXLA,1729
15
+ kostyl/ml/integrations/clearml/loading_utils.py,sha256=NAMmB9NTGCXCHh-bR_nrQZyqImUVZqicNjExDyPM2mU,5224
16
+ kostyl/ml/integrations/clearml/version_utils.py,sha256=GBjIIZbH_itd5sj7XpvxjkyZwxxGOpEcQ3BiWaJTyq8,1210
17
+ kostyl/ml/integrations/lightning/__init__.py,sha256=r96os8kTuKIAymx3k9Td1JBrO2PH7nQAWUC54NsY5yY,392
18
+ kostyl/ml/integrations/lightning/callbacks/__init__.py,sha256=EnKkNwwNDZnEqKRlpY4FVrqP88ECPF6nlT2bSLUIKRk,194
19
+ kostyl/ml/integrations/lightning/callbacks/checkpoint.py,sha256=SfcaQRkXviMUej0UgrfXcqMDlRKYaAN3rgYCMKI97Os,18433
20
+ kostyl/ml/integrations/lightning/callbacks/early_stopping.py,sha256=D5nyjktCJ9XYAf28-kgXG8jORvXLl1N3nbDQnvValPM,615
21
+ kostyl/ml/integrations/lightning/loggers/__init__.py,sha256=e51dszaoJbuzwBkbdugmuDsPldoSO4yaRgmZUg1Bdy0,71
22
+ kostyl/ml/integrations/lightning/loggers/tb_logger.py,sha256=CpjlcEIT187cJXJgRYafqfzvcnwPgPaVZ0vLUflIr7k,899
23
+ kostyl/ml/integrations/lightning/metrics_formatting.py,sha256=U6vdNENZLvp2dT1L3HqFKtXrHwGKoDXN93hvamPGHjM,1341
24
+ kostyl/ml/integrations/lightning/mixins.py,sha256=hVIsIUu6Iryrz6S7GQTqog9vNq8LQyjJd2aoJ5Ws6KU,5253
25
+ kostyl/ml/integrations/lightning/module.py,sha256=39hcVNZSGyj5tLpXyX8IoqMGWt5vf6-Bx5JnNJ2-Wag,5218
26
+ kostyl/ml/integrations/lightning/utils.py,sha256=DhLy_3JA5VyMQkB1v6xxRxDNHfisjXFYVjuIKPpO81M,1967
27
+ kostyl/ml/params_groups.py,sha256=nUyw5d06Pvy9QPiYtZzLYR87xwXqJLxbHthgQH8oSCM,3583
28
+ kostyl/ml/schedulers/__init__.py,sha256=VIo8MOP4w5Ll24XqFb3QGi2rKvys6c0dEFYPIdDoPlw,526
29
+ kostyl/ml/schedulers/base.py,sha256=bjmwgdZpnSqpCnHPnKC6MEiRO79cwxMJpZq-eQVNs2M,1353
30
+ kostyl/ml/schedulers/composite.py,sha256=ee4xlMDMMtjKPkbTF2ue9GTr9DuGCGjZWf11mHbi6aE,2387
31
+ kostyl/ml/schedulers/cosine.py,sha256=y8ylrgVOkVcr2-ExoqqNW--tdDX88TBYPQCOppIf2_M,8685
32
+ kostyl/ml/schedulers/linear.py,sha256=RnnnblRuRXP3LT03QVIHUaK2kNsiMP1AedrMoeyh3qk,5843
33
+ kostyl/ml/schedulers/plateau.py,sha256=N-hiostPtTR0W4xnEJYB_1dv0DRx39iufLkGUrSIoWE,11235
34
+ kostyl/utils/__init__.py,sha256=hkpmB6c5pr4Ti5BshOROebb7cvjDZfNCw83qZ_FFKMM,240
35
+ kostyl/utils/dict_manipulations.py,sha256=e3vBicID74nYP8lHkVTQc4-IQwoJimrbFELy5uSF6Gk,1073
36
+ kostyl/utils/fs.py,sha256=gAQNIU4R_2DhwjgzOS8BOMe0gZymtY1eZwmdgOdDgqo,510
37
+ kostyl/utils/logging.py,sha256=CgNFNogcK0hoZmygvBWlTcq5A3m2Pfv9eOAP_gwx0pM,6633
38
+ kostyl_toolkit-0.1.38.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
39
+ kostyl_toolkit-0.1.38.dist-info/METADATA,sha256=nz5AzlWjKBqh7OZCklk-efWZ1jVDihw3YrrpLyoII3k,4269
40
+ kostyl_toolkit-0.1.38.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.24
2
+ Generator: uv 0.9.27
3
3
  Root-Is-Purelib: true
4
- Tag: py3-none-any
4
+ Tag: py3-none-any
@@ -1,5 +0,0 @@
1
- from .extensions import KostylLightningModule
2
- from .extensions import LightningCheckpointLoaderMixin
3
-
4
-
5
- __all__ = ["KostylLightningModule", "LightningCheckpointLoaderMixin"]
@@ -1,5 +0,0 @@
1
- from .custom_module import KostylLightningModule
2
- from .pretrained_model import LightningCheckpointLoaderMixin
3
-
4
-
5
- __all__ = ["KostylLightningModule", "LightningCheckpointLoaderMixin"]
@@ -1,38 +0,0 @@
1
- kostyl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- kostyl/ml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- kostyl/ml/clearml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- kostyl/ml/clearml/dataset_utils.py,sha256=eij_sr2KDhm8GxEbVbK8aBjPsuVvLl9-PIGGaKVgXLA,1729
5
- kostyl/ml/clearml/logging_utils.py,sha256=GBjIIZbH_itd5sj7XpvxjkyZwxxGOpEcQ3BiWaJTyq8,1210
6
- kostyl/ml/clearml/pulling_utils.py,sha256=jMlVXcYRumwWnPlELRlgEdfq5L6Wir_EcfTmOoWBLTA,4077
7
- kostyl/ml/configs/__init__.py,sha256=IetcivbqYGutowLqxdKp7QR4tkXKBr4m8t4Zkk9jHZU,911
8
- kostyl/ml/configs/base_model.py,sha256=Eofn14J9RsjpVx_J4rp6C19pDDCANU4hr3JtX-d0FpQ,4820
9
- kostyl/ml/configs/hyperparams.py,sha256=lvtbvOFEoTBAJug7FR35xMQdPLgDQjRoP2fyDP-jD7E,3305
10
- kostyl/ml/configs/training_settings.py,sha256=wT9CHuLaKrLwonsc87Ee421EyFis_c9fqOgn9bSClm8,2747
11
- kostyl/ml/data_processing_utils.py,sha256=jjEjV0S0wREgZkzg27ip0LpI8cQqkwe2QwATmAqm9-g,3832
12
- kostyl/ml/dist_utils.py,sha256=lK9_aAh9L1SvvXWzcWiBoFjczfDiKzEpcno5csImAYQ,4635
13
- kostyl/ml/lightning/__init__.py,sha256=R36PImjVvzBF9t_z9u6RYVnUFJJ-sNDUOdboWUojHmM,173
14
- kostyl/ml/lightning/callbacks/__init__.py,sha256=EnKkNwwNDZnEqKRlpY4FVrqP88ECPF6nlT2bSLUIKRk,194
15
- kostyl/ml/lightning/callbacks/checkpoint.py,sha256=HI17gu-GxnfXUchflWBTwly7cCYnlpKcshuR-TgD6s4,19066
16
- kostyl/ml/lightning/callbacks/early_stopping.py,sha256=D5nyjktCJ9XYAf28-kgXG8jORvXLl1N3nbDQnvValPM,615
17
- kostyl/ml/lightning/extensions/__init__.py,sha256=OY6QGv1agYgqqKf1xJBrxgp_i8FunVfPzYezfaRrGXU,182
18
- kostyl/ml/lightning/extensions/custom_module.py,sha256=qYffgPwIB_ePwK_MIaRruuDxPKJZb42kg2yy996eGwY,6415
19
- kostyl/ml/lightning/extensions/pretrained_model.py,sha256=hVIsIUu6Iryrz6S7GQTqog9vNq8LQyjJd2aoJ5Ws6KU,5253
20
- kostyl/ml/lightning/loggers/__init__.py,sha256=e51dszaoJbuzwBkbdugmuDsPldoSO4yaRgmZUg1Bdy0,71
21
- kostyl/ml/lightning/loggers/tb_logger.py,sha256=CpjlcEIT187cJXJgRYafqfzvcnwPgPaVZ0vLUflIr7k,899
22
- kostyl/ml/lightning/utils.py,sha256=DhLy_3JA5VyMQkB1v6xxRxDNHfisjXFYVjuIKPpO81M,1967
23
- kostyl/ml/metrics_formatting.py,sha256=U6vdNENZLvp2dT1L3HqFKtXrHwGKoDXN93hvamPGHjM,1341
24
- kostyl/ml/params_groups.py,sha256=nUyw5d06Pvy9QPiYtZzLYR87xwXqJLxbHthgQH8oSCM,3583
25
- kostyl/ml/registry_uploader.py,sha256=BbyLXvF8AL145k7g6MRkJ7gf_3Um53p3Pn5280vVD9U,4384
26
- kostyl/ml/schedulers/__init__.py,sha256=_EtZu8DwTCSv4-eR84kRstEZblHylVqda7WQUOXIKfw,534
27
- kostyl/ml/schedulers/base.py,sha256=bjmwgdZpnSqpCnHPnKC6MEiRO79cwxMJpZq-eQVNs2M,1353
28
- kostyl/ml/schedulers/composite.py,sha256=ee4xlMDMMtjKPkbTF2ue9GTr9DuGCGjZWf11mHbi6aE,2387
29
- kostyl/ml/schedulers/cosine.py,sha256=y8ylrgVOkVcr2-ExoqqNW--tdDX88TBYPQCOppIf2_M,8685
30
- kostyl/ml/schedulers/cosine_with_plateu.py,sha256=0-X6wl3HgsTiLIbISb9lOxIVWXHDEND7rILitMWtIiM,10195
31
- kostyl/ml/schedulers/linear.py,sha256=RnnnblRuRXP3LT03QVIHUaK2kNsiMP1AedrMoeyh3qk,5843
32
- kostyl/utils/__init__.py,sha256=hkpmB6c5pr4Ti5BshOROebb7cvjDZfNCw83qZ_FFKMM,240
33
- kostyl/utils/dict_manipulations.py,sha256=e3vBicID74nYP8lHkVTQc4-IQwoJimrbFELy5uSF6Gk,1073
34
- kostyl/utils/fs.py,sha256=gAQNIU4R_2DhwjgzOS8BOMe0gZymtY1eZwmdgOdDgqo,510
35
- kostyl/utils/logging.py,sha256=CgNFNogcK0hoZmygvBWlTcq5A3m2Pfv9eOAP_gwx0pM,6633
36
- kostyl_toolkit-0.1.37.dist-info/WHEEL,sha256=eycQt0QpYmJMLKpE3X9iDk8R04v2ZF0x82ogq-zP6bQ,79
37
- kostyl_toolkit-0.1.37.dist-info/METADATA,sha256=yHPgSAhPnm5tDQjvDIfs213-bsVX6vMfVsUbX9GboGU,4269
38
- kostyl_toolkit-0.1.37.dist-info/RECORD,,
File without changes