sigularty 0.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.
- sigularty-0.0.0/PKG-INFO +279 -0
- sigularty-0.0.0/PublicReadme.md +253 -0
- sigularty-0.0.0/README.md +2497 -0
- sigularty-0.0.0/pyproject.toml +39 -0
- sigularty-0.0.0/setup.cfg +4 -0
- sigularty-0.0.0/sigularty/__init__.py +50 -0
- sigularty-0.0.0/sigularty/_api.py +1250 -0
- sigularty-0.0.0/sigularty/_results.py +138 -0
- sigularty-0.0.0/sigularty/_search.py +112 -0
- sigularty-0.0.0/sigularty/compression.py +5169 -0
- sigularty-0.0.0/sigularty/helper_functions.py +3625 -0
- sigularty-0.0.0/sigularty/model_registry.py +1040 -0
- sigularty-0.0.0/sigularty/optimization.py +1996 -0
- sigularty-0.0.0/sigularty/visualization.py +1457 -0
- sigularty-0.0.0/sigularty.egg-info/PKG-INFO +279 -0
- sigularty-0.0.0/sigularty.egg-info/SOURCES.txt +17 -0
- sigularty-0.0.0/sigularty.egg-info/dependency_links.txt +1 -0
- sigularty-0.0.0/sigularty.egg-info/requires.txt +14 -0
- sigularty-0.0.0/sigularty.egg-info/top_level.txt +1 -0
sigularty-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sigularty
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Production-grade PyTorch model compression: pruning, LRF, clustering, quantization, GPTQ.
|
|
5
|
+
Author: sigularty
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: License :: Other/Proprietary License
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: torch>=2.0
|
|
15
|
+
Requires-Dist: torchvision>=0.15
|
|
16
|
+
Requires-Dist: torchmetrics>=0.11
|
|
17
|
+
Requires-Dist: tqdm
|
|
18
|
+
Requires-Dist: numpy
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Provides-Extra: pruning
|
|
21
|
+
Requires-Dist: torch-pruning>=1.3; extra == "pruning"
|
|
22
|
+
Provides-Extra: full
|
|
23
|
+
Requires-Dist: torch-pruning>=1.3; extra == "full"
|
|
24
|
+
Requires-Dist: onnx; extra == "full"
|
|
25
|
+
Requires-Dist: onnxruntime; extra == "full"
|
|
26
|
+
|
|
27
|
+
# Using sigularty
|
|
28
|
+
|
|
29
|
+
This is a quick reference for calling sigularty as a library: how to
|
|
30
|
+
import it, the two ways to get a model in, and what every `compress()`
|
|
31
|
+
argument does. For the theory behind each technique — why pruning runs
|
|
32
|
+
before LRF, what CQI means, why quantization is always last — see
|
|
33
|
+
[README.md](README.md).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/<you>/sigularty.git
|
|
41
|
+
cd sigularty
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Quickstart
|
|
48
|
+
|
|
49
|
+
**Fastest path — a registry model + its paired dataset in one call:**
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from sigularty import load_from_registry, compress
|
|
53
|
+
|
|
54
|
+
r = load_from_registry('resnet18', device='cuda')
|
|
55
|
+
|
|
56
|
+
result = compress(
|
|
57
|
+
r.model,
|
|
58
|
+
r.train_loader,
|
|
59
|
+
num_classes=r.num_classes,
|
|
60
|
+
use_pruning=True,
|
|
61
|
+
use_lrf=True,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
print(result)
|
|
65
|
+
# CompressionResult(ratio=3.42x, accuracy_retention=96.1%, size=42.7->12.5 MB, speedup=1.8x, cqi=2.113)
|
|
66
|
+
|
|
67
|
+
compressed_model = result.model
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Bring your own model:**
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from sigularty import compress
|
|
74
|
+
|
|
75
|
+
result = compress(model, train_loader, num_classes=num_classes)
|
|
76
|
+
compressed_model = result.model
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`model` can be any `nn.Module`. `dataloader` (positional, second argument)
|
|
80
|
+
is used for calibration, fine-tuning, and evaluation throughout the
|
|
81
|
+
pipeline — it's never optional. The original model is never modified;
|
|
82
|
+
`compress()` always works on a deep copy.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Other entry points
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from sigularty import (
|
|
90
|
+
compress, # run the full compression pipeline
|
|
91
|
+
analyze, # inspect a model, get technique recommendations
|
|
92
|
+
load_from_registry, # pull a registry model + its dataset together
|
|
93
|
+
load_model_and_data, # older form of the above, returns a plain tuple
|
|
94
|
+
finetune, # fine-tune a model before compressing it
|
|
95
|
+
find_best_lr, # LR range test — run before finetune()/pretrain_*
|
|
96
|
+
plot_compression_report,
|
|
97
|
+
plot_pruning_report,
|
|
98
|
+
plot_epsilon_landscape,
|
|
99
|
+
)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
| Function | Signature | Returns |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `analyze(model, dataloader=None, *, device=None)` | Inspects a model without modifying it. | `AnalysisResult` |
|
|
105
|
+
| `load_from_registry(model_name, *, device=None, train_sample=None, test_sample=500, batch_size=32, model_path=None, force_retrain=False, pretrain_epochs=10, pretrain_lr=1e-4)` | See list of registry model names below. | `RegistryResult` |
|
|
106
|
+
| `load_model_and_data(model_name, device=None, ...)` | Same idea as above, older interface. | `(model, train_loader, test_loader, meta)` |
|
|
107
|
+
| `finetune(model, train_loader, *, test_loader=None, num_classes=10, epochs=10, lr=1e-3, max_batches=0, device=None, save_path=None)` | Fine-tunes in place and returns the same object. | `nn.Module` |
|
|
108
|
+
| `find_best_lr(model, dataloader, *, device=None, num_classes=10, start_lr=1e-7, end_lr=10.0, num_steps=100)` | LR range test; run before `finetune()` or `pretrain_epochs > 0`. | `float` |
|
|
109
|
+
|
|
110
|
+
Registry model names (pass as `model_name`): `resnet18`, `resnet50`,
|
|
111
|
+
`resnext50_32x4d`, `wide_resnet50_2`, `vgg16`, `densenet121`,
|
|
112
|
+
`convnext_tiny`, `regnet_y_400mf`, `shufflenet_v2_x1_0`, `squeezenet1_1`,
|
|
113
|
+
`mobilenet_v3_large`, `efficientnet_b0`, `inception_v3`, `vit_b_16`,
|
|
114
|
+
`swin_t`, `bert_base`, `distilbert`, `roberta_base`, `albert_base`,
|
|
115
|
+
`distilgpt2`, `custom_cnn`.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## What `compress()` returns
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
result.model # nn.Module — the compressed model, ready to use
|
|
123
|
+
result.compression_ratio # size_original / size_compressed, e.g. 3.8 = 3.8x smaller
|
|
124
|
+
result.accuracy_retention # (compressed_acc / original_acc) * 100
|
|
125
|
+
result.size_original_mb
|
|
126
|
+
result.size_compressed_mb
|
|
127
|
+
result.original_accuracy
|
|
128
|
+
result.compressed_accuracy
|
|
129
|
+
result.original_latency_ms
|
|
130
|
+
result.compressed_latency_ms
|
|
131
|
+
result.latency_speedup # original_lat / compressed_lat, >1.0 = faster
|
|
132
|
+
result.cqi # Compression Quality Index — see README.md
|
|
133
|
+
result.techniques_applied # list[str], only techniques that actually ran/survived
|
|
134
|
+
result.report_path # path to the saved PNG report, or None
|
|
135
|
+
result.pruning_report # dict of per-layer pruning detail, or None
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`analyze()` returns an `AnalysisResult`: `size_mb`, `num_parameters`,
|
|
139
|
+
`architecture_type` (`'cnn'` / `'transformer'` / `'hybrid'` / `'unknown'`),
|
|
140
|
+
`recommended_techniques`, `per_layer_signals` (a `LayerSignal` per eligible
|
|
141
|
+
layer: `name`, `layer_type`, `lrf_epsilon`, `prunable`, `size_kb`), and
|
|
142
|
+
`accuracy` if you passed a dataloader.
|
|
143
|
+
|
|
144
|
+
`load_from_registry()` returns a `RegistryResult`: `model`, `train_loader`,
|
|
145
|
+
`test_loader`, `num_classes`, `model_name`, `dataset_name`.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## `compress()` hyperparameters
|
|
150
|
+
|
|
151
|
+
Every argument after `model` and `dataloader` is keyword-only. Grouped
|
|
152
|
+
the same way the function itself groups them.
|
|
153
|
+
|
|
154
|
+
### Device
|
|
155
|
+
|
|
156
|
+
| Arg | Default | What it does |
|
|
157
|
+
|---|---|---|
|
|
158
|
+
| `device` | `None` | `'cuda'` or `'cpu'`. Auto-detected when not set. |
|
|
159
|
+
|
|
160
|
+
### Model metadata
|
|
161
|
+
|
|
162
|
+
| Arg | Default | What it does |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `model_type` | `'unknown'` | Architecture class for pruning's safety clamp: `'classifier'`, `'embedding'`, `'generative'`, or `'unknown'`. |
|
|
165
|
+
| `num_classes` | `10` | Output class count, used by every fine-tune step's accuracy metric. |
|
|
166
|
+
|
|
167
|
+
### Pre-training
|
|
168
|
+
|
|
169
|
+
Use these when the model hasn't been trained on your target dataset yet
|
|
170
|
+
(e.g. fresh ImageNet weights with an untrained head).
|
|
171
|
+
|
|
172
|
+
| Arg | Default | What it does |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| `pretrain_epochs` | `0` | Epochs to fine-tune before compressing. `0` skips this entirely. |
|
|
175
|
+
| `pretrain_lr` | `1e-3` | Learning rate for that pre-training. |
|
|
176
|
+
| `pretrain_test_loader` | `None` | Validation loader for pre-training. Falls back to `dataloader`. |
|
|
177
|
+
|
|
178
|
+
### Hyperparameter search (optional, adds evaluations before the pipeline runs)
|
|
179
|
+
|
|
180
|
+
| Arg | Default | What it does |
|
|
181
|
+
|---|---|---|
|
|
182
|
+
| `find_optimal_epsilon` | `False` | Auto-search for the best LRF epsilon instead of using `lrf_epsilon` as-is. |
|
|
183
|
+
| `find_optimal_pruning` | `False` | Auto-search for the best pruning ratio instead of using `pruning_ratio` as-is. |
|
|
184
|
+
| `epsilon_search_trials` | `15` | Evaluation budget for the epsilon search. |
|
|
185
|
+
| `pruning_search_trials` | `16` | Evaluation budget for the pruning search. |
|
|
186
|
+
| `pruning_search_ft_epochs` | `1` | Fine-tune epochs per trial during the pruning search (kept low for speed — the real run uses `pruning_fine_tune_epochs`). |
|
|
187
|
+
| `pruning_search_ft_lr` | `1e-4` | Fine-tune learning rate per trial during the pruning search. |
|
|
188
|
+
| `accuracy_drop_threshold` | `5.0` | Max acceptable accuracy drop in percentage points — used by both searches' final selection and the pipeline's per-technique revert gate. |
|
|
189
|
+
|
|
190
|
+
### Technique enable flags
|
|
191
|
+
|
|
192
|
+
| Arg | Default |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `use_pruning` | `False` |
|
|
195
|
+
| `use_lrf` | `True` |
|
|
196
|
+
| `use_clustering` | `True` |
|
|
197
|
+
| `use_quantization` | `True` |
|
|
198
|
+
| `use_kd_finetune` | `True` |
|
|
199
|
+
| `use_gptq` | `False` |
|
|
200
|
+
|
|
201
|
+
### Pruning hyperparameters
|
|
202
|
+
|
|
203
|
+
| Arg | Default | What it does |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `pruning_ratio` | `0.3` | Target fraction of channels removed globally. |
|
|
206
|
+
| `pruning_max_ratio` | `0.95` | Hard cap on how much any single layer/dependency-group can be pruned. |
|
|
207
|
+
| `pruning_model_type` | `'classifier'` | Same role as `model_type`, specific to pruning's clamp. |
|
|
208
|
+
| `pruning_fine_tune_epochs` | `3` | KD recovery epochs after pruning. |
|
|
209
|
+
| `pruning_fine_tune_lr` | `1e-4` | Learning rate for that recovery fine-tune. |
|
|
210
|
+
| `pruning_cal_batches` | `50` | Calibration batches for activation-statistics importance scoring. |
|
|
211
|
+
| `pruning_iterative_steps` | `1` | Prune in one shot (`1`) or multiple incremental rounds (more stable, slower). |
|
|
212
|
+
| `pruning_isomorphic` | `False` | Force identical pruning structure across coupled dependency groups. |
|
|
213
|
+
| `pruning_round_to` | `None` | Round pruned channel counts to a multiple of this (e.g. `8`/`16` for Tensor Core alignment). |
|
|
214
|
+
|
|
215
|
+
### Low-Rank Factorization (LRF) hyperparameters
|
|
216
|
+
|
|
217
|
+
| Arg | Default | What it does |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| `lrf_epsilon` | `0.5` | Rank ratio kept. Lower = more compression, more accuracy risk. |
|
|
220
|
+
| `lrf_adaptive` | `False` | Compute epsilon per layer from SVD energy decay instead of one global value. |
|
|
221
|
+
| `lrf_energy_threshold` | `0.99` | Fraction of SVD energy retained per layer, when adaptive. |
|
|
222
|
+
| `lrf_min_layer_size` | `64` | Skip layers with a dimension below this. |
|
|
223
|
+
| `lrf_min_rank` | `2` | Skip a layer if its computed rank would fall below this. |
|
|
224
|
+
| `lrf_skip_large_kernels` | `False` | Skip Conv2d layers with kernel > 1x1 — prevents latency regression on 3x3-heavy CNNs (ResNet/VGG-style). |
|
|
225
|
+
|
|
226
|
+
### Weight clustering hyperparameters
|
|
227
|
+
|
|
228
|
+
| Arg | Default | What it does |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| `num_clusters` | `16` | k for k-means weight clustering. |
|
|
231
|
+
| `cluster_fine_tune_epochs` | `5` | Recovery fine-tune epochs after clustering. |
|
|
232
|
+
| `cluster_fine_tune_lr` | `1e-5` | Learning rate for that recovery fine-tune. |
|
|
233
|
+
|
|
234
|
+
### Knowledge distillation fine-tuning hyperparameters
|
|
235
|
+
|
|
236
|
+
The final recovery step, run after quantization/GPTQ so it can recover
|
|
237
|
+
accuracy lost from every prior step at once.
|
|
238
|
+
|
|
239
|
+
| Arg | Default | What it does |
|
|
240
|
+
|---|---|---|
|
|
241
|
+
| `kd_epochs` | `3` | Fine-tune epochs. |
|
|
242
|
+
| `kd_lr` | `1e-5` | Learning rate. |
|
|
243
|
+
| `kd_temperature` | `4.0` | Softmax temperature for the teacher's soft labels. |
|
|
244
|
+
| `kd_alpha` | `0.7` | Weight on hard-label loss; `1 - kd_alpha` goes to the distillation loss. |
|
|
245
|
+
|
|
246
|
+
### Quantization hyperparameters
|
|
247
|
+
|
|
248
|
+
| Arg | Default | What it does |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| `quant_mode` | `'fp16'` | `'fp16'`, `'dynamic'` (INT8, CPU-friendly), or `'static'` (auto-switched to `'dynamic'`). |
|
|
251
|
+
| `quant_cal_batches` | `100` | Calibration batches — only used by `'static'`. |
|
|
252
|
+
|
|
253
|
+
### GPTQ hyperparameters
|
|
254
|
+
|
|
255
|
+
| Arg | Default | What it does |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `gptq_bits` | `4` | `4` for INT4 (8x compression) or `8` for INT8 (4x). |
|
|
258
|
+
| `gptq_cal_batches` | `16` | Batches used to estimate the Hessian from activations. |
|
|
259
|
+
| `gptq_block_size` | `128` | Columns processed per Hessian update block. |
|
|
260
|
+
|
|
261
|
+
### CQI scoring weights
|
|
262
|
+
|
|
263
|
+
Each is an exponent applied to that factor's ratio in the Compression
|
|
264
|
+
Quality Index — raise one to make the search/report weight that factor
|
|
265
|
+
more heavily.
|
|
266
|
+
|
|
267
|
+
| Arg | Default |
|
|
268
|
+
|---|---|
|
|
269
|
+
| `cqi_w_accuracy` | `1.0` |
|
|
270
|
+
| `cqi_w_size` | `1.0` |
|
|
271
|
+
| `cqi_w_latency` | `1.0` |
|
|
272
|
+
| `cqi_w_kl` | `1.0` (only meaningful when pruning ran) |
|
|
273
|
+
|
|
274
|
+
### Report
|
|
275
|
+
|
|
276
|
+
| Arg | Default | What it does |
|
|
277
|
+
|---|---|---|
|
|
278
|
+
| `save_report` | `True` | Generate the PNG compression report. |
|
|
279
|
+
| `report_path` | `'compression_report.png'` | Where to save it. |
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Using sigularty
|
|
2
|
+
|
|
3
|
+
This is a quick reference for calling sigularty as a library: how to
|
|
4
|
+
import it, the two ways to get a model in, and what every `compress()`
|
|
5
|
+
argument does. For the theory behind each technique — why pruning runs
|
|
6
|
+
before LRF, what CQI means, why quantization is always last — see
|
|
7
|
+
[README.md](README.md).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/<you>/sigularty.git
|
|
15
|
+
cd sigularty
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quickstart
|
|
22
|
+
|
|
23
|
+
**Fastest path — a registry model + its paired dataset in one call:**
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from sigularty import load_from_registry, compress
|
|
27
|
+
|
|
28
|
+
r = load_from_registry('resnet18', device='cuda')
|
|
29
|
+
|
|
30
|
+
result = compress(
|
|
31
|
+
r.model,
|
|
32
|
+
r.train_loader,
|
|
33
|
+
num_classes=r.num_classes,
|
|
34
|
+
use_pruning=True,
|
|
35
|
+
use_lrf=True,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
print(result)
|
|
39
|
+
# CompressionResult(ratio=3.42x, accuracy_retention=96.1%, size=42.7->12.5 MB, speedup=1.8x, cqi=2.113)
|
|
40
|
+
|
|
41
|
+
compressed_model = result.model
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Bring your own model:**
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from sigularty import compress
|
|
48
|
+
|
|
49
|
+
result = compress(model, train_loader, num_classes=num_classes)
|
|
50
|
+
compressed_model = result.model
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`model` can be any `nn.Module`. `dataloader` (positional, second argument)
|
|
54
|
+
is used for calibration, fine-tuning, and evaluation throughout the
|
|
55
|
+
pipeline — it's never optional. The original model is never modified;
|
|
56
|
+
`compress()` always works on a deep copy.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Other entry points
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from sigularty import (
|
|
64
|
+
compress, # run the full compression pipeline
|
|
65
|
+
analyze, # inspect a model, get technique recommendations
|
|
66
|
+
load_from_registry, # pull a registry model + its dataset together
|
|
67
|
+
load_model_and_data, # older form of the above, returns a plain tuple
|
|
68
|
+
finetune, # fine-tune a model before compressing it
|
|
69
|
+
find_best_lr, # LR range test — run before finetune()/pretrain_*
|
|
70
|
+
plot_compression_report,
|
|
71
|
+
plot_pruning_report,
|
|
72
|
+
plot_epsilon_landscape,
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| Function | Signature | Returns |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `analyze(model, dataloader=None, *, device=None)` | Inspects a model without modifying it. | `AnalysisResult` |
|
|
79
|
+
| `load_from_registry(model_name, *, device=None, train_sample=None, test_sample=500, batch_size=32, model_path=None, force_retrain=False, pretrain_epochs=10, pretrain_lr=1e-4)` | See list of registry model names below. | `RegistryResult` |
|
|
80
|
+
| `load_model_and_data(model_name, device=None, ...)` | Same idea as above, older interface. | `(model, train_loader, test_loader, meta)` |
|
|
81
|
+
| `finetune(model, train_loader, *, test_loader=None, num_classes=10, epochs=10, lr=1e-3, max_batches=0, device=None, save_path=None)` | Fine-tunes in place and returns the same object. | `nn.Module` |
|
|
82
|
+
| `find_best_lr(model, dataloader, *, device=None, num_classes=10, start_lr=1e-7, end_lr=10.0, num_steps=100)` | LR range test; run before `finetune()` or `pretrain_epochs > 0`. | `float` |
|
|
83
|
+
|
|
84
|
+
Registry model names (pass as `model_name`): `resnet18`, `resnet50`,
|
|
85
|
+
`resnext50_32x4d`, `wide_resnet50_2`, `vgg16`, `densenet121`,
|
|
86
|
+
`convnext_tiny`, `regnet_y_400mf`, `shufflenet_v2_x1_0`, `squeezenet1_1`,
|
|
87
|
+
`mobilenet_v3_large`, `efficientnet_b0`, `inception_v3`, `vit_b_16`,
|
|
88
|
+
`swin_t`, `bert_base`, `distilbert`, `roberta_base`, `albert_base`,
|
|
89
|
+
`distilgpt2`, `custom_cnn`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## What `compress()` returns
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
result.model # nn.Module — the compressed model, ready to use
|
|
97
|
+
result.compression_ratio # size_original / size_compressed, e.g. 3.8 = 3.8x smaller
|
|
98
|
+
result.accuracy_retention # (compressed_acc / original_acc) * 100
|
|
99
|
+
result.size_original_mb
|
|
100
|
+
result.size_compressed_mb
|
|
101
|
+
result.original_accuracy
|
|
102
|
+
result.compressed_accuracy
|
|
103
|
+
result.original_latency_ms
|
|
104
|
+
result.compressed_latency_ms
|
|
105
|
+
result.latency_speedup # original_lat / compressed_lat, >1.0 = faster
|
|
106
|
+
result.cqi # Compression Quality Index — see README.md
|
|
107
|
+
result.techniques_applied # list[str], only techniques that actually ran/survived
|
|
108
|
+
result.report_path # path to the saved PNG report, or None
|
|
109
|
+
result.pruning_report # dict of per-layer pruning detail, or None
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`analyze()` returns an `AnalysisResult`: `size_mb`, `num_parameters`,
|
|
113
|
+
`architecture_type` (`'cnn'` / `'transformer'` / `'hybrid'` / `'unknown'`),
|
|
114
|
+
`recommended_techniques`, `per_layer_signals` (a `LayerSignal` per eligible
|
|
115
|
+
layer: `name`, `layer_type`, `lrf_epsilon`, `prunable`, `size_kb`), and
|
|
116
|
+
`accuracy` if you passed a dataloader.
|
|
117
|
+
|
|
118
|
+
`load_from_registry()` returns a `RegistryResult`: `model`, `train_loader`,
|
|
119
|
+
`test_loader`, `num_classes`, `model_name`, `dataset_name`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## `compress()` hyperparameters
|
|
124
|
+
|
|
125
|
+
Every argument after `model` and `dataloader` is keyword-only. Grouped
|
|
126
|
+
the same way the function itself groups them.
|
|
127
|
+
|
|
128
|
+
### Device
|
|
129
|
+
|
|
130
|
+
| Arg | Default | What it does |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `device` | `None` | `'cuda'` or `'cpu'`. Auto-detected when not set. |
|
|
133
|
+
|
|
134
|
+
### Model metadata
|
|
135
|
+
|
|
136
|
+
| Arg | Default | What it does |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `model_type` | `'unknown'` | Architecture class for pruning's safety clamp: `'classifier'`, `'embedding'`, `'generative'`, or `'unknown'`. |
|
|
139
|
+
| `num_classes` | `10` | Output class count, used by every fine-tune step's accuracy metric. |
|
|
140
|
+
|
|
141
|
+
### Pre-training
|
|
142
|
+
|
|
143
|
+
Use these when the model hasn't been trained on your target dataset yet
|
|
144
|
+
(e.g. fresh ImageNet weights with an untrained head).
|
|
145
|
+
|
|
146
|
+
| Arg | Default | What it does |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `pretrain_epochs` | `0` | Epochs to fine-tune before compressing. `0` skips this entirely. |
|
|
149
|
+
| `pretrain_lr` | `1e-3` | Learning rate for that pre-training. |
|
|
150
|
+
| `pretrain_test_loader` | `None` | Validation loader for pre-training. Falls back to `dataloader`. |
|
|
151
|
+
|
|
152
|
+
### Hyperparameter search (optional, adds evaluations before the pipeline runs)
|
|
153
|
+
|
|
154
|
+
| Arg | Default | What it does |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `find_optimal_epsilon` | `False` | Auto-search for the best LRF epsilon instead of using `lrf_epsilon` as-is. |
|
|
157
|
+
| `find_optimal_pruning` | `False` | Auto-search for the best pruning ratio instead of using `pruning_ratio` as-is. |
|
|
158
|
+
| `epsilon_search_trials` | `15` | Evaluation budget for the epsilon search. |
|
|
159
|
+
| `pruning_search_trials` | `16` | Evaluation budget for the pruning search. |
|
|
160
|
+
| `pruning_search_ft_epochs` | `1` | Fine-tune epochs per trial during the pruning search (kept low for speed — the real run uses `pruning_fine_tune_epochs`). |
|
|
161
|
+
| `pruning_search_ft_lr` | `1e-4` | Fine-tune learning rate per trial during the pruning search. |
|
|
162
|
+
| `accuracy_drop_threshold` | `5.0` | Max acceptable accuracy drop in percentage points — used by both searches' final selection and the pipeline's per-technique revert gate. |
|
|
163
|
+
|
|
164
|
+
### Technique enable flags
|
|
165
|
+
|
|
166
|
+
| Arg | Default |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `use_pruning` | `False` |
|
|
169
|
+
| `use_lrf` | `True` |
|
|
170
|
+
| `use_clustering` | `True` |
|
|
171
|
+
| `use_quantization` | `True` |
|
|
172
|
+
| `use_kd_finetune` | `True` |
|
|
173
|
+
| `use_gptq` | `False` |
|
|
174
|
+
|
|
175
|
+
### Pruning hyperparameters
|
|
176
|
+
|
|
177
|
+
| Arg | Default | What it does |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `pruning_ratio` | `0.3` | Target fraction of channels removed globally. |
|
|
180
|
+
| `pruning_max_ratio` | `0.95` | Hard cap on how much any single layer/dependency-group can be pruned. |
|
|
181
|
+
| `pruning_model_type` | `'classifier'` | Same role as `model_type`, specific to pruning's clamp. |
|
|
182
|
+
| `pruning_fine_tune_epochs` | `3` | KD recovery epochs after pruning. |
|
|
183
|
+
| `pruning_fine_tune_lr` | `1e-4` | Learning rate for that recovery fine-tune. |
|
|
184
|
+
| `pruning_cal_batches` | `50` | Calibration batches for activation-statistics importance scoring. |
|
|
185
|
+
| `pruning_iterative_steps` | `1` | Prune in one shot (`1`) or multiple incremental rounds (more stable, slower). |
|
|
186
|
+
| `pruning_isomorphic` | `False` | Force identical pruning structure across coupled dependency groups. |
|
|
187
|
+
| `pruning_round_to` | `None` | Round pruned channel counts to a multiple of this (e.g. `8`/`16` for Tensor Core alignment). |
|
|
188
|
+
|
|
189
|
+
### Low-Rank Factorization (LRF) hyperparameters
|
|
190
|
+
|
|
191
|
+
| Arg | Default | What it does |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| `lrf_epsilon` | `0.5` | Rank ratio kept. Lower = more compression, more accuracy risk. |
|
|
194
|
+
| `lrf_adaptive` | `False` | Compute epsilon per layer from SVD energy decay instead of one global value. |
|
|
195
|
+
| `lrf_energy_threshold` | `0.99` | Fraction of SVD energy retained per layer, when adaptive. |
|
|
196
|
+
| `lrf_min_layer_size` | `64` | Skip layers with a dimension below this. |
|
|
197
|
+
| `lrf_min_rank` | `2` | Skip a layer if its computed rank would fall below this. |
|
|
198
|
+
| `lrf_skip_large_kernels` | `False` | Skip Conv2d layers with kernel > 1x1 — prevents latency regression on 3x3-heavy CNNs (ResNet/VGG-style). |
|
|
199
|
+
|
|
200
|
+
### Weight clustering hyperparameters
|
|
201
|
+
|
|
202
|
+
| Arg | Default | What it does |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| `num_clusters` | `16` | k for k-means weight clustering. |
|
|
205
|
+
| `cluster_fine_tune_epochs` | `5` | Recovery fine-tune epochs after clustering. |
|
|
206
|
+
| `cluster_fine_tune_lr` | `1e-5` | Learning rate for that recovery fine-tune. |
|
|
207
|
+
|
|
208
|
+
### Knowledge distillation fine-tuning hyperparameters
|
|
209
|
+
|
|
210
|
+
The final recovery step, run after quantization/GPTQ so it can recover
|
|
211
|
+
accuracy lost from every prior step at once.
|
|
212
|
+
|
|
213
|
+
| Arg | Default | What it does |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `kd_epochs` | `3` | Fine-tune epochs. |
|
|
216
|
+
| `kd_lr` | `1e-5` | Learning rate. |
|
|
217
|
+
| `kd_temperature` | `4.0` | Softmax temperature for the teacher's soft labels. |
|
|
218
|
+
| `kd_alpha` | `0.7` | Weight on hard-label loss; `1 - kd_alpha` goes to the distillation loss. |
|
|
219
|
+
|
|
220
|
+
### Quantization hyperparameters
|
|
221
|
+
|
|
222
|
+
| Arg | Default | What it does |
|
|
223
|
+
|---|---|---|
|
|
224
|
+
| `quant_mode` | `'fp16'` | `'fp16'`, `'dynamic'` (INT8, CPU-friendly), or `'static'` (auto-switched to `'dynamic'`). |
|
|
225
|
+
| `quant_cal_batches` | `100` | Calibration batches — only used by `'static'`. |
|
|
226
|
+
|
|
227
|
+
### GPTQ hyperparameters
|
|
228
|
+
|
|
229
|
+
| Arg | Default | What it does |
|
|
230
|
+
|---|---|---|
|
|
231
|
+
| `gptq_bits` | `4` | `4` for INT4 (8x compression) or `8` for INT8 (4x). |
|
|
232
|
+
| `gptq_cal_batches` | `16` | Batches used to estimate the Hessian from activations. |
|
|
233
|
+
| `gptq_block_size` | `128` | Columns processed per Hessian update block. |
|
|
234
|
+
|
|
235
|
+
### CQI scoring weights
|
|
236
|
+
|
|
237
|
+
Each is an exponent applied to that factor's ratio in the Compression
|
|
238
|
+
Quality Index — raise one to make the search/report weight that factor
|
|
239
|
+
more heavily.
|
|
240
|
+
|
|
241
|
+
| Arg | Default |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `cqi_w_accuracy` | `1.0` |
|
|
244
|
+
| `cqi_w_size` | `1.0` |
|
|
245
|
+
| `cqi_w_latency` | `1.0` |
|
|
246
|
+
| `cqi_w_kl` | `1.0` (only meaningful when pruning ran) |
|
|
247
|
+
|
|
248
|
+
### Report
|
|
249
|
+
|
|
250
|
+
| Arg | Default | What it does |
|
|
251
|
+
|---|---|---|
|
|
252
|
+
| `save_report` | `True` | Generate the PNG compression report. |
|
|
253
|
+
| `report_path` | `'compression_report.png'` | Where to save it. |
|