easymodd 0.1.0__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.
Files changed (35) hide show
  1. easymodd-0.1.0/LICENSE +21 -0
  2. easymodd-0.1.0/PKG-INFO +231 -0
  3. easymodd-0.1.0/README.md +193 -0
  4. easymodd-0.1.0/pyproject.toml +48 -0
  5. easymodd-0.1.0/setup.cfg +4 -0
  6. easymodd-0.1.0/src/easymodd/__init__.py +85 -0
  7. easymodd-0.1.0/src/easymodd/callbacks.py +40 -0
  8. easymodd-0.1.0/src/easymodd/checkpoints.py +59 -0
  9. easymodd-0.1.0/src/easymodd/cli.py +36 -0
  10. easymodd-0.1.0/src/easymodd/config.py +56 -0
  11. easymodd-0.1.0/src/easymodd/data.py +127 -0
  12. easymodd-0.1.0/src/easymodd/experiments.py +37 -0
  13. easymodd-0.1.0/src/easymodd/losses.py +57 -0
  14. easymodd-0.1.0/src/easymodd/metrics.py +18 -0
  15. easymodd-0.1.0/src/easymodd/models/__init__.py +7 -0
  16. easymodd-0.1.0/src/easymodd/models/mlp.py +24 -0
  17. easymodd-0.1.0/src/easymodd/models/text_transformer.py +29 -0
  18. easymodd-0.1.0/src/easymodd/models/vision_transformer.py +30 -0
  19. easymodd-0.1.0/src/easymodd/nn.py +165 -0
  20. easymodd-0.1.0/src/easymodd/optim.py +76 -0
  21. easymodd-0.1.0/src/easymodd/py.typed +0 -0
  22. easymodd-0.1.0/src/easymodd/registry.py +38 -0
  23. easymodd-0.1.0/src/easymodd/schedulers.py +37 -0
  24. easymodd-0.1.0/src/easymodd/secret_store.py +30 -0
  25. easymodd-0.1.0/src/easymodd/serialization.py +43 -0
  26. easymodd-0.1.0/src/easymodd/tensor.py +69 -0
  27. easymodd-0.1.0/src/easymodd/training.py +93 -0
  28. easymodd-0.1.0/src/easymodd/transforms.py +47 -0
  29. easymodd-0.1.0/src/easymodd/visualization.py +20 -0
  30. easymodd-0.1.0/src/easymodd.egg-info/PKG-INFO +231 -0
  31. easymodd-0.1.0/src/easymodd.egg-info/SOURCES.txt +33 -0
  32. easymodd-0.1.0/src/easymodd.egg-info/dependency_links.txt +1 -0
  33. easymodd-0.1.0/src/easymodd.egg-info/entry_points.txt +2 -0
  34. easymodd-0.1.0/src/easymodd.egg-info/requires.txt +14 -0
  35. easymodd-0.1.0/src/easymodd.egg-info/top_level.txt +1 -0
