Commit 1011377c authored by qianyj's avatar qianyj
Browse files

the source code of NNI for DCU

parent abc22158
.. 8a4c54c8127199ad4c95e20247e33fe2
#################
模型压缩
#################
以下介绍了如何将知识蒸馏应用于 NNI 模型压缩。 将来会添加更多用例和解决方案。
.. toctree::
:maxdepth: 1
使用 NNI 模型压缩进行知识蒸馏<../TrialExample/KDExample>
\ No newline at end of file
.. 7d625bd21018f53834e9db08a619c494
################################################
性能测量,比较和分析
################################################
性能比较和分析可以帮助用户在他们的场景中选择适合的算法(例如 Tuner,NAS 算法)。 以下是一些供用户参考的测量和比较数据。
.. toctree::
:maxdepth: 1
神经网络结构搜索(NAS)的对比<NasComparison>
超参调优算法的对比<HpoComparison>
模型压缩算法的对比<ModelCompressionComparison>
\ No newline at end of file
../../en_US/Compression/AutoCompression.rst
\ No newline at end of file
../../en_US/Compression/CompressionReference.rst
\ No newline at end of file
../../en_US/Compression/CompressionUtils.rst
\ No newline at end of file
../../en_US/Compression/CustomizeCompressor.rst
\ No newline at end of file
../../en_US/Compression/DependencyAware.rst
\ No newline at end of file
../../en_US/Compression/Framework.rst
\ No newline at end of file
../../en_US/Compression/ModelSpeedup.rst
\ No newline at end of file
.. 37577199d91c137b881450f825f38fa2
使用 NNI 进行模型压缩
====================
.. contents::
目前的大型神经网络较之以往具有更多的层和节点,而如何降低其存储和计算成本是一个重要的话题,尤其是针对于那些需要实时响应的应用程序。
模型压缩的相关方法可以用于解决这些问题。
NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略,帮助压缩并加速模型。NNI 模型压缩支持的主要功能有:
* 支持多种流行的剪枝和量化算法。
* 通过 NNI 强大的自动调优功能,可使用最先进的策略来自动化模型的剪枝和量化过程。
* 加速压缩的模型,使其在推理时有更低的延迟,同时文件也会变小。
* 提供友好易用的压缩工具,帮助用户深入了解压缩过程和结果。
* 提供简洁的接口,帮助用户实现自己的压缩算法。
压缩流水线
----------
.. image:: ../../img/compression_flow.jpg
:target: ../../img/compression_flow.jpg
:alt:
NNI整体的模型压缩流水线图。对于压缩一个预训练的模型,剪枝和量化可以单独使用或结合使用。
.. note::
NNI 压缩算法并不意味着真正使模型变小或者减少延迟,NNI 的加速工具才可以真正压缩模型并减少延迟。要获得真正压缩后的模型,用户应该进行 `模型加速 <./ModelSpeedup.rst>`__。* 注意,PyTorch 和 TensorFlow 有统一的 API 接口,当前仅支持 PyTorch 版本,未来会提供 TensorFlow 的支持。
支持的算法
----------
包括剪枝和量化算法。
剪枝算法
^^^^^^^^
剪枝算法通过删除冗余权重或层通道来压缩原始网络,从而降低模型复杂性并解决过拟合问题。
.. list-table::
:header-rows: 1
:widths: auto
* - 名称
- 算法简介
* - `Level Pruner <Pruner.rst#level-pruner>`__
- 根据权重的绝对值,来按比例修剪权重。
* - `AGP Pruner <../Compression/Pruner.rst#agp-pruner>`__
- 自动的逐步剪枝(To prune, or not to prune: exploring the efficacy of pruning for model compression)`参考论文 <https://arxiv.org/abs/1710.01878>`__
* - `Lottery Ticket Pruner <../Compression/Pruner.rst#lottery-ticket>`__
- "The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks" 提出的剪枝过程。 它会反复修剪模型。 `参考论文 <https://arxiv.org/abs/1803.03635>`__
* - `FPGM Pruner <../Compression/Pruner.rst#fpgm-pruner>`__
- Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration `参考论文 <https://arxiv.org/pdf/1811.00250.pdf>`__
* - `L1Filter Pruner <../Compression/Pruner.rst#l1filter-pruner>`__
- 在卷积层中具有最小 L1 权重规范的剪枝滤波器。(Pruning Filters for Efficient Convnets) `参考论文 <https://arxiv.org/abs/1608.08710>`__
* - `L2Filter Pruner <../Compression/Pruner.rst#l2filter-pruner>`__
- 在卷积层中具有最小 L2 权重规范的剪枝滤波器。
* - `ActivationAPoZRankFilterPruner <../Compression/Pruner.rst#activationapozrankfilter-pruner>`__
- 基于指标 APoZ(平均百分比零)的剪枝滤波器,该指标测量(卷积)图层激活值中零的百分比。 `参考论文 <https://arxiv.org/abs/1607.03250>`__
* - `ActivationMeanRankFilterPruner <../Compression/Pruner.rst#activationmeanrankfilter-pruner>`__
- 基于计算输出激活最小平均值指标的剪枝滤波器。
* - `Slim Pruner <../Compression/Pruner.rst#slim-pruner>`__
- 通过修剪 BN 层中的缩放因子来修剪卷积层中的通道。 (Learning Efficient Convolutional Networks through Network Slimming) `参考论文 <https://arxiv.org/abs/1708.06519>`__
* - `TaylorFO Pruner <../Compression/Pruner.rst#taylorfoweightfilter-pruner>`__
- 基于一阶泰勒展开的权重对滤波器剪枝。 (Importance Estimation for Neural Network Pruning) `参考论文 <http://jankautz.com/publications/Importance4NNPruning_CVPR19.pdf>`__
* - `ADMM Pruner <../Compression/Pruner.rst#admm-pruner>`__
- 基于 ADMM 优化技术的剪枝。 `参考论文 <https://arxiv.org/abs/1804.03294>`__
* - `NetAdapt Pruner <../Compression/Pruner.rst#netadapt-pruner>`__
- 在满足计算资源预算的情况下,对预训练的网络迭代剪枝。 `参考论文 <https://arxiv.org/abs/1804.03230>`__
* - `SimulatedAnnealing Pruner <../Compression/Pruner.rst#simulatedannealing-pruner>`__
- 通过启发式的模拟退火算法进行自动剪枝。 `参考论文 <https://arxiv.org/abs/1907.03141>`__
* - `AutoCompress Pruner <../Compression/Pruner.rst#autocompress-pruner>`__
- 通过迭代调用 SimulatedAnnealing Pruner 和 ADMM Pruner 进行自动剪枝。 `参考论文 - <https://arxiv.org/abs/1907.03141>`__
* - `AMC Pruner <../Compression/Pruner.rst#amc-pruner>`__
- AMC: AutoML for Model Compression and Acceleration on Mobile Devices `参考论文 <https://arxiv.org/pdf/1802.03494.pdf>`__
* - `Transformer Head Pruner <../Compression/Pruner.rst#transformer-head-pruner>`__
- 针对transformer中的注意力头的剪枝.
参考此 :githublink:`基准测试 <../CommunitySharings/ModelCompressionComparison.rst>` 来查看这些剪枝器在一些基准问题上的表现。
量化算法
^^^^^^^^
量化算法通过减少表示权重或激活函数所需的精度位数来压缩原始网络,这可以减少计算和推理时间。
.. list-table::
:header-rows: 1
:widths: auto
* - 名称
- 算法简介
* - `Naive Quantizer <../Compression/Quantizer.rst#naive-quantizer>`__
- 默认将权重量化为 8 位。
* - `QAT Quantizer <../Compression/Quantizer.rst#qat-quantizer>`__
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference. `参考论文 <http://openaccess.thecvf.com/content_cvpr_2018/papers/Jacob_Quantization_and_Training_CVPR_2018_paper.pdf>`__
* - `DoReFa Quantizer <../Compression/Quantizer.rst#dorefa-quantizer>`__
- DoReFa-Net: Training Low Bitwidth Convolutional Neural Networks with Low Bitwidth Gradients. `参考论文 <https://arxiv.org/abs/1606.06160>`__
* - `BNN Quantizer <../Compression/Quantizer.rst#bnn-quantizer>`__
- Binarized Neural Networks: Training Deep Neural Networks with Weights and Activations Constrained to +1 or -1. `参考论文 <https://arxiv.org/abs/1602.02830>`__
* - `LSQ Quantizer <../Compression/Quantizer.rst#lsq-quantizer>`__
- Learned step size quantization. `参考论文 <https://arxiv.org/pdf/1902.08153.pdf>`__
* - `Observer Quantizer <../Compression/Quantizer.rst#observer-quantizer>`__
- Post training quantizaiton. 使用 observer 在校准期间收集量化信息。
模型加速
--------
模型压缩的目的是减少推理延迟和模型大小。但现有的模型压缩算法主要通过模拟的方法来检查压缩模型性能(如精度)。例如,剪枝算法中使用掩码,而量化算法中量化值仍然是以 32 位浮点数来存储。只要给出这些算法产生的掩码和量化位,NNI 可真正的加速模型。基于掩码的模型加速详细教程可以在 `这里 <./ModelSpeedup.rst>`__ 找到。混合精度量化的详细教程可以在 `这里 <./QuantizationSpeedup.rst>`__ 找到。
压缩工具
--------
压缩工具包括了一些有用的工具,能帮助用户理解并分析要压缩的模型。例如,可检查每层对剪枝的敏感度。可很容易的计算模型的 FLOPs 和参数数量。`点击这里 <./CompressionUtils.rst>`__,查看压缩工具的完整列表。
高级用法
--------
NNI 模型压缩提供了简洁的接口,用于自定义新的压缩算法。接口的设计理念是,将框架相关的实现细节包装起来,让用户能聚焦于压缩逻辑。用户可以进一步了解我们的压缩框架,并根据我们的框架定制新的压缩算法(剪枝算法或量化算法)。此外,还可利用 NNI 的自动调参功能来自动的压缩模型。参考 `这里 <./advanced.rst>`__ 了解更多细节。
参考和反馈
----------
* 在Github 中 `提交此功能的 Bug <https://github.com/microsoft/nni/issues/new?template=bug-report.rst>`__
* 在Github 中 `提交新功能或请求改进 <https://github.com/microsoft/nni/issues/new?template=enhancement.rst>`__
* 了解更多关于 NNI 中的 `特征工程 <../FeatureEngineering/Overview.rst>`__\ ;
* 了解更多关于 NNI 中的 `NAS <../NAS/Overview.rst>`__\ ;
* 了解更多关于 NNI 中的 `超参调优 <../Tuner/BuiltinTuner.rst>`__\ ;
../../en_US/Compression/Pruner.rst
\ No newline at end of file
../../en_US/Compression/QuantizationSpeedup.rst
\ No newline at end of file
../../en_US/Compression/Quantizer.rst
\ No newline at end of file
.. a67033195635ebcd510103eab8703b6a
快速入门
===========
.. toctree::
:hidden:
Notebook Example <compression_pipeline_example>
模型压缩通常包括三个阶段:1)预训练模型,2)压缩模型,3)微调模型。 NNI 主要关注于第二阶段,并为模型压缩提供易于使用的 API
遵循本指南,您将快速了解如何使用 NNI 来压缩模型。
更深入地了解 NNI 中的模型压缩模块,请查看 `Tutorial <./Tutorial.rst>`__
提供了一个在 Jupyter notebook 中进行完整的模型压缩流程的 `示例 <./compression_pipeline_example.rst>`__,参考 :githublink:`代码 <examples/notebooks/compression_pipeline_example.ipynb>`
模型剪枝
-------------
这里通过 `level pruner <../Compression/Pruner.rst#level-pruner>`__ 举例说明 NNI 中模型剪枝的用法。
Step1. 编写配置
^^^^^^^^^^^^^^^^^^^^^^^^^^
编写配置来指定要剪枝的层。以下配置表示剪枝所有的 ``default`` 层,稀疏度设为 0.5,其它层保持不变。
.. code-block:: python
config_list = [{
'sparsity': 0.5,
'op_types': ['default'],
}]
配置说明在 `这里 <./Tutorial.rst#specify-the-configuration>`__。注意,不同的 Pruner 可能有自定义的配置字段。
详情参考每个 Pruner `具体用法 <./Pruner.rst>`__,来调整相应的配置。
Step2. 选择 Pruner 来压缩模型
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
首先,使用模型来初始化 Pruner,并将配置作为参数传入,然后调用 ``compress()`` 来压缩模型。
请注意,有些算法可能会检查训练过程中的梯度,因此我们可能会定义一组 trainer, optimizer, criterion 并传递给 Pruner
.. code-block:: python
from nni.algorithms.compression.pytorch.pruning import LevelPruner
pruner = LevelPruner(model, config_list)
model = pruner.compress()
然后,使用正常的训练方法来训练模型 (如,SGD),剪枝在训练过程中是透明的。
有些 Pruner(如 L1FilterPrunerFPGMPruner)在开始时修剪一次,下面的训练可以看作是微调。
有些 Pruner(例如AGPPruner)会迭代的对模型剪枝,在训练过程中逐步修改掩码。
如果使用 Pruner 进行迭代剪枝,或者剪枝过程中需要训练或者推理,则需要将 finetune 逻辑传到 Pruner 中。
例如:
.. code-block:: python
from nni.algorithms.compression.pytorch.pruning import AGPPruner
pruner = AGPPruner(model, config_list, optimizer, trainer, criterion, num_iterations=10, epochs_per_iteration=1, pruning_algorithm='level')
model = pruner.compress()
Step3. 导出压缩结果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
训练之后,可将模型权重导出到文件,同时将生成的掩码也导出到文件, 也支持导出 ONNX 模型。
.. code-block:: python
pruner.export_model(model_path='pruned_vgg19_cifar10.pth', mask_path='mask_vgg19_cifar10.pth')
参考 :githublink:`mnist 示例 <examples/model_compress/pruning/naive_prune_torch.py>` 获取代码。
更多剪枝算法的示例在 :githublink:`basic_pruners_torch <examples/model_compress/pruning/basic_pruners_torch.py>` :githublink:`auto_pruners_torch <examples/model_compress/pruning/auto_pruners_torch.py>`
模型量化
------------------
这里通过 `QAT Quantizer <../Compression/Quantizer.rst#qat-quantizer>`__ 举例说明在 NNI 中量化的用法。
Step1. 编写配置
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
config_list = [{
'quant_types': ['weight', 'input'],
'quant_bits': {
'weight': 8,
'input': 8,
}, # 这里可以仅使用 `int`,因为所有 `quan_types` 使用了一样的位长,参考下方 `ReLu6` 配置。
'op_types':['Conv2d', 'Linear'],
'quant_dtype': 'int',
'quant_scheme': 'per_channel_symmetric'
}, {
'quant_types': ['output'],
'quant_bits': 8,
'quant_start_step': 7000,
'op_types':['ReLU6'],
'quant_dtype': 'uint',
'quant_scheme': 'per_tensor_affine'
}]
配置说明在 `这里 <./Tutorial.rst#quantization-specific-keys>`__
Step2. 选择 Quantizer 来压缩模型
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: python
from nni.algorithms.compression.pytorch.quantization import QAT_Quantizer
quantizer = QAT_Quantizer(model, config_list)
quantizer.compress()
Step3. 导出压缩结果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在训练和校准之后,你可以将模型权重导出到一个文件,并将生成的校准参数也导出到一个文件。 也支持导出 ONNX 模型。
.. code-block:: python
calibration_config = quantizer.export_model(model_path, calibration_path, onnx_path, input_shape, device)
参考 :githublink:`mnist example <examples/model_compress/quantization/QAT_torch_quantizer.py>` 获取示例代码。
恭喜! 您已经通过 NNI 压缩了您的第一个模型。 更深入地了解 NNI 中的模型压缩,请查看 `Tutorial <./Tutorial.rst>`__
\ No newline at end of file
../../en_US/Compression/Tutorial.rst
\ No newline at end of file
.. acd3f66ad7c2d82b950568efcba1f175
高级用法
==============
.. toctree::
:maxdepth: 2
框架 <./Framework>
自定义压缩算法 <./CustomizeCompressor>
自动模型压缩 (Beta) <./AutoCompression>
../../en_US/Compression/compression_pipeline_example.ipynb
\ No newline at end of file
.. 0f2050a973cfb2207984b4e58c4baf28
#################
剪枝
#################
剪枝是一种常用的神经网络模型压缩技术。
剪枝算法探索模型权重(参数)中的冗余,并尝试去除冗余和非关键权重,
将它们的值归零,确保其不参与反向传播过程。
从剪枝粒度的角度来看,细粒度剪枝或非结构化剪枝是指分别对每个权重进行剪枝。
粗粒度剪枝或结构化剪枝是修剪整组权重,例如卷积滤波器。
NNI 提供了多种非结构化和结构化剪枝算法。
其使用了统一的接口来支持 TensorFlow 和 PyTorch。
只需要添加几行代码即可压缩模型。
对于结构化滤波器剪枝,NNI 还提供了依赖感知模式。 在依赖感知模式下,
滤波器剪枝在加速后会获得更好的速度增益。
详细信息,参考以下教程:
.. toctree::
:maxdepth: 2
Pruners <Pruner>
依赖感知模式 <DependencyAware>
模型加速 <ModelSpeedup>
.. fe32a6de0be31a992afadba5cf6ffe23
#################
量化
#################
量化是指通过减少权重表示或激活所需的比特数来压缩模型,
从而减少计算量和推理时间。 在深度神经网络的背景下,模型权重主要的数据
格式是32位浮点数。 许多研究工作表明,在不显着降低精度的情况下,权重和激活
可以使用8位整数表示, 更低的比特位数,例如4/2/1比特,
是否能够表示权重也是目前非常活跃的研究方向。
一个 Quantizer 是指一种 NNI 实现的量化算法,NNI 提供了多个 Quantizer,如下所示。你也可以
使用 NNI 模型压缩的接口来创造你的 Quantizer。
.. toctree::
:maxdepth: 2
Quantizers <Quantizer>
量化加速 <QuantizationSpeedup>
.. 1ec93e31648291b0c881655304116b50
#################
剪枝(V2版本)
#################
剪枝(V2版本)是对旧版本的重构,提供了更强大的功能。
与旧版本相比,迭代剪枝过程与剪枝器(pruner)分离,剪枝器只负责剪枝且生成掩码一次。
更重要的是,V2版本统一了剪枝过程,并提供了更自由的剪枝组件组合。
任务生成器(task generator)只关心在每一轮中应该达到的修剪效果,并使用配置列表(config list)来表示下一步如何修剪。
剪枝器将使用任务生成器提供的模型和配置列表重置,然后在当前步骤中生成掩码。
有关更清晰的架构,请参考下图。
.. image:: ../../img/pruning_process.png
:target: ../../img/pruning_process.png
:alt:
在V2版本中,修剪过程通常由剪枝调度器(pruning scheduler)驱动,它包含一个特定的剪枝器和一个任务生成器。
但是用户也可以像V1版本中那样直接使用剪枝器。
有关详细信息,请参阅以下教程:
.. toctree::
:maxdepth: 1
剪枝算法 <../en_US/Compression/v2_pruning_algo>
剪枝调度器接口 <../en_US/Compression/v2_scheduler>
剪枝配置 <../en_US/Compression/v2_pruning_config_list>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment