dnaty 1.0.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.
- dnaty-1.0.0/LICENSE +44 -0
- dnaty-1.0.0/PKG-INFO +243 -0
- dnaty-1.0.0/README.md +210 -0
- dnaty-1.0.0/dnaty/__init__.py +21 -0
- dnaty-1.0.0/dnaty/analysis/__init__.py +1 -0
- dnaty-1.0.0/dnaty/analysis/cl_metrics.py +40 -0
- dnaty-1.0.0/dnaty/compress.py +176 -0
- dnaty-1.0.0/dnaty/core/__init__.py +1 -0
- dnaty-1.0.0/dnaty/core/arch.py +85 -0
- dnaty-1.0.0/dnaty/core/arch_cnn.py +140 -0
- dnaty-1.0.0/dnaty/core/individual.py +34 -0
- dnaty-1.0.0/dnaty/core/memory.py +88 -0
- dnaty-1.0.0/dnaty/evolution/__init__.py +1 -0
- dnaty-1.0.0/dnaty/evolution/evolver.py +285 -0
- dnaty-1.0.0/dnaty/evolution/selection.py +78 -0
- dnaty-1.0.0/dnaty/experiments/__init__.py +1 -0
- dnaty-1.0.0/dnaty/experiments/fast_dataset.py +106 -0
- dnaty-1.0.0/dnaty/logging_config.py +40 -0
- dnaty-1.0.0/dnaty/operators/__init__.py +1 -0
- dnaty-1.0.0/dnaty/operators/mutations.py +256 -0
- dnaty-1.0.0/dnaty/operators/mutations_cnn.py +259 -0
- dnaty-1.0.0/dnaty/tracking.py +113 -0
- dnaty-1.0.0/dnaty/training/__init__.py +1 -0
- dnaty-1.0.0/dnaty/training/local_train.py +214 -0
- dnaty-1.0.0/dnaty.egg-info/PKG-INFO +243 -0
- dnaty-1.0.0/dnaty.egg-info/SOURCES.txt +42 -0
- dnaty-1.0.0/dnaty.egg-info/dependency_links.txt +1 -0
- dnaty-1.0.0/dnaty.egg-info/requires.txt +10 -0
- dnaty-1.0.0/dnaty.egg-info/top_level.txt +1 -0
- dnaty-1.0.0/pyproject.toml +58 -0
- dnaty-1.0.0/setup.cfg +4 -0
- dnaty-1.0.0/tests/test_auth_rate_limit.py +316 -0
- dnaty-1.0.0/tests/test_compress.py +54 -0
- dnaty-1.0.0/tests/test_docker.py +321 -0
- dnaty-1.0.0/tests/test_e2e_integration.py +261 -0
- dnaty-1.0.0/tests/test_edge_cases.py +278 -0
- dnaty-1.0.0/tests/test_exp23.py +79 -0
- dnaty-1.0.0/tests/test_load.py +239 -0
- dnaty-1.0.0/tests/test_market_real_models.py +318 -0
- dnaty-1.0.0/tests/test_market_reality.py +230 -0
- dnaty-1.0.0/tests/test_market_validation.py +284 -0
- dnaty-1.0.0/tests/test_regression.py +190 -0
- dnaty-1.0.0/tests/test_reproducibility.py +230 -0
- dnaty-1.0.0/tests/test_sanity.py +95 -0
dnaty-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Parameters
|
|
4
|
+
|
|
5
|
+
Licensor: Pedro Vergueiro
|
|
6
|
+
Licensed Work: dNaty — Dynamic Neuro-Adaptive sYstem with evoluTionarY Learning
|
|
7
|
+
Copyright (c) 2026 Pedro Vergueiro
|
|
8
|
+
Additional Use Grant: You may use the Licensed Work for non-commercial research,
|
|
9
|
+
academic, and personal purposes free of charge.
|
|
10
|
+
Commercial use requires a separate commercial license.
|
|
11
|
+
Contact: legal@vergueiro.co for commercial licensing.
|
|
12
|
+
Change Date: 2029-01-01
|
|
13
|
+
Change License: Apache License, Version 2.0
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Terms
|
|
18
|
+
|
|
19
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
20
|
+
works, redistribute, and make non-production use of the Licensed Work.
|
|
21
|
+
|
|
22
|
+
The Licensor may make an Additional Use Grant, above, permitting limited
|
|
23
|
+
production use.
|
|
24
|
+
|
|
25
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
26
|
+
available distribution of a specific version of the Licensed Work under this
|
|
27
|
+
License, whichever comes first, the Licensor hereby grants you rights under
|
|
28
|
+
the terms of the Change License, and the rights granted in the paragraphs
|
|
29
|
+
above terminate.
|
|
30
|
+
|
|
31
|
+
COMMERCIAL USE RESTRICTION:
|
|
32
|
+
Any use of the Licensed Work in a commercial product or service — including
|
|
33
|
+
but not limited to SaaS, APIs, embedded systems, or consulting services —
|
|
34
|
+
requires a separate commercial license from the Licensor.
|
|
35
|
+
|
|
36
|
+
For commercial licensing inquiries, contact: legal@vergueiro.co
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
NOTICE: This is NOT an open source license. The source is available for
|
|
41
|
+
inspection and non-commercial use only. Commercial use without a license
|
|
42
|
+
is a violation of this agreement.
|
|
43
|
+
|
|
44
|
+
Full BSL 1.1 text: https://mariadb.com/bsl11/
|
dnaty-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dnaty
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Evolutionary Neural Architecture Search — compress any PyTorch model with one function call
|
|
5
|
+
Author-email: Pedro Vergueiro <pedrol.vergueiro@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/pedrovergueiroo/dNATY
|
|
8
|
+
Project-URL: Repository, https://github.com/pedrovergueiroo/dNATY
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/pedrovergueiroo/dNATY/issues
|
|
10
|
+
Keywords: neural architecture search,neuroevolution,model compression,continual learning,pytorch,evolutionary algorithms,nas,edge ml
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: torch>=2.0.0
|
|
24
|
+
Requires-Dist: torchvision>=0.15.0
|
|
25
|
+
Requires-Dist: numpy>=1.24.0
|
|
26
|
+
Requires-Dist: scipy>=1.10.0
|
|
27
|
+
Requires-Dist: tqdm>=4.65.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: matplotlib>=3.7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: jupyter; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
<div align="center">
|
|
35
|
+
|
|
36
|
+
# dNATY
|
|
37
|
+
|
|
38
|
+
### Evolutionary AI Model Compression
|
|
39
|
+
|
|
40
|
+
**46.5% fewer FLOPs • 1.6× faster inference • 98.85% accuracy retained**
|
|
41
|
+
|
|
42
|
+
[](https://pypi.org/project/dnaty/)
|
|
43
|
+
[](https://www.python.org/)
|
|
44
|
+
[](https://pytorch.org/)
|
|
45
|
+
[](LICENSE)
|
|
46
|
+
|
|
47
|
+
Automated model compression using multi-objective evolutionary search. Zero manual engineering. One function call: `compress(model, dataset)`.
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Why dNATY?
|
|
56
|
+
|
|
57
|
+
**Problem:** Most production models are oversized — too slow for real-time inference, too expensive to run.
|
|
58
|
+
|
|
59
|
+
**Existing solutions require:**
|
|
60
|
+
- Manual architecture tuning
|
|
61
|
+
- Days of hyperparameter search
|
|
62
|
+
- Accuracy/speed trade-offs
|
|
63
|
+
|
|
64
|
+
**dNATY solves this** with episodic memory-guided evolutionary search — operators that worked before are tried more often. Finds Pareto-optimal solutions in minutes.
|
|
65
|
+
|
|
66
|
+
### Proven Results (CIFAR-100)
|
|
67
|
+
|
|
68
|
+
| Model | FLOPs Reduction | Speedup | Accuracy | Time |
|
|
69
|
+
|-------|-----------------|---------|----------|------|
|
|
70
|
+
| ResNet-50 | **-46.5%** | 1.6× | 98.85% | 5min |
|
|
71
|
+
| EfficientNet-B0 | **-40%** | 1.4× | 98.85% | 6min |
|
|
72
|
+
| MobileNetV3-Large | **-98%** | 1.8× | 97.2% | 4min |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Project Structure
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
dNATY/
|
|
80
|
+
├── dnaty/ # Core compression framework
|
|
81
|
+
├── dnaty_saas/ # Production API (FastAPI)
|
|
82
|
+
├── frontend/ # Web UI (React + TypeScript)
|
|
83
|
+
├── notebooks/ # Experiments & benchmarks
|
|
84
|
+
├── scripts/ # Demo & utilities
|
|
85
|
+
├── tests/ # Unit tests
|
|
86
|
+
└── pyproject.toml # Package config
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Quick Start
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install dnaty
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from dnaty import compress
|
|
99
|
+
from dnaty.experiments.fast_dataset import FastDataset
|
|
100
|
+
|
|
101
|
+
# Your existing model (any PyTorch model with Linear layers)
|
|
102
|
+
model = your_trained_model
|
|
103
|
+
|
|
104
|
+
# Your data
|
|
105
|
+
ds = FastDataset("MNIST", device="cpu", train_subset=10_000)
|
|
106
|
+
|
|
107
|
+
# Compress
|
|
108
|
+
result = compress(model, ds, target_flops=0.5, n_generations=30)
|
|
109
|
+
|
|
110
|
+
print(result.summary())
|
|
111
|
+
# CompressResult | arch=[128, 64] | FLOPs -46.5% (327680 -> 175104) |
|
|
112
|
+
# params -52.3% (328K -> 156K) | acc=0.9821
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## How It Works
|
|
118
|
+
|
|
119
|
+
dNATY runs a population of candidate architectures through an evolution loop:
|
|
120
|
+
|
|
121
|
+
1. **Mutate** — apply structural operators (add/remove neurons, merge layers, etc.)
|
|
122
|
+
2. **Train** — locally train each candidate for a few epochs
|
|
123
|
+
3. **Select** — NSGA-II Pareto selection: maximize accuracy, minimize FLOPs
|
|
124
|
+
4. **Remember** — episodic memory records which operators helped most; they get picked more often next round
|
|
125
|
+
|
|
126
|
+
The memory mechanism is dNATY's core innovation. Over generations, the search becomes smarter — not random.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## API
|
|
131
|
+
|
|
132
|
+
### `compress(model, train_data, **kwargs) -> CompressResult`
|
|
133
|
+
|
|
134
|
+
| Parameter | Default | Description |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `model` | required | Any `nn.Module` with Linear layers |
|
|
137
|
+
| `train_data` | required | `DataLoader` or `FastDataset` |
|
|
138
|
+
| `target_flops` | `0.5` | Target fraction of original FLOPs (0.5 = 50% less) |
|
|
139
|
+
| `n_generations` | `30` | Evolutionary generations |
|
|
140
|
+
| `n_pop` | `15` | Population size |
|
|
141
|
+
| `device` | auto | `'cpu'` or `'cuda'` |
|
|
142
|
+
| `seed` | `None` | Fix for reproducibility |
|
|
143
|
+
|
|
144
|
+
### `CompressResult`
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
result.model # compressed nn.Module, ready to use
|
|
148
|
+
result.accuracy # validation accuracy
|
|
149
|
+
result.flops_reduction # e.g. 0.465 = 46.5% fewer FLOPs
|
|
150
|
+
result.flops_reduction_pct # same as percentage
|
|
151
|
+
result.params_reduction_pct
|
|
152
|
+
result.arch # hidden layer sizes found [128, 64]
|
|
153
|
+
result.summary() # one-line human-readable summary
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## SaaS API
|
|
159
|
+
|
|
160
|
+
dNATY ships with a production-ready FastAPI backend.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cd dnaty_saas
|
|
164
|
+
cp .env.example .env # fill DATABASE_URL, JWT_SECRET, ANTHROPIC_API_KEY
|
|
165
|
+
uvicorn main:app --reload
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `POST /api/v1/compress`
|
|
169
|
+
|
|
170
|
+
```json
|
|
171
|
+
{
|
|
172
|
+
"description": "classifica defeitos em pecas, precisa rodar no Raspberry Pi",
|
|
173
|
+
"dataset": "MNIST",
|
|
174
|
+
"target_flops": 0.5,
|
|
175
|
+
"n_generations": 30
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Response `202`:
|
|
180
|
+
```json
|
|
181
|
+
{ "job_id": "a3f2c1b0", "status": "queued", "message": "..." }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### `GET /api/v1/compress/{job_id}`
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"status": "completed",
|
|
189
|
+
"result": {
|
|
190
|
+
"accuracy": 0.9821,
|
|
191
|
+
"flops_reduction": 0.465,
|
|
192
|
+
"arch": [128, 64],
|
|
193
|
+
"explanation": "...", // Claude-generated explanation
|
|
194
|
+
"deployment_code": "..." // ready-to-use Python code
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
> Set `ANTHROPIC_API_KEY` in `.env` to enable Claude explanations.
|
|
200
|
+
> Without it, the endpoint still works — returns template text instead.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Getting Started
|
|
205
|
+
|
|
206
|
+
### Web UI
|
|
207
|
+
```bash
|
|
208
|
+
cd frontend
|
|
209
|
+
npm install
|
|
210
|
+
npm run dev
|
|
211
|
+
```
|
|
212
|
+
Open [http://localhost:5173](http://localhost:5173)
|
|
213
|
+
|
|
214
|
+
### Jupyter Notebooks
|
|
215
|
+
- **CIFAR-100 Baseline** — [notebooks/colab_cifar100_notebook.ipynb](notebooks/colab_cifar100_notebook.ipynb)
|
|
216
|
+
- **ImageNet Benchmark** — [notebooks/colab_imagenet_simple_FIXED.ipynb](notebooks/colab_imagenet_simple_FIXED.ipynb)
|
|
217
|
+
- **CPU Latency** — [notebooks/benchmark_cpu_latency.py](notebooks/benchmark_cpu_latency.py)
|
|
218
|
+
|
|
219
|
+
### CLI Demo
|
|
220
|
+
```bash
|
|
221
|
+
python scripts/demo_compress.py # 20 gens, MNIST (~5 min CPU)
|
|
222
|
+
python scripts/demo_compress.py --full # 30 gens, more accurate
|
|
223
|
+
python scripts/demo_compress.py --dataset FashionMNIST
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Benchmarks
|
|
229
|
+
|
|
230
|
+
| Metric | Value |
|
|
231
|
+
|---|---|
|
|
232
|
+
| FLOPs reduction vs. initial arch | -46.5% |
|
|
233
|
+
| FLOPs reduction vs. RandomNAS | better in Pareto front |
|
|
234
|
+
| Speedup to target accuracy | 1.6x fewer generations |
|
|
235
|
+
| CL: BWT vs. EWC | 6.9x less forgetting |
|
|
236
|
+
|
|
237
|
+
All numbers reproducible with `python scripts/prove_it.py`.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
[BSL 1.1](LICENSE) — free for non-commercial use; contact pedrol.vergueiro@gmail.com for commercial licensing.
|
dnaty-1.0.0/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# dNATY
|
|
4
|
+
|
|
5
|
+
### Evolutionary AI Model Compression
|
|
6
|
+
|
|
7
|
+
**46.5% fewer FLOPs • 1.6× faster inference • 98.85% accuracy retained**
|
|
8
|
+
|
|
9
|
+
[](https://pypi.org/project/dnaty/)
|
|
10
|
+
[](https://www.python.org/)
|
|
11
|
+
[](https://pytorch.org/)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
Automated model compression using multi-objective evolutionary search. Zero manual engineering. One function call: `compress(model, dataset)`.
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Why dNATY?
|
|
23
|
+
|
|
24
|
+
**Problem:** Most production models are oversized — too slow for real-time inference, too expensive to run.
|
|
25
|
+
|
|
26
|
+
**Existing solutions require:**
|
|
27
|
+
- Manual architecture tuning
|
|
28
|
+
- Days of hyperparameter search
|
|
29
|
+
- Accuracy/speed trade-offs
|
|
30
|
+
|
|
31
|
+
**dNATY solves this** with episodic memory-guided evolutionary search — operators that worked before are tried more often. Finds Pareto-optimal solutions in minutes.
|
|
32
|
+
|
|
33
|
+
### Proven Results (CIFAR-100)
|
|
34
|
+
|
|
35
|
+
| Model | FLOPs Reduction | Speedup | Accuracy | Time |
|
|
36
|
+
|-------|-----------------|---------|----------|------|
|
|
37
|
+
| ResNet-50 | **-46.5%** | 1.6× | 98.85% | 5min |
|
|
38
|
+
| EfficientNet-B0 | **-40%** | 1.4× | 98.85% | 6min |
|
|
39
|
+
| MobileNetV3-Large | **-98%** | 1.8× | 97.2% | 4min |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Project Structure
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
dNATY/
|
|
47
|
+
├── dnaty/ # Core compression framework
|
|
48
|
+
├── dnaty_saas/ # Production API (FastAPI)
|
|
49
|
+
├── frontend/ # Web UI (React + TypeScript)
|
|
50
|
+
├── notebooks/ # Experiments & benchmarks
|
|
51
|
+
├── scripts/ # Demo & utilities
|
|
52
|
+
├── tests/ # Unit tests
|
|
53
|
+
└── pyproject.toml # Package config
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install dnaty
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from dnaty import compress
|
|
66
|
+
from dnaty.experiments.fast_dataset import FastDataset
|
|
67
|
+
|
|
68
|
+
# Your existing model (any PyTorch model with Linear layers)
|
|
69
|
+
model = your_trained_model
|
|
70
|
+
|
|
71
|
+
# Your data
|
|
72
|
+
ds = FastDataset("MNIST", device="cpu", train_subset=10_000)
|
|
73
|
+
|
|
74
|
+
# Compress
|
|
75
|
+
result = compress(model, ds, target_flops=0.5, n_generations=30)
|
|
76
|
+
|
|
77
|
+
print(result.summary())
|
|
78
|
+
# CompressResult | arch=[128, 64] | FLOPs -46.5% (327680 -> 175104) |
|
|
79
|
+
# params -52.3% (328K -> 156K) | acc=0.9821
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## How It Works
|
|
85
|
+
|
|
86
|
+
dNATY runs a population of candidate architectures through an evolution loop:
|
|
87
|
+
|
|
88
|
+
1. **Mutate** — apply structural operators (add/remove neurons, merge layers, etc.)
|
|
89
|
+
2. **Train** — locally train each candidate for a few epochs
|
|
90
|
+
3. **Select** — NSGA-II Pareto selection: maximize accuracy, minimize FLOPs
|
|
91
|
+
4. **Remember** — episodic memory records which operators helped most; they get picked more often next round
|
|
92
|
+
|
|
93
|
+
The memory mechanism is dNATY's core innovation. Over generations, the search becomes smarter — not random.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## API
|
|
98
|
+
|
|
99
|
+
### `compress(model, train_data, **kwargs) -> CompressResult`
|
|
100
|
+
|
|
101
|
+
| Parameter | Default | Description |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `model` | required | Any `nn.Module` with Linear layers |
|
|
104
|
+
| `train_data` | required | `DataLoader` or `FastDataset` |
|
|
105
|
+
| `target_flops` | `0.5` | Target fraction of original FLOPs (0.5 = 50% less) |
|
|
106
|
+
| `n_generations` | `30` | Evolutionary generations |
|
|
107
|
+
| `n_pop` | `15` | Population size |
|
|
108
|
+
| `device` | auto | `'cpu'` or `'cuda'` |
|
|
109
|
+
| `seed` | `None` | Fix for reproducibility |
|
|
110
|
+
|
|
111
|
+
### `CompressResult`
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
result.model # compressed nn.Module, ready to use
|
|
115
|
+
result.accuracy # validation accuracy
|
|
116
|
+
result.flops_reduction # e.g. 0.465 = 46.5% fewer FLOPs
|
|
117
|
+
result.flops_reduction_pct # same as percentage
|
|
118
|
+
result.params_reduction_pct
|
|
119
|
+
result.arch # hidden layer sizes found [128, 64]
|
|
120
|
+
result.summary() # one-line human-readable summary
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## SaaS API
|
|
126
|
+
|
|
127
|
+
dNATY ships with a production-ready FastAPI backend.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
cd dnaty_saas
|
|
131
|
+
cp .env.example .env # fill DATABASE_URL, JWT_SECRET, ANTHROPIC_API_KEY
|
|
132
|
+
uvicorn main:app --reload
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### `POST /api/v1/compress`
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"description": "classifica defeitos em pecas, precisa rodar no Raspberry Pi",
|
|
140
|
+
"dataset": "MNIST",
|
|
141
|
+
"target_flops": 0.5,
|
|
142
|
+
"n_generations": 30
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Response `202`:
|
|
147
|
+
```json
|
|
148
|
+
{ "job_id": "a3f2c1b0", "status": "queued", "message": "..." }
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `GET /api/v1/compress/{job_id}`
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"status": "completed",
|
|
156
|
+
"result": {
|
|
157
|
+
"accuracy": 0.9821,
|
|
158
|
+
"flops_reduction": 0.465,
|
|
159
|
+
"arch": [128, 64],
|
|
160
|
+
"explanation": "...", // Claude-generated explanation
|
|
161
|
+
"deployment_code": "..." // ready-to-use Python code
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
> Set `ANTHROPIC_API_KEY` in `.env` to enable Claude explanations.
|
|
167
|
+
> Without it, the endpoint still works — returns template text instead.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Getting Started
|
|
172
|
+
|
|
173
|
+
### Web UI
|
|
174
|
+
```bash
|
|
175
|
+
cd frontend
|
|
176
|
+
npm install
|
|
177
|
+
npm run dev
|
|
178
|
+
```
|
|
179
|
+
Open [http://localhost:5173](http://localhost:5173)
|
|
180
|
+
|
|
181
|
+
### Jupyter Notebooks
|
|
182
|
+
- **CIFAR-100 Baseline** — [notebooks/colab_cifar100_notebook.ipynb](notebooks/colab_cifar100_notebook.ipynb)
|
|
183
|
+
- **ImageNet Benchmark** — [notebooks/colab_imagenet_simple_FIXED.ipynb](notebooks/colab_imagenet_simple_FIXED.ipynb)
|
|
184
|
+
- **CPU Latency** — [notebooks/benchmark_cpu_latency.py](notebooks/benchmark_cpu_latency.py)
|
|
185
|
+
|
|
186
|
+
### CLI Demo
|
|
187
|
+
```bash
|
|
188
|
+
python scripts/demo_compress.py # 20 gens, MNIST (~5 min CPU)
|
|
189
|
+
python scripts/demo_compress.py --full # 30 gens, more accurate
|
|
190
|
+
python scripts/demo_compress.py --dataset FashionMNIST
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Benchmarks
|
|
196
|
+
|
|
197
|
+
| Metric | Value |
|
|
198
|
+
|---|---|
|
|
199
|
+
| FLOPs reduction vs. initial arch | -46.5% |
|
|
200
|
+
| FLOPs reduction vs. RandomNAS | better in Pareto front |
|
|
201
|
+
| Speedup to target accuracy | 1.6x fewer generations |
|
|
202
|
+
| CL: BWT vs. EWC | 6.9x less forgetting |
|
|
203
|
+
|
|
204
|
+
All numbers reproducible with `python scripts/prove_it.py`.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
[BSL 1.1](LICENSE) — free for non-commercial use; contact pedrol.vergueiro@gmail.com for commercial licensing.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
dNATY — Dynamic Neuro-Adaptive sYstem.
|
|
3
|
+
|
|
4
|
+
Evolutionary Neural Architecture Search with episodic memory.
|
|
5
|
+
Finds compact, efficient models via guided evolution — not random search.
|
|
6
|
+
|
|
7
|
+
Quick start:
|
|
8
|
+
from dnaty import compress
|
|
9
|
+
from dnaty.experiments.fast_dataset import FastDataset
|
|
10
|
+
|
|
11
|
+
ds = FastDataset("MNIST", device="cpu", train_subset=10_000)
|
|
12
|
+
result = compress(your_model, ds, target_flops=0.5)
|
|
13
|
+
print(result.summary())
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
__version__ = "1.0.0"
|
|
17
|
+
|
|
18
|
+
from dnaty.compress import compress, CompressResult
|
|
19
|
+
from dnaty.evolution.evolver import DnatyEvolver
|
|
20
|
+
|
|
21
|
+
__all__ = ["compress", "CompressResult", "DnatyEvolver", "__version__"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Métricas de Continual Learning — Lopez-Paz et al. (2017).
|
|
3
|
+
BWT, FWT, FM implementados conforme formalização seção 1.5.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def compute_cl_metrics(R: np.ndarray, baselines: np.ndarray | None = None) -> dict[str, float]:
|
|
10
|
+
"""
|
|
11
|
+
R[i, j] = acurácia na tarefa j após treinar sequencialmente até tarefa i.
|
|
12
|
+
R é indexado de 0 (após tarefa 0) até T-1 (após tarefa T-1).
|
|
13
|
+
baselines[j] = acurácia single-task na tarefa j (para FWT).
|
|
14
|
+
"""
|
|
15
|
+
T = R.shape[1]
|
|
16
|
+
|
|
17
|
+
# BWT: Backward Transfer — forgetting
|
|
18
|
+
# BWT = (1/(T-1)) * Σ_{i=1}^{T-1} (R[T-1,i] - R[i,i])
|
|
19
|
+
bwt_terms = [R[T - 1, i] - R[i, i] for i in range(T - 1)]
|
|
20
|
+
BWT = float(np.mean(bwt_terms)) if bwt_terms else 0.0
|
|
21
|
+
|
|
22
|
+
# FWT: Forward Transfer
|
|
23
|
+
if baselines is not None:
|
|
24
|
+
fwt_terms = [R[i - 1, i] - baselines[i] for i in range(1, T)]
|
|
25
|
+
FWT = float(np.mean(fwt_terms)) if fwt_terms else 0.0
|
|
26
|
+
else:
|
|
27
|
+
FWT = 0.0
|
|
28
|
+
|
|
29
|
+
# FM: Forgetting Measure — queda do pico
|
|
30
|
+
fm_terms = []
|
|
31
|
+
for i in range(T - 1):
|
|
32
|
+
peak = max(R[j, i] for j in range(T))
|
|
33
|
+
fm_terms.append(peak - R[T - 1, i])
|
|
34
|
+
FM = float(np.mean(fm_terms)) if fm_terms else 0.0
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
"BWT": round(BWT, 4),
|
|
38
|
+
"FWT": round(FWT, 4),
|
|
39
|
+
"FM": round(FM, 4),
|
|
40
|
+
}
|