easymodd-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vnex Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: easymodd
3
+ Version: 0.1.0
4
+ Summary: A configurable, training-first numerical machine learning library
5
+ Author: Vnex Lab
6
+ Maintainer: Vnex Lab
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/vnex-lab/EasyMoDD
9
+ Project-URL: Repository, https://github.com/vnex-lab/EasyMoDD
10
+ Project-URL: Issues, https://github.com/vnex-lab/EasyMoDD/issues
11
+ Project-URL: Documentation, https://github.com/vnex-lab/EasyMoDD#readme
12
+ Project-URL: Support, https://ko-fi.com/vnexlab
13
+ Keywords: machine-learning,deep-learning,numpy,cuda,training,transformers
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: numpy>=2.0
27
+ Provides-Extra: cuda
28
+ Requires-Dist: cupy-cuda12x>=13.6; extra == "cuda"
29
+ Provides-Extra: data
30
+ Requires-Dist: pandas>=2.0; extra == "data"
31
+ Requires-Dist: pyarrow>=15.0; extra == "data"
32
+ Requires-Dist: scikit-learn>=1.4; extra == "data"
33
+ Provides-Extra: dev
34
+ Requires-Dist: build>=1.2; extra == "dev"
35
+ Requires-Dist: pytest>=8.0; extra == "dev"
36
+ Requires-Dist: twine>=5.0; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # EasyMoDD
40
+
41
+ EasyMoDD is a configurable, training-first machine-learning library. It is
42
+ programmable from Python like a numerical library, with reusable tensors,
43
+ modules, datasets, losses, optimizers, trainers, model families, and checkpoint
44
+ policies.
45
+
46
+ Models initialize randomly unless a consuming project explicitly resumes from
47
+ its own checkpoint. EasyMoDD does not include a chatbot, web application,
48
+ built-in corpus, project `config.txt`, generated checkpoints, or demo data.
49
+
50
+ ## Install
51
+
52
+ ```powershell
53
+ python -m pip install easymodd
54
+ ```
55
+
56
+ For a local checkout:
57
+
58
+ ```powershell
59
+ python -m pip install -e .
60
+ ```
61
+
62
+ ## Publish to PyPI
63
+
64
+ The package is configured for GitHub Actions Trusted Publishing. Before the
65
+ first release, create a PyPI project named `easymodd`, then add this trusted
66
+ publisher on PyPI:
67
+
68
+ - Owner: `vnex-lab`
69
+ - Repository: `EasyMoDD`
70
+ - Workflow: `publish.yml`
71
+ - Environment: `pypi`
72
+
73
+ After that one-time setup, publish a release from GitHub. The workflow builds
74
+ the wheel and source archive, validates both with Twine, and publishes them
75
+ without a stored PyPI token.
76
+
77
+ For a local dry run:
78
+
79
+ ```powershell
80
+ python -m pip install --upgrade build twine
81
+ python -m build
82
+ python -m twine check dist/*
83
+ ```
84
+
85
+ The package version is controlled by `project.version` in `pyproject.toml`.
86
+ Increase it for every PyPI release, and do not reuse an already-uploaded
87
+ version.
88
+
89
+ Optional integrations:
90
+
91
+ ```powershell
92
+ python -m pip install easymodd[cuda]
93
+ python -m pip install easymodd[data]
94
+ python -m pip install easymodd[dev]
95
+ ```
96
+
97
+ ## Python API
98
+
99
+ ```python
100
+ import numpy as np
101
+ from easymodd import ArrayDataset, MSELoss, SGD, Trainer, build_mlp
102
+
103
+ model = build_mlp(input_size=1, hidden_sizes=[8], output_size=1)
104
+ dataset = ArrayDataset(
105
+ np.array([[1.0], [2.0], [3.0]], dtype=np.float32),
106
+ np.array([[2.0], [4.0], [6.0]], dtype=np.float32),
107
+ )
108
+ history = Trainer(
109
+ SGD(model.parameters(), learning_rate=0.01),
110
+ MSELoss(),
111
+ max_steps=100,
112
+ ).fit(model, dataset)
113
+ print(history.values["loss"][-1])
114
+ ```
115
+
116
+ The programmable foundation includes:
117
+
118
+ - NumPy and explicit CUDA backend helpers
119
+ - `Module`, `Parameter`, `Linear`, `ReLU`, and `Sequential`
120
+ - GELU, sigmoid, tanh, and dropout layers
121
+ - MLP model factory
122
+ - Model registries for custom factories
123
+ - `ArrayDataset` and packed `TextDataset`
124
+ - `BatchLoader`, deterministic splits, and `Subset`
125
+ - Composable transforms and batch collation
126
+ - MSE and cross-entropy loss contracts
127
+ - L1 and Huber losses
128
+ - SGD, Adam, and AdamW optimizers
129
+ - Cosine and warmup learning-rate schedulers
130
+ - Reusable `Trainer` and `TrainingHistory`
131
+ - Accuracy, MAE, and perplexity metrics
132
+ - JSONL metrics logging and early stopping callbacks
133
+ - Local experiment tracking and dependency-free summaries
134
+ - Versioned model/optimizer/scheduler serialization
135
+ - Environment-only secrets for optional integrations
136
+ - Config loading and validation for consuming projects
137
+ - Checkpoint enable/disable, retention, and compression policy
138
+ - Separate text Transformer and Vision Transformer configuration modules
139
+
140
+ The restored prototype scripts remain available as compatibility programs for
141
+ existing custom checkpoints. New projects should import EasyMoDD directly.
142
+
143
+ ## Consumer Project Configuration
144
+
145
+ EasyMoDD does not force users into one project layout. A consuming project can
146
+ create its own `config.txt` using TOML syntax and load it with:
147
+
148
+ ```python
149
+ from easymodd import load_config
150
+ config = load_config("config.txt")
151
+ ```
152
+
153
+ The config loader supports project-defined paths for datasets, runs, models,
154
+ logs, and checkpoints. The library never assumes a filename such as
155
+ `best.bin`.
156
+
157
+ A consumer project can configure checkpoint behavior like this:
158
+
159
+ ```toml
160
+ [checkpoints]
161
+ enabled = true
162
+ keep_recent = 2
163
+ compress_old = true
164
+ ```
165
+
166
+ When disabled, `CheckpointManager` creates no directory or files. When enabled,
167
+ older numbered checkpoints can be compressed while recent checkpoints remain
168
+ available.
169
+
170
+ ## Package Layout
171
+
172
+ ```text
173
+ src/easymodd/
174
+ models/
175
+ mlp.py
176
+ text_transformer.py
177
+ vision_transformer.py
178
+ data.py
179
+ losses.py
180
+ nn.py
181
+ tensor.py
182
+ optim.py
183
+ training.py
184
+ checkpoints.py
185
+ config.py
186
+ cli.py
187
+ ```
188
+
189
+ Each model family has its own module. The shared training contracts are designed
190
+ so new model types can be added without changing dataset or checkpoint code.
191
+
192
+ ## Extending EasyMoDD
193
+
194
+ Register a custom model factory:
195
+
196
+ ```python
197
+ from easymodd import ModelRegistry
198
+
199
+ registry = ModelRegistry()
200
+ registry.register("my_model", lambda width=8: build_my_model(width))
201
+ model = registry.create("my_model", width=32)
202
+ ```
203
+
204
+ Optional integrations can read environment variables without storing secrets:
205
+
206
+ ```python
207
+ from easymodd import SecretStore
208
+
209
+ secrets = SecretStore(prefix="MY_APP_")
210
+ token = secrets.get("TRACKING_TOKEN")
211
+ ```
212
+
213
+ EasyMoDD never writes API keys to configs, checkpoints, experiment files, or
214
+ logs. Provider-specific integrations can be built on top of this helper.
215
+
216
+ ## Data and Training
217
+
218
+ The library does not ship a general-purpose training database. Users provide
219
+ legally obtained text, image, or tabular data in their own projects. EasyMoDD
220
+ provides dataset contracts and validation helpers; it does not pretend that a
221
+ small demo corpus can produce a general assistant.
222
+
223
+ ## Development Status
224
+
225
+ The tensor/module API, programmable MLP training loop, dataset contracts,
226
+ checkpoint policy, model-family layout, and config loader are implemented.
227
+ Text Transformer training, Vision Transformer training, full resume manifests,
228
+ evaluation, schedulers, callbacks, and additional model families are active
229
+ parts of the public-library roadmap.
230
+
231
+ Support development on [Ko-fi](https://ko-fi.com/vnexlab).
@@ -0,0 +1,193 @@
1
+ # EasyMoDD
2
+
3
+ EasyMoDD is a configurable, training-first machine-learning library. It is
4
+ programmable from Python like a numerical library, with reusable tensors,
5
+ modules, datasets, losses, optimizers, trainers, model families, and checkpoint
6
+ policies.
7
+
8
+ Models initialize randomly unless a consuming project explicitly resumes from
9
+ its own checkpoint. EasyMoDD does not include a chatbot, web application,
10
+ built-in corpus, project `config.txt`, generated checkpoints, or demo data.
11
+
12
+ ## Install
13
+
14
+ ```powershell
15
+ python -m pip install easymodd
16
+ ```
17
+
18
+ For a local checkout:
19
+
20
+ ```powershell
21
+ python -m pip install -e .
22
+ ```
23
+
24
+ ## Publish to PyPI
25
+
26
+ The package is configured for GitHub Actions Trusted Publishing. Before the
27
+ first release, create a PyPI project named `easymodd`, then add this trusted
28
+ publisher on PyPI:
29
+
30
+ - Owner: `vnex-lab`
31
+ - Repository: `EasyMoDD`
32
+ - Workflow: `publish.yml`
33
+ - Environment: `pypi`
34
+
35
+ After that one-time setup, publish a release from GitHub. The workflow builds
36
+ the wheel and source archive, validates both with Twine, and publishes them
37
+ without a stored PyPI token.
38
+
39
+ For a local dry run:
40
+
41
+ ```powershell
42
+ python -m pip install --upgrade build twine
43
+ python -m build
44
+ python -m twine check dist/*
45
+ ```
46
+
47
+ The package version is controlled by `project.version` in `pyproject.toml`.
48
+ Increase it for every PyPI release, and do not reuse an already-uploaded
49
+ version.
50
+
51
+ Optional integrations:
52
+
53
+ ```powershell
54
+ python -m pip install easymodd[cuda]
55
+ python -m pip install easymodd[data]
56
+ python -m pip install easymodd[dev]
57
+ ```
58
+
59
+ ## Python API
60
+
61
+ ```python
62
+ import numpy as np
63
+ from easymodd import ArrayDataset, MSELoss, SGD, Trainer, build_mlp
64
+
65
+ model = build_mlp(input_size=1, hidden_sizes=[8], output_size=1)
66
+ dataset = ArrayDataset(
67
+ np.array([[1.0], [2.0], [3.0]], dtype=np.float32),
68
+ np.array([[2.0], [4.0], [6.0]], dtype=np.float32),
69
+ )
70
+ history = Trainer(
71
+ SGD(model.parameters(), learning_rate=0.01),
72
+ MSELoss(),
73
+ max_steps=100,
74
+ ).fit(model, dataset)
75
+ print(history.values["loss"][-1])
76
+ ```
77
+
78
+ The programmable foundation includes:
79
+
80
+ - NumPy and explicit CUDA backend helpers
81
+ - `Module`, `Parameter`, `Linear`, `ReLU`, and `Sequential`
82
+ - GELU, sigmoid, tanh, and dropout layers
83
+ - MLP model factory
84
+ - Model registries for custom factories
85
+ - `ArrayDataset` and packed `TextDataset`
86
+ - `BatchLoader`, deterministic splits, and `Subset`
87
+ - Composable transforms and batch collation
88
+ - MSE and cross-entropy loss contracts
89
+ - L1 and Huber losses
90
+ - SGD, Adam, and AdamW optimizers
91
+ - Cosine and warmup learning-rate schedulers
92
+ - Reusable `Trainer` and `TrainingHistory`
93
+ - Accuracy, MAE, and perplexity metrics
94
+ - JSONL metrics logging and early stopping callbacks
95
+ - Local experiment tracking and dependency-free summaries
96
+ - Versioned model/optimizer/scheduler serialization
97
+ - Environment-only secrets for optional integrations
98
+ - Config loading and validation for consuming projects
99
+ - Checkpoint enable/disable, retention, and compression policy
100
+ - Separate text Transformer and Vision Transformer configuration modules
101
+
102
+ The restored prototype scripts remain available as compatibility programs for
103
+ existing custom checkpoints. New projects should import EasyMoDD directly.
104
+
105
+ ## Consumer Project Configuration
106
+
107
+ EasyMoDD does not force users into one project layout. A consuming project can
108
+ create its own `config.txt` using TOML syntax and load it with:
109
+
110
+ ```python
111
+ from easymodd import load_config
112
+ config = load_config("config.txt")
113
+ ```
114
+
115
+ The config loader supports project-defined paths for datasets, runs, models,
116
+ logs, and checkpoints. The library never assumes a filename such as
117
+ `best.bin`.
118
+
119
+ A consumer project can configure checkpoint behavior like this:
120
+
121
+ ```toml
122
+ [checkpoints]
123
+ enabled = true
124
+ keep_recent = 2
125
+ compress_old = true
126
+ ```
127
+
128
+ When disabled, `CheckpointManager` creates no directory or files. When enabled,
129
+ older numbered checkpoints can be compressed while recent checkpoints remain
130
+ available.
131
+
132
+ ## Package Layout
133
+
134
+ ```text
135
+ src/easymodd/
136
+ models/
137
+ mlp.py
138
+ text_transformer.py
139
+ vision_transformer.py
140
+ data.py
141
+ losses.py
142
+ nn.py
143
+ tensor.py
144
+ optim.py
145
+ training.py
146
+ checkpoints.py
147
+ config.py
148
+ cli.py
149
+ ```
150
+
151
+ Each model family has its own module. The shared training contracts are designed
152
+ so new model types can be added without changing dataset or checkpoint code.
153
+
154
+ ## Extending EasyMoDD
155
+
156
+ Register a custom model factory:
157
+
158
+ ```python
159
+ from easymodd import ModelRegistry
160
+
161
+ registry = ModelRegistry()
162
+ registry.register("my_model", lambda width=8: build_my_model(width))
163
+ model = registry.create("my_model", width=32)
164
+ ```
165
+
166
+ Optional integrations can read environment variables without storing secrets:
167
+
168
+ ```python
169
+ from easymodd import SecretStore
170
+
171
+ secrets = SecretStore(prefix="MY_APP_")
172
+ token = secrets.get("TRACKING_TOKEN")
173
+ ```
174
+
175
+ EasyMoDD never writes API keys to configs, checkpoints, experiment files, or
176
+ logs. Provider-specific integrations can be built on top of this helper.
177
+
178
+ ## Data and Training
179
+
180
+ The library does not ship a general-purpose training database. Users provide
181
+ legally obtained text, image, or tabular data in their own projects. EasyMoDD
182
+ provides dataset contracts and validation helpers; it does not pretend that a
183
+ small demo corpus can produce a general assistant.
184
+
185
+ ## Development Status
186
+
187
+ The tensor/module API, programmable MLP training loop, dataset contracts,
188
+ checkpoint policy, model-family layout, and config loader are implemented.
189
+ Text Transformer training, Vision Transformer training, full resume manifests,
190
+ evaluation, schedulers, callbacks, and additional model families are active
191
+ parts of the public-library roadmap.
192
+
193
+ Support development on [Ko-fi](https://ko-fi.com/vnexlab).
@@ -0,0 +1,48 @@
1
+ [project]
2
+ name = "easymodd"
3
+ version = "0.1.0"
4
+ description = "A configurable, training-first numerical machine learning library"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "Vnex Lab" }]
10
+ maintainers = [{ name = "Vnex Lab" }]
11
+ keywords = ["machine-learning", "deep-learning", "numpy", "cuda", "training", "transformers"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Developers",
15
+ "Intended Audience :: Science/Research",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Programming Language :: Python :: 3.14",
21
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
22
+ ]
23
+ dependencies = ["numpy>=2.0"]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/vnex-lab/EasyMoDD"
27
+ Repository = "https://github.com/vnex-lab/EasyMoDD"
28
+ Issues = "https://github.com/vnex-lab/EasyMoDD/issues"
29
+ Documentation = "https://github.com/vnex-lab/EasyMoDD#readme"
30
+ Support = "https://ko-fi.com/vnexlab"
31
+
32
+ [project.optional-dependencies]
33
+ cuda = ["cupy-cuda12x>=13.6"]
34
+ data = ["pandas>=2.0", "pyarrow>=15.0", "scikit-learn>=1.4"]
35
+ dev = ["build>=1.2", "pytest>=8.0", "twine>=5.0"]
36
+
37
+ [project.scripts]
38
+ easymodd = "easymodd.cli:main"
39
+
40
+ [build-system]
41
+ requires = ["setuptools>=68"]
42
+ build-backend = "setuptools.build_meta"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ easymodd = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,85 @@
1
+ """EasyMoDD: configurable, training-first numerical machine learning tools."""
2
+
3
+ from .config import EasyMoDDConfig, load_config
4
+ from .tensor import Device, array, backend_of, get_backend, matmul, ones, randn, seed, zeros
5
+ from .nn import Dropout, GELU, Linear, Module, Parameter, ReLU, Sequential, Sigmoid, Tanh
6
+ from .optim import Adam, AdamW, SGD
7
+ from .schedulers import CosineScheduler, WarmupScheduler
8
+ from .metrics import accuracy, mean_absolute_error, perplexity
9
+ from .callbacks import EarlyStopping, MetricsLogger
10
+ from .serialization import load_state, save_state
11
+ from .training import Trainer, TrainingHistory
12
+ from .data import ArrayDataset, BatchLoader, Dataset, Subset, TextDataset, collate_batch, split_dataset
13
+ from .losses import CrossEntropyLoss, HuberLoss, L1Loss, MSELoss
14
+ from .checkpoints import CheckpointManager
15
+ from .experiments import Experiment
16
+ from .registry import ModelRegistry, models
17
+ from .secret_store import SecretStore
18
+ from .transforms import Compose, Flatten, MapTransform, Normalize, Standardize, ToFloat32
19
+ from .visualization import summarize_history, summarize_model
20
+ from .models import MLP, TextTransformerConfig, VisionTransformerConfig, build_mlp
21
+
22
+ __all__ = [
23
+ "Device",
24
+ "ArrayDataset",
25
+ "BatchLoader",
26
+ "Adam",
27
+ "AdamW",
28
+ "CheckpointManager",
29
+ "Compose",
30
+ "CrossEntropyLoss",
31
+ "CosineScheduler",
32
+ "Dataset",
33
+ "Dropout",
34
+ "EarlyStopping",
35
+ "EasyMoDDConfig",
36
+ "Experiment",
37
+ "Flatten",
38
+ "GELU",
39
+ "HuberLoss",
40
+ "L1Loss",
41
+ "Linear",
42
+ "MSELoss",
43
+ "MapTransform",
44
+ "ModelRegistry",
45
+ "Normalize",
46
+ "MetricsLogger",
47
+ "Module",
48
+ "Parameter",
49
+ "ReLU",
50
+ "Sequential",
51
+ "SGD",
52
+ "SecretStore",
53
+ "Sigmoid",
54
+ "Standardize",
55
+ "Tanh",
56
+ "ToFloat32",
57
+ "WarmupScheduler",
58
+ "Trainer",
59
+ "TrainingHistory",
60
+ "TextDataset",
61
+ "Subset",
62
+ "array",
63
+ "accuracy",
64
+ "backend_of",
65
+ "MLP",
66
+ "TextTransformerConfig",
67
+ "VisionTransformerConfig",
68
+ "build_mlp",
69
+ "get_backend",
70
+ "load_config",
71
+ "load_state",
72
+ "matmul",
73
+ "mean_absolute_error",
74
+ "perplexity",
75
+ "collate_batch",
76
+ "models",
77
+ "ones",
78
+ "randn",
79
+ "seed",
80
+ "save_state",
81
+ "zeros",
82
+ "split_dataset",
83
+ "summarize_history",
84
+ "summarize_model",
85
+ ]
@@ -0,0 +1,40 @@
1
+ """Reusable training callbacks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+
9
+ class MetricsLogger:
10
+ """Append one JSON object per training event."""
11
+
12
+ def __init__(self, path: str | Path):
13
+ self.path = Path(path)
14
+ self.path.parent.mkdir(parents=True, exist_ok=True)
15
+
16
+ def __call__(self, *, step: int, metrics: dict[str, float]) -> None:
17
+ with self.path.open("a", encoding="utf-8") as handle:
18
+ handle.write(json.dumps({"step": step, **metrics}) + "\n")
19
+
20
+
21
+ class EarlyStopping:
22
+ def __init__(self, metric: str = "loss", patience: int = 10, minimum_delta: float = 0.0):
23
+ if patience < 1:
24
+ raise ValueError("patience must be at least 1")
25
+ self.metric = metric
26
+ self.patience = patience
27
+ self.minimum_delta = minimum_delta
28
+ self.best = float("inf")
29
+ self.bad_steps = 0
30
+
31
+ def __call__(self, *, step: int, metrics: dict[str, float]) -> bool:
32
+ value = metrics.get(self.metric)
33
+ if value is None:
34
+ return False
35
+ if value < self.best - self.minimum_delta:
36
+ self.best = value
37
+ self.bad_steps = 0
38
+ else:
39
+ self.bad_steps += 1
40
+ return self.bad_steps >= self.patience
@@ -0,0 +1,59 @@
1
+ """Config-controlled checkpoint management."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+ import zipfile
8
+ from .serialization import save_state
9
+
10
+
11
+ class CheckpointManager:
12
+ """Checkpoint policy that creates no files when disabled."""
13
+
14
+ def __init__(self, directory: str | Path, enabled: bool = True,
15
+ keep_recent: int = 2, compress_old: bool = True):
16
+ if keep_recent < 1:
17
+ raise ValueError("keep_recent must be at least 1")
18
+ self.directory = Path(directory)
19
+ self.enabled = bool(enabled)
20
+ self.keep_recent = keep_recent
21
+ self.compress_old = bool(compress_old)
22
+
23
+ def save(self, state: dict, step: int) -> Path | None:
24
+ if not self.enabled:
25
+ return None
26
+ self.directory.mkdir(parents=True, exist_ok=True)
27
+ path = self.directory / f"step_{step:07d}.json"
28
+ path.write_text(json.dumps(state, indent=2), encoding="utf-8")
29
+ self._compress_old()
30
+ return path
31
+
32
+ def save_training_state(self, step: int, *, model, optimizer=None,
33
+ scheduler=None, config=None, metrics=None) -> Path | None:
34
+ if not self.enabled:
35
+ return None
36
+ self.directory.mkdir(parents=True, exist_ok=True)
37
+ path = self.directory / f"step_{step:07d}.pkl"
38
+ save_state(path, model=model, optimizer=optimizer, scheduler=scheduler,
39
+ config=config, metrics=metrics)
40
+ self._compress_artifacts()
41
+ return path
42
+
43
+ def _compress_old(self) -> None:
44
+ files = sorted(self.directory.glob("step_*.json"), key=lambda item: item.stat().st_mtime)
45
+ for path in files[:-self.keep_recent]:
46
+ archive = path.with_suffix(".zip")
47
+ if self.compress_old and not archive.exists():
48
+ with zipfile.ZipFile(archive, "w", zipfile.ZIP_DEFLATED) as handle:
49
+ handle.write(path, arcname=path.name)
50
+ path.unlink()
51
+
52
+ def _compress_artifacts(self) -> None:
53
+ files = sorted(self.directory.glob("step_*.pkl"), key=lambda item: item.stat().st_mtime)
54
+ for path in files[:-self.keep_recent]:
55
+ archive = path.with_suffix(".zip")
56
+ if self.compress_old and not archive.exists():
57
+ with zipfile.ZipFile(archive, "w", zipfile.ZIP_DEFLATED) as handle:
58
+ handle.write(path, arcname=path.name)
59
+ path.unlink()