Unverified Commit 39432390 authored by kvartet's avatar kvartet Committed by GitHub
Browse files

Update Chinese documentation (#3886)

parent 93dbaf3e
This diff is collapsed.
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
## 安全
微软非常重视软件产品和服务的安全性,包括通过我们的 GitHub 组织管理的所有源代码库,其中涵盖 [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin),和 [我们 GitHub 的组织](https://opensource.microsoft.com/)
如果你在任何微软拥有的资源库中发现了安全漏洞,并且符合 [微软对安全漏洞的定义](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)),请按照下文所述向我们报告。
## 报告安全问题
**请不要通过公开的 GitHub 问题报告安全漏洞。**
相反,请向微软安全响应中心(MSRC)报告,链接是 [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report)
如果您希望在不登录的情况下提交,请发送电子邮件至 [secure@microsoft.com](mailto:secure@microsoft.com)。 如果可能的话,请用我们的 PGP 密钥对您的信息进行加密;请从以下网站下载该密钥 [微软安全响应中心 PGP 密钥页面](https://www.microsoft.com/en-us/msrc/pgp-key-msrc)
你应该在24小时内收到回复。 如果由于某些原因你没有收到,请通过电子邮件跟进,以确保我们收到你的原始信息。 其他信息可以在以下网站找到 [microsoft.com/msrc](https://www.microsoft.com/msrc)
请包括以下所要求的信息(尽可能多地提供),以帮助我们更好地了解可能的问题的性质和范围。
* 问题类型(如缓冲区溢出、SQL 注入、跨站脚本等)
* 与问题表现有关的源文件的完整路径
* 受影响的源代码位置(标签/分支/提交或 URL)
* 重现该问题所需的任何特殊配置
* 重现该问题的分步骤说明
* 概念证明或漏洞代码(如果可能的话)
* 该问题的影响,包括攻击者如何利用该问题
这些信息将帮助我们更快地对你的报告进行分流。
如果您需要报告错误赏金,更完整的报告可有助于获得更高的赏金奖励。 请访问我们的[微软漏洞赏金计划](https://microsoft.com/msrc/bounty)页面,以了解有关我们活动计划的更多详细信息。
## 首选语言
我们希望所有的交流都是用英语进行的。
## 政策
微软遵循[协调漏洞披露](https://www.microsoft.com/en-us/msrc/cvd)的原则。
<!-- END MICROSOFT SECURITY.MD BLOCK -->
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
NNI 提供了先进的评估算法,使用上也很简单。 下面是内置 Assessor 的介绍。 NNI 提供了先进的评估算法,使用上也很简单。 下面是内置 Assessor 的介绍。
注意:点击 **Assessor 的名称** 可了解每个 Assessor 的安装需求,建议的场景以及示例。 在每个 Assessor 建议场景最后,还有算法的详细说明。 注意:点击 **Assessor 的名称** 可了解每个 Assessor 的安装需求,建议的场景以及示例。在每个 Assessor 建议场景最后,还有算法的详细说明。
当前支持以下 Assessor: 当前支持以下 Assessor:
...@@ -47,7 +47,7 @@ Median Stop Assessor ...@@ -47,7 +47,7 @@ Median Stop Assessor
**classArgs 要求:** **classArgs 要求:**
* **optimize_mode** ( *maximize 或 minimize,可选默认值是maximize* )。如果为 'maximize',Assessor 会在结果小于期望值时 **中止** Trial。 如果为 'minimize',Assessor 会在结果大于期望值时**终止** Trial。 * **optimize_mode** ( *maximize 或 minimize,可选默认值是maximize* )。如果为 'maximize',Assessor 会在结果小于期望值时 **中止** Trial。如果为 'minimize',Assessor 会在结果大于期望值时 **终止** Trial。
* **start_step** ( *int,可选,默认值为 0* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。 * **start_step** ( *int,可选,默认值为 0* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
**使用示例:** **使用示例:**
...@@ -82,10 +82,10 @@ Curve Fitting Assessor ...@@ -82,10 +82,10 @@ Curve Fitting Assessor
**classArgs 要求:** **classArgs 要求:**
* **epoch_num** ( *int,必需* ),epoch 的总数。 需要此数据来决定需要预测点的总数。 * **epoch_num** ( *int,必需* ),epoch 的总数。需要此数据来决定需要预测点的总数。
* **start_step** ( *int,可选,默认值为 6* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。 * **start_step** ( *int,可选,默认值为 6* )。只有收到 start_step 个中间结果后,才开始判断是否一个 Trial 应该被终止。
* **threshold** ( *float,可选,默认值为 0.95* ),用来确定提前终止较差结果的阈值。 例如,如果 threshold = 0.95,最好的历史结果是 0.9,那么会在 Trial 的预测值低于 0.95 * 0.9 = 0.855 时停止。 * **threshold** ( *float,可选,默认值为 0.95* ),用来确定提前终止较差结果的阈值。例如,如果 threshold = 0.95,最好的历史结果是 0.9,那么会在 Trial 的预测值低于 0.95 * 0.9 = 0.855 时停止。
* **gap** ( *int,可选,默认值为 1* ),Assessor 两次评估之间的间隔次数。 例如:如果 gap = 2, start_step = 6,就会评估第 6, 8, 10, 12... 个中间结果。 * **gap** ( *int,可选,默认值为 1* ),Assessor 两次评估之间的间隔次数。例如:如果 gap = 2, start_step = 6,就会评估第 6, 8, 10, 12... 个中间结果。
**使用示例:** **使用示例:**
......
...@@ -25,7 +25,7 @@ NNI的命令行工具 **nnictl** 支持自动补全,也就是说,您可以 ...@@ -25,7 +25,7 @@ NNI的命令行工具 **nnictl** 支持自动补全,也就是说,您可以
cd ~ cd ~
wget https://raw.githubusercontent.com/microsoft/nni/{nni-version}/tools/bash-completion wget https://raw.githubusercontent.com/microsoft/nni/{nni-version}/tools/bash-completion
{nni-version} 应该填充 NNI 的版本,例如 ``master``\ , ``v2.0``。 你也可以 :githublink:`在这里 <tools/bash-completion>` 查看最新的 ``bash-completion`` 脚本。 {nni-version} 应该填充 NNI 的版本,例如 ``master``\ , ``v2.3``。 你也可以 :githublink:`在这里 <tools/bash-completion>` 查看最新的 ``bash-completion`` 脚本。
.. cannot find :githublink:`here <tools/bash-completion>`. .. cannot find :githublink:`here <tools/bash-completion>`.
......
...@@ -24,7 +24,6 @@ NNI (Neural Network Intelligence) 是一个微软开源的自动机器学习工 ...@@ -24,7 +24,6 @@ NNI (Neural Network Intelligence) 是一个微软开源的自动机器学习工
或复杂系统的参数 或复杂系统的参数
链接
:`https://github.com/Microsoft/nni <https://github.com/Microsoft/nni>`__ :`https://github.com/Microsoft/nni <https://github.com/Microsoft/nni>`__
总体看微软的工具都有一个比较大的特点, 总体看微软的工具都有一个比较大的特点,
...@@ -138,5 +137,6 @@ NNI 的 AutoFeature 模块是给整个行业制定了一个教科书般的标准 ...@@ -138,5 +137,6 @@ NNI 的 AutoFeature 模块是给整个行业制定了一个教科书般的标准
大家用的时候如果是 Mac 电脑可能会遇到 gcc 的问题,因为开源项目自带的脚本是基于 gcc7 编译的, 可以用下面的方法绕过去: 大家用的时候如果是 Mac 电脑可能会遇到 gcc 的问题,因为开源项目自带的脚本是基于 gcc7 编译的, 可以用下面的方法绕过去:
brew install libomp .. code-block:: bash
===================
brew install libomp
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
在 Google Colab 中使用 NNI <NNI_colab_support> 在 Google Colab 中使用 NNI <NNI_colab_support>
自动补全 nnictl 命令 <AutoCompletion> 自动补全 nnictl 命令 <AutoCompletion>
其它代码库和参考 外部代码库
==================================== ====================================
经作者许可的一些 NNI 用法示例和相关文档。 经作者许可的一些 NNI 用法示例和相关文档。
外部代码库 外部代码库
===================== =====================
* 使用 NNI 的 `矩阵分解超参调优 <https://github.com/microsoft/recommenders/blob/master/examples/04_model_select_and_optimize/nni_surprise_svd.ipynb>`__ 。 * 使用 NNI 的 `矩阵分解超参调优 <https://github.com/microsoft/recommenders/blob/master/examples/04_model_select_and_optimize/nni_surprise_svd.ipynb>`__ 。
* 使用 NNI 为 scikit-learn 开发的超参搜索 `scikit-nni <https://github.com/ksachdeva/scikit-nni>`__ * `使用 NNI 为 scikit-learn 开发的超参搜索 - 2019年11月6日 <https://towardsdatascience.com/find-thy-hyper-parameters-for-scikit-learn-pipelines-using-microsoft-nni-f1015b1224c1>`__
相关文章 相关文章
================= =================
* `使用AdaptDL 和 NNI进行经济高效的超参调优 - 2021年2月23日 <https://medium.com/casl-project/cost-effective-hyper-parameter-tuning-using-adaptdl-with-nni-e55642888761>`__ * `使用AdaptDL 和 NNI进行经济高效的超参调优 - 2021年2月23日 <https://medium.com/casl-project/cost-effective-hyper-parameter-tuning-using-adaptdl-with-nni-e55642888761>`__
* `(中文博客)NNI v2.0 新功能概述 - 2021年1月21日 <https://www.msra.cn/zh-cn/news/features/nni-2>`__ * `(中文博客)NNI v2.0 新功能概述 - 2021年1月21日 <https://www.msra.cn/zh-cn/news/features/nni-2>`__
* `(中文博客)2019年 NNI 新功能概览 - 2019年12月26日 <https://mp.weixin.qq.com/s/7_KRT-rRojQbNuJzkjFMuA>`__ * `(中文博客)2019年 NNI 新功能概览 - 2019年12月26日 <https://mp.weixin.qq.com/s/7_KRT-rRojQbNuJzkjFMuA>`__
* `使用 NNI 为 scikit-learn 开发的超参搜索 - 2019年11月6日 <https://towardsdatascience.com/find-thy-hyper-parameters-for-scikit-learn-pipelines-using-microsoft-nni-f1015b1224c1>`__ * 使用 NNI 为 scikit-learn 开发的超参搜索 `scikit-nni <https://github.com/ksachdeva/scikit-nni>`__
* `(中文博客)自动机器学习工具(Advisor、NNI 和 Google Vizier)对比 - 2019年8月5日 <http://gaocegege.com/Blog/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/katib-new#%E6%80%BB%E7%BB%93%E4%B8%8E%E5%88%86%E6%9E%90>`__ * `(中文博客)自动机器学习工具(Advisor、NNI 和 Google Vizier)对比 - 2019年8月5日 <http://gaocegege.com/Blog/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/katib-new#%E6%80%BB%E7%BB%93%E4%B8%8E%E5%88%86%E6%9E%90>`__
* `超参优化的对比 <./HpoComparison.rst>`__ * `超参优化的对比 <./HpoComparison.rst>`__
* `神经网络架构搜索对比 <./NasComparison.rst>`__ * `神经网络架构搜索对比 <./NasComparison.rst>`__
......
使用 NNI Experiment 自动压缩
================================================
如果你想压缩你的模型,但不知道该选择什么压缩算法,或者不知道什么稀疏度适合你的模型,或者只是想尝试更多的可能性,自动压缩可能会帮助你。
用户可以选择不同的压缩算法,并定义算法的搜索空间,然后自动压缩将启动一个 NNI 实验,并自动尝试不同稀疏度的压缩算法。
当然,除了稀疏度之外,用户还可以在搜索空间中引入其他相关参数。
如果你不知道什么是搜索空间或如何编写搜索空间,可以参考 `此教程 <./Tutorial/SearchSpaceSpec.rst>`__ 。
在 Python 中使用自动压缩与 NNI Experiment 很相似。
主要区别如下:
* 使用生成器帮助生成搜索空间对象
* 需要提供要压缩的模型,并且模型应该已经过预训练
* 不需要设置 ``trial_command``,需要额外设置 ``auto_compress_module`` 作为 ``AutoCompressionExperiment`` 的输入。
生成搜索空间
---------------------
由于大量使用嵌套搜索空间,我们建议使用生成器来配置搜索空间。
示例如下: 使用 ``add_config()`` 增加子配置,然后 ``dumps()`` 搜索空间字典。
.. code-block:: python
from nni.algorithms.compression.pytorch.auto_compress import AutoCompressionSearchSpaceGenerator
generator = AutoCompressionSearchSpaceGenerator()
generator.add_config('level', [
{
"sparsity": {
"_type": "uniform",
"_value": [0.01, 0.99]
},
'op_types': ['default']
}
])
generator.add_config('qat', [
{
'quant_types': ['weight', 'output'],
'quant_bits': {
'weight': 8,
'output': 8
},
'op_types': ['Conv2d', 'Linear']
}])
search_space = generator.dumps()
目前我们支持以下 Pruner 和 Quantizer:
.. code-block:: python
PRUNER_DICT = {
'level': LevelPruner,
'slim': SlimPruner,
'l1': L1FilterPruner,
'l2': L2FilterPruner,
'fpgm': FPGMPruner,
'taylorfo': TaylorFOWeightFilterPruner,
'apoz': ActivationAPoZRankFilterPruner,
'mean_activation': ActivationMeanRankFilterPruner
}
QUANTIZER_DICT = {
'naive': NaiveQuantizer,
'qat': QAT_Quantizer,
'dorefa': DoReFaQuantizer,
'bnn': BNNQuantizer
}
提供用户模型进行压缩
----------------------------------------------
用户需要继承 ``AbstractAutoCompressionModule`` 并重写抽象类的函数。
.. code-block:: python
from nni.algorithms.compression.pytorch.auto_compress import AbstractAutoCompressionModule
class AutoCompressionModule(AbstractAutoCompressionModule):
@classmethod
def model(cls) -> nn.Module:
...
return _model
@classmethod
def evaluator(cls) -> Callable[[nn.Module], float]:
...
return _evaluator
用户至少需要实现 ``model()`` 和 ``evaluator()``。
如果使用迭代 Pruner,则需要额外实现 ``optimizer_factory()``, ``criterion()`` 和 ``sparsifying_trainer()``。
如果要在压缩后对模型进行微调,则需要实现 ``optimizer_factory()``, ``criterion()``, ``post_compress_finetuning_trainer()`` 和 ``post_compress_finetuning_epochs()``。
``optimizer_factory()`` 应该返回一个工厂函数,输入是一个可迭代变量,即, 你的 ``model.parameters()``,输出是 optimizer 实例。
这两种 ``trainer()`` 应该返回一个输出为 ``model, optimizer, criterion, current_epoch`` 的 Trainer。
完整的抽象接口在 :githublink:`interface.py <nni/algorithms/compression/pytorch/auto_compress/interface.py>`。
``AutoCompressionModule`` 实施的例子参考 :githublink:`auto_compress_module.py <examples/model_compress/auto_compress/torch/auto_compress_module.py>`。
发起 NNI Experiment
---------------------
类似于从 python 启动,区别是不需要设置 ``trial_command`` 并把用户提供的 ``AutoCompressionModule`` 作为 ``AutoCompressionExperiment`` 的输入。
.. code-block:: python
from pathlib import Path
from nni.algorithms.compression.pytorch.auto_compress import AutoCompressionExperiment
from auto_compress_module import AutoCompressionModule
experiment = AutoCompressionExperiment(AutoCompressionModule, 'local')
experiment.config.experiment_name = 'auto compression torch example'
experiment.config.trial_concurrency = 1
experiment.config.max_trial_number = 10
experiment.config.search_space = search_space
experiment.config.trial_code_directory = Path(__file__).parent
experiment.config.tuner.name = 'TPE'
experiment.config.tuner.class_args['optimize_mode'] = 'maximize'
experiment.config.training_service.use_active_gpu = True
experiment.run(8088)
使用 NNI Tuners 自动进行模型压缩
========================================
使用 NNI 能轻松实现自动模型压缩
首先,使用 NNI 压缩模型
---------------------------------
可使用 NNI 轻松压缩模型。 以剪枝为例,可通过 L2FilterPruner 对预训练模型剪枝:
.. code-block:: python
from nni.algorithms.compression.pytorch.pruning import L2FilterPruner
config_list = [{ 'sparsity': 0.5, 'op_types': ['Conv2d'] }]
pruner = L2FilterPruner(model, config_list)
pruner.compress()
op_type 'Conv2d' 表示在 PyTorch 框架下定义在 :githublink:`default_layers.py <nni/compression/pytorch/default_layers.py>` 中的模块类型。
因此 ``{ 'sparsity': 0.5, 'op_types': ['Conv2d'] }`` 表示 **所有指定 op_types 的层都会被压缩到 0.5 的稀疏度**。 当调用 ``pruner.compress()`` 时,模型会通过掩码进行压缩。随后还可以微调模型,此时 **被剪除的权重不会被更新**。
然后,进行自动化
-------------------------
上一个示例手动选择 L2FilterPruner 并使用指定的稀疏度进行剪枝。 不同的稀疏度和不同的 Pruner 对不同的模型可能有不同的影响。 这个过程可以通过 NNI Tuner 完成。
首先,修改几行代码
.. code-block:: python
import nni
from nni.algorithms.compression.pytorch.pruning import *
params = nni.get_parameters()
sparsity = params['sparsity']
pruner_name = params['pruner']
model_name = params['model']
model, pruner = get_model_pruner(model_name, pruner_name, sparsity)
pruner.compress()
train(model) # 微调模型的代码
acc = test(model) # 测试微调后的模型
nni.report_final_results(acc)
然后,在 YAML 中定义一个 ``config`` 文件来自动调整模型、剪枝算法和稀疏度。
.. code-block:: yaml
searchSpace:
sparsity:
_type: choice
_value: [0.25, 0.5, 0.75]
pruner:
_type: choice
_value: ['slim', 'l2filter', 'fpgm', 'apoz']
model:
_type: choice
_value: ['vgg16', 'vgg19']
trainingService:
platform: local
trialCodeDirectory: .
trialCommand: python3 basic_pruners_torch.py --nni
trialConcurrency: 1
trialGpuNumber: 0
tuner:
name: grid
完整实验代码在 :githublink:`这里 <examples/model_compress/pruning/config.yml>`
最后,开始搜索
.. code-block:: bash
nnictl create -c config.yml
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.. contents:: .. contents::
Compressor Compressors
----------- -----------
Compressor Compressor
...@@ -19,8 +19,8 @@ Compressor ...@@ -19,8 +19,8 @@ Compressor
:members: :members:
module 的包装 Module 的包装
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
.. autoclass:: nni.compression.pytorch.compressor.PrunerModuleWrapper .. autoclass:: nni.compression.pytorch.compressor.PrunerModuleWrapper
:members: :members:
...@@ -34,7 +34,7 @@ module 的包装 ...@@ -34,7 +34,7 @@ module 的包装
.. autoclass:: nni.algorithms.compression.pytorch.pruning.weight_masker.WeightMasker .. autoclass:: nni.algorithms.compression.pytorch.pruning.weight_masker.WeightMasker
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.structured_pruning.StructuredWeightMasker .. autoclass:: nni.algorithms.compression.pytorch.pruning.structured_pruning_masker.StructuredWeightMasker
:members: :members:
...@@ -43,40 +43,40 @@ Pruners ...@@ -43,40 +43,40 @@ Pruners
.. autoclass:: nni.algorithms.compression.pytorch.pruning.sensitivity_pruner.SensitivityPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.sensitivity_pruner.SensitivityPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.OneshotPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot_pruner.OneshotPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.LevelPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot_pruner.LevelPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.SlimPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot_pruner.L1FilterPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.L1FilterPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot_pruner.L2FilterPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.L2FilterPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot_pruner.FPGMPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.FPGMPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.IterativePruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.TaylorFOWeightFilterPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.SlimPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.ActivationAPoZRankFilterPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.TaylorFOWeightFilterPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.one_shot.ActivationMeanRankFilterPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.ActivationAPoZRankFilterPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.lottery_ticket.LotteryTicketPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.ActivationMeanRankFilterPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.agp.AGPPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.AGPPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.admm_pruner.ADMMPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.iterative_pruner.ADMMPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.auto_compress_pruner.AutoCompressPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.auto_compress_pruner.AutoCompressPruner
...@@ -88,6 +88,9 @@ Pruners ...@@ -88,6 +88,9 @@ Pruners
.. autoclass:: nni.algorithms.compression.pytorch.pruning.simulated_annealing_pruner.SimulatedAnnealingPruner .. autoclass:: nni.algorithms.compression.pytorch.pruning.simulated_annealing_pruner.SimulatedAnnealingPruner
:members: :members:
.. autoclass:: nni.algorithms.compression.pytorch.pruning.lottery_ticket.LotteryTicketPruner
:members:
Quantizers Quantizers
^^^^^^^^^^ ^^^^^^^^^^
...@@ -103,6 +106,20 @@ Quantizers ...@@ -103,6 +106,20 @@ Quantizers
.. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.BNNQuantizer .. autoclass:: nni.algorithms.compression.pytorch.quantization.quantizers.BNNQuantizer
:members: :members:
模型加速
-------------
量化模型加速
^^^^^^^^^^^^^^^^^^^^
.. autoclass:: nni.compression.pytorch.quantization_speedup.backend.BaseModelSpeedup
:members:
.. autoclass:: nni.compression.pytorch.quantization_speedup.integrated_tensorrt.ModelSpeedupTensorRT
:members:
.. autoclass:: nni.compression.pytorch.quantization_speedup.calibrator.Calibrator
:members:
压缩工具 压缩工具
...@@ -135,4 +152,4 @@ Quantizers ...@@ -135,4 +152,4 @@ Quantizers
模型 FLOPs 和参数计数器 模型 FLOPs 和参数计数器
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: nni.compression.pytorch.utils.counter.count_flops_params .. autofunction:: nni.compression.pytorch.utils.counter.count_flops_params
\ No newline at end of file
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
就像 `dependency analysis utils <./CompressionUtils.md>`__ 显示,如果将两个卷积层(conv1,conv2)的输出通道相加,这两个卷积层之间将具有通道依赖关系(更多详细信息参见 `Compression Utils <./CompressionUtils.rst>`__\ )。 以下图为例。 就像 `dependency analysis utils <./CompressionUtils.md>`__ 显示,如果将两个卷积层(conv1,conv2)的输出通道相加,这两个卷积层之间将具有通道依赖关系(更多详细信息参见 `Compression Utils <./CompressionUtils.rst>`__\ )。 以下图为例。
.. image:: ../../img/mask_conflict.jpg .. image:: ../../img/mask_conflict.jpg
:target: ../../img/mask_conflict.jpg :target: ../../img/mask_conflict.jpg
:alt: :alt:
......
...@@ -29,7 +29,6 @@ Compressor 是 Pruner 和 Quantizer 的基类,提供了统一的接口,可 ...@@ -29,7 +29,6 @@ Compressor 是 Pruner 和 Quantizer 的基类,提供了统一的接口,可
'op_types': ['Conv2d', 'Linear'], 'op_types': ['Conv2d', 'Linear'],
}] }]
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9, weight_decay=1e-4)
pruner = LevelPruner(model, configure_list, optimizer) pruner = LevelPruner(model, configure_list, optimizer)
model = pruner.compress() model = pruner.compress()
...@@ -103,7 +102,7 @@ Compressor 是 Pruner 和 Quantizer 的基类,提供了统一的接口,可 ...@@ -103,7 +102,7 @@ Compressor 是 Pruner 和 Quantizer 的基类,提供了统一的接口,可
Pruner Pruner
------ ------
Pruner 接收 ``模型````配置`` ``优化器`` 作为参数。 通过 ``optimizer.step()`` 增加回调,在训练过程中根据 ``config_list`` 来对模型剪枝 Pruner 接收 ``模型````配置`` ``优化器`` 作为参数。一些剪枝器,比如 ``TaylorFOWeightFilter Pruner`` 通过 ``optimizer.step()`` 添加一个钩子,在训练循环期间根据 ``config_list`` 修剪模型
Pruner 类是 Compressor 的子类,因此它包含了 Compressor 的所有功能,并添加了剪枝所需要的组件,包括: Pruner 类是 Compressor 的子类,因此它包含了 Compressor 的所有功能,并添加了剪枝所需要的组件,包括:
......
...@@ -14,7 +14,18 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略 ...@@ -14,7 +14,18 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
* 提供优化且易用的压缩工具,帮助用户深入了解压缩过程和结果。 * 提供优化且易用的压缩工具,帮助用户深入了解压缩过程和结果。
* 提供简洁的接口,帮助用户实现自己的压缩算法。 * 提供简洁的接口,帮助用户实现自己的压缩算法。
* 注意,PyTorch 和 TensorFlow 有统一的 API 接口,当前仅支持 PyTorch 版本,未来会提供 TensorFlow 的支持。
压缩流水线
--------------------
.. image:: ../../img/compression_flow.jpg
:target: ../../img/compression_flow.jpg
:alt:
NNI的模型压缩流水线。 对于压缩预训练的模型,剪枝和量化可以单独使用或结合使用。
.. note::
NNI 压缩算法并不意味着压缩模型,NNI 的加速工具才可以真正压缩模型并减少延迟。 要获得真正压缩后的模型,用户应该进行 `模型加速 <./ModelSpeedup.rst>`__。 * 注意,PyTorch 和 TensorFlow 有统一的 API 接口,当前仅支持 PyTorch 版本,未来会提供 TensorFlow 的支持。
支持的算法 支持的算法
-------------------- --------------------
...@@ -36,7 +47,7 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略 ...@@ -36,7 +47,7 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
- 根据权重的绝对值,来按比例修剪权重。 - 根据权重的绝对值,来按比例修剪权重。
* - `AGP Pruner <../Compression/Pruner.rst#agp-pruner>`__ * - `AGP Pruner <../Compression/Pruner.rst#agp-pruner>`__
- 自动的逐步剪枝(是否剪枝的判断:基于对模型剪枝的效果)`参考论文 <https://arxiv.org/abs/1710.01878>`__ - 自动的逐步剪枝(是否剪枝的判断:基于对模型剪枝的效果)`参考论文 <https://arxiv.org/abs/1710.01878>`__
* - `Lottery Ticket Pruner <../Compression/Pruner.rst#lottery-ticket-hypothesis>`__ * - `Lottery Ticket Pruner <../Compression/Pruner.rst#lottery-ticket>`__
- "The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks" 提出的剪枝过程。 它会反复修剪模型。 `参考论文 <https://arxiv.org/abs/1803.03635>`__ - "The Lottery Ticket Hypothesis: Finding Sparse, Trainable Neural Networks" 提出的剪枝过程。 它会反复修剪模型。 `参考论文 <https://arxiv.org/abs/1803.03635>`__
* - `FPGM Pruner <../Compression/Pruner.rst#fpgm-pruner>`__ * - `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>`__ - Filter Pruning via Geometric Median for Deep Convolutional Neural Networks Acceleration `参考论文 <https://arxiv.org/pdf/1811.00250.pdf>`__
...@@ -85,12 +96,15 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略 ...@@ -85,12 +96,15 @@ NNI 的模型压缩工具包,提供了最先进的模型压缩算法和策略
- DoReFa-Net: 通过低位宽的梯度算法来训练低位宽的卷积神经网络。 `参考论文 <https://arxiv.org/abs/1606.06160>`__ - DoReFa-Net: 通过低位宽的梯度算法来训练低位宽的卷积神经网络。 `参考论文 <https://arxiv.org/abs/1606.06160>`__
* - `BNN Quantizer <../Compression/Quantizer.rst#bnn-quantizer>`__ * - `BNN Quantizer <../Compression/Quantizer.rst#bnn-quantizer>`__
- 二进制神经网络:使用权重和激活限制为 +1 或 -1 的深度神经网络。 `参考论文 <https://arxiv.org/abs/1602.02830>`__ - 二进制神经网络:使用权重和激活限制为 +1 或 -1 的深度神经网络。 `参考论文 <https://arxiv.org/abs/1602.02830>`__
* - `LSQ Quantizer <../Compression/Quantizer.rst#lsq-quantizer>`__
- 可学习的步长量化。 `参考论文 <https://arxiv.org/pdf/1902.08153.pdf>`__
模型加速 模型加速
------------- -------------
模型压缩的目的是减少推理延迟和模型大小。 但现有的模型压缩算法主要通过模拟的方法来检查压缩模型性能(如精度)。例如,剪枝算法中使用掩码,而量化算法中量化值仍然是以 32 位浮点数来存储。 只要给出这些算法产生的掩码和量化位,NNI 可真正的加速模型。 模型加速的详细文档参考 `这里 <./ModelSpeedup.rst>`__。 模型压缩的目的是减少推理延迟和模型大小。 但现有的模型压缩算法主要通过模拟的方法来检查压缩模型性能(如精度)。例如,剪枝算法中使用掩码,而量化算法中量化值仍然是以 32 位浮点数来存储。 只要给出这些算法产生的掩码和量化位,NNI 可真正的加速模型。 基于掩码的模型加速详细教程可以在 `这里 <./ModelSpeedup.rst>`__ 找到。混合精度量化的详细教程可以在 `这里 <./QuantizationSpeedup.rst>`__ 找到。
压缩工具 压缩工具
--------------------- ---------------------
...@@ -106,7 +120,6 @@ NNI 模型压缩提供了简洁的接口,用于自定义新的压缩算法。 ...@@ -106,7 +120,6 @@ NNI 模型压缩提供了简洁的接口,用于自定义新的压缩算法。
参考和反馈 参考和反馈
---------------------- ----------------------
* 在Github 中 `提交此功能的 Bug <https://github.com/microsoft/nni/issues/new?template=bug-report.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>`__ * 在Github 中 `提交新功能或请求改进 <https://github.com/microsoft/nni/issues/new?template=enhancement.rst>`__
* 了解更多关于 NNI 中的 `特征工程 <../FeatureEngineering/Overview.rst>`__\ ; * 了解更多关于 NNI 中的 `特征工程 <../FeatureEngineering/Overview.rst>`__\ ;
......
NNI 支持的剪枝算法 NNI 支持的剪枝算法
=================================== ===================================
NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算法。 **细粒度剪枝** 通常会生成非结构化模型,这需要专门的硬件或软件来加速稀疏网络。 **滤波器剪枝** 通过移除整个滤波器来实现加速。 一些剪枝算法使用 One-Shot 的方法,即根据重要性指标一次性剪枝权重。 其他剪枝算法控制在优化过程中剪枝权重的 **剪枝调度**,包括一些自动剪枝算法。 NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算法。 **细粒度剪枝** 通常会生成非结构化模型,这需要专门的硬件或软件来加速稀疏网络。 **滤波器剪枝** 一些剪枝算法使用 One-Shot 的方法,即根据重要性指标一次性剪枝权重(有必要对模型进行微调以补偿精度的损失)。 其他剪枝算法控制在优化过程中剪枝权重的 **剪枝调度**,包括一些自动剪枝算法。
**细粒度剪枝** **细粒度剪枝**
* `Level Pruner <#level-pruner>`__ * `Level Pruner <#level-pruner>`__
**滤波器剪枝**
* `Slim Pruner <#slim-pruner>`__ * `Slim Pruner <#slim-pruner>`__
* `FPGM Pruner <#fpgm-pruner>`__ * `FPGM Pruner <#fpgm-pruner>`__
* `L1Filter Pruner <#l1filter-pruner>`__ * `L1Filter Pruner <#l1filter-pruner>`__
...@@ -26,10 +23,10 @@ NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算 ...@@ -26,10 +23,10 @@ NNI 提供了一些支持细粒度权重剪枝和结构化的滤波器剪枝算
* `AutoCompress Pruner <#autocompress-pruner>`__ * `AutoCompress Pruner <#autocompress-pruner>`__
* `AMC Pruner <#amc-pruner>`__ * `AMC Pruner <#amc-pruner>`__
* `Sensitivity Pruner <#sensitivity-pruner>`__ * `Sensitivity Pruner <#sensitivity-pruner>`__
* `ADMM Pruner <#admm-pruner>`__
**其它** **其它**
* `ADMM Pruner <#admm-pruner>`__
* `Lottery Ticket Hypothesis <#lottery-ticket-hypothesis>`__ * `Lottery Ticket Hypothesis <#lottery-ticket-hypothesis>`__
Level Pruner Level Pruner
...@@ -65,7 +62,7 @@ PyTorch ...@@ -65,7 +62,7 @@ PyTorch
Slim Pruner Slim Pruner
----------- -----------
这是 One-Shot Pruner,它在训练过程中对 batch normalization(BN)层的比例因子进行稀疏正则化,以识别不重要的通道。 比例因子值较小的通道将被修剪。 更多细节,请参考论文 `'Learning Efficient Convolutional Networks through Network Slimming' <https://arxiv.org/pdf/1708.06519.pdf>`__\ 这是 One-Shot Pruner,它在训练过程中对 batch normalization(BN)层的比例因子进行稀疏正则化,以识别不重要的通道。 比例因子值较小的通道将被修剪。 更多细节,请参考论文 `'Learning Efficient Convolutional Networks through Network Slimming' <https://arxiv.org/pdf/1708.06519.pdf>`__。
用法 用法
^^^^^ ^^^^^
...@@ -274,7 +271,7 @@ PyTorch 代码 ...@@ -274,7 +271,7 @@ PyTorch 代码
'sparsity': 0.5, 'sparsity': 0.5,
'op_types': ['Conv2d'] 'op_types': ['Conv2d']
}] }]
pruner = ActivationAPoZRankFilterPruner(model, config_list, statistics_batch_num=1) pruner = ActivationMeanRankFilterPruner(model, config_list, statistics_batch_num=1)
pruner.compress() pruner.compress()
注意:ActivationAPoZRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。 注意:ActivationAPoZRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。
...@@ -293,8 +290,7 @@ ActivationAPoZRankFilterPruner 的用户配置 ...@@ -293,8 +290,7 @@ ActivationAPoZRankFilterPruner 的用户配置
ActivationMeanRankFilter Pruner ActivationMeanRankFilter Pruner
------------------------------- -------------------------------
ActivationMeanRankFilterPruner 是从卷积层激活的输出,用最小的重要性标准 ActivationMeanRankFilterPruner 是从卷积层激活的输出,用最小的重要性标准 ``平均激活`` 来修剪滤波器,来达到预设的网络稀疏度。剪枝标准 ``平均激活``,在论文 `Pruning Convolutional Neural Networks for Resource Efficient Inference <https://arxiv.org/abs/1611.06440>`__ 的 2.2 节中进行了介绍。 本文中提到的其他修剪标准将在以后的版本中支持。
``平均激活`` 来修剪滤波器,来达到预设的网络稀疏度。 剪枝标准 ``平均激活``,在论文 `Pruning Convolutional Neural Networks for Resource Efficient Inference <https://arxiv.org/abs/1611.06440>`__ 的 2.2 节中进行了介绍。 本文中提到的其他修剪标准将在以后的版本中支持。
我们还为这个 Pruner 提供了一个依赖感知模式,以更好地提高修剪的速度。 请参考 `dependency-aware <./DependencyAware.rst>`__ 获取更多信息。 我们还为这个 Pruner 提供了一个依赖感知模式,以更好地提高修剪的速度。 请参考 `dependency-aware <./DependencyAware.rst>`__ 获取更多信息。
...@@ -310,7 +306,7 @@ PyTorch 代码 ...@@ -310,7 +306,7 @@ PyTorch 代码
'sparsity': 0.5, 'sparsity': 0.5,
'op_types': ['Conv2d'] 'op_types': ['Conv2d']
}] }]
pruner = ActivationMeanRankFilterPruner(model, config_list, statistics_batch_num=1) pruner = ActivationAPoZRankFilterPruner(model, config_list, statistics_batch_num=1)
pruner.compress() pruner.compress()
注意:ActivationMeanRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。 注意:ActivationMeanRankFilterPruner 用于修剪深度神经网络中的卷积层,因此 ``op_types`` 字段仅支持卷积层。
...@@ -383,11 +379,7 @@ PyTorch 代码 ...@@ -383,11 +379,7 @@ PyTorch 代码
from nni.algorithms.compression.pytorch.pruning import AGPPruner from nni.algorithms.compression.pytorch.pruning import AGPPruner
config_list = [{ config_list = [{
'initial_sparsity': 0, 'sparsity': 0.8,
'final_sparsity': 0.8,
'start_epoch': 0,
'end_epoch': 10,
'frequency': 1,
'op_types': ['default'] 'op_types': ['default']
}] }]
...@@ -414,14 +406,6 @@ AGP Pruner 默认使用 ``LevelPruner`` 算法来修建权重,还可以设置 ...@@ -414,14 +406,6 @@ AGP Pruner 默认使用 ``LevelPruner`` 算法来修建权重,还可以设置
* ``apoz``\ : ActivationAPoZRankFilterPruner * ``apoz``\ : ActivationAPoZRankFilterPruner
* ``mean_activation``\ : ActivationMeanRankFilterPruner * ``mean_activation``\ : ActivationMeanRankFilterPruner
在训练代码中每完成一个 Epoch,需要更新一下 Epoch 的值。
PyTorch 代码
.. code-block:: python
pruner.update_epoch(epoch)
AGP Pruner 的用户配置 AGP Pruner 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
加速混合精度量化模型(实验性)
==========================================================
介绍
------------
深度神经网络一直是计算密集型和内存密集型的,
这增加了部署深度神经网络模型的难度。 量化是
一种广泛用于减少内存占用和加速推理过程的基础技术
。 许多框架开始支持量化,但很少有框架支持混合精度
量化并取得真正的速度提升。 像 `HAQ: Hardware-Aware Automated Quantization with Mixed Precision <https://arxiv.org/pdf/1811.08886.pdf>`__\ 这样的框架只支持模拟混合精度量化,这将
不加快推理过程。 为了获得混合精度量化的真正加速和
帮助人们从硬件中获得真实的反馈,我们设计了一个具有简单接口的通用框架,允许 NNI 量化算法连接不同的
DL 模型优化后端(例如 TensorRT、NNFusion),使用量化算法,在量化模型后为用户提供端到端体验
量化模型可以直接通过连接的优化后端加速。 在这个阶段,NNI 连接了
TensorRT,并将在未来支持更多的后端。
设计和实现
-------------------------
为了支持加速混合精度量化,我们将框架划分为两个部分,前端和后端。
前端可以是流行的训练框架,如 PyTorch、TensorFlow 等。 后端可以是
为不同硬件设计的推理框架,如 TensorRT。 目前,我们支持 PyTorch 作为前端和
TensorRT 作为后端。 为了将 PyTorch 模型转换为 TensorRT 引擎,我们利用 onnx 作为中间图
表示。 通过这种方式,我们将 PyTorch 模型转换为 onnx 模型,然后 TensorRT 解析 onnx
模型生成推理引擎。
量化感知训练结合了 NNI 量化算法 'QAT' 和 NNI 量化加速工具。
用户应该设置配置,使用 QAT 算法训练量化模型(请参考 `NNI量化算法 <https://nni.readthedocs.io/zh/stable/Compression/Quantizer.html>`__)。
经过量化感知训练,用户可以得到带有校准参数的新配置和带有量化权重的模型。 通过将新的配置和模型传递给量化加速工具,用户可以得到真正的混合精度加速引擎来进行推理。
在得到混合精度引擎后,用户可以使用输入数据进行推理。
注意
* 用户也可以直接利用 TensorRT 进行训练后的量化处理(需要提供校准数据集)。
* 并非所有OP类型都已支持。 目前,NNI 支持 Conv, Linear, Relu 和 MaxPool。 未来版本中将支持更多操作类型。
先决条件
------------
CUDA version >= 11.0
TensorRT version >= 7.2
用法
-----
量化感知训练:
.. code-block:: python
# 为QAT算法设置比特配置
configure_list = [{
'quant_types': ['weight', 'output'],
'quant_bits': {'weight':8, 'output':8},
'op_names': ['conv1']
}, {
'quant_types': ['output'],
'quant_bits': {'output':8},
'op_names': ['relu1']
}
]
quantizer = QAT_Quantizer(model, configure_list, optimizer)
quantizer.compress()
calibration_config = quantizer.export_model(model_path, calibration_path)
engine = ModelSpeedupTensorRT(model, input_shape, config=calibration_config, batchsize=batch_size)
# 建立 Tensorrt 推理引擎
engine.compress()
# 数据应该是 Pytorch Tensor
output, time = engine.inference(data)
请注意,NNI还直接支持后训练量化,请参阅完整的示例以获取详细信息。
完整的例子请参考 :githublink:`这里 <examples/model_compress/quantization/mixed_precision_speedup_mnist.py>`。
关于 'TensorRTModelSpeedUp' 类的更多参数,你可以参考 `Model Compression API Reference <https://nni.readthedocs.io/zh/stable/Compression/CompressionReference.html#quantization-speedup>`__ 。
Mnist 测试
^^^^^^^^^^^^^^^^^^^
在一块 GTX2080 GPU 上
输入张量:``torch.randn(128, 1, 28, 28)``
.. list-table::
:header-rows: 1
:widths: auto
* - 量化策略
- 延迟
- 准确率
* - 均为 32bit
- 0.001199961
- 96%
* - 混合精度(平均 bit 20.4)
- 0.000753688
- 96%
* - 均为 8bit
- 0.000229869
- 93.7%
Cifar10 resnet18 测试(训练一个 epoch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在一块 GTX2080 GPU 上
输入张量: ``torch.randn(128, 3, 32, 32)``
.. list-table::
:header-rows: 1
:widths: auto
* - 量化策略
- 延迟
- 准确率
* - 均为 32bit
- 0.003286268
- 54.21%
* - 混合精度(平均 bit 11.55)
- 0.001358022
- 54.78%
* - 均为 8bit
- 0.000859139
- 52.81%
\ No newline at end of file
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* `QAT Quantizer <#qat-quantizer>`__ * `QAT Quantizer <#qat-quantizer>`__
* `DoReFa Quantizer <#dorefa-quantizer>`__ * `DoReFa Quantizer <#dorefa-quantizer>`__
* `BNN Quantizer <#bnn-quantizer>`__ * `BNN Quantizer <#bnn-quantizer>`__
* `LSQ Quantizer <#lsq-quantizer>`__
Naive Quantizer Naive Quantizer
--------------- ---------------
...@@ -86,6 +87,61 @@ QAT Quantizer 的用户配置 ...@@ -86,6 +87,61 @@ QAT Quantizer 的用户配置
当前不支持批处理规范化折叠。 当前不支持批处理规范化折叠。
----
LSQ Quantizer
-------------
`可训练的步长量化 <https://arxiv.org/pdf/1902.08153.pdf>`__\ 中,作者 Steven K. Esser Jeffrey L. McKinstry 提供一种算法来训练带有梯度的尺度。
..
作者介绍了一种新颖的方法来估计和缩放每个权重和激活层的量化器步长的任务损失梯度,使得它可以与其他网络参数结合使用。
用法
^^^^^
您可以在训练代码之前添加下面的代码。 必须完成三件事:
1. 配置哪一层要被量化,以及该层的哪个张量(输入/输出/权重)要被量化。
2. 构建 lsq quantizer
3. 调用 `compress` API
PyTorch 代码
.. code-block:: python
from nni.algorithms.compression.pytorch.quantization import LsqQuantizer
model = Mnist()
configure_list = [{
'op_types': 'default'
'quant_bits': {
'weight': 8,
'input': 8,
},
'op_names': ['conv1']
}, {
'quant_types': ['output'],
'quant_bits': {'output': 8,},
'op_names': ['relu1']
}]
quantizer = LsqQuantizer(model, configure_list, optimizer)
quantizer.compress()
查看示例了解更多信息 :githublink:`examples/model_compress/quantization/LSQ_torch_quantizer.py <examples/model_compress/quantization/LSQ_torch_quantizer.py>`
LSQ Quantizer 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
压缩算法的公共配置可在 `config_list 说明 <./QuickStart.rst>`__ 中找到。
此算法所需的配置:
---- ----
DoReFa Quantizer DoReFa Quantizer
...@@ -106,7 +162,7 @@ PyTorch 代码 ...@@ -106,7 +162,7 @@ PyTorch 代码
config_list = [{ config_list = [{
'quant_types': ['weight'], 'quant_types': ['weight'],
'quant_bits': 8, 'quant_bits': 8,
'op_types': 'default' 'op_types': ['default']
}] }]
quantizer = DoReFaQuantizer(model, config_list) quantizer = DoReFaQuantizer(model, config_list)
quantizer.compress() quantizer.compress()
...@@ -160,7 +216,7 @@ PyTorch 代码 ...@@ -160,7 +216,7 @@ PyTorch 代码
可以查看 :githublink:`示例 <examples/model_compress/quantization/BNN_quantizer_cifar10.py>` 了解更多信息。 可以查看 :githublink:`示例 <examples/model_compress/quantization/BNN_quantizer_cifar10.py>` 了解更多信息。
BNN Quantizer 的用户配置 BNN Quantizer 的用户配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
压缩算法的公共配置可在 `config_list 说明 <./QuickStart.rst>`__ 中找到。 压缩算法的公共配置可在 `config_list 说明 <./QuickStart.rst>`__ 中找到。
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
教程 <Tutorial> 教程 <Tutorial>
模型压缩通常包括三个阶段:1)预训练模型,2)压缩模型,3)微调模型。 NNI 主要关注于第二阶段,并为模型压缩提供非常简单的 API 遵循本指南,快速了解如何使用 NNI 压缩模型。 模型压缩通常包括三个阶段:1)预训练模型,2)压缩模型,3)微调模型。 NNI 主要关注于第二阶段,并为模型压缩提供非常简单的 API 遵循本指南,快速了解如何使用 NNI 压缩模型。 NNI 主要关注于第二阶段,并为模型压缩提供非常简单的 API 恭喜! 您已经通过 NNI 压缩了您的第一个模型。 更深入地了解 NNI 中的模型压缩,请查看 `Tutorial <./Tutorial.rst>`__
模型剪枝 模型剪枝
------------- -------------
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
Step1. 编写配置 Step1. 编写配置
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
编写配置来指定要剪枝的层。 以下配置表示剪枝所有的 ``default`` 操作,稀疏度设为 0.5,其它层保持不变。 编写配置来指定要剪枝的层。以下配置表示剪枝所有的 ``default`` 操作,稀疏度设为 0.5,其它层保持不变。
.. code-block:: python .. code-block:: python
...@@ -26,7 +26,7 @@ Step1. 编写配置 ...@@ -26,7 +26,7 @@ Step1. 编写配置
'op_types': ['default'], 'op_types': ['default'],
}] }]
配置说明在 `这里 <./Tutorial.rst#specify-the-configuration>`__ 注意,不同的 Pruner 可能有自定义的配置字段,例如,AGP Pruner ``start_epoch`` 详情参考每个 Pruner `用法 <./Pruner.rst>`__,来调整相应的配置。 配置说明在 `这里 <./Tutorial.rst#quantization-specific-keys>`__ 注意,不同的 Pruner 可能有自定义的配置字段,例如,AGP Pruner ``start_epoch`` 详情参考每个 Pruner `用法 <./Pruner.rst>`__,来调整相应的配置。
Step2. 选择 Pruner 来压缩模型 Step2. 选择 Pruner 来压缩模型
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...@@ -37,7 +37,6 @@ Step2. 选择 Pruner 来压缩模型 ...@@ -37,7 +37,6 @@ Step2. 选择 Pruner 来压缩模型
from nni.algorithms.compression.pytorch.pruning import LevelPruner from nni.algorithms.compression.pytorch.pruning import LevelPruner
optimizer_finetune = torch.optim.SGD(model.parameters(), lr=0.01)
pruner = LevelPruner(model, config_list, optimizer_finetune) pruner = LevelPruner(model, config_list, optimizer_finetune)
model = pruner.compress() model = pruner.compress()
...@@ -54,7 +53,7 @@ Step2. 选择 Pruner 来压缩模型 ...@@ -54,7 +53,7 @@ Step2. 选择 Pruner 来压缩模型
train(args, model, device, train_loader, optimizer_finetune, epoch) train(args, model, device, train_loader, optimizer_finetune, epoch)
test(model, device, test_loader) test(model, device, test_loader)
更多关于微调的 API `这里 <./Tutorial.rst#apis-to-control-the-fine-tuning>`__ 更多关于微调的 API `这里 <./Tutorial.rst#api>`__
Step3. 导出压缩结果 Step3. 导出压缩结果
...@@ -110,12 +109,11 @@ Step2. 选择 Quantizer 来压缩模型 ...@@ -110,12 +109,11 @@ Step2. 选择 Quantizer 来压缩模型
Step3. 导出压缩结果 Step3. 导出压缩结果
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您可以使用 ``torch.save`` api 直接导出量化模型。量化后的模型可以通过 ``torch.load`` 加载,不需要做任何额外的修改 在训练和校准之后,你可以将模型权重导出到一个文件,并将生成的校准参数也导出到一个文件。 也支持导出 ONNX 模型
.. code-block:: python .. code-block:: python
# 保存使用 NNI QAT 算法生成的量化模型 calibration_config = quantizer.export_model(model_path, calibration_path, onnx_path, input_shape, device)
torch.save(model.state_dict(), "quantized_model.pth")
参考 :githublink:`mnist example <examples/model_compress/quantization/QAT_torch_quantizer.py>` 获取示例代码。 参考 :githublink:`mnist example <examples/model_compress/quantization/QAT_torch_quantizer.py>` 获取示例代码。
......
...@@ -11,48 +11,54 @@ ...@@ -11,48 +11,54 @@
指定配置 指定配置
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
用户可为压缩算法指定配置 (即, ``config_list`` )。 例如,压缩模型时,用户可能希望指定稀疏率,为不同类型的操作指定不同的稀疏比例,排除某些类型的操作,或仅压缩某类操作。 配置规范可用于表达此类需求。 可将其视为一个 Python 的 ``list`` 对象,其中每个元素都是一个 ``dict`` 对象。 用户可为压缩算法指定配置 (即, ``config_list`` )。 例如,压缩模型时,用户可能希望指定稀疏率,为不同类型的操作指定不同的稀疏比例,排除某些类型的操作,或仅压缩某类操作。 配置规范可用于表达此类需求。 可将其视为一个 Python 的 ``list`` 对象,其中每个元素都是一个 ``dict`` 对象。
``list`` 中的 ``dict`` 会依次被应用,也就是说,如果一个操作出现在两个配置里,后面的 ``dict`` 会覆盖前面的配置。 ``list`` 中的 ``dict`` 会依次被应用,也就是说,如果一个操作出现在两个配置里,后面的 ``dict`` 会覆盖前面的配置。
``dict`` 中有不同的键值。 以下是所有压缩算法都支持的: ``dict`` 中有不同的键值。以下是所有压缩算法都支持的:
* **op_types**:指定要压缩的操作类型。 'default' 表示使用算法的默认设置。 * **op_types**:指定要压缩的操作类型。'default' 表示使用算法的默认设置。 所有在 Pytorch 中支持的模块类型都定义在 :githublink:`default_layers.py <nni/compression/pytorch/default_layers.py>` 。
* **op_names**:指定需要压缩的操作的名称。 如果没有设置此字段,操作符不会通过名称筛选。 * **op_names**:指定需要压缩的操作的名称。如果没有设置此字段,操作符不会通过名称筛选。
* **exclude**:默认为 False。 如果此字段为 True,表示要通过类型和名称,将一些操作从压缩中排除。 * **exclude**:默认为 False。如果此字段为 True,表示要通过类型和名称,将一些操作从压缩中排除。
其他一些键值通常是针对某个特定算法的,可参考 `剪枝算法 <./Pruner.rst>`__ 和 `量化算法 <./Quantizer.rst>`__,查看每个算法的键值。 其他一些键值通常是针对某个特定算法的,可参考 `剪枝算法 <./Pruner.rst>`__ 和 `量化算法 <./Quantizer.rst>`__,查看每个算法的键值。
配置的简单示例如下 修剪所有 ``conv2d`` 层,稀疏性0.6为,配置可以写作
.. code-block:: python .. code-block:: python
[ [
{ 'sparsity': 0.6,
'sparsity': 0.8, 'op_types': ['Conv2d']
'op_types': ['default']
},
{
'sparsity': 0.6,
'op_names': ['op_name1', 'op_name2']
},
{
'exclude': True,
'op_names': ['op_name3']
}
] ]
为了控制特定层的稀疏度,配置可以写成:
.. code-block:: python
]
'sparsity': 0.8,
'op_types': ['default']
},
{
'sparsity': 0.6,
'op_names': ['op_name1', 'op_name2']
},
{
'exclude': True,
'op_names': ['op_name3']
}, {
其表示压缩操作的默认稀疏度为 0.8,但 ``op_name1`` 和 ``op_name2`` 会使用 0.6,且不压缩 ``op_name3``。 其表示压缩操作的默认稀疏度为 0.8,但 ``op_name1`` 和 ``op_name2`` 会使用 0.6,且不压缩 ``op_name3``。
量化算法特定键 Quantization Specific Keys
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
如果使用量化算法,则需要设置下面的 ``config_list``。 如果使用剪枝算法,则可以忽略这些键值。 如果使用量化算法,则需要设置下面的 ``config_list``。 如果使用剪枝算法,则可以忽略这些键值。
* **quant_types** : 字符串列表。 * **quant_types** : 字符串列表。
要应用量化的类型,当前支持 "权重","输入","输出"。 "权重"是指将量化操作 要应用量化的类型,当前支持 "权重","输入","输出"。"权重"是指将量化操作应用到 module 的权重参数上。"输入" 是指对 module 的 forward 方法的输入应用量化操作。 "输出"是指将量化运法应用于模块 forward 方法的输出,在某些论文中,这种方法称为"激活"。
应用到 module 的权重参数上。 "输入" 是指对 module 的 forward 方法的输入应用量化操作。 "输出"是指将量化运法应用于模块 forward 方法的输出,在某些论文中,这种方法称为"激活"。
* **quant_bits**:int 或 dict {str : int} * **quant_bits**:int 或 dict {str : int}
...@@ -62,18 +68,18 @@ ...@@ -62,18 +68,18 @@
.. code-block:: bash .. code-block:: bash
{ {
quant_bits: { quant_bits: {
'weight': 8, 'weight': 8,
'output': 4, 'output': 4,
}, },
} }
当值为 int 类型时,所有量化类型使用相同的位宽。 例如: 当值为 int 类型时,所有量化类型使用相同的位宽。 例如:
.. code-block:: bash .. code-block:: bash
{ {
quant_bits: 8, # 权重和输出的位宽都为 8 bits quant_bits: 8, # 权重和输出的位宽都为 8 bits
} }
下面的示例展示了一个更完整的 ``config_list``,它使用 ``op_names``(或者 ``op_types``)指定目标层以及这些层的量化位数。 下面的示例展示了一个更完整的 ``config_list``,它使用 ``op_names``(或者 ``op_types``)指定目标层以及这些层的量化位数。
...@@ -81,25 +87,26 @@ ...@@ -81,25 +87,26 @@
.. code-block:: bash .. code-block:: bash
config_list = [{ config_list = [{
'quant_types': ['weight'], 'quant_types': ['weight'],
'quant_bits': 8, 'quant_bits': 8,
'op_names': ['conv1'] 'op_names': ['conv1']
}, { },
'quant_types': ['weight'], {
'quant_bits': 4, 'quant_types': ['weight'],
'quant_start_step': 0, 'quant_bits': 4,
'op_names': ['conv2'] 'quant_start_step': 0,
}, { 'op_names': ['conv2']
'quant_types': ['weight'], },
'quant_bits': 3, {
'op_names': ['fc1'] 'quant_types': ['weight'],
}, 'quant_bits': 3,
{ 'op_names': ['fc1']
'quant_types': ['weight'], },
'quant_bits': 2, {
'op_names': ['fc2'] 'quant_types': ['weight'],
} 'quant_bits': 2,
] 'op_names': ['fc2']
}]
在这个示例中,'op_names' 是层的名字,四个层将被量化为不同的 quant_bits。 在这个示例中,'op_names' 是层的名字,四个层将被量化为不同的 quant_bits。
...@@ -107,10 +114,10 @@ ...@@ -107,10 +114,10 @@
导出压缩结果 导出压缩结果
------------------------- -------------------------
导出裁剪后的模型 导出量化后的模型
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
使用下列 API 可轻松将裁剪后的模型导出,稀疏模型权重的 ``state_dict`` 会保存在 ``model.pth`` 文件中,可通过 ``torch.load('model.pth')`` 加载。 注意,导出的 ``model.pth`` 具有与原始模型相同的参数,只是掩码的权重为零。 ``mask_dict`` 存储剪枝算法产生的二进制值,可以进一步用来加速模型。 使用下列 API 可轻松将裁剪后的模型导出,稀疏模型权重的 ``state_dict`` 会保存在 ``model.pth`` 文件中,可通过 ``torch.load('model.pth')`` 加载。注意,导出的 ``model.pth`` 具有与原始模型相同的参数,只是掩码的权重为零。 ``mask_dict`` 存储剪枝算法产生的二进制值,可以进一步用来加速模型。
.. code-block:: python .. code-block:: python
...@@ -130,10 +137,10 @@ ...@@ -130,10 +137,10 @@
pruner.export_model(model_path='model.pth', mask_path='mask.pth', onnx_path='model.onnx', input_shape=[1, 1, 28, 28]) pruner.export_model(model_path='model.pth', mask_path='mask.pth', onnx_path='model.onnx', input_shape=[1, 1, 28, 28])
导出量化后的模型 导出裁剪后的模型
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
您可以使用 ``torch.save`` api 直接导出量化模型。量化后的模型可以通过 ``torch.load`` 加载,不需要做任何额外的修改。 下面的例子展示了使用 QAT quantizer 保存、加载量化模型并获取相关参数的过程。 您可以使用 ``torch.save`` api 直接导出量化模型。量化后的模型可以通过 ``torch.load`` 加载,不需要做任何额外的修改。下面的例子展示了使用 QAT quantizer 保存、加载量化模型并获取相关参数的过程。
.. code-block:: python .. code-block:: python
...@@ -160,7 +167,7 @@ ...@@ -160,7 +167,7 @@
模型加速 模型加速
------------------ ------------------
掩码实际上并不能加速模型。 应该基于导出的掩码来对模型加速,因此,NNI 提供了 API 来加速模型。 在模型上调用 ``apply_compression_results`` 后,模型会变得更小,推理延迟也会减小。 掩码实际上并不能加速模型。 应该基于导出的掩码来对模型加速,因此,NNI 提供了 API 来加速模型。在模型上调用 ``apply_compression_results`` 后,模型会变得更小,推理延迟也会减小。
.. code-block:: python .. code-block:: python
...@@ -171,7 +178,7 @@ ...@@ -171,7 +178,7 @@
m_speedup.speedup_model() m_speedup.speedup_model()
参考 `这里 <ModelSpeedup.rst>`__,了解详情。 模型加速的示例代码在 :githublink:`这里 <examples/model_compress/pruning/model_speedup.py>`。 参考 `这里 <ModelSpeedup.rst>`__,了解详情。 模型加速的示例代码在 :githublink:`这里 <examples/model_compress/pruning/model_speedup.py>`。 知识蒸馏有效地从大型教师模型中学习小型学生模型。 用户可以通过知识蒸馏来增强模型的微调过程,提高压缩模型的性能。 示例代码在 :githublink:`这里 <examples/model_compress/pruning/finetune_kd_torch.py>`。
控制微调过程 控制微调过程
...@@ -180,9 +187,9 @@ ...@@ -180,9 +187,9 @@
控制微调的 API 控制微调的 API
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
某些压缩算法会控制微调过程中的压缩进度(例如, `AGP <../Compression/Pruner.rst#agp-pruner>`__),一些算法需要在每个批处理步骤后执行一些逻辑。 因此,NNI 提供了两个 API:``pruner.update_epoch(epoch)`` 和 ``pruner.step()``。 某些压缩算法会控制微调过程中的压缩进度(例如, `AGP <../Compression/Pruner.rst#agp-pruner>`__),一些算法需要在每个批处理步骤后执行一些逻辑。 因此,NNI 提供了两个 API:``pruner.update_epoch(epoch)`` 和 ``pruner.step()``。 `AGP <../Compression/Pruner.rst#agp-pruner>`__),一些算法需要在每个批处理步骤后执行一些逻辑。 因此,NNI 提供了两个 API:``pruner.update_epoch(epoch)`` 和 ``pruner.step()``。
``update_epoch`` 会在每个 Epoch 时调用,而 ``step`` 会在每次批处理后调用。 注意,大多数算法不需要调用这两个 API。 详细情况可参考具体算法文档。 对于不需要这两个 API 的算法,可以调用它们,但不会有实际作用。 ``update_epoch`` 会在每个 Epoch 时调用,而 ``step`` 会在每次批处理后调用。 注意,大多数算法不需要调用这两个 API。详细情况可参考具体算法文档。对于不需要这两个 API 的算法,可以调用它们,但不会有实际作用。
强化微调过程 强化微调过程
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
...@@ -6,4 +6,4 @@ ...@@ -6,4 +6,4 @@
框架 <./Framework> 框架 <./Framework>
自定义压缩算法 <./CustomizeCompressor> 自定义压缩算法 <./CustomizeCompressor>
自动模型压缩 <./AutoPruningUsingTuners> 自动模型压缩 (Beta) <./AutoCompression>
...@@ -21,6 +21,5 @@ NNI 提供了多种非结构化和结构化剪枝算法。 ...@@ -21,6 +21,5 @@ NNI 提供了多种非结构化和结构化剪枝算法。
:maxdepth: 2 :maxdepth: 2
Pruners <Pruner> Pruners <Pruner>
Dependency Aware Mode <DependencyAware> 依赖感知模式 <DependencyAware>
Model Speedup <ModelSpeedup> 模型加速 <ModelSpeedup>
Automatic Model Pruning with NNI Tuners <AutoPruningUsingTuners>
...@@ -8,10 +8,11 @@ ...@@ -8,10 +8,11 @@
可以使用8位整数表示, 更低的比特位数,例如4/2/1比特, 可以使用8位整数表示, 更低的比特位数,例如4/2/1比特,
是否能够表示权重也是目前非常活跃的研究方向。 是否能够表示权重也是目前非常活跃的研究方向。
一个 Quantizer 是指一种 NNI 实现的量化算法,NNI 提供了多个 Quantizer,如下所示。 你也可以 一个 Quantizer 是指一种 NNI 实现的量化算法,NNI 提供了多个 Quantizer,如下所示。你也可以
使用 NNI 模型压缩的接口来创造你的 Quantizer。 使用 NNI 模型压缩的接口来创造你的 Quantizer。
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
Quantizers <Quantizer> Quantizers <Quantizer>
量化加速 <QuantizationSpeedup>
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