Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Auto pruners #2490

Merged
merged 107 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from 104 commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
80165e9
init sapruner
suiguoxin Apr 21, 2020
3fcebef
seperate sapruners from other one-shot pruners
suiguoxin Apr 22, 2020
b4be2d0
update
suiguoxin Apr 22, 2020
805c32c
fix model params issue
suiguoxin Apr 23, 2020
4c33432
make the process runnable
suiguoxin Apr 23, 2020
489f7b6
show evaluation result in example
suiguoxin Apr 23, 2020
00dbddf
sort the sparsities and scale it
suiguoxin Apr 23, 2020
e1f9654
fix rescale issue
suiguoxin Apr 23, 2020
4b5ea0d
fix scale issue; add pruning history
suiguoxin Apr 24, 2020
6120b70
record the actual total sparsity
suiguoxin Apr 24, 2020
a6114f7
fix sparsity 0/1 problem
suiguoxin Apr 26, 2020
2e928ae
revert useless modif
suiguoxin Apr 26, 2020
546ca73
revert useless modif
suiguoxin Apr 26, 2020
1dc4713
fix 0 pruning weights problem
suiguoxin Apr 27, 2020
d1a5646
save pruning history in csv file
suiguoxin Apr 28, 2020
75a53da
fix typo
suiguoxin Apr 28, 2020
e8900f8
remove check perm in Makefile
suiguoxin Apr 28, 2020
9c5ba41
use os path
suiguoxin Apr 29, 2020
9a60501
save config list in json format
suiguoxin Apr 29, 2020
951c60f
update analyze py; update docker
suiguoxin Apr 30, 2020
c784790
update
suiguoxin Apr 30, 2020
836e74b
update analyze
suiguoxin May 4, 2020
70aca26
update log info in compressor
suiguoxin May 4, 2020
efa0637
init NetAdapt Pruner
suiguoxin May 4, 2020
8695564
refine examples
suiguoxin May 6, 2020
8fdad96
Merge remote-tracking branch 'msft/master' into sapruner
suiguoxin May 6, 2020
db3074e
update
suiguoxin May 7, 2020
78ee01a
fine tune
suiguoxin May 7, 2020
3e40c4a
update
suiguoxin May 7, 2020
2560050
fix quote issue
suiguoxin May 7, 2020
d6e4101
add code for imagenet integrity
suiguoxin May 8, 2020
65f8e2b
update
suiguoxin May 8, 2020
d27ac7d
use datasets.ImageNet
suiguoxin May 8, 2020
f47260f
update
suiguoxin May 8, 2020
358921c
update
suiguoxin May 9, 2020
f50e947
add channel pruning in SAPruner; refine example
suiguoxin May 11, 2020
ea07c00
update net_adapt pruner; add dependency constraint in sapruner(beta)
suiguoxin May 11, 2020
7d73050
update
suiguoxin May 12, 2020
220e4a3
update
suiguoxin May 12, 2020
e692eb1
update
suiguoxin May 12, 2020
fc389d0
fix zero division problem
suiguoxin May 12, 2020
a69da67
fix typo
suiguoxin May 12, 2020
e0ab4bc
update
suiguoxin May 12, 2020
7724104
fix naive issue of NetAdaptPruner
suiguoxin May 12, 2020
f9f4a61
fix data issue for no-dependency modules
suiguoxin May 13, 2020
93698ac
add cifar10 vgg16 examplel
suiguoxin May 14, 2020
7d7f36d
update
suiguoxin May 14, 2020
9fc1029
update
suiguoxin May 14, 2020
9d506b1
fix folder creation issue; change lr for vgg exp
suiguoxin May 15, 2020
6ca5b27
update
suiguoxin May 15, 2020
fe9c1bf
add save model arg
suiguoxin May 15, 2020
1ec68a4
fix model copy issue
suiguoxin May 15, 2020
c99e4a3
init related weights calc
suiguoxin May 15, 2020
b6ce773
update analyze file
suiguoxin May 15, 2020
559c631
NetAdaptPruner: use fine-tuned weights after each iteration; fix modu…
suiguoxin May 18, 2020
2bd5a80
Merge remote-tracking branch 'msft/master' into sapruner
suiguoxin May 18, 2020
5ebea45
consider channel/filter cross pruning
suiguoxin May 18, 2020
f74324c
NetAdapt: consider previous op when calc total sparsity
suiguoxin May 18, 2020
27ad5f7
update
suiguoxin May 18, 2020
7f607ce
use customized vgg
suiguoxin May 19, 2020
6137373
add performances comparison plt
suiguoxin May 19, 2020
b9222c7
fix netadaptPruner mask copy issue
suiguoxin May 19, 2020
71e3651
add resnet18 example
suiguoxin May 19, 2020
045f114
fix example issue
suiguoxin May 19, 2020
e7b0410
Merge remote-tracking branch 'msft/master' into sapruner
suiguoxin May 19, 2020
98c5cb4
update experiment data
suiguoxin May 20, 2020
c220f84
fix bool arg parsing issue
suiguoxin May 20, 2020
5a1728e
update
suiguoxin May 20, 2020
b1a4058
init ADMMPruner
suiguoxin May 21, 2020
b36a170
ADMMPruner: update
suiguoxin May 21, 2020
fd6f3a6
ADMMPruner: finish v1.0
suiguoxin May 22, 2020
0b8840f
ADMMPruner: refine
suiguoxin May 22, 2020
7f1c319
update
suiguoxin May 22, 2020
87b090c
AutoCompress init
suiguoxin May 25, 2020
6c82d6c
AutoCompress: update
suiguoxin May 25, 2020
efd8f10
AutoCompressPruner: fix issues:
suiguoxin May 26, 2020
85a4483
add test for auto pruners
suiguoxin May 26, 2020
180a709
add doc for auto pruners
suiguoxin May 26, 2020
e87122c
fix link in md
suiguoxin May 26, 2020
955a6ee
remove irrelevant files
suiguoxin May 26, 2020
51e004e
Clean code
suiguoxin May 26, 2020
4eeb65e
code clean
suiguoxin May 26, 2020
f8ebc19
fix pylint issue
suiguoxin May 26, 2020
e241708
fix pylint issue
suiguoxin May 26, 2020
0edddeb
rename admm & autoCompress param
suiguoxin May 26, 2020
c93e0eb
use abs link in doc
suiguoxin May 26, 2020
e88e4d7
merge from master % resolve conflict
suiguoxin May 28, 2020
67c41d5
reorder import to fix import issue: autocompress relies on speedup
suiguoxin May 28, 2020
c057307
refine doc
suiguoxin Jun 4, 2020
7f3de4e
NetAdaptPruner: decay pruning step
suiguoxin Jun 11, 2020
55e705e
take changes from testing branch
suiguoxin Jun 29, 2020
e1775b3
merge from master
suiguoxin Jun 29, 2020
840213d
refine
suiguoxin Jun 29, 2020
d4b80bc
fix typo
suiguoxin Jun 29, 2020
c9fffe0
ADMMPruenr: check base_algo together with config schema
suiguoxin Jun 29, 2020
87f3232
fix broken link
suiguoxin Jun 29, 2020
16b1c95
doc refine
suiguoxin Jun 29, 2020
6bff198
ADMM:refine
suiguoxin Jun 29, 2020
d86fad4
refine doc
suiguoxin Jun 30, 2020
c29f758
resolve conflict
suiguoxin Jun 30, 2020
32d14d9
refine doc
suiguoxin Jun 30, 2020
5950bec
refince doc
ultmaster Jun 29, 2020
8a11b45
resolve conflict
suiguoxin Jun 30, 2020
be782bc
refine doc
suiguoxin Jun 30, 2020
d449e6a
refine doc
suiguoxin Jun 30, 2020
cb6376b
refine doc
suiguoxin Jun 30, 2020
cee3fdd
refine doc
suiguoxin Jun 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ Within the following table, we summarized the current NNI capabilities, we are g
<li><a href="docs/en_US/Compressor/Pruner.md#agp-pruner">AGP Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#slim-pruner">Slim Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#fpgm-pruner">FPGM Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#netadapt-pruner">NetAdapt Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#simulatedannealing-pruner">SimulatedAnnealing Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#admm-pruner">ADMM Pruner</a></li>
<li><a href="docs/en_US/Compressor/Pruner.md#autocompress-pruner">AutoCompress Pruner</a></li>
</ul>
<b>Quantization</b>
<ul>
Expand Down
183 changes: 179 additions & 4 deletions docs/en_US/Compressor/Pruner.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ We provide several pruning algorithms that support fine-grained weight pruning a

