python-somax 0.0.1__tar.gz → 1.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.
- python_somax-1.1.0/PKG-INFO +182 -0
- python_somax-1.1.0/README.md +138 -0
- python_somax-1.1.0/pyproject.toml +94 -0
- python_somax-1.1.0/src/python_somax.egg-info/PKG-INFO +182 -0
- python_somax-1.1.0/src/python_somax.egg-info/SOURCES.txt +58 -0
- python_somax-1.1.0/src/python_somax.egg-info/requires.txt +23 -0
- python_somax-1.1.0/src/somax/__init__.py +64 -0
- python_somax-1.1.0/src/somax/assembler.py +161 -0
- python_somax-1.1.0/src/somax/curvature/__init__.py +16 -0
- python_somax-1.1.0/src/somax/curvature/base.py +140 -0
- python_somax-1.1.0/src/somax/curvature/fgnha_ce.py +338 -0
- python_somax-1.1.0/src/somax/curvature/ggn_ce.py +281 -0
- python_somax-1.1.0/src/somax/curvature/ggn_mse.py +145 -0
- python_somax-1.1.0/src/somax/curvature/hessian.py +83 -0
- python_somax-1.1.0/src/somax/curvature/with_estimators.py +70 -0
- python_somax-1.1.0/src/somax/damping/__init__.py +15 -0
- python_somax-1.1.0/src/somax/damping/base.py +33 -0
- python_somax-1.1.0/src/somax/damping/constant.py +28 -0
- python_somax-1.1.0/src/somax/damping/scheduled.py +63 -0
- python_somax-1.1.0/src/somax/damping/trust_region.py +162 -0
- python_somax-1.1.0/src/somax/estimators/__init__.py +24 -0
- python_somax-1.1.0/src/somax/estimators/base.py +55 -0
- python_somax-1.1.0/src/somax/estimators/diagpp.py +251 -0
- python_somax-1.1.0/src/somax/estimators/gnb_ce.py +68 -0
- python_somax-1.1.0/src/somax/estimators/hutchinson.py +113 -0
- python_somax-1.1.0/src/somax/estimators/lanczos.py +94 -0
- python_somax-1.1.0/src/somax/executor.py +622 -0
- python_somax-1.1.0/src/somax/methods/__init__.py +35 -0
- python_somax-1.1.0/src/somax/methods/adahessian.py +82 -0
- python_somax-1.1.0/src/somax/methods/direct_methods.py +198 -0
- python_somax-1.1.0/src/somax/methods/egn.py +327 -0
- python_somax-1.1.0/src/somax/methods/fgn.py +168 -0
- python_somax-1.1.0/src/somax/methods/newton_cg.py +100 -0
- python_somax-1.1.0/src/somax/methods/sgn.py +198 -0
- python_somax-1.1.0/src/somax/methods/sophia_g.py +75 -0
- python_somax-1.1.0/src/somax/methods/sophia_h.py +75 -0
- python_somax-1.1.0/src/somax/metrics.py +83 -0
- python_somax-1.1.0/src/somax/optax.py +61 -0
- python_somax-1.1.0/src/somax/planner.py +192 -0
- python_somax-1.1.0/src/somax/preconditioners/__init__.py +15 -0
- python_somax-1.1.0/src/somax/preconditioners/base.py +43 -0
- python_somax-1.1.0/src/somax/preconditioners/diag_direct.py +86 -0
- python_somax-1.1.0/src/somax/preconditioners/diag_ema.py +185 -0
- python_somax-1.1.0/src/somax/preconditioners/identity.py +35 -0
- python_somax-1.1.0/src/somax/presets.py +60 -0
- python_somax-1.1.0/src/somax/solvers/__init__.py +16 -0
- python_somax-1.1.0/src/somax/solvers/base.py +49 -0
- python_somax-1.1.0/src/somax/solvers/cg.py +602 -0
- python_somax-1.1.0/src/somax/solvers/direct.py +204 -0
- python_somax-1.1.0/src/somax/solvers/identity.py +36 -0
- python_somax-1.1.0/src/somax/solvers/row_cg.py +65 -0
- python_somax-1.1.0/src/somax/solvers/row_cg_lifted.py +183 -0
- python_somax-1.1.0/src/somax/solvers/row_common.py +74 -0
- python_somax-1.1.0/src/somax/specs.py +280 -0
- python_somax-1.1.0/src/somax/types.py +72 -0
- python_somax-1.1.0/src/somax/utils.py +190 -0
- python_somax-0.0.1/PKG-INFO +0 -131
- python_somax-0.0.1/README.md +0 -112
- python_somax-0.0.1/setup.py +0 -40
- python_somax-0.0.1/src/python_somax.egg-info/PKG-INFO +0 -131
- python_somax-0.0.1/src/python_somax.egg-info/SOURCES.txt +0 -30
- python_somax-0.0.1/src/python_somax.egg-info/requires.txt +0 -1
- python_somax-0.0.1/src/somax/__init__.py +0 -19
- python_somax-0.0.1/src/somax/diagonal/__init__.py +0 -0
- python_somax-0.0.1/src/somax/diagonal/adahessian.py +0 -192
- python_somax-0.0.1/src/somax/diagonal/sophia_g.py +0 -208
- python_somax-0.0.1/src/somax/diagonal/sophia_h.py +0 -191
- python_somax-0.0.1/src/somax/gn/__init__.py +0 -0
- python_somax-0.0.1/src/somax/gn/egn.py +0 -567
- python_somax-0.0.1/src/somax/gn/sgn.py +0 -237
- python_somax-0.0.1/src/somax/hf/__init__.py +0 -0
- python_somax-0.0.1/src/somax/hf/newton_cg.py +0 -339
- python_somax-0.0.1/src/somax/ng/__init__.py +0 -0
- python_somax-0.0.1/src/somax/ng/swm_ng.py +0 -411
- python_somax-0.0.1/src/somax/qn/__init__.py +0 -0
- python_somax-0.0.1/src/somax/qn/sqn.py +0 -311
- python_somax-0.0.1/tests/test_adahessian.py +0 -134
- python_somax-0.0.1/tests/test_egn.py +0 -306
- python_somax-0.0.1/tests/test_newton_cg.py +0 -254
- python_somax-0.0.1/tests/test_sgn.py +0 -273
- python_somax-0.0.1/tests/test_sophia_g.py +0 -72
- python_somax-0.0.1/tests/test_sophia_h.py +0 -130
- python_somax-0.0.1/tests/test_sqn.py +0 -126
- python_somax-0.0.1/tests/test_swm_ng.py +0 -138
- {python_somax-0.0.1 → python_somax-1.1.0}/LICENSE +0 -0
- {python_somax-0.0.1 → python_somax-1.1.0}/setup.cfg +0 -0
- {python_somax-0.0.1 → python_somax-1.1.0}/src/python_somax.egg-info/dependency_links.txt +0 -0
- {python_somax-0.0.1 → python_somax-1.1.0}/src/python_somax.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-somax
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Composable Second-Order Optimization for JAX and Optax.
|
|
5
|
+
Author: Nick Korbit
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/cor3bit/somax
|
|
8
|
+
Project-URL: Repository, https://github.com/cor3bit/somax
|
|
9
|
+
Project-URL: Issues, https://github.com/cor3bit/somax/issues
|
|
10
|
+
Project-URL: Releases, https://github.com/cor3bit/somax/releases
|
|
11
|
+
Project-URL: Documentation, https://github.com/cor3bit/somax/tree/main/docs
|
|
12
|
+
Project-URL: Paper, https://arxiv.org/abs/2603.25976
|
|
13
|
+
Keywords: jax,optax,optimization,second-order,gauss-newton,hessian,machine-learning
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: jax>=0.4.20
|
|
25
|
+
Requires-Dist: optax>=0.1.7
|
|
26
|
+
Requires-Dist: flax>=0.7.5
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
29
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
33
|
+
Requires-Dist: pyright>=1.1; extra == "dev"
|
|
34
|
+
Requires-Dist: pre-commit>=3; extra == "dev"
|
|
35
|
+
Requires-Dist: chex>=0.1.8; extra == "dev"
|
|
36
|
+
Provides-Extra: docs
|
|
37
|
+
Requires-Dist: mkdocs>=1.5; extra == "docs"
|
|
38
|
+
Requires-Dist: mkdocs-material>=9; extra == "docs"
|
|
39
|
+
Provides-Extra: matfree
|
|
40
|
+
Requires-Dist: matfree; extra == "matfree"
|
|
41
|
+
Provides-Extra: lineax
|
|
42
|
+
Requires-Dist: lineax; extra == "lineax"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
<h1 align="center">Somax</h1>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<img src="assets/somax_logo_mini.png" alt="Somax logo" width="250" />
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<strong>Second-Order Methods in JAX</strong>
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
Somax is a JAX-native library for composable second-order optimization.
|
|
58
|
+
It combines curvature operators, solvers, damping, preconditioners,
|
|
59
|
+
and update transforms into flexible optimization methods.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
Features:
|
|
63
|
+
- **Composable:** combine curvature, solvers, damping, preconditioners, and update rules.
|
|
64
|
+
- **Matrix-free:** compute curvature products without forming dense matrices.
|
|
65
|
+
- **JAX-first:** JIT-compiled steps with explicit control over execution.
|
|
66
|
+
- **Optax integration:** apply standard Optax transformations to computed directions.
|
|
67
|
+
- **Research-friendly:** swap components, run ablations, and prototype new methods.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
> The catfish in the logo is a small nod to *som*, the Belarusian word for catfish.
|
|
73
|
+
> A quiet bottom-dweller, but not a first-order creature.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
Install [JAX](https://docs.jax.dev/en/latest/installation.html) for your hardware, then:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install python-somax
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For development:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/cor3bit/somax.git
|
|
92
|
+
cd somax
|
|
93
|
+
pip install -e ".[dev]"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The `lineax` package is optional and needed only for CG with `backend="lineax"`.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Quickstart
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
A minimal stochastic Gauss-Newton training loop for multiclass classification:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import jax
|
|
110
|
+
import jax.numpy as jnp
|
|
111
|
+
import somax
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def predict_fn(params, x):
|
|
115
|
+
h = jnp.tanh(x @ params["W1"] + params["b1"])
|
|
116
|
+
return h @ params["W2"] + params["b2"]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
rng = jax.random.PRNGKey(0)
|
|
120
|
+
k1, k2, k3, k4 = jax.random.split(rng, 4)
|
|
121
|
+
|
|
122
|
+
params = {
|
|
123
|
+
"W1": 0.1 * jax.random.normal(k1, (16, 32)),
|
|
124
|
+
"b1": jnp.zeros((32,)),
|
|
125
|
+
"W2": 0.1 * jax.random.normal(k2, (32, 10)),
|
|
126
|
+
"b2": jnp.zeros((10,)),
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
batch = {
|
|
130
|
+
"x": jax.random.normal(k3, (64, 16)),
|
|
131
|
+
"y": jax.random.randint(k4, (64,), 0, 10),
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
method = somax.sgn_ce(
|
|
135
|
+
predict_fn=predict_fn,
|
|
136
|
+
learning_rate=0.1,
|
|
137
|
+
lam0=1.0,
|
|
138
|
+
maxiter=10,
|
|
139
|
+
tol=1e-4,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
state = method.init(params)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@jax.jit
|
|
146
|
+
def train_step(params, batch, state, rng):
|
|
147
|
+
return method.step(params, batch, state, rng)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
for step in range(10):
|
|
151
|
+
step_rng = jax.random.fold_in(rng, step)
|
|
152
|
+
params, state, info = train_step(params, batch, state, step_rng)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For more examples, see [Usage: A paper in a few lines](docs/USAGE.md).
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
## Citation
|
|
161
|
+
|
|
162
|
+
Mikalai Korbit and Mario Zanon,
|
|
163
|
+
"Second-Order, First-Class: A Composable Stack for Curvature-Aware Training",
|
|
164
|
+
ECML PKDD 2026, [arXiv](https://arxiv.org/abs/2603.25976).
|
|
165
|
+
|
|
166
|
+
```bibtex
|
|
167
|
+
@inproceedings{korbit2026second,
|
|
168
|
+
title={Second-Order, First-Class: A Composable Stack for Curvature-Aware Training},
|
|
169
|
+
author={Korbit, Mikalai and Zanon, Mario},
|
|
170
|
+
booktitle={Joint European Conference on Machine Learning and Knowledge Discovery in Databases},
|
|
171
|
+
pages={90--105},
|
|
172
|
+
year={2026},
|
|
173
|
+
organization={Springer}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
Apache-2.0
|
|
182
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<h1 align="center">Somax</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/somax_logo_mini.png" alt="Somax logo" width="250" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Second-Order Methods in JAX</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Somax is a JAX-native library for composable second-order optimization.
|
|
14
|
+
It combines curvature operators, solvers, damping, preconditioners,
|
|
15
|
+
and update transforms into flexible optimization methods.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Features:
|
|
19
|
+
- **Composable:** combine curvature, solvers, damping, preconditioners, and update rules.
|
|
20
|
+
- **Matrix-free:** compute curvature products without forming dense matrices.
|
|
21
|
+
- **JAX-first:** JIT-compiled steps with explicit control over execution.
|
|
22
|
+
- **Optax integration:** apply standard Optax transformations to computed directions.
|
|
23
|
+
- **Research-friendly:** swap components, run ablations, and prototype new methods.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
> The catfish in the logo is a small nod to *som*, the Belarusian word for catfish.
|
|
29
|
+
> A quiet bottom-dweller, but not a first-order creature.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Install [JAX](https://docs.jax.dev/en/latest/installation.html) for your hardware, then:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install python-somax
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
For development:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
git clone https://github.com/cor3bit/somax.git
|
|
48
|
+
cd somax
|
|
49
|
+
pip install -e ".[dev]"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The `lineax` package is optional and needed only for CG with `backend="lineax"`.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Quickstart
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
A minimal stochastic Gauss-Newton training loop for multiclass classification:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import jax
|
|
66
|
+
import jax.numpy as jnp
|
|
67
|
+
import somax
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def predict_fn(params, x):
|
|
71
|
+
h = jnp.tanh(x @ params["W1"] + params["b1"])
|
|
72
|
+
return h @ params["W2"] + params["b2"]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
rng = jax.random.PRNGKey(0)
|
|
76
|
+
k1, k2, k3, k4 = jax.random.split(rng, 4)
|
|
77
|
+
|
|
78
|
+
params = {
|
|
79
|
+
"W1": 0.1 * jax.random.normal(k1, (16, 32)),
|
|
80
|
+
"b1": jnp.zeros((32,)),
|
|
81
|
+
"W2": 0.1 * jax.random.normal(k2, (32, 10)),
|
|
82
|
+
"b2": jnp.zeros((10,)),
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
batch = {
|
|
86
|
+
"x": jax.random.normal(k3, (64, 16)),
|
|
87
|
+
"y": jax.random.randint(k4, (64,), 0, 10),
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
method = somax.sgn_ce(
|
|
91
|
+
predict_fn=predict_fn,
|
|
92
|
+
learning_rate=0.1,
|
|
93
|
+
lam0=1.0,
|
|
94
|
+
maxiter=10,
|
|
95
|
+
tol=1e-4,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
state = method.init(params)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@jax.jit
|
|
102
|
+
def train_step(params, batch, state, rng):
|
|
103
|
+
return method.step(params, batch, state, rng)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
for step in range(10):
|
|
107
|
+
step_rng = jax.random.fold_in(rng, step)
|
|
108
|
+
params, state, info = train_step(params, batch, state, step_rng)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For more examples, see [Usage: A paper in a few lines](docs/USAGE.md).
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## Citation
|
|
117
|
+
|
|
118
|
+
Mikalai Korbit and Mario Zanon,
|
|
119
|
+
"Second-Order, First-Class: A Composable Stack for Curvature-Aware Training",
|
|
120
|
+
ECML PKDD 2026, [arXiv](https://arxiv.org/abs/2603.25976).
|
|
121
|
+
|
|
122
|
+
```bibtex
|
|
123
|
+
@inproceedings{korbit2026second,
|
|
124
|
+
title={Second-Order, First-Class: A Composable Stack for Curvature-Aware Training},
|
|
125
|
+
author={Korbit, Mikalai and Zanon, Mario},
|
|
126
|
+
booktitle={Joint European Conference on Machine Learning and Knowledge Discovery in Databases},
|
|
127
|
+
pages={90--105},
|
|
128
|
+
year={2026},
|
|
129
|
+
organization={Springer}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
Apache-2.0
|
|
138
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "python-somax"
|
|
7
|
+
version = "1.1.0"
|
|
8
|
+
description = "Composable Second-Order Optimization for JAX and Optax."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Nick Korbit" }
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"jax>=0.4.20",
|
|
18
|
+
"optax>=0.1.7",
|
|
19
|
+
"flax>=0.7.5",
|
|
20
|
+
]
|
|
21
|
+
keywords = [
|
|
22
|
+
"jax",
|
|
23
|
+
"optax",
|
|
24
|
+
"optimization",
|
|
25
|
+
"second-order",
|
|
26
|
+
"gauss-newton",
|
|
27
|
+
"hessian",
|
|
28
|
+
"machine-learning",
|
|
29
|
+
]
|
|
30
|
+
classifiers = [
|
|
31
|
+
"Development Status :: 4 - Beta",
|
|
32
|
+
"Intended Audience :: Science/Research",
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
37
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/cor3bit/somax"
|
|
42
|
+
Repository = "https://github.com/cor3bit/somax"
|
|
43
|
+
Issues = "https://github.com/cor3bit/somax/issues"
|
|
44
|
+
Releases = "https://github.com/cor3bit/somax/releases"
|
|
45
|
+
Documentation = "https://github.com/cor3bit/somax/tree/main/docs"
|
|
46
|
+
Paper = "https://arxiv.org/abs/2603.25976"
|
|
47
|
+
|
|
48
|
+
[project.optional-dependencies]
|
|
49
|
+
dev = [
|
|
50
|
+
"build>=1.2",
|
|
51
|
+
"twine>=5",
|
|
52
|
+
"pytest>=8",
|
|
53
|
+
"pytest-cov>=5",
|
|
54
|
+
"ruff>=0.5",
|
|
55
|
+
"pyright>=1.1",
|
|
56
|
+
"pre-commit>=3",
|
|
57
|
+
"chex>=0.1.8",
|
|
58
|
+
]
|
|
59
|
+
docs = [
|
|
60
|
+
"mkdocs>=1.5",
|
|
61
|
+
"mkdocs-material>=9",
|
|
62
|
+
]
|
|
63
|
+
matfree = ["matfree"]
|
|
64
|
+
lineax = ["lineax"]
|
|
65
|
+
|
|
66
|
+
[tool.setuptools.packages.find]
|
|
67
|
+
where = ["src"]
|
|
68
|
+
|
|
69
|
+
[tool.ruff]
|
|
70
|
+
line-length = 100
|
|
71
|
+
target-version = "py311"
|
|
72
|
+
|
|
73
|
+
[tool.ruff.lint]
|
|
74
|
+
select = ["E", "F", "I", "N", "W", "UP", "B", "SIM"]
|
|
75
|
+
ignore = ["E501", "N803", "N806"]
|
|
76
|
+
|
|
77
|
+
[tool.ruff.format]
|
|
78
|
+
quote-style = "double"
|
|
79
|
+
indent-style = "space"
|
|
80
|
+
skip-magic-trailing-comma = false
|
|
81
|
+
line-ending = "lf"
|
|
82
|
+
|
|
83
|
+
[tool.pyright]
|
|
84
|
+
include = ["src"]
|
|
85
|
+
exclude = ["**/node_modules", "**/__pycache__"]
|
|
86
|
+
reportMissingImports = true
|
|
87
|
+
reportMissingTypeStubs = false
|
|
88
|
+
pythonVersion = "3.11"
|
|
89
|
+
typeCheckingMode = "basic"
|
|
90
|
+
|
|
91
|
+
[tool.pytest.ini_options]
|
|
92
|
+
testpaths = ["tests"]
|
|
93
|
+
addopts = "-q --strict-markers"
|
|
94
|
+
xfail_strict = true
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-somax
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Composable Second-Order Optimization for JAX and Optax.
|
|
5
|
+
Author: Nick Korbit
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/cor3bit/somax
|
|
8
|
+
Project-URL: Repository, https://github.com/cor3bit/somax
|
|
9
|
+
Project-URL: Issues, https://github.com/cor3bit/somax/issues
|
|
10
|
+
Project-URL: Releases, https://github.com/cor3bit/somax/releases
|
|
11
|
+
Project-URL: Documentation, https://github.com/cor3bit/somax/tree/main/docs
|
|
12
|
+
Project-URL: Paper, https://arxiv.org/abs/2603.25976
|
|
13
|
+
Keywords: jax,optax,optimization,second-order,gauss-newton,hessian,machine-learning
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: jax>=0.4.20
|
|
25
|
+
Requires-Dist: optax>=0.1.7
|
|
26
|
+
Requires-Dist: flax>=0.7.5
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
29
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
33
|
+
Requires-Dist: pyright>=1.1; extra == "dev"
|
|
34
|
+
Requires-Dist: pre-commit>=3; extra == "dev"
|
|
35
|
+
Requires-Dist: chex>=0.1.8; extra == "dev"
|
|
36
|
+
Provides-Extra: docs
|
|
37
|
+
Requires-Dist: mkdocs>=1.5; extra == "docs"
|
|
38
|
+
Requires-Dist: mkdocs-material>=9; extra == "docs"
|
|
39
|
+
Provides-Extra: matfree
|
|
40
|
+
Requires-Dist: matfree; extra == "matfree"
|
|
41
|
+
Provides-Extra: lineax
|
|
42
|
+
Requires-Dist: lineax; extra == "lineax"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
<h1 align="center">Somax</h1>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<img src="assets/somax_logo_mini.png" alt="Somax logo" width="250" />
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<strong>Second-Order Methods in JAX</strong>
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
Somax is a JAX-native library for composable second-order optimization.
|
|
58
|
+
It combines curvature operators, solvers, damping, preconditioners,
|
|
59
|
+
and update transforms into flexible optimization methods.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
Features:
|
|
63
|
+
- **Composable:** combine curvature, solvers, damping, preconditioners, and update rules.
|
|
64
|
+
- **Matrix-free:** compute curvature products without forming dense matrices.
|
|
65
|
+
- **JAX-first:** JIT-compiled steps with explicit control over execution.
|
|
66
|
+
- **Optax integration:** apply standard Optax transformations to computed directions.
|
|
67
|
+
- **Research-friendly:** swap components, run ablations, and prototype new methods.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
> The catfish in the logo is a small nod to *som*, the Belarusian word for catfish.
|
|
73
|
+
> A quiet bottom-dweller, but not a first-order creature.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
## Installation
|
|
81
|
+
|
|
82
|
+
Install [JAX](https://docs.jax.dev/en/latest/installation.html) for your hardware, then:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install python-somax
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For development:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
git clone https://github.com/cor3bit/somax.git
|
|
92
|
+
cd somax
|
|
93
|
+
pip install -e ".[dev]"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The `lineax` package is optional and needed only for CG with `backend="lineax"`.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Quickstart
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
A minimal stochastic Gauss-Newton training loop for multiclass classification:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
import jax
|
|
110
|
+
import jax.numpy as jnp
|
|
111
|
+
import somax
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def predict_fn(params, x):
|
|
115
|
+
h = jnp.tanh(x @ params["W1"] + params["b1"])
|
|
116
|
+
return h @ params["W2"] + params["b2"]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
rng = jax.random.PRNGKey(0)
|
|
120
|
+
k1, k2, k3, k4 = jax.random.split(rng, 4)
|
|
121
|
+
|
|
122
|
+
params = {
|
|
123
|
+
"W1": 0.1 * jax.random.normal(k1, (16, 32)),
|
|
124
|
+
"b1": jnp.zeros((32,)),
|
|
125
|
+
"W2": 0.1 * jax.random.normal(k2, (32, 10)),
|
|
126
|
+
"b2": jnp.zeros((10,)),
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
batch = {
|
|
130
|
+
"x": jax.random.normal(k3, (64, 16)),
|
|
131
|
+
"y": jax.random.randint(k4, (64,), 0, 10),
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
method = somax.sgn_ce(
|
|
135
|
+
predict_fn=predict_fn,
|
|
136
|
+
learning_rate=0.1,
|
|
137
|
+
lam0=1.0,
|
|
138
|
+
maxiter=10,
|
|
139
|
+
tol=1e-4,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
state = method.init(params)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@jax.jit
|
|
146
|
+
def train_step(params, batch, state, rng):
|
|
147
|
+
return method.step(params, batch, state, rng)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
for step in range(10):
|
|
151
|
+
step_rng = jax.random.fold_in(rng, step)
|
|
152
|
+
params, state, info = train_step(params, batch, state, step_rng)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For more examples, see [Usage: A paper in a few lines](docs/USAGE.md).
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
## Citation
|
|
161
|
+
|
|
162
|
+
Mikalai Korbit and Mario Zanon,
|
|
163
|
+
"Second-Order, First-Class: A Composable Stack for Curvature-Aware Training",
|
|
164
|
+
ECML PKDD 2026, [arXiv](https://arxiv.org/abs/2603.25976).
|
|
165
|
+
|
|
166
|
+
```bibtex
|
|
167
|
+
@inproceedings{korbit2026second,
|
|
168
|
+
title={Second-Order, First-Class: A Composable Stack for Curvature-Aware Training},
|
|
169
|
+
author={Korbit, Mikalai and Zanon, Mario},
|
|
170
|
+
booktitle={Joint European Conference on Machine Learning and Knowledge Discovery in Databases},
|
|
171
|
+
pages={90--105},
|
|
172
|
+
year={2026},
|
|
173
|
+
organization={Springer}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
Apache-2.0
|
|
182
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/python_somax.egg-info/PKG-INFO
|
|
5
|
+
src/python_somax.egg-info/SOURCES.txt
|
|
6
|
+
src/python_somax.egg-info/dependency_links.txt
|
|
7
|
+
src/python_somax.egg-info/requires.txt
|
|
8
|
+
src/python_somax.egg-info/top_level.txt
|
|
9
|
+
src/somax/__init__.py
|
|
10
|
+
src/somax/assembler.py
|
|
11
|
+
src/somax/executor.py
|
|
12
|
+
src/somax/metrics.py
|
|
13
|
+
src/somax/optax.py
|
|
14
|
+
src/somax/planner.py
|
|
15
|
+
src/somax/presets.py
|
|
16
|
+
src/somax/specs.py
|
|
17
|
+
src/somax/types.py
|
|
18
|
+
src/somax/utils.py
|
|
19
|
+
src/somax/curvature/__init__.py
|
|
20
|
+
src/somax/curvature/base.py
|
|
21
|
+
src/somax/curvature/fgnha_ce.py
|
|
22
|
+
src/somax/curvature/ggn_ce.py
|
|
23
|
+
src/somax/curvature/ggn_mse.py
|
|
24
|
+
src/somax/curvature/hessian.py
|
|
25
|
+
src/somax/curvature/with_estimators.py
|
|
26
|
+
src/somax/damping/__init__.py
|
|
27
|
+
src/somax/damping/base.py
|
|
28
|
+
src/somax/damping/constant.py
|
|
29
|
+
src/somax/damping/scheduled.py
|
|
30
|
+
src/somax/damping/trust_region.py
|
|
31
|
+
src/somax/estimators/__init__.py
|
|
32
|
+
src/somax/estimators/base.py
|
|
33
|
+
src/somax/estimators/diagpp.py
|
|
34
|
+
src/somax/estimators/gnb_ce.py
|
|
35
|
+
src/somax/estimators/hutchinson.py
|
|
36
|
+
src/somax/estimators/lanczos.py
|
|
37
|
+
src/somax/methods/__init__.py
|
|
38
|
+
src/somax/methods/adahessian.py
|
|
39
|
+
src/somax/methods/direct_methods.py
|
|
40
|
+
src/somax/methods/egn.py
|
|
41
|
+
src/somax/methods/fgn.py
|
|
42
|
+
src/somax/methods/newton_cg.py
|
|
43
|
+
src/somax/methods/sgn.py
|
|
44
|
+
src/somax/methods/sophia_g.py
|
|
45
|
+
src/somax/methods/sophia_h.py
|
|
46
|
+
src/somax/preconditioners/__init__.py
|
|
47
|
+
src/somax/preconditioners/base.py
|
|
48
|
+
src/somax/preconditioners/diag_direct.py
|
|
49
|
+
src/somax/preconditioners/diag_ema.py
|
|
50
|
+
src/somax/preconditioners/identity.py
|
|
51
|
+
src/somax/solvers/__init__.py
|
|
52
|
+
src/somax/solvers/base.py
|
|
53
|
+
src/somax/solvers/cg.py
|
|
54
|
+
src/somax/solvers/direct.py
|
|
55
|
+
src/somax/solvers/identity.py
|
|
56
|
+
src/somax/solvers/row_cg.py
|
|
57
|
+
src/somax/solvers/row_cg_lifted.py
|
|
58
|
+
src/somax/solvers/row_common.py
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
jax>=0.4.20
|
|
2
|
+
optax>=0.1.7
|
|
3
|
+
flax>=0.7.5
|
|
4
|
+
|
|
5
|
+
[dev]
|
|
6
|
+
build>=1.2
|
|
7
|
+
twine>=5
|
|
8
|
+
pytest>=8
|
|
9
|
+
pytest-cov>=5
|
|
10
|
+
ruff>=0.5
|
|
11
|
+
pyright>=1.1
|
|
12
|
+
pre-commit>=3
|
|
13
|
+
chex>=0.1.8
|
|
14
|
+
|
|
15
|
+
[docs]
|
|
16
|
+
mkdocs>=1.5
|
|
17
|
+
mkdocs-material>=9
|
|
18
|
+
|
|
19
|
+
[lineax]
|
|
20
|
+
lineax
|
|
21
|
+
|
|
22
|
+
[matfree]
|
|
23
|
+
matfree
|