optipfair 0.2.2__tar.gz → 0.2.4__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.
- {optipfair-0.2.2/optipfair.egg-info → optipfair-0.2.4}/PKG-INFO +21 -19
- {optipfair-0.2.2 → optipfair-0.2.4}/README.md +20 -18
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/api.md +25 -5
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/examples.md +9 -1
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/index.md +3 -1
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/usage.md +169 -9
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/__init__.py +43 -17
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/cli/commands.py +1 -1
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/depth.py +10 -6
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/mlp_glu.py +105 -74
- optipfair-0.2.4/optipfair/pruning/utils.py +341 -0
- {optipfair-0.2.2 → optipfair-0.2.4/optipfair.egg-info}/PKG-INFO +21 -19
- {optipfair-0.2.2 → optipfair-0.2.4}/setup.py +1 -1
- optipfair-0.2.2/optipfair/pruning/utils.py +0 -179
- {optipfair-0.2.2 → optipfair-0.2.4}/CONTRIBUTING.md +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/LICENSE +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/MANIFEST.in +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/bias_visualization.md +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/contributing.md +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/installation.md +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/docs/roadmap.md +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/__init__.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/activations.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/bias_visualization_example.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/defaults.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/metrics.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/utils.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/bias/visualization.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/cli/__init__.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/evaluation/__init__.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/evaluation/benchmarks.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/__init__.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/future_extensions/__init__.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/future_extensions/attention.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair/pruning/future_extensions/block.py +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair.egg-info/SOURCES.txt +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair.egg-info/dependency_links.txt +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair.egg-info/entry_points.txt +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair.egg-info/requires.txt +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/optipfair.egg-info/top_level.txt +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/pyproject.toml +0 -0
- {optipfair-0.2.2 → optipfair-0.2.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: optipfair
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A library for structured pruning & Bias visualization of large language models
|
|
5
5
|
Home-page: https://github.com/peremartra/optipfair
|
|
6
6
|
Author: Pere Martra
|
|
@@ -80,6 +80,8 @@ Dynamic: summary
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
> **New to optipfair?** Use our [LLM Reference Manual](optipfair_llm_reference_manual.txt) - paste it into ChatGPT, Claude or your Favourite LLM for guided assistance with any optipfair task.
|
|
83
|
+
|
|
84
|
+
> **Note on Terminology:** The default neuron selection method is **PPM (Peak-to-Peak Magnitude)**, which calculates neuron importance based on the full dynamic range of weights (max + |min|). This method is formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*. For backward compatibility, the parameter value `"MAW"` is still accepted and maps to PPM.
|
|
83
85
|
### 🚀 Interactive Demos: Try optipfair NOW
|
|
84
86
|
|
|
85
87
|
Experience optipfair's capabilities directly in your browser.
|
|
@@ -149,17 +151,17 @@ See how to use optipfair's core features in just a few lines of code.
|
|
|
149
151
|
|
|
150
152
|
### Pruning with the Python API
|
|
151
153
|
|
|
152
|
-
Prune 20% of the MLP neurons from a model using the
|
|
154
|
+
Prune 20% of the MLP neurons from a model using the Peak-to-Peak Magnitude (PPM) method.
|
|
153
155
|
|
|
154
156
|
```python
|
|
155
157
|
from transformers import AutoModelForCausalLM
|
|
156
|
-
|
|
158
|
+
import optipfair as opf
|
|
157
159
|
|
|
158
160
|
# Load a pre-trained model
|
|
159
161
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
160
162
|
|
|
161
163
|
# Prune 20% of neurons from MLP layers
|
|
162
|
-
pruned_model, stats = prune_model(
|
|
164
|
+
pruned_model, stats = opf.prune_model(
|
|
163
165
|
model=model,
|
|
164
166
|
pruning_type="MLP_GLU",
|
|
165
167
|
neuron_selection_method="MAW",
|
|
@@ -185,7 +187,7 @@ The pruning process yields tangible results in model size and performance. Here'
|
|
|
185
187
|
| **Inference Speed** | *Benchmark in progress* | *Benchmark in progress* | *Coming soon* |
|
|
186
188
|
| **MMLU Score** | *Benchmark in progress* | *Benchmark in progress* | *Minimal change expected* |
|
|
187
189
|
|
|
188
|
-
*Results based on the [
|
|
190
|
+
*Results based on the [PPM pruning method](#neuron-selection-methods) (parameter `"MAW"`). Full benchmark results will be published shortly.*
|
|
189
191
|
|
|
190
192
|
### Data-Driven Width Pruning (NEW in v0.2.0)
|
|
191
193
|
|
|
@@ -194,7 +196,7 @@ Enhance pruning decisions with activation statistics from calibration data. This
|
|
|
194
196
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
195
197
|
from torch.utils.data import DataLoader, TensorDataset
|
|
196
198
|
import torch
|
|
197
|
-
|
|
199
|
+
import optipfair as opf
|
|
198
200
|
|
|
199
201
|
# Load model and tokenizer
|
|
200
202
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
@@ -213,9 +215,9 @@ dataset = TensorDataset(inputs['input_ids'], inputs['attention_mask'])
|
|
|
213
215
|
dataloader = DataLoader(dataset, batch_size=8)
|
|
214
216
|
|
|
215
217
|
# Prune with data-driven importance calculation
|
|
216
|
-
pruned_model, stats = prune_model(
|
|
218
|
+
pruned_model, stats = opf.prune_model(
|
|
217
219
|
model=model,
|
|
218
|
-
neuron_selection_method="MAW", # Only MAW supports data-driven pruning
|
|
220
|
+
neuron_selection_method="MAW", # Only PPM (parameter "MAW") supports data-driven pruning
|
|
219
221
|
pruning_percentage=20,
|
|
220
222
|
dataloader=dataloader, # ← Enables hybrid pruning
|
|
221
223
|
show_progress=True,
|
|
@@ -232,7 +234,7 @@ pruned_model.save_pretrained("./pruned-datadriven-model")
|
|
|
232
234
|
- 🔬 **Research-Backed**: Based on CFSP methodology (arXiv:2409.13199v2)
|
|
233
235
|
- ⚡ **Easy Integration**: Just add a dataloader - no other changes needed
|
|
234
236
|
|
|
235
|
-
**Note:** Data-driven pruning is currently only available with `neuron_selection_method="MAW"
|
|
237
|
+
**Note:** Data-driven pruning is currently only available with `neuron_selection_method="MAW"` (PPM method). Using a dataloader with "VOW" or "PON" will raise a `ValueError`.
|
|
236
238
|
|
|
237
239
|
### Selective Layer Width Pruning (NEW in v0.2.0)
|
|
238
240
|
|
|
@@ -240,13 +242,13 @@ Prune neurons only in specific layers while leaving others unchanged. Perfect fo
|
|
|
240
242
|
|
|
241
243
|
```python
|
|
242
244
|
from transformers import AutoModelForCausalLM
|
|
243
|
-
|
|
245
|
+
import optipfair as opf
|
|
244
246
|
|
|
245
247
|
# Load a pre-trained model
|
|
246
248
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
247
249
|
|
|
248
250
|
# Prune neurons only in specific layers (e.g., middle layers)
|
|
249
|
-
pruned_model, stats = prune_model(
|
|
251
|
+
pruned_model, stats = opf.prune_model(
|
|
250
252
|
model=model,
|
|
251
253
|
pruning_type="MLP_GLU",
|
|
252
254
|
neuron_selection_method="MAW",
|
|
@@ -282,13 +284,13 @@ The `expansion_divisor` parameter ensures that intermediate layer sizes are divi
|
|
|
282
284
|
|
|
283
285
|
```python
|
|
284
286
|
from transformers import AutoModelForCausalLM
|
|
285
|
-
|
|
287
|
+
import optipfair as opf
|
|
286
288
|
|
|
287
289
|
# Load model
|
|
288
290
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
289
291
|
|
|
290
292
|
# Prune with hardware optimization
|
|
291
|
-
pruned_model, stats = prune_model(
|
|
293
|
+
pruned_model, stats = opf.prune_model(
|
|
292
294
|
model=model,
|
|
293
295
|
neuron_selection_method="MAW",
|
|
294
296
|
pruning_percentage=20,
|
|
@@ -317,13 +319,13 @@ Prune neurons only in specific layers while leaving others unchanged. Perfect fo
|
|
|
317
319
|
|
|
318
320
|
```python
|
|
319
321
|
from transformers import AutoModelForCausalLM
|
|
320
|
-
|
|
322
|
+
import optipfair as opf
|
|
321
323
|
|
|
322
324
|
# Load a pre-trained model
|
|
323
325
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
324
326
|
|
|
325
327
|
# Prune neurons only in specific layers (e.g., middle layers)
|
|
326
|
-
pruned_model, stats = prune_model(
|
|
328
|
+
pruned_model, stats = opf.prune_model(
|
|
327
329
|
model=model,
|
|
328
330
|
pruning_type="MLP_GLU",
|
|
329
331
|
neuron_selection_method="MAW",
|
|
@@ -335,7 +337,7 @@ pruned_model, stats = prune_model(
|
|
|
335
337
|
|
|
336
338
|
# Print pruning statistics
|
|
337
339
|
print(f"Pruned {stats['pruned_layers']} of {stats['total_layers']} layers")
|
|
338
|
-
print(f"Total reduction: {stats['reduction']:,} parameters ({stats['percentage_reduction']:.2f}%)
|
|
340
|
+
print(f"Total reduction: {stats['reduction']:,} parameters ({stats['percentage_reduction']:.2f}%)")
|
|
339
341
|
|
|
340
342
|
# Save the pruned model
|
|
341
343
|
pruned_model.save_pretrained("./selective-pruned-llama")
|
|
@@ -359,13 +361,13 @@ Remove entire layers from a model for significant efficiency gains. Here, we rem
|
|
|
359
361
|
|
|
360
362
|
```python
|
|
361
363
|
from transformers import AutoModelForCausalLM
|
|
362
|
-
|
|
364
|
+
import optipfair as opf
|
|
363
365
|
|
|
364
366
|
# Load a pre-trained model
|
|
365
367
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
366
368
|
|
|
367
369
|
# Remove the last 4 transformer layers
|
|
368
|
-
pruned_model, stats = prune_model(
|
|
370
|
+
pruned_model, stats = opf.prune_model(
|
|
369
371
|
model=model,
|
|
370
372
|
pruning_type="DEPTH",
|
|
371
373
|
num_layers_to_remove=4,
|
|
@@ -475,7 +477,7 @@ optipfair is designed to work with transformer-based language models that use GL
|
|
|
475
477
|
optipfair offers two powerful structured pruning strategies:
|
|
476
478
|
|
|
477
479
|
1. **MLP Pruning (Width Pruning)**: Reduces the number of neurons within the MLP layers of GLU-based models. This is a fine-grained approach to improve efficiency. You can control it via `pruning_percentage` or a target `expansion_rate`. It uses several neuron importance metrics:
|
|
478
|
-
* **
|
|
480
|
+
* **PPM (Peak-to-Peak Magnitude)**: Default and most effective method (parameter `"MAW"` for backward compatibility).
|
|
479
481
|
* **VOW (Variance of Weights)**
|
|
480
482
|
* **PON (Product of Norms)**
|
|
481
483
|
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
> **New to optipfair?** Use our [LLM Reference Manual](optipfair_llm_reference_manual.txt) - paste it into ChatGPT, Claude or your Favourite LLM for guided assistance with any optipfair task.
|
|
33
|
+
|
|
34
|
+
> **Note on Terminology:** The default neuron selection method is **PPM (Peak-to-Peak Magnitude)**, which calculates neuron importance based on the full dynamic range of weights (max + |min|). This method is formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*. For backward compatibility, the parameter value `"MAW"` is still accepted and maps to PPM.
|
|
33
35
|
### 🚀 Interactive Demos: Try optipfair NOW
|
|
34
36
|
|
|
35
37
|
Experience optipfair's capabilities directly in your browser.
|
|
@@ -99,17 +101,17 @@ See how to use optipfair's core features in just a few lines of code.
|
|
|
99
101
|
|
|
100
102
|
### Pruning with the Python API
|
|
101
103
|
|
|
102
|
-
Prune 20% of the MLP neurons from a model using the
|
|
104
|
+
Prune 20% of the MLP neurons from a model using the Peak-to-Peak Magnitude (PPM) method.
|
|
103
105
|
|
|
104
106
|
```python
|
|
105
107
|
from transformers import AutoModelForCausalLM
|
|
106
|
-
|
|
108
|
+
import optipfair as opf
|
|
107
109
|
|
|
108
110
|
# Load a pre-trained model
|
|
109
111
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
110
112
|
|
|
111
113
|
# Prune 20% of neurons from MLP layers
|
|
112
|
-
pruned_model, stats = prune_model(
|
|
114
|
+
pruned_model, stats = opf.prune_model(
|
|
113
115
|
model=model,
|
|
114
116
|
pruning_type="MLP_GLU",
|
|
115
117
|
neuron_selection_method="MAW",
|
|
@@ -135,7 +137,7 @@ The pruning process yields tangible results in model size and performance. Here'
|
|
|
135
137
|
| **Inference Speed** | *Benchmark in progress* | *Benchmark in progress* | *Coming soon* |
|
|
136
138
|
| **MMLU Score** | *Benchmark in progress* | *Benchmark in progress* | *Minimal change expected* |
|
|
137
139
|
|
|
138
|
-
*Results based on the [
|
|
140
|
+
*Results based on the [PPM pruning method](#neuron-selection-methods) (parameter `"MAW"`). Full benchmark results will be published shortly.*
|
|
139
141
|
|
|
140
142
|
### Data-Driven Width Pruning (NEW in v0.2.0)
|
|
141
143
|
|
|
@@ -144,7 +146,7 @@ Enhance pruning decisions with activation statistics from calibration data. This
|
|
|
144
146
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
145
147
|
from torch.utils.data import DataLoader, TensorDataset
|
|
146
148
|
import torch
|
|
147
|
-
|
|
149
|
+
import optipfair as opf
|
|
148
150
|
|
|
149
151
|
# Load model and tokenizer
|
|
150
152
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
@@ -163,9 +165,9 @@ dataset = TensorDataset(inputs['input_ids'], inputs['attention_mask'])
|
|
|
163
165
|
dataloader = DataLoader(dataset, batch_size=8)
|
|
164
166
|
|
|
165
167
|
# Prune with data-driven importance calculation
|
|
166
|
-
pruned_model, stats = prune_model(
|
|
168
|
+
pruned_model, stats = opf.prune_model(
|
|
167
169
|
model=model,
|
|
168
|
-
neuron_selection_method="MAW", # Only MAW supports data-driven pruning
|
|
170
|
+
neuron_selection_method="MAW", # Only PPM (parameter "MAW") supports data-driven pruning
|
|
169
171
|
pruning_percentage=20,
|
|
170
172
|
dataloader=dataloader, # ← Enables hybrid pruning
|
|
171
173
|
show_progress=True,
|
|
@@ -182,7 +184,7 @@ pruned_model.save_pretrained("./pruned-datadriven-model")
|
|
|
182
184
|
- 🔬 **Research-Backed**: Based on CFSP methodology (arXiv:2409.13199v2)
|
|
183
185
|
- ⚡ **Easy Integration**: Just add a dataloader - no other changes needed
|
|
184
186
|
|
|
185
|
-
**Note:** Data-driven pruning is currently only available with `neuron_selection_method="MAW"
|
|
187
|
+
**Note:** Data-driven pruning is currently only available with `neuron_selection_method="MAW"` (PPM method). Using a dataloader with "VOW" or "PON" will raise a `ValueError`.
|
|
186
188
|
|
|
187
189
|
### Selective Layer Width Pruning (NEW in v0.2.0)
|
|
188
190
|
|
|
@@ -190,13 +192,13 @@ Prune neurons only in specific layers while leaving others unchanged. Perfect fo
|
|
|
190
192
|
|
|
191
193
|
```python
|
|
192
194
|
from transformers import AutoModelForCausalLM
|
|
193
|
-
|
|
195
|
+
import optipfair as opf
|
|
194
196
|
|
|
195
197
|
# Load a pre-trained model
|
|
196
198
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
197
199
|
|
|
198
200
|
# Prune neurons only in specific layers (e.g., middle layers)
|
|
199
|
-
pruned_model, stats = prune_model(
|
|
201
|
+
pruned_model, stats = opf.prune_model(
|
|
200
202
|
model=model,
|
|
201
203
|
pruning_type="MLP_GLU",
|
|
202
204
|
neuron_selection_method="MAW",
|
|
@@ -232,13 +234,13 @@ The `expansion_divisor` parameter ensures that intermediate layer sizes are divi
|
|
|
232
234
|
|
|
233
235
|
```python
|
|
234
236
|
from transformers import AutoModelForCausalLM
|
|
235
|
-
|
|
237
|
+
import optipfair as opf
|
|
236
238
|
|
|
237
239
|
# Load model
|
|
238
240
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
239
241
|
|
|
240
242
|
# Prune with hardware optimization
|
|
241
|
-
pruned_model, stats = prune_model(
|
|
243
|
+
pruned_model, stats = opf.prune_model(
|
|
242
244
|
model=model,
|
|
243
245
|
neuron_selection_method="MAW",
|
|
244
246
|
pruning_percentage=20,
|
|
@@ -267,13 +269,13 @@ Prune neurons only in specific layers while leaving others unchanged. Perfect fo
|
|
|
267
269
|
|
|
268
270
|
```python
|
|
269
271
|
from transformers import AutoModelForCausalLM
|
|
270
|
-
|
|
272
|
+
import optipfair as opf
|
|
271
273
|
|
|
272
274
|
# Load a pre-trained model
|
|
273
275
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
274
276
|
|
|
275
277
|
# Prune neurons only in specific layers (e.g., middle layers)
|
|
276
|
-
pruned_model, stats = prune_model(
|
|
278
|
+
pruned_model, stats = opf.prune_model(
|
|
277
279
|
model=model,
|
|
278
280
|
pruning_type="MLP_GLU",
|
|
279
281
|
neuron_selection_method="MAW",
|
|
@@ -285,7 +287,7 @@ pruned_model, stats = prune_model(
|
|
|
285
287
|
|
|
286
288
|
# Print pruning statistics
|
|
287
289
|
print(f"Pruned {stats['pruned_layers']} of {stats['total_layers']} layers")
|
|
288
|
-
print(f"Total reduction: {stats['reduction']:,} parameters ({stats['percentage_reduction']:.2f}%)
|
|
290
|
+
print(f"Total reduction: {stats['reduction']:,} parameters ({stats['percentage_reduction']:.2f}%)")
|
|
289
291
|
|
|
290
292
|
# Save the pruned model
|
|
291
293
|
pruned_model.save_pretrained("./selective-pruned-llama")
|
|
@@ -309,13 +311,13 @@ Remove entire layers from a model for significant efficiency gains. Here, we rem
|
|
|
309
311
|
|
|
310
312
|
```python
|
|
311
313
|
from transformers import AutoModelForCausalLM
|
|
312
|
-
|
|
314
|
+
import optipfair as opf
|
|
313
315
|
|
|
314
316
|
# Load a pre-trained model
|
|
315
317
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
316
318
|
|
|
317
319
|
# Remove the last 4 transformer layers
|
|
318
|
-
pruned_model, stats = prune_model(
|
|
320
|
+
pruned_model, stats = opf.prune_model(
|
|
319
321
|
model=model,
|
|
320
322
|
pruning_type="DEPTH",
|
|
321
323
|
num_layers_to_remove=4,
|
|
@@ -425,7 +427,7 @@ optipfair is designed to work with transformer-based language models that use GL
|
|
|
425
427
|
optipfair offers two powerful structured pruning strategies:
|
|
426
428
|
|
|
427
429
|
1. **MLP Pruning (Width Pruning)**: Reduces the number of neurons within the MLP layers of GLU-based models. This is a fine-grained approach to improve efficiency. You can control it via `pruning_percentage` or a target `expansion_rate`. It uses several neuron importance metrics:
|
|
428
|
-
* **
|
|
430
|
+
* **PPM (Peak-to-Peak Magnitude)**: Default and most effective method (parameter `"MAW"` for backward compatibility).
|
|
429
431
|
* **VOW (Variance of Weights)**
|
|
430
432
|
* **PON (Product of Norms)**
|
|
431
433
|
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# API Reference
|
|
2
2
|
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
**Note on Terminology:** The default neuron selection method is **PPM (Peak-to-Peak Magnitude)**, which calculates neuron importance based on the full dynamic range of weights (max + |min|). This method is formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*
|
|
6
|
+
|
|
7
|
+
For backward compatibility, the parameter value `"MAW"` is still accepted and maps to PPM.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
3
11
|
## Core Functions
|
|
4
12
|
|
|
5
13
|
### `prune_model`
|
|
@@ -24,13 +32,13 @@ def prune_model(
|
|
|
24
32
|
Prune a pre-trained language model using the specified pruning method.
|
|
25
33
|
|
|
26
34
|
Supports both width pruning (neuron-level) and depth pruning (layer-level).
|
|
27
|
-
For width pruning with
|
|
35
|
+
For width pruning with PPM method (parameter "MAW"), can use static (weight-only) or hybrid
|
|
28
36
|
(weight + activation) importance calculation.
|
|
29
37
|
|
|
30
38
|
Args:
|
|
31
39
|
model: Pre-trained model to prune
|
|
32
40
|
pruning_type: Type of pruning to apply ("MLP_GLU" or "DEPTH")
|
|
33
|
-
neuron_selection_method: Method to calculate neuron importance ("MAW", "VOW", or "
|
|
41
|
+
neuron_selection_method: Method to calculate neuron importance ("MAW"/PPM, "VOW", "PON", or "L2") - for MLP_GLU only
|
|
34
42
|
pruning_percentage: Percentage of neurons to prune (0-100) - for MLP_GLU only
|
|
35
43
|
expansion_rate: Target expansion rate in percentage (mutually exclusive with pruning_percentage) - for MLP_GLU only
|
|
36
44
|
dataloader: Optional PyTorch DataLoader for data-driven pruning (MLP_GLU with MAW only).
|
|
@@ -40,8 +48,8 @@ def prune_model(
|
|
|
40
48
|
or as tuples of (input_ids, attention_mask). Typically 100-1000 samples
|
|
41
49
|
from your target domain yield best results.
|
|
42
50
|
|
|
43
|
-
**Compatibility:** Only works with neuron_selection_method='MAW'.
|
|
44
|
-
Will raise ValueError if used with 'VOW' or '
|
|
51
|
+
**Compatibility:** Only works with neuron_selection_method='MAW' (PPM method).
|
|
52
|
+
Will raise ValueError if used with 'VOW', 'PON', or 'L2'.
|
|
45
53
|
|
|
46
54
|
**Example:**
|
|
47
55
|
>>> from torch.utils.data import DataLoader, TensorDataset
|
|
@@ -62,7 +70,7 @@ def prune_model(
|
|
|
62
70
|
|
|
63
71
|
Raises:
|
|
64
72
|
ValueError: If parameters are invalid or incompatible
|
|
65
|
-
ValueError: If dataloader is provided with non-MAW
|
|
73
|
+
ValueError: If dataloader is provided with non-PPM method (use "MAW" parameter)
|
|
66
74
|
|
|
67
75
|
Examples:
|
|
68
76
|
>>> # Static width pruning (traditional)
|
|
@@ -328,6 +336,18 @@ def compute_neuron_pair_importance_pon(gate_weight: torch.Tensor, up_weight: tor
|
|
|
328
336
|
"""
|
|
329
337
|
Compute neuron pair importance scores using Product of Norms method.
|
|
330
338
|
|
|
339
|
+
Args:
|
|
340
|
+
gate_weight: Weight matrix from the gate_proj layer
|
|
341
|
+
up_weight: Weight matrix from the up_proj layer
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
importance_scores: Importance scores for each neuron pair
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
def compute_neuron_pair_importance_l2(gate_weight: torch.Tensor, up_weight: torch.Tensor) -> torch.Tensor:
|
|
348
|
+
"""
|
|
349
|
+
Compute neuron pair importance scores using L2 norm method.
|
|
350
|
+
|
|
331
351
|
Args:
|
|
332
352
|
gate_weight: Weight matrix from the gate_proj layer
|
|
333
353
|
up_weight: Weight matrix from the up_proj layer
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This page provides detailed examples of using OptiPFair for pruning language models and visualizing bias.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Note on Terminology:** The default neuron selection method is **PPM (Peak-to-Peak Magnitude)**, which calculates neuron importance based on the full dynamic range of weights (max + |min|). This method is formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*
|
|
8
|
+
|
|
9
|
+
For backward compatibility, the parameter value `"MAW"` is still accepted and maps to PPM.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
5
13
|
## Basic Pruning Example
|
|
6
14
|
|
|
7
15
|
This example demonstrates how to prune a LLaMA model using the default settings:
|
|
@@ -29,7 +37,7 @@ outputs = model.generate(inputs.input_ids, max_length=50)
|
|
|
29
37
|
original_output = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
|
30
38
|
print(f"Original model output: {original_output}")
|
|
31
39
|
|
|
32
|
-
# Apply pruning with default settings (10% pruning,
|
|
40
|
+
# Apply pruning with default settings (10% pruning, PPM method)
|
|
33
41
|
pruned_model = prune_model(model)
|
|
34
42
|
|
|
35
43
|
# Get pruned parameter count
|
|
@@ -26,12 +26,14 @@ Understanding bias in language models is crucial for:
|
|
|
26
26
|
- **Layer Importance Analysis**: Analyze transformer layers using cosine similarity to inform pruning decisions
|
|
27
27
|
- **Bias Visualization Tools**: Comprehensive analysis of how models process demographic attributes
|
|
28
28
|
- **Quantitative Bias Metrics**: Numeric measurements for consistent evaluation
|
|
29
|
-
- **Multiple Neuron Selection Methods**:
|
|
29
|
+
- **Multiple Neuron Selection Methods**: PPM (Peak-to-Peak Magnitude), VOW, and PON for different pruning strategies
|
|
30
30
|
- **Flexible Pruning Targets**: Support for both pruning percentage and target expansion rate
|
|
31
31
|
- **Layer Selection Methods**: Choose specific layers or use automatic selection strategies
|
|
32
32
|
- **Simple API and CLI**: Easy to use interfaces for Python and command line
|
|
33
33
|
- **Progress Tracking**: Visual progress bars and detailed statistics
|
|
34
34
|
|
|
35
|
+
**Note:** The default neuron selection method is PPM (Peak-to-Peak Magnitude), formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*. For backward compatibility, the parameter value `"MAW"` is still accepted.
|
|
36
|
+
|
|
35
37
|
## Getting Started
|
|
36
38
|
|
|
37
39
|
- [Installation](installation.md): How to install OptiPFair
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Usage Guide
|
|
2
2
|
This guide provides detailed instructions on how to use the core functionalities of OptiPFair, from pruning models to analyzing bias.
|
|
3
3
|
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
**Note on Terminology:** The default neuron selection method is **PPM (Peak-to-Peak Magnitude)**, which calculates neuron importance based on the full dynamic range of weights (max + |min|). This method is formally described in: *Martra, P. (2025). Fragile Knowledge, Robust Instruction-Following: The Width Pruning Dichotomy in Llama-3.2. ArXiv. https://arxiv.org/abs/2512.22671*
|
|
7
|
+
|
|
8
|
+
For backward compatibility, the parameter value `"MAW"` is still accepted and maps to PPM.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
4
12
|
## Python API
|
|
5
13
|
|
|
6
14
|
OptiPFair provides a simple Python API for pruning models.
|
|
@@ -14,7 +22,7 @@ from optipfair import prune_model
|
|
|
14
22
|
# Load a pre-trained model
|
|
15
23
|
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")
|
|
16
24
|
|
|
17
|
-
# Prune the model with default settings (10% pruning,
|
|
25
|
+
# Prune the model with default settings (10% pruning, PPM method)
|
|
18
26
|
pruned_model = prune_model(model=model)
|
|
19
27
|
|
|
20
28
|
# Save the pruned model
|
|
@@ -48,7 +56,7 @@ OptiPFair provides a command-line interface for pruning models:
|
|
|
48
56
|
### Basic Usage
|
|
49
57
|
|
|
50
58
|
```bash
|
|
51
|
-
# Prune a model with default settings (10% pruning,
|
|
59
|
+
# Prune a model with default settings (10% pruning, PPM method)
|
|
52
60
|
optipfair prune --model-path meta-llama/Llama-3.2-1B --output-path ./pruned-model
|
|
53
61
|
```
|
|
54
62
|
|
|
@@ -75,19 +83,58 @@ optipfair analyze --model-path meta-llama/Llama-3.2-1B
|
|
|
75
83
|
|
|
76
84
|
## Neuron Selection Methods
|
|
77
85
|
|
|
78
|
-
OptiPFair supports
|
|
86
|
+
OptiPFair supports four methods for calculating neuron importance:
|
|
79
87
|
|
|
80
|
-
###
|
|
88
|
+
### PPM (Peak-to-Peak Magnitude)
|
|
81
89
|
|
|
82
|
-
The
|
|
90
|
+
The PPM method identifies neurons based on the peak-to-peak magnitude of weights (max + |min|), capturing the full dynamic range of each neuron's weight values. This is typically the most effective method for GLU architectures. Use parameter value `"MAW"` for backward compatibility.
|
|
83
91
|
|
|
84
92
|
```python
|
|
85
93
|
pruned_model = prune_model(
|
|
86
94
|
model=model,
|
|
87
|
-
neuron_selection_method="MAW",
|
|
95
|
+
neuron_selection_method="MAW", # PPM method ("MAW" for compatibility)
|
|
96
|
+
pruning_percentage=20
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### VOW (Variance of Weights)
|
|
101
|
+
|
|
102
|
+
The VOW method identifies neurons based on the variance of their weight values.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
pruned_model = prune_model(
|
|
106
|
+
model=model,
|
|
107
|
+
neuron_selection_method="VOW",
|
|
108
|
+
pruning_percentage=20
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### PON (Product of Norms)
|
|
113
|
+
|
|
114
|
+
The PON method uses the product of L1 norms to identify important neurons.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
pruned_model = prune_model(
|
|
118
|
+
model=model,
|
|
119
|
+
neuron_selection_method="PON",
|
|
120
|
+
pruning_percentage=20
|
|
121
|
+
)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### L2 (L2 Norm)
|
|
125
|
+
|
|
126
|
+
The L2 method calculates neuron importance using L2 norms of weight values.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
pruned_model = prune_model(
|
|
130
|
+
model=model,
|
|
131
|
+
neuron_selection_method="L2",
|
|
88
132
|
pruning_percentage=20
|
|
89
133
|
)
|
|
90
134
|
```
|
|
135
|
+
|
|
136
|
+
**Note:** Data-driven pruning (hybrid mode) is only available with the PPM method (`"MAW"`). VOW, PON, and L2 support static (weight-only) pruning only.
|
|
137
|
+
|
|
91
138
|
## Data-Driven Pruning (v0.2.0+)
|
|
92
139
|
|
|
93
140
|
### Overview
|
|
@@ -260,9 +307,9 @@ pruned_datadriven = prune_model(
|
|
|
260
307
|
### Troubleshooting
|
|
261
308
|
|
|
262
309
|
#### Error: "Data-driven pruning with dataloader is only supported for 'MAW' method"
|
|
263
|
-
**Solution:** Change `neuron_selection_method` to `"MAW"
|
|
310
|
+
**Solution:** Change `neuron_selection_method` to `"MAW"` (PPM method):
|
|
264
311
|
```python
|
|
265
|
-
pruned = prune_model(model, neuron_selection_method="MAW", dataloader=dl)
|
|
312
|
+
pruned = prune_model(model, neuron_selection_method="MAW", dataloader=dl) # PPM method
|
|
266
313
|
```
|
|
267
314
|
|
|
268
315
|
#### Out of Memory during calibration
|
|
@@ -354,6 +401,35 @@ This approach is often more intuitive when comparing across different model scal
|
|
|
354
401
|
|
|
355
402
|
## Depth Pruning
|
|
356
403
|
|
|
404
|
+
Depth pruning removes entire transformer layers. When calling `prune_model(..., pruning_type="DEPTH", return_stats=True)`, the returned `stats` dictionary includes depth-specific fields:
|
|
405
|
+
|
|
406
|
+
```python
|
|
407
|
+
pruned_model, stats = prune_model(
|
|
408
|
+
model=model,
|
|
409
|
+
pruning_type="DEPTH",
|
|
410
|
+
num_layers_to_remove=3, # or depth_pruning_percentage / layer_indices
|
|
411
|
+
layer_selection_method="last", # "last" (default), "first", or "custom"
|
|
412
|
+
return_stats=True,
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
print(stats)
|
|
416
|
+
# {
|
|
417
|
+
# 'original_parameters': int, # Parameter count before pruning
|
|
418
|
+
# 'pruned_parameters': int, # Parameter count after pruning
|
|
419
|
+
# 'reduction': int, # Absolute reduction in parameters
|
|
420
|
+
# 'percentage_reduction': float, # Percentage reduction of parameters
|
|
421
|
+
# 'original_layer_count': int, # Layers before pruning
|
|
422
|
+
# 'final_layer_count': int, # Layers after pruning
|
|
423
|
+
# 'layers_removed': int, # Number of removed layers
|
|
424
|
+
# 'layer_reduction_percentage': float # Percentage of layers removed
|
|
425
|
+
# }
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
- Depth pruning stats do not include `expansion_rate` (only relevant for MLP/GLU width pruning).
|
|
429
|
+
- Internally, stats are captured before modifying the model to ensure correctness and avoid deepcopy issues.
|
|
430
|
+
|
|
431
|
+
## Depth Pruning
|
|
432
|
+
|
|
357
433
|
OptiPFair also supports depth pruning, which removes entire transformer layers from models. This is more aggressive than neuron-level pruning but can lead to significant efficiency gains.
|
|
358
434
|
|
|
359
435
|
### Python API
|
|
@@ -577,4 +653,88 @@ pruned_model = prune_model(
|
|
|
577
653
|
pruning_type="DEPTH",
|
|
578
654
|
layer_indices=layers_to_remove
|
|
579
655
|
)
|
|
580
|
-
```
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
### DataLoader Format Support (v0.2.4+)
|
|
659
|
+
|
|
660
|
+
Starting from OptiPFair v0.2.4, `analyze_layer_importance` automatically handles multiple DataLoader batch formats, making it compatible with both HuggingFace datasets and native PyTorch structures.
|
|
661
|
+
|
|
662
|
+
#### Supported Batch Formats
|
|
663
|
+
|
|
664
|
+
**1. Dictionary Format (HuggingFace)**
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
from datasets import load_dataset
|
|
668
|
+
from torch.utils.data import DataLoader
|
|
669
|
+
|
|
670
|
+
# HuggingFace datasets return dict batches
|
|
671
|
+
dataset = load_dataset('wikitext', 'wikitext-2-raw-v1', split='train[:100]')
|
|
672
|
+
tokenized = dataset.map(tokenize_function, batched=True)
|
|
673
|
+
tokenized.set_format(type='torch', columns=['input_ids', 'attention_mask'])
|
|
674
|
+
dataloader = DataLoader(tokenized, batch_size=8)
|
|
675
|
+
|
|
676
|
+
# Batch format: {'input_ids': tensor, 'attention_mask': tensor}
|
|
677
|
+
importance_scores = analyze_layer_importance(model, dataloader)
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
**2. Tuple Format (TensorDataset)**
|
|
681
|
+
|
|
682
|
+
```python
|
|
683
|
+
from torch.utils.data import DataLoader, TensorDataset
|
|
684
|
+
|
|
685
|
+
# Tokenize texts manually
|
|
686
|
+
inputs = tokenizer(
|
|
687
|
+
texts,
|
|
688
|
+
truncation=True,
|
|
689
|
+
padding='max_length',
|
|
690
|
+
max_length=512,
|
|
691
|
+
return_tensors='pt'
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
# TensorDataset returns tuples
|
|
695
|
+
dataset = TensorDataset(inputs['input_ids'], inputs['attention_mask'])
|
|
696
|
+
dataloader = DataLoader(dataset, batch_size=8)
|
|
697
|
+
|
|
698
|
+
# Batch format: (input_ids, attention_mask)
|
|
699
|
+
# Automatically mapped: [0]=input_ids, [1]=attention_mask
|
|
700
|
+
importance_scores = analyze_layer_importance(model, dataloader)
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**3. List Format (Custom Datasets)**
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
class CustomDataset(Dataset):
|
|
707
|
+
def __getitem__(self, idx):
|
|
708
|
+
return [self.input_ids[idx], self.attention_mask[idx]]
|
|
709
|
+
|
|
710
|
+
# Batch format: [input_ids, attention_mask]
|
|
711
|
+
# Same positional mapping as tuples
|
|
712
|
+
importance_scores = analyze_layer_importance(model, dataloader)
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
**4. Single Tensor Format**
|
|
716
|
+
|
|
717
|
+
```python
|
|
718
|
+
# Dataset with only input_ids (no attention_mask)
|
|
719
|
+
dataset = TensorDataset(input_ids_tensor)
|
|
720
|
+
dataloader = DataLoader(dataset, batch_size=8)
|
|
721
|
+
|
|
722
|
+
# Batch format: single tensor
|
|
723
|
+
# Automatically treated as input_ids
|
|
724
|
+
importance_scores = analyze_layer_importance(model, dataloader)
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
#### Positional Mapping for Tuple/List Formats
|
|
728
|
+
|
|
729
|
+
When using tuple or list batches, elements are automatically mapped to standard transformer arguments:
|
|
730
|
+
|
|
731
|
+
- `[0]` → `input_ids` (required)
|
|
732
|
+
- `[1]` → `attention_mask` (optional)
|
|
733
|
+
- `[2]` → `token_type_ids` (optional)
|
|
734
|
+
- `[3]` → `position_ids` (optional)
|
|
735
|
+
- `[4]` → `head_mask` (optional)
|
|
736
|
+
- `[5]` → `inputs_embeds` (optional)
|
|
737
|
+
|
|
738
|
+
**Note**: All formats are fully backward compatible. Existing code continues to work without modifications.
|
|
739
|
+
|
|
740
|
+
---
|