**Pruning Schedule**
* [AGP Pruner](#agp-pruner)
* [NetAdapt Pruner](#netadapt-pruner)
* [SimulatedAnnealing Pruner](#simulatedannealing-pruner)
* [AutoCompress Pruner](#autocompress-pruner)

**Others**
* [ADMM Pruner](#admm-pruner)
* [Lottery Ticket Hypothesis](#lottery-ticket-hypothesis)

## Level Pruner
Expand Down Expand Up @@ -349,6 +353,181 @@ You can view example for more information

***

## NetAdapt Pruner
Copy link
Contributor

@chicm-ms chicm-ms Jun 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order of each section is better consistent with the content directory/list at beginning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

NetAdapt allows a user to automatically simplify a pretrained network to meet the resource budget.
Given the overall sparsity, NetAdapt will automatically generate the sparsities distribution among different layers by iterative pruning.

For more details, please refer to [NetAdapt: Platform-Aware Neural Network Adaptation for Mobile Applications](https://arxiv.org/abs/1804.03230).

![](../../img/algo_NetAdapt.png)

#### Usage

PyTorch code

```python
from nni.compression.torch import NetAdaptPruner
config_list = [{
'sparsity': 0.5,
'op_types': ['Conv2d']
}]
pruner = NetAdaptPruner(model, config_list, short_term_fine_tuner=short_term_fine_tuner, evaluator=evaluator,base_algo='l1', experiment_data_dir='./')
pruner.compress()
```

You can view [example](https://github.com/microsoft/nni/blob/master/examples/model_compress/auto_pruners_torch.py) for more information.

#### User configuration for NetAdapt Pruner

- **sparsity:** The target overall sparsity.
- **op_types:** The operation type to prune. If `base_algo` is `l1` or `l2`, then only `Conv2d` is supported as `op_types`.
- **short_term_fine_tuner:** Function to short-term fine tune the masked model.
This function should include `model` as the only parameter, and fine tune the model for a short term after each pruning iteration.
- **evaluator:** Function to evaluate the masked model. This function should include `model` as the only parameter, and returns a scalar value.
- **optimize_mode:** Optimize mode, `maximize` or `minimize`, by default `maximize`.
- **base_algo:** Base pruning algorithm. `level`, `l1` or `l2`, by default `l1`.
Given the sparsity distrution among the ops, the assigned `base_algo` is used to decide which filters/channels/weights to prune.
- **sparsity_per_iteration:** The sparsity to prune in each iteration. NetAdapt Pruner prune the model by the same level in each iteration to meet the resource budget progressively.
- **experiment_data_dir:** PATH to save experiment data, including the config_list generated for the base pruning algorithm and the performance of the pruned model.


## SimulatedAnnealing Pruner

We implement a guided heuristic search method, Simulated Annealing (SA) algorithm, with enhancement on guided search based on prior experience.
The enhanced SA technique is based on the observation that a DNN layer with more number of weights often has a higher degree of model compression with less impact on overall accuracy.

- Randomly initialize a pruning rate distribution (sparsities).
- While current_temperature < stop_temperature:
1. generate a perturbation to current distribution
2. Perform fast evaluation on the perturbated distribution
3. accept the perturbation according to the performance and probability, if not accepted, return to step 1
4. cool down, current_temperature <- current_temperature * cool_down_rate

For more details, please refer to [AutoCompress: An Automatic DNN Structured Pruning Framework for Ultra-High Compression Rates](https://arxiv.org/abs/1907.03141).

#### Usage

PyTorch code

```python
from nni.compression.torch import SimulatedAnnealingPruner
config_list = [{
'sparsity': 0.5,
'op_types': ['Conv2d']
}]
pruner = SimulatedAnnealingPruner(model, config_list, evaluator=evaluator, base_algo='l1', cool_down_rate=0.9, experiment_data_dir='./')
pruner.compress()
```

You can view [example](https://github.com/microsoft/nni/blob/master/examples/model_compress/auto_pruners_torch.py) for more information.

#### User configuration for SimulatedAnnealing Pruner

- **sparsity:** The target overall sparsity.
- **op_types:** The operation type to prune. If `base_algo` is `l1` or `l2`, then only `Conv2d` is supported as `op_types`.
- **evaluator:** Function to evaluate the masked model. This function should include `model` as the only parameter, and returns a scalar value.
- **optimize_mode:** Optimize mode, `maximize` or `minimize`, by default `maximize`.
- **base_algo:** Base pruning algorithm. `level`, `l1` or `l2`, by default `l1`.
Given the sparsity distrution among the ops, the assigned `base_algo` is used to decide which filters/channels/weights to prune.
- **start_temperature:** Simualated Annealing related parameter.
- **stop_temperature:** Simualated Annealing related parameter.
- **cool_down_rate:** Simualated Annealing related parameter.
- **perturbation_magnitude:** Initial perturbation magnitude to the sparsities. The magnitude decreases with current temperature.
- **experiment_data_dir:** PATH to save experiment data, including the config_list generated for the base pruning algorithm, the performance of the pruned model and the pruning history.


## AutoCompress Pruner
For each round, AutoCompressPruner prune the model for the same sparsity to achive the ovrall sparsity:
1. Generate sparsities distribution using SimualtedAnnealingPruner
2. Perform ADMM-based structured pruning to generate pruning result for the next round.
Here we use `speedup` to perform real pruning.

For more details, please refer to [AutoCompress: An Automatic DNN Structured Pruning Framework for Ultra-High Compression Rates](https://arxiv.org/abs/1907.03141).

#### Usage

PyTorch code

```python
from nni.compression.torch import ADMMPruner
config_list = [{
'sparsity': 0.5,
'op_types': ['Conv2d']
}]
pruner = AutoCompressPruner(
model, config_list, trainer=trainer, evaluator=evaluator,
dummy_input=dummy_input, num_iterations=3, optimize_mode='maximize', base_algo='l1',
cool_down_rate=0.9, admm_num_iterations=30, admm_training_epochs=5, experiment_data_dir='./')
pruner.compress()
```

You can view [example](https://github.com/microsoft/nni/blob/master/examples/model_compress/auto_pruners_torch.py) for more information.

#### User configuration for AutoCompress Pruner

- **sparsity:** The target overall sparsity.
- **op_types:** The operation type to prune. If `base_algo` is `l1` or `l2`, then only `Conv2d` is supported as `op_types`.
- **trainer:** Function used for the first subproblem.
Users should write this function as a normal function to train the Pytorch model and include `model, optimizer, criterion, epoch, callback` as function arguments.
Here `callback` acts as an L2 regulizer as presented in the formula (7) of the original paper.
The logic of `callback` is implemented inside the Pruner, users are just required to insert `callback()` between `loss.backward()` and `optimizer.step()`.
- **evaluator:** Function to evaluate the masked model. This function should include `model` as the only parameter, and returns a scalar value.
- **dummy_input:** The dummy input for model speed up, users should put it on right device before pass in.
- **iterations:** The number of overall iterations.
- **optimize_mode:** Optimize mode, `maximize` or `minimize`, by default `maximize`.
- **base_algo:** Base pruning algorithm. `level`, `l1` or `l2`, by default `l1`.
Given the sparsity distrution among the ops, the assigned `base_algo` is used to decide which filters/channels/weights to prune.
- **start_temperature:** Simualated Annealing related parameter.
- **stop_temperature:** Simualated Annealing related parameter.
- **cool_down_rate:** Simualated Annealing related parameter.
- **perturbation_magnitude:** Initial perturbation magnitude to the sparsities. The magnitude decreases with current temperature.
- **admm_num_iterations:** Number of iterations of ADMM Pruner.
- **admm_training_epochs:** Training epochs of the first optimization subproblem of ADMMPruner.
- **experiment_data_dir:** PATH to store temporary experiment data.


## ADMM Pruner
Alternating Direction Method of Multipliers (ADMM) is a mathematical optimization technique,
by decomposing the original nonconvex problem into two subproblems that can be solved iteratively. In weight pruning problem, these two subproblems are solved via 1) gradient descent algorithm and 2) Euclidean projection respectively. This solution framework applies both to non-structured and different variations of structured pruning schemes.

For more details, please refer to [A Systematic DNN Weight Pruning Framework using Alternating Direction Method of Multipliers](https://arxiv.org/abs/1804.03294).

#### Usage

PyTorch code

```python
from nni.compression.torch import ADMMPruner
config_list = [{
'sparsity': 0.8,
'op_types': ['Conv2d'],
'op_names': ['conv1']
}, {
'sparsity': 0.92,
'op_types': ['Conv2d'],
'op_names': ['conv2']
}]
pruner = ADMMPruner(model, config_list, trainer=trainer, num_iterations=30, epochs=5)
pruner.compress()
```

You can view [example](https://github.com/microsoft/nni/blob/master/examples/model_compress/auto_pruners_torch.py) for more information.

#### User configuration for ADMM Pruner

- **sparsity:** This is to specify the sparsity operations to be compressed to.
- **op_types:** The operation type to prune. If `base_algo` is `l1` or `l2`, then only `Conv2d` is supported as `op_types`.
- **trainer:** Function used for the first subproblem.
Users should write this function as a normal function to train the Pytorch model and include `model, optimizer, criterion, epoch, callback` as function arguments.
Here `callback` acts as an L2 regulizer as presented in the formula (7) of the original paper.
The logic of `callback` is implemented inside the Pruner, users are just required to insert `callback()` between `loss.backward()` and `optimizer.step()`.
- **num_iterations:** Total number of iterations.
- **training_epochs:** Training epochs of the first subproblem.
- **row:** Penalty parameters for ADMM training.
- **base_algo:** Base pruning algorithm. `level`, `l1` or `l2`, by default `l1`.
Given the sparsity distrution among the ops, the assigned `base_algo` is used to decide which filters/channels/weights to prune.


## Lottery Ticket Hypothesis
[The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks](https://arxiv.org/abs/1803.03635), authors Jonathan Frankle and Michael Carbin,provides comprehensive measurement and analysis, and articulate the *lottery ticket hypothesis*: dense, randomly-initialized, feed-forward networks contain subnetworks (*winning tickets*) that -- when trained in isolation -- reach test accuracy comparable to the original network in a similar number of iterations.

Expand Down Expand Up @@ -396,7 +575,3 @@ We try to reproduce the experiment result of the fully connected network on MNIS
![](../../img/lottery_ticket_mnist_fc.png)

The above figure shows the result of the fully connected network. `round0-sparsity-0.0` is the performance without pruning. Consistent with the paper, pruning around 80% also obtain similar performance compared to non-pruning, and converges a little faster. If pruning too much, e.g., larger than 94%, the accuracy becomes lower and convergence becomes a little slower. A little different from the paper, the trend of the data in the paper is relatively more clear.




Binary file added docs/img/algo_NetAdapt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading