diff --git a/README.md b/README.md index 65c7b70ce1a284c6f0b954ed4d4a6c7d61d944cf..b1afeee0d2cdd276df769ec4af519caa8637fd27 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # PaddleSlim -中文 | [English](README_en.md) - [![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat)](https://paddleslim.readthedocs.io/en/latest/) [![Documentation Status](https://img.shields.io/badge/中文文档-最新-brightgreen.svg)](https://paddleslim.readthedocs.io/zh_CN/latest/) [![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE) @@ -16,7 +14,7 @@ PaddleSlim是一个专注于深度学习模型压缩的工具库,提供**剪 | :-----------: | :------------: | :------------:| :----------:| | 1.0.1 | <=1.7 | 2.7 | 支持静态图 | | 1.1.1 | 1.8 | 2.7 | 支持静态图 | -| 1.2.0 | 2.0Beta/RC | 2.8 | 支持静态图; 新增CPU预测 | +| 1.2.0 | 2.0Beta/RC | 2.8 | 支持静态图 | | 2.0.0 | 2.0 | 2.8 | 支持动态图和静态图 | @@ -29,12 +27,15 @@ pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple 安装指定版本: ```bash -pip install paddleslim=1.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple +pip install paddleslim=2.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple ``` ## 最近更新 2021.2.5: 发布V2.0.0版本,新增支持动态图,新增OFA压缩功能,优化剪枝功能。 +2020.9.16: 发布V1.2.0版本,新增PACT量化训练功能,新增DML(互蒸馏功能),修复部分剪裁bug,加强对depthwise_conv2d的剪裁能力,优化剪裁和量化API的易用性和灵活性。 + +更多信息请参考:[release note](https://github.com/PaddlePaddle/PaddleSlim/releases) ## 功能概览 @@ -105,52 +106,92 @@ PaddleSlim在典型视觉和自然语言处理任务上做了模型压缩,并 ## 文档教程 -### 快速上手 +### 快速开始 -- 量化训练 - [动态图]() | [静态图]() -- 离线量化 - [动态图]() | [静态图]() -- 剪裁 - [动态图]() | [静态图]() -- 蒸馏 - [动态图]() | [静态图]() -- NAS - [动态图]() | [静态图]() +- 量化训练 - [动态图](docs/zh_cn/quick_start/dygraph/dygraph_quant_aware_training_tutorial.md) | [静态图](docs/zh_cn/quick_start/static/quant_aware_tutorial.md) +- 离线量化 - [动态图](docs/zh_cn/quick_start/dygraph/dygraph_quant_post_tutorial.md) | [静态图](docs/zh_cn/quick_start/static/quant_post_static_tutorial.md) +- 剪裁 - [动态图](docs/zh_cn/quick_start/dygraph/dygraph_pruning_tutorial.md) | [静态图](docs/zh_cn/quick_start/static/pruning_tutorial.md) +- 蒸馏 - [静态图](docs/zh_cn/quick_start/static/distillation_tutorial.md) +- NAS - [静态图](docs/zh_cn/quick_start/static/nas_tutorial.md) ### 进阶教程 -#### 压缩功能详解 +- 通道剪裁 + - [四种剪裁策略效果对比与应用方法](docs/zh_cn/tutorials/pruning/overview.md) + - [L1NormFilterPruner](docs/zh_cn/tutorials/pruning/overview.md#l1normfilterpruner) + - [FPGMFilterPruner](docs/zh_cn/tutorials/pruning/overview.md#fpgmfilterpruner) + - [SlimFilterFilterPruner](docs/zh_cn/tutorials/pruning/overview.md#slimfilterpruner) + - [OptSlimFilterPruner](docs/zh_cn/tutorials/pruning/overview.md#optslimfilterpruner) + - 剪裁功能详解: [动态图](docs/zh_cn/tutorials/pruning/dygraph/filter_pruning.md) | [静态图](docs/zh_cn/tutorials/pruning/static/image_classification_sensitivity_analysis_tutorial.md) + - 自定义剪裁策略:[动态图](docs/zh_cn/tutorials/pruning/dygraph/self_defined_filter_pruning.md) + +- 低比特量化 + - [三种量化方法介绍与应用](docs/zh_cn/tutorials/quant/overview.md) + - 量化训练:[动态图](docs/zh_cn/tutorials/quant/dygraph/quant_aware_training_tutorial.md) | [静态图](docs/zh_cn/quick_start/static/quant_aware_tutorial.md) + - 离线量化:[动态图](docs/zh_cn/tutorials/quant/dygraph/dygraph_quant_post_tutorial.md) | [静态图](docs/zh_cn/tutorials/quant/static/quant_post_tutorial.md) + - embedding量化:[静态图](docs/zh_cn/tutorials/quant/static/embedding_quant_tutorial.md) + +- NAS + - [四种NAS策略介绍和应用](docs/zh_cn/tutorials/nas/overview.md) + +- 蒸馏 + - [知识蒸馏示例](demo/distillation) -[量化训练]() | [离线量化]() | [剪裁]() | [蒸馏]() | [NAS]() #### 推理部署 -- [概述]() -- [PaddleInference量化部署]() - - [Intel CPU量化部署]() - - [GPU量化部署]() -- [PaddleLite量化部署]() +- [Intel CPU量化部署](demo/mkldnn_quant/README.md) +- [Nvidia GPU量化部署](demo/quant/deploy/TensorRT/README.md) +- [PaddleLite量化部署](docs/zh_cn/deploy/deploy_cls_model_on_mobile_device.md) ### CV模型压缩 -- [检测模型压缩(基于PaddleDetection)]() - - YOLOv3 3.5倍加速方案 +- 检测模型压缩(基于PaddleDetection) + - 压缩方案 + - YOLOv3 3.5倍加速方案: 文档整理中... + - 方法应用-静态图 + - [在COCO和VOC上蒸馏MobileNetV1-YOLOv3](docs/zh_cn/cv/detection/static/paddledetection_slim_distillation_tutorial.md) + - [MobileNetV1-YOLOv3低比特量化训练](docs/zh_cn/cv/detection/static/paddledetection_slim_quantization_tutorial.md) + - [人脸检测模型小模型结构搜索](docs/zh_cn/cv/detection/static/paddledetection_slim_nas_tutorial.md) + - [剪枝](docs/zh_cn/cv/detection/static/paddledetection_slim_pruing_tutorial.md) + - [剪枝与蒸馏的结合使用](docs/zh_cn/cv/detection/static/paddledetection_slim_prune_dist_tutorial.md) + - [卷积层敏感度分析](docs/zh_cn/cv/detection/static/paddledetection_slim_sensitivy_tutorial.md) + - 方法应用-动态图 + - 文档整理中... + +- 分割模型压缩(基于PaddleSeg) + + - 压缩方案 + - 方案建设中... -- [分割模型压缩(基于PaddleSeg)]() + - 方法应用-静态图 + - 文档整理中... + + - 方法应用-动态图 + - 文档整理中... - [OCR模型压缩(基于PaddleOCR)]() - - [3.5M模型压缩方案]() -### NLP模型压缩 + - 压缩方案 + - 3.5M模型压缩方案: 文档整理中... + + - 方法应用-静态图 + - [低比特量化训练](https://github.com/PaddlePaddle/PaddleOCR/tree/release/1.1/deploy/slim/quantization) + - [剪枝](https://github.com/PaddlePaddle/PaddleOCR/tree/release/1.1/deploy/slim/prune) -- [BERT]() -- [ERNIE]() + - 方法应用-动态图 + - 文档整理中... -### 通用轻量级模型 -- 人脸模型(SlimfaceNet) -- 图像分类模型(SlimMobileNet) +### NLP模型压缩 + +- [BERT](docs/zh_cn/nlp/paddlenlp_slim_ofa_tutorial.md) +- [ERNIE](docs/zh_cn/nlp/ernie_slim_ofa_tutorial.md) ### API文档 -- 动态图 -- 静态图 +- [动态图](docs/zh_cn/api_cn/dygraph) +- [静态图](docs/zh_cn/api_cn/static) ### [FAQ]() @@ -163,3 +204,5 @@ PaddleSlim在典型视觉和自然语言处理任务上做了模型压缩,并 我们非常欢迎你可以为PaddleSlim提供代码,也十分感谢你的反馈。 ## 欢迎加入PaddleSlim技术交流群 + +请添加微信公众号"AIDigest",备注“压缩”,飞桨同学会拉您进入微信交流群。 diff --git a/demo/mkldnn_quant/README.md b/demo/mkldnn_quant/README.md index 601b5f3fcf8028bdda96d497ec6f4157d188141f..58159b376272998a02d8244f412ec90790ecbd5d 100644 --- a/demo/mkldnn_quant/README.md +++ b/demo/mkldnn_quant/README.md @@ -1,4 +1,4 @@ -# PaddleSlim INT8量化模型在CPU上的部署和预测 +# Intel CPU量化部署 ## 概述 diff --git a/demo/quant/deploy/TensorRT/README.md b/demo/quant/deploy/TensorRT/README.md index c1a8d88782e5b7a0be4be1805327171e164ea9bb..c0ad3b76c686ab874258bf1d26ae02a60e2770f5 100644 --- a/demo/quant/deploy/TensorRT/README.md +++ b/demo/quant/deploy/TensorRT/README.md @@ -1,4 +1,4 @@ -# PaddleSlim INT8量化模型使用TensorRT的部署和预测 +# Nvidia GPU量化部署 ## 概述 NVIDIA TensorRT 是一个高性能的深度学习预测库,适用于Nvidia GPU,可为深度学习推理应用程序提供低延迟和高吞吐量。PaddlePaddle 采用子图的形式对TensorRT进行了集成,即我们可以使用该模块来提升Paddle模型的预测性能。本教程将介绍如何使用TensortRT部署PaddleSlim量化得到的模型,无论是量化训练(QAT)还是离线量化(PTQ)模型均可支持。对于常见图像分类模型,INT8模型的推理速度通常是FP32模型的3.2-6.7倍。 diff --git a/docs/images/algo/ofa_bert.jpg b/docs/images/algo/ofa_bert.jpg deleted file mode 100644 index cb8b67049813099e520cc24b339434a4692d3dbe..0000000000000000000000000000000000000000 Binary files a/docs/images/algo/ofa_bert.jpg and /dev/null differ diff --git a/docs/zh_cn/CHANGELOG.md b/docs/zh_cn/CHANGELOG.md index 800c089a5ca4b7747378f193096920f9dc39edb5..403312d56c393eb8a3d00121b93a9e0e4c28992d 100644 --- a/docs/zh_cn/CHANGELOG.md +++ b/docs/zh_cn/CHANGELOG.md @@ -2,6 +2,22 @@ ## 最新版本信息 +### v2.0.0(02/2020) + +- 新增支持动态图剪枝、量化 +- 新增OFA压缩策略 +- 修复若干剪枝相关问题 + +## 历史版本信息 + +### v1.2.0 + +- 新增PACT量化训练功能,提升PaddleSlim在图像目标检测、图像语义分割、OCR等模型上的量化训练效果。 +- 新增DML(互蒸馏功能),提升部分模型的蒸馏效果。 +- 修复部分剪裁bug,加强对depthwise_conv2d的剪裁能力。 +- 优化剪裁和量化API的易用性和灵活性。 + + ### v1.1.0(05/2020) - 量化 @@ -17,8 +33,6 @@ - 新增一种基于强化学习的模型结构搜索策略,并提供扩展接口,为用户调研实现新策略提供参考。 -## 历史版本信息 - ### v1.0.1 - 拆分PaddleSlim为独立repo。 diff --git a/docs/zh_cn/algo/algo.md b/docs/zh_cn/algo/algo.md deleted file mode 100644 index 67977e70f1f9618352575374aa8605bde3a80a62..0000000000000000000000000000000000000000 --- a/docs/zh_cn/algo/algo.md +++ /dev/null @@ -1,294 +0,0 @@ -# 算法原理 - -## 目录 - -- [量化原理介绍](#1-quantization-aware-training量化介绍) -- [剪裁原理介绍](#2-卷积核剪裁原理) -- [蒸馏原理介绍](#3-蒸馏) -- [轻量级模型结构搜索原理介绍](#4-轻量级模型结构搜索) - -## 1. Quantization Aware Training量化介绍 - -### 1.1 背景 - -近年来,定点量化使用更少的比特数(如8-bit、3-bit、2-bit等)表示神经网络的权重和激活已被验证是有效的。定点量化的优点包括低内存带宽、低功耗、低计算资源占用以及低模型存储需求等。 - -

-
-表1: 不同类型操作的开销对比 -

- -由表1可知,低精度定点数操作的硬件面积大小及能耗比高精度浮点数要少几个数量级。 使用定点量化可带来4倍的模型压缩、4倍的内存带宽提升,以及更高效的cache利用(很多硬件设备,内存访问是主要能耗)。除此之外,计算速度也会更快(通常具有2x-3x的性能提升)。由表2可知,在很多场景下,定点量化操作对精度并不会造成损失。另外,定点量化对神经网络于嵌入式设备上的推断来说是极其重要的。 - -

-
-表2:模型量化前后精度对比 -

- -目前,学术界主要将量化分为两大类:`Post Training Quantization`和`Quantization Aware Training`。`Post Training Quantization`是指使用KL散度、滑动平均等方法确定量化参数且不需要重新训练的定点量化方法。`Quantization Aware Training`是在训练过程中对量化进行建模以确定量化参数,它与`Post Training Quantization`模式相比可以提供更高的预测精度。 - -### 1.2 量化原理 - -#### 1.2.1 量化方式 -目前,存在着许多方法可以将浮点数量化成定点数。例如: -$$ r = min(max(x, a), b)$$ $$ s = \frac{b - a}{n - 1} $$ $$ q = \left \lfloor \frac{r - a}{s} \right \rceil $$ -式中,$x$是待量化的浮点值,$[a, b]$是量化范围,$a$是待量化浮点数中的最小值, $b$ 是待量化浮点数中的最大值。$\left \lfloor \right \rceil$ 表示将结果四舍五入到最近的整数。如果量化级别为$k$,则$n$为$2^k$。例如,若$k$为8,则$n$为256。$q$是量化得到的整数。 -PaddleSlim框架中选择的量化方法为最大绝对值量化(`max-abs`),具体描述如下: -$$ M = max(abs(x)) $$ $$ q = \left \lfloor \frac{x}{M} * (n - 1) \right \rceil $$ -式中,$x$是待被量化的浮点值,$M$是待量化浮点数中的绝对值最大值。$\left \lfloor \right \rceil$表示将结果四舍五入到最近的整数。对于8bit量化,PaddleSlim采用`int8_t`,即$n=2^7=128$。$q$是量化得到的整数。 -无论是`min-max量化`还是`max-abs量化`,他们都可以表示为如下形式: -$q = scale * r + b$ -其中`min-max`和`max-abs`被称为量化参数或者量化比例或者量化范围。 - -#### 1.2.2 量化训练 -##### 1.2.2.1 前向传播 -前向传播过程采用模拟量化的方式,具体描述如下: - -

-
-图1:基于模拟量化训练的前向过程 -

- -由图1可知,基于模拟量化训练的前向过程可被描述为以下四个部分: -1) 输入和权重均被量化成8-bit整数。 -2) 在8-bit整数上执行矩阵乘法或者卷积操作。 -3) 反量化矩阵乘法或者卷积操作的输出结果为32-bit浮点型数据。 -4) 在32-bit浮点型数据上执行偏置加法操作。此处,偏置并未被量化。 -对于通用矩阵乘法(`GEMM`),输入$X$和权重$W$的量化操作可被表述为如下过程: -$$ X_q = \left \lfloor \frac{X}{X_m} * (n - 1) \right \rceil $$ $$ W_q = \left \lfloor \frac{W}{W_m} * (n - 1) \right \rceil $$ -执行通用矩阵乘法: -$$ Y_q = X_q * W_q $$ -对量化乘积结果$Yq$进行反量化: -$$ -\begin{align} -Y_{dq} = \frac{Y_q}{(n - 1) * (n - 1)} * X_m * W_m \ -=\frac{X_q * W_q}{(n - 1) * (n - 1)} * X_m * W_m \ -=(\frac{X_q}{n - 1} * X_m) * (\frac{W_q}{n - 1} * W_m) \ -\end{align} -$$ -上述公式表明反量化操作可以被移动到`GEMM`之前,即先对$Xq$和$Wq$执行反量化操作再做`GEMM`操作。因此,前向传播的工作流亦可表示为如下方式: - -

-
-图2:基于模拟量化训练前向过程的等价工作流 -

- -训练过程中,PaddleSlim使用图2中所示的等价工作流。在设计中,量化Pass在IrGraph中插入量化op和反量化op。因为在连续的量化、反量化操作之后输入仍然为32-bit浮点型数据。因此,PaddleSlim量化训练框架所采用的量化方式被称为模拟量化。 - -##### 1.2.2.2 反向传播 -由图3可知,权重更新所需的梯度值可以由量化后的权重和量化后的激活求得。反向传播过程中的所有输入和输出均为32-bit浮点型数据。注意,梯度更新操作需要在原始权重上进行,即计算出的梯度将被加到原始权重上而非量化后或反量化后的权重上。 - -

-
-图3:基于模拟量化训练的反向传播和权重更新过程 -

- -因此,量化Pass也会改变相应反向算子的某些输入。 - -##### 1.2.2.3 确定量化比例系数 -存在着两种策略可以计算求取量化比例系数,即动态策略和静态策略。动态策略会在每次迭代过程中计算量化比例系数的值。静态策略则对不同的输入采用相同的量化比例系数。 -对于权重而言,在训练过程中采用动态策略。换句话说,在每次迭代过程中量化比例系数均会被重新计算得到直至训练过程结束。 -对于激活而言,可以选择动态策略也可以选择静态策略。若选择使用静态策略,则量化比例系数会在训练过程中被评估求得,且在推断过程中被使用(不同的输入均保持不变)。静态策略中的量化比例系数可于训练过程中通过如下三种方式进行评估: - -1. 在一个窗口中计算激活最大绝对值的平均值。 - -2. 在一个窗口中计算激活最大绝对值的最大值。 - -3. 在一个窗口中计算激活最大绝对值的滑动平均值,计算公式如下: - -$$ Vt = (1 - k) * V + k * V_{t-1} $$ - -式中,$V$ 是当前batch的最大绝对值, $Vt$是滑动平均值。$k$是一个因子,例如其值可取为0.9。 - -#### 1.2.4 训练后量化 - -训练后量化是基于采样数据,采用KL散度等方法计算量化比例因子的方法。相比量化训练,训练后量化不需要重新训练,可以快速得到量化模型。 - -训练后量化的目标是求取量化比例因子,主要有两种方法:非饱和量化方法 ( No Saturation) 和饱和量化方法 (Saturation)。非饱和量化方法计算FP32类型Tensor中绝对值的最大值`abs_max`,将其映射为127,则量化比例因子等于`abs_max/127`。饱和量化方法使用KL散度计算一个合适的阈值`T` (`0 -
-图4 -

- - -**剪裁注意事项2** - -如**图5**所示,剪裁完$X_i$之后,根据注意事项1我们从$X_{i+1}$的filter中删除了一行(图中蓝色行),在计算$X_{i+1}$的filters的l1_norm(图中绿色一列)的时候,有两种选择: -算上被删除的一行:independent pruning -减去被删除的一行:greedy pruning - -

-
-图5 -

- -**剪裁注意事项3** -在对ResNet等复杂网络剪裁的时候,还要考虑到后当前卷积层的修改对上一层卷积层的影响。 -如**图6**所示,在对residual block剪裁时,$X_{i+1}$层如何剪裁取决于project shortcut的剪裁结果,因为我们要保证project shortcut的output和$X_{i+1}$的output能被正确的concat. - - -

-
-图6 -

- -### 2.2 Uniform剪裁卷积网络 - -每层剪裁一样比例的卷积核。 -在剪裁一个卷积核之前,按l1_norm对filter从高到低排序,越靠后的filter越不重要,优先剪掉靠后的filter. - - -### 2.3 基于敏感度剪裁卷积网络 - -根据每个卷积层敏感度的不同,剪掉不同比例的卷积核。 - -#### 两个假设 - -- 在一个conv layer的parameter内部,按l1_norm对filter从高到低排序,越靠后的filter越不重要。 -- 两个layer剪裁相同的比例的filters,我们称对模型精度影响更大的layer的敏感度相对高。 - -#### 剪裁filter的指导原则 - -- layer的剪裁比例与其敏感度成反比 -- 优先剪裁layer内l1_norm相对低的filter - -#### 敏感度的理解 - -

-
-图7 -

- -如**图7**所示,横坐标是将filter剪裁掉的比例,竖坐标是精度的损失,每条彩色虚线表示的是网络中的一个卷积层。 -以不同的剪裁比例**单独**剪裁一个卷积层,并观察其在验证数据集上的精度损失,并绘出**图7**中的虚线。虚线上升较慢的,对应的卷积层相对不敏感,我们优先剪不敏感的卷积层的filter. - -#### 选择最优的剪裁率组合 - -我们将**图7**中的折线拟合为**图8**中的曲线,每在竖坐标轴上选取一个精度损失值,就在横坐标轴上对应着一组剪裁率,如**图8**中黑色实线所示。 -用户给定一个模型整体的剪裁率,我们通过移动**图5**中的黑色实线来找到一组满足条件的且合法的剪裁率。 - -

-
-图8 -

- -#### 迭代剪裁 -考虑到多个卷积层间的相关性,一个卷积层的修改可能会影响其它卷积层的敏感度,我们采取了多次剪裁的策略,步骤如下: - -- step1: 统计各卷积层的敏感度信息 -- step2: 根据当前统计的敏感度信息,对每个卷积层剪掉少量filter, 并统计FLOPS,如果FLOPS已满足要求,进入step4,否则进行step3。 -- step3: 对网络进行简单的fine-tune,进入step1 -- step4: fine-tune训练至收敛 - -## 3. 蒸馏 - - 一般情况下,模型参数量越多,结构越复杂,其性能越好,但参数也越允余,运算量和资源消耗也越大;模型蒸馏是将复杂网络中的有用信息将复杂网络中的有用信息提取出来提取出来,迁移到一个更小的网络中去,在我们的工具包中,支持两种蒸馏的方法。 - 第一种是传统的蒸馏方法(参考论文:[Distilling the Knowledge in a Neural Network](https://arxiv.org/pdf/1503.02531.pdf)) - 使用复杂的网络作为teacher模型去监督训练一个参数量和运算量更少的student模型。teacher模型可以是一个或者多个提前训练好的高性能模型。student模型的训练有两个目标:一个是原始的目标函数,为student模型输出的类别概率和label的交叉熵,记为hard-target;另一个是student模型输出的类别概率和teacher模型输出的类别概率的交叉熵,记为soft target,这两个loss加权后得到最终的训练loss,共同监督studuent模型的训练。 - 第二种是基于FSP的蒸馏方法(参考论文:[A Gift from Knowledge Distillation: Fast Optimization, Network Minimization and Transfer Learning](http://openaccess.thecvf.com/content_cvpr_2017/papers/Yim_A_Gift_From_CVPR_2017_paper.pdf)) - 相比传统的蒸馏方法直接用小模型去拟合大模型的输出,该方法用小模型去拟合大模型不同层特征之间的转换关系,其用一个FSP矩阵(特征的内积)来表示不同层特征之间的关系,大模型和小模型不同层之间分别获得多个FSP矩阵,然后使用L2 loss让小模型的对应层FSP矩阵和大模型对应层的FSP矩阵尽量一致,具体如下图所示。这种方法的优势,通俗的解释是,比如将蒸馏类比成teacher(大模型)教student(小模型)解决一个问题,传统的蒸馏是直接告诉小模型问题的答案,让小模型学习,而学习FSP矩阵是让小模型学习解决问题的中间过程和方法,因此其学到的信息更多。 - -

-
-图9 -

- - 由于小模型和大模型之间通过L2 loss进行监督,必须保证两个FSP矩阵的维度必须相同,而FSP矩阵的维度为M*N,其中M、N分别为输入和输出特征的channel数,因此大模型和小模型的FSP矩阵需要一一对应。 - -## 4. 轻量级模型结构搜索 - -深度学习模型在很多任务上都取得了不错的效果,网络结构的好坏对最终模型的效果有非常重要的影响。手工设计网络需要非常丰富的经验和众多尝试,并且众多的超参数和网络结构参数会产生爆炸性的组合,常规的random search几乎不可行,因此最近几年自动模型搜索技术(Neural Architecture Search)成为研究热点。区别于传统NAS,我们专注在搜索精度高并且速度快的模型结构,我们将该功能统称为Light-NAS. - -### 4.1 搜索策略 - -搜索策略定义了使用怎样的算法可以快速、准确找到最优的网络结构参数配置。常见的搜索方法包括:强化学习、贝叶斯优化、进化算法、基于梯度的算法。我们当前的实现以模拟退火算法为主。 - -#### 4.1.1 模拟退火 - -模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。 - -鉴于物理中固体物质的退火过程与一般组合优化问题之间的相似性,我们将其用于网络结构的搜索。 - -使用模拟退火算法搜索模型的过程如下: - -$$ -T_k = T_0*\theta^k -$$ - -$$ -\begin{equation} -P(r_k) = -\begin{cases} -e^{\frac{(r_k-r)}{T_k}} & r_k < r\\ -1 & r_k>=r -\end{cases} -\end{equation} -$$ - -在第k次迭代,搜到的网络为$N_k$, 对$N_k$训练若干epoch后,在测试集上得到reward为$r_k$, 以概率$P(r_k)$接受$r_k$,即执行$r=r_k$。$r$在搜索过程起始时被初始化为0. $T_0$为初始化温度,$\theta$为温度衰减系数,$T_k$为第k次迭代的温度。 - - -在我们的NAS任务中,区别于RL每次重新生成一个完整的网络,我们将网络结构映射成一段编码,第一次随机初始化,然后每次随机修改编码中的一部分(对应于网络结构的一部分)生成一个新的编码,然后将这个编码再映射回网络结构,通过在训练集上训练一定的epochs后的精度以及网络延时融合获得reward,来指导退火算法的收敛。 - - -### 4.2 搜索空间 - -搜索空间定义了优化问题的变量,变量规模决定了搜索算法的难度和搜索时间。因此为了加快搜索速度,定义一个合理的搜索空间至关重要。在Light-NAS中,为了加速搜索速度,我们将一个网络划分为多个block,先手动按链状层级结构堆叠c,再 使用搜索算法自动搜索每个block内部的结构。 - -因为要搜索出在移动端运行速度快的模型,我们参考了MobileNetV2中的Linear Bottlenecks和Inverted residuals结构,搜索每一个Inverted residuals中的具体参数,包括kernelsize、channel扩张倍数、重复次数、channels number。如图10所示: - -

-
-图10 -

- - -### 4.3 模型延时评估 - -搜索过程支持 FLOPS 约束和模型延时约束。而基于 Android/iOS 移动端、开发板等硬件平台,迭代搜索过程中不断测试模型的延时不仅消耗时间而且非常不方便,因此我们开发了模型延时评估器来评估搜索得到模型的延时。通过延时评估器评估得到的延时与模型实际测试的延时波动偏差小于 10%。 - -延时评估器分为配置硬件延时评估器和评估模型延时两个阶段,配置硬件延时评估器只需要执行一次,而评估模型延时则在搜索过程中不断评估搜索得到的模型延时。 - -- 配置硬件延时评估器 - - 1. 获取搜索空间中所有不重复的 op 及其参数 - 2. 获取每组 op 及其参数的延时 - -- 评估模型延时 - - 1. 获取给定模型的所有 op 及其参数 - 2. 根据给定模型的所有 op 及参数,利用延时评估器去估计模型的延时 - - -## 5. 参考文献 - -1. [High-Performance Hardware for Machine Learning](https://media.nips.cc/Conferences/2015/tutorialslides/Dally-NIPS-Tutorial-2015.pdf) - -2. [Quantizing deep convolutional networks for efficient inference: A whitepaper](https://arxiv.org/pdf/1806.08342.pdf) - -3. [Pruning Filters for Efficient ConvNets](https://arxiv.org/pdf/1608.08710.pdf) - -4. [Distilling the Knowledge in a Neural Network](https://arxiv.org/pdf/1503.02531.pdf) - -5. [A Gift from Knowledge Distillation: Fast Optimization, Network Minimization and Transfer Learning](http://openaccess.thecvf.com/content_cvpr_2017/papers/Yim_A_Gift_From_CVPR_2017_paper.pdf) diff --git a/docs/zh_cn/cv/detection/index.rst b/docs/zh_cn/cv/detection/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..7f37c415e3b735cbe36615765fb51669174104a6 --- /dev/null +++ b/docs/zh_cn/cv/detection/index.rst @@ -0,0 +1,9 @@ + +目标检测(PaddleDetection) +========================= + +.. toctree:: + :maxdepth: 1 + + dygraph/index + static/index diff --git a/docs/zh_cn/tutorials/static/index.rst b/docs/zh_cn/cv/detection/static/index.rst similarity index 64% rename from docs/zh_cn/tutorials/static/index.rst rename to docs/zh_cn/cv/detection/static/index.rst index 542cbb6d05cd4199d3e4eab793fbe70bb589b232..1d1bce77d12afea82120f27993e27b0f455f7f9a 100644 --- a/docs/zh_cn/tutorials/static/index.rst +++ b/docs/zh_cn/cv/detection/static/index.rst @@ -1,16 +1,13 @@ -静态图压缩教程 -============== +静态图 +========================= .. toctree:: :maxdepth: 1 - image_classification_sensitivity_analysis_tutorial.md - darts_nas_turorial.md paddledetection_slim_distillation_tutorial.md paddledetection_slim_nas_tutorial.md paddledetection_slim_pruing_tutorial.md paddledetection_slim_prune_dist_tutorial.md paddledetection_slim_quantization_tutorial.md - image_classification_mkldnn_quant_tutorial.md paddledetection_slim_sensitivy_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_distillation_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_distillation_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_distillation_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_distillation_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_nas_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_nas_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_nas_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_nas_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_pruing_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_pruing_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_pruing_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_pruing_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_prune_dist_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_prune_dist_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_prune_dist_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_prune_dist_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_quantization_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_quantization_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_quantization_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_quantization_tutorial.md diff --git a/docs/zh_cn/tutorials/static/paddledetection_slim_sensitivy_tutorial.md b/docs/zh_cn/cv/detection/static/paddledetection_slim_sensitivy_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/paddledetection_slim_sensitivy_tutorial.md rename to docs/zh_cn/cv/detection/static/paddledetection_slim_sensitivy_tutorial.md diff --git a/docs/zh_cn/cv/index.rst b/docs/zh_cn/cv/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..3a94091f7d76d01662ed09d12b4f93914e2dd267 --- /dev/null +++ b/docs/zh_cn/cv/index.rst @@ -0,0 +1,8 @@ + +CV模型压缩 +============== + +.. toctree:: + :maxdepth: 1 + + detection/index diff --git a/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_mobile_device.md b/docs/zh_cn/deploy/deploy_cls_model_on_mobile_device.md similarity index 100% rename from docs/zh_cn/tutorials/deploy/deploy_cls_model_on_mobile_device.md rename to docs/zh_cn/deploy/deploy_cls_model_on_mobile_device.md diff --git a/docs/zh_cn/deploy/deploy_cls_model_on_nvidia_gpu.md b/docs/zh_cn/deploy/deploy_cls_model_on_nvidia_gpu.md new file mode 120000 index 0000000000000000000000000000000000000000..3bb6cc51ee13aa6a533f40ccfc2b0a27781aa84d --- /dev/null +++ b/docs/zh_cn/deploy/deploy_cls_model_on_nvidia_gpu.md @@ -0,0 +1 @@ +../../../demo/quant/deploy/TensorRT/README.md \ No newline at end of file diff --git a/docs/zh_cn/deploy/deploy_cls_model_on_x86_cpu.md b/docs/zh_cn/deploy/deploy_cls_model_on_x86_cpu.md new file mode 120000 index 0000000000000000000000000000000000000000..0544352cecc23f7e0d078758056715554dc5f4a0 --- /dev/null +++ b/docs/zh_cn/deploy/deploy_cls_model_on_x86_cpu.md @@ -0,0 +1 @@ +../../../demo/mkldnn_quant/README.md \ No newline at end of file diff --git a/docs/zh_cn/deploy/index.rst b/docs/zh_cn/deploy/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..d5b2a08dc7729deb0257282e24ced288dd86180c --- /dev/null +++ b/docs/zh_cn/deploy/index.rst @@ -0,0 +1,13 @@ + +推理部署 +============== + +该部分介绍如何将PaddleSlim产出的量化模型部署到移动端、Intel CPU和Nvidia GPU上。 + +.. toctree:: + :maxdepth: 1 + + deploy_cls_model_on_mobile_device.md + deploy_cls_model_on_x86_cpu.md + deploy_cls_model_on_nvidia_gpu.md + diff --git a/docs/zh_cn/index.rst b/docs/zh_cn/index.rst index 8c6debe0a5e1768a3c1edeabbbcb43eb638bd496..58c067848f95b47c26c2727c1c80c5a7dedfa037 100644 --- a/docs/zh_cn/index.rst +++ b/docs/zh_cn/index.rst @@ -7,15 +7,19 @@ ================== .. toctree:: - :maxdepth: 1 + :maxdepth: 2 intro.md install.md quick_start/index tutorials/index + deploy/index + cv/index + nlp/index + models/index api_cn/index FAQ/index - model_zoo/index + model_zoo.md algo/algo.md CHANGELOG.md diff --git a/docs/zh_cn/install.md b/docs/zh_cn/install.md index cc39f6311692184532659bc302e252e5a59281ac..65daca5cae40bababfbd2c4e319cc22c64d146b2 100644 --- a/docs/zh_cn/install.md +++ b/docs/zh_cn/install.md @@ -1,23 +1,21 @@ -# 安装 - -安装PaddleSlim前,请确认已正确安装Paddle1.6版本或更新版本。Paddle安装请参考:[Paddle安装教程](https://www.paddlepaddle.org.cn/install/quick)。 - - -- 安装develop版本 +# 安装 +安装最新版本: ```bash -git clone https://github.com/PaddlePaddle/PaddleSlim.git -cd PaddleSlim -python setup.py install +pip install paddleslim -i https://pypi.tuna.tsinghua.edu.cn/simple ``` -- 安装官方发布的最新版本 - +安装指定版本: ```bash -pip install paddleslim -i https://pypi.org/simple +pip install paddleslim=2.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple ``` -- 安装历史版本 +## 版本对齐 -请点击[pypi.org](https://pypi.org/project/paddleslim/#history)查看可安装历史版本。 +| PaddleSlim | PaddlePaddle | PaddleLite | 备注 | +| :-----------: | :------------: | :------------:| :----------:| +| 1.0.1 | <=1.7 | 2.7 | 支持静态图 | +| 1.1.1 | 1.8 | 2.7 | 支持静态图 | +| 1.2.0 | 2.0Beta/RC | 2.8 | 支持静态图 | +| 2.0.0 | 2.0 | 2.8 | 支持动态图和静态图 | diff --git a/docs/zh_cn/intro.md b/docs/zh_cn/intro.md index 814f1eeef837c0400abfdf1c6264114bb9c5b3c2..e84cd4f2b97d57de2b3233d4cfdbbe274e344758 100644 --- a/docs/zh_cn/intro.md +++ b/docs/zh_cn/intro.md @@ -1,77 +1,90 @@ -# 介绍 - -PaddleSlim是一个模型压缩工具库,包含模型剪裁、定点量化、知识蒸馏、超参搜索和模型结构搜索等一系列模型压缩策略。 - -对于业务用户,PaddleSlim提供完整的模型压缩解决方案,可用于图像分类、检测、分割等各种类型的视觉场景。 -同时也在持续探索NLP领域模型的压缩方案。另外,PaddleSlim提供且在不断完善各种压缩策略在经典开源任务的benchmark, -以便业务用户参考。 - -对于模型压缩算法研究者或开发者,PaddleSlim提供各种压缩策略的底层辅助接口,方便用户复现、调研和使用最新论文方法。 -PaddleSlim会从底层能力、技术咨询合作和业务场景等角度支持开发者进行模型压缩策略相关的创新工作。 - - -## 功能 - -- 模型剪裁 - - 卷积通道均匀剪裁 - - 基于敏感度的卷积通道剪裁 - - 基于进化算法的自动剪裁 - -- 定点量化 - - 在线量化训练(training aware) - - 静态离线量化(static post training) - - 动态离线量化(dynamic post training) - -- 知识蒸馏 - - 支持单进程知识蒸馏 - - 支持多进程分布式知识蒸馏 - -- 神经网络结构自动搜索(NAS) - - 支持基于进化算法的轻量神经网络结构自动搜索 - - 支持One-Shot网络结构自动搜索 - - 支持基于梯度的DARTS网络结构自动搜索 - - 支持 FLOPS / 硬件延时约束 - - 支持多平台模型延时评估 - - 支持用户自定义搜索算法和搜索空间 - - -## 部分压缩策略效果 - -### 分类模型 - -数据: ImageNet2012; 模型: MobileNetV1; - -|压缩策略 |精度收益(baseline: 70.91%) |模型大小(baseline: 17.0M)| -|:---:|:---:|:---:| -| 知识蒸馏(ResNet50)| **+1.06%** | | -| 知识蒸馏(ResNet50) + int8量化训练 |**+1.10%**| **-71.76%**| -| 剪裁(FLOPs-50%) + int8量化训练|**-1.71%**|**-86.47%**| - - -### 图像检测模型 - -#### 数据:Pascal VOC;模型:MobileNet-V1-YOLOv3 - -| 压缩方法 | mAP(baseline: 76.2%) | 模型大小(baseline: 94MB) | -| :---------------------: | :------------: | :------------:| -| 知识蒸馏(ResNet34-YOLOv3) | **+2.8%** | | -| 剪裁 FLOPs -52.88% | **+1.4%** | **-67.76%** | -|知识蒸馏(ResNet34-YOLOv3)+剪裁(FLOPs-69.57%)| **+2.6%**|**-67.00%**| - - -#### 数据:COCO;模型:MobileNet-V1-YOLOv3 - -| 压缩方法 | mAP(baseline: 29.3%) | 模型大小| -| :---------------------: | :------------: | :------:| -| 知识蒸馏(ResNet34-YOLOv3) | **+2.1%** | | -| 知识蒸馏(ResNet34-YOLOv3)+剪裁(FLOPs-67.56%) | **-0.3%** | **-66.90%**| - -### 搜索 - -数据:ImageNet2012; 模型:MobileNetV2 - -|硬件环境 | 推理耗时 | Top1准确率(baseline:71.90%) | -|:---------------:|:---------:|:--------------------:| -| RK3288 | **-23%** | +0.07% | -| Android cellphone | **-20%** | +0.16% | -| iPhone 6s | **-17%** | +0.32% | +# 简介 + +PaddleSlim是一个专注于深度学习模型压缩的工具库,提供**剪裁、量化、蒸馏、和模型结构搜索**等模型压缩策略,帮助用户快速实现模型的小型化。 + +## 版本对齐 + +| PaddleSlim | PaddlePaddle | PaddleLite | 备注 | +| :-----------: | :------------: | :------------:| :----------:| +| 1.0.1 | <=1.7 | 2.7 | 支持静态图 | +| 1.1.1 | 1.8 | 2.7 | 支持静态图 | +| 1.2.0 | 2.0Beta/RC | 2.8 | 支持静态图 | +| 2.0.0 | 2.0 | 2.8 | 支持动态图和静态图 | + + +## 最近更新 + +- 2021.2.5: 发布V2.0.0版本,新增支持动态图,新增OFA压缩功能,优化剪枝功能。 + +- 2020.9.16: 发布V1.2.0版本,新增PACT量化训练功能,新增DML(互蒸馏功能),修复部分剪裁bug,加强对depthwise_conv2d的剪裁能力,优化剪裁和量化API的易用性和灵活性。 + +## 功能概览 + +PaddleSlim支持以下功能,也支持自定义量化、裁剪等功能。 + + + + + + + + + + + + + + +
QuantizationPruningNASDistilling
+
    +
  • QAT
  • +
  • PACT
  • +
  • PTQ-Static
  • +
  • PTQ-Dynamic
  • +
  • Embedding Quant
  • +
+
+
    +
  • SensitivityPruner
  • +
  • FPGMFilterPruner
  • +
  • L1NormFilterPruner
  • +
  • L2NormFilterPruner
  • +
  • *SlimFilterPruner
  • +
  • *OptSlimFilterPruner
  • +
+
+
    +
  • *Simulate Anneal based NAS
  • +
  • *Reinforcement Learning based NAS
  • +
  • **DARTS
  • +
  • **PC-DARTS
  • +
  • **Once-for-All
  • +
  • *Hardware-aware Search
  • +
+
+
    +
  • *FSP
  • +
  • *DML
  • +
  • *DK for YOLOv3
  • +
+
+ +注:*表示仅支持静态图,**表示仅支持动态图 + +### 效果展示 + +PaddleSlim在典型视觉和自然语言处理任务上做了模型压缩,并且测试了Nvidia GPU、ARM等设备上的加速情况,这里展示部分模型的压缩效果,详细方案可以参考下面CV和NLP模型压缩方案: + +

+
+表1: 部分模型压缩加速情况 +

+ +注: +- YOLOv3: 在移动端SD855上加速3.55倍。 +- PP-OCR: 体积由8.9M减少到2.9M, 在SD855上加速1.27倍。 +- BERT: 模型参数由110M减少到80M,精度提升的情况下,Tesla T4 GPU FP16计算加速1.47倍。 + +## 许可证书 + +本项目的发布受[Apache 2.0 license](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/LICENSE)许可认证。 diff --git a/docs/zh_cn/model_zoo/distillation_model_zoo.md b/docs/zh_cn/model_zoo/distillation_model_zoo.md deleted file mode 100644 index bba7a41d2334fa5292cb7f97c3ba3708ff316f3e..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/distillation_model_zoo.md +++ /dev/null @@ -1 +0,0 @@ -# 蒸馏模型库 diff --git a/docs/zh_cn/model_zoo/index.rst b/docs/zh_cn/model_zoo/index.rst deleted file mode 100644 index d38a3ac11934ddf98cef5e5787b4de7c5b46bc85..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/index.rst +++ /dev/null @@ -1,13 +0,0 @@ - -模型库 -======== - -.. toctree:: - :maxdepth: 1 - - model_zoo.md - quant_model_zoo.md - distillation_model_zoo.md - prune_model_zoo.md - nas_model_zoo.md - diff --git a/docs/zh_cn/model_zoo/model_zoo.md b/docs/zh_cn/model_zoo/model_zoo.md deleted file mode 100644 index a990f4db22e28fa327f355fa2af6a8ee892fcc9b..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/model_zoo.md +++ /dev/null @@ -1,27 +0,0 @@ -## 模型库概览 - -### 量化主要结论 - -| 任务 | 模型 | 数据集 | 结论 | 更多细节和模型下载 | -|:--:|:---:|:--:|:--:|:--:| -| 分类| MobileNetV1 | ImageNet | top1 -0.39%
高通835 1.6-2倍加速
高通855 armv8 2倍加速
麒麟970 1.6-2倍加速 |[详细数据和模型下载]() | - -### 蒸馏主要结论 - -| 任务 | 模型 | 数据集 | 结论 | 更多细节和模型下载 | -|:--:|:---:|:--:|:--:|:--:| -| 分类| MobileNetV1 | ImageNet | top1 -0.39%
高通835 1.6-2倍加速
高通855 armv8 2倍加速
麒麟970 1.6-2倍加速 |[详细数据和模型下载]() | - -### 剪裁主要结论 - - -| 任务 | 模型 | 数据集 | 结论 | 更多细节和模型下载 | -|:--:|:---:|:--:|:--:|:--:| -| 分类| MobileNetV1 | ImageNet | top1 -0.39%
高通835 1.6-2倍加速
高通855 armv8 2倍加速
麒麟970 1.6-2倍加速 |[详细数据和模型下载]() | - -### nas 主要结论 - - -| 任务 | 模型 | 数据集 | 结论 | 更多细节和模型下载 | -|:--:|:---:|:--:|:--:|:--:| -| 分类| MobileNetV1 | ImageNet | top1 -0.39%
高通835 1.6-2倍加速
高通855 armv8 2倍加速
麒麟970 1.6-2倍加速 |[详细数据和模型下载]() | diff --git a/docs/zh_cn/model_zoo/nas_model_zoo.md b/docs/zh_cn/model_zoo/nas_model_zoo.md deleted file mode 100644 index f924d4167f0045878343d0afa9647b1bd0605144..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/nas_model_zoo.md +++ /dev/null @@ -1 +0,0 @@ -# 模型结构搜索模型库 diff --git a/docs/zh_cn/model_zoo/prune_model_zoo.md b/docs/zh_cn/model_zoo/prune_model_zoo.md deleted file mode 100644 index c9e4c16f193923b838cf220317a3cef8f4693570..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/prune_model_zoo.md +++ /dev/null @@ -1 +0,0 @@ -# 剪裁模型库 diff --git a/docs/zh_cn/model_zoo/quant_model_zoo.md b/docs/zh_cn/model_zoo/quant_model_zoo.md deleted file mode 100644 index c5062253a7ac12032e3b2e6df38d25758cc7fd10..0000000000000000000000000000000000000000 --- a/docs/zh_cn/model_zoo/quant_model_zoo.md +++ /dev/null @@ -1 +0,0 @@ -# 量化模型库 diff --git a/docs/zh_cn/models/index.rst b/docs/zh_cn/models/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..36c606bd6b467bbfcb285bca67e09562e6fdcdad --- /dev/null +++ b/docs/zh_cn/models/index.rst @@ -0,0 +1,8 @@ + +通用轻量级模型 +============== + +.. toctree:: + :maxdepth: 1 + + slimfacenet.md diff --git a/docs/zh_cn/models/slimfacenet.md b/docs/zh_cn/models/slimfacenet.md new file mode 120000 index 0000000000000000000000000000000000000000..cf8c49f7bf06571803145cacfcedc72e098b82d4 --- /dev/null +++ b/docs/zh_cn/models/slimfacenet.md @@ -0,0 +1 @@ +../../../demo/slimfacenet/README.md \ No newline at end of file diff --git a/docs/zh_cn/tutorials/nas/ernie_slim_ofa_tutorial.md b/docs/zh_cn/nlp/ernie_slim_ofa_tutorial.md similarity index 98% rename from docs/zh_cn/tutorials/nas/ernie_slim_ofa_tutorial.md rename to docs/zh_cn/nlp/ernie_slim_ofa_tutorial.md index 33630c82adcc3c25a1dcbd57f24270954d99bcf0..f76342951597fe5d97e0d3df832193c01fb514e5 100644 --- a/docs/zh_cn/tutorials/nas/ernie_slim_ofa_tutorial.md +++ b/docs/zh_cn/nlp/ernie_slim_ofa_tutorial.md @@ -13,10 +13,8 @@ 4. 每个batch数据在训练前首先中会选择当前要训练的子网络配置(子网络配置目前仅包括对整个模型的宽度的选择),参数更新时仅会更新当前子网络计算中用到的那部分参数。 5. 通过以上的方式来优化整个超网络参数,训练完成后选择满足加速要求和精度要求的子模型。 -

-
-整体流程图 -

+![](./images/ofa_bert.png) +
整体流程
## 基于ERNIE repo代码进行压缩 本教程基于PaddleSlim2.0及之后版本、Paddle1.8.5和ERNIE 0.0.4dev及之后版本,请确认已正确安装Paddle、PaddleSlim和ERNIE。 diff --git a/docs/zh_cn/nlp/images/ofa_bert.png b/docs/zh_cn/nlp/images/ofa_bert.png new file mode 100644 index 0000000000000000000000000000000000000000..650eafdeab5be09c3c734eaafc6f573be937f5c8 Binary files /dev/null and b/docs/zh_cn/nlp/images/ofa_bert.png differ diff --git a/docs/zh_cn/nlp/index.rst b/docs/zh_cn/nlp/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..5985b298c2544424102679df6faf0fca38a46d7c --- /dev/null +++ b/docs/zh_cn/nlp/index.rst @@ -0,0 +1,9 @@ + +NLP模型压缩 +============== + +.. toctree:: + :maxdepth: 1 + + ernie_slim_ofa_tutorial.md + paddlenlp_slim_ofa_tutorial.md diff --git a/docs/zh_cn/tutorials/nas/paddlenlp_slim_ofa_tutorial.md b/docs/zh_cn/nlp/paddlenlp_slim_ofa_tutorial.md similarity index 97% rename from docs/zh_cn/tutorials/nas/paddlenlp_slim_ofa_tutorial.md rename to docs/zh_cn/nlp/paddlenlp_slim_ofa_tutorial.md index aea31974128f5240908de4e005b771917cffcf26..29779cc615dab5b1b85df69de5df9520a379ea00 100644 --- a/docs/zh_cn/tutorials/nas/paddlenlp_slim_ofa_tutorial.md +++ b/docs/zh_cn/nlp/paddlenlp_slim_ofa_tutorial.md @@ -13,10 +13,9 @@ 4. 每个batch数据在训练前首先中会选择当前要训练的子网络配置(子网络配置目前仅包括对整个模型的宽度的选择),参数更新时仅会更新当前子网络计算中用到的那部分参数。 5. 通过以上的方式来优化整个超网络参数,训练完成后选择满足加速要求和精度要求的子模型。 -

-
-整体流程图 -

+![](./images/ofa_bert.png) +
整体流程
+ ## 基于PaddleNLP repo代码进行压缩 本教程基于PaddleSlim2.0及之后版本、Paddle2.0rc1及之后版本和PaddleNLP2.0beta及之后版本,请确认已正确安装Paddle、PaddleSlim和PaddleNLP。 diff --git a/docs/zh_cn/quick_start/dygraph_pruning_tutorial.md b/docs/zh_cn/quick_start/dygraph/dygraph_pruning_tutorial.md similarity index 89% rename from docs/zh_cn/quick_start/dygraph_pruning_tutorial.md rename to docs/zh_cn/quick_start/dygraph/dygraph_pruning_tutorial.md index 440aa84ba5750f9e73b7d7c9fb53e423302d6251..a34bd97a42bbf99048dda92f9879f850b3587707 100644 --- a/docs/zh_cn/quick_start/dygraph_pruning_tutorial.md +++ b/docs/zh_cn/quick_start/dygraph/dygraph_pruning_tutorial.md @@ -1,6 +1,6 @@ -# 图像分类模型通道剪裁-快速开始 +# 卷积Filter剪裁 -该教程以图像分类模型MobileNetV1为例,说明如何快速使用[PaddleSlim的卷积通道剪裁接口](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/dygraph_docs)。 +该教程以图像分类模型MobileNetV1为例,说明如何快速使用[PaddleSlim的卷积通道剪裁接口]()。 该示例包含以下步骤: 1. 导入依赖 @@ -27,7 +27,7 @@ from paddleslim.dygraph import L1NormFilterPruner ## 2. 构建网络和数据集 该章节构造一个用于对CIFAR10数据进行分类的分类模型,选用`MobileNetV1`,并将输入大小设置为`[3, 32, 32]`,输出类别数为10。 -为了方便展示示例,我们使用Paddle提供的[预定义分类模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/vision/models/mobilenetv1/MobileNetV1_cn.html#mobilenetv1)和[高层API](https://www.paddlepaddle.org.cn/documentation/docs/zh/2.0-rc1/tutorial/quick_start/high_level_api/high_level_api.html),执行以下代码构建分类模型: +为了方便展示示例,我们使用Paddle提供的[预定义分类模型](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/vision/models/mobilenetv1/MobileNetV1_cn.html#mobilenetv1)和[高层API](),执行以下代码构建分类模型: ``` net = models.mobilenet_v1(pretrained=False, scale=1.0, num_classes=10) diff --git a/docs/zh_cn/quick_start/dygraph_quant_aware_training_tutorial.md b/docs/zh_cn/quick_start/dygraph/dygraph_quant_aware_training_tutorial.md similarity index 98% rename from docs/zh_cn/quick_start/dygraph_quant_aware_training_tutorial.md rename to docs/zh_cn/quick_start/dygraph/dygraph_quant_aware_training_tutorial.md index 45fee3c02180cc6594b451f621b765cca96a5af1..1eab3af94548ae7d00fbbfb0d6c3e8b6d3b31baa 100644 --- a/docs/zh_cn/quick_start/dygraph_quant_aware_training_tutorial.md +++ b/docs/zh_cn/quick_start/dygraph/dygraph_quant_aware_training_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类模型量化训练-快速开始 +# 量化训练 量化训练要解决的问题是将FP32浮点数量化成INT8整数进行存储和计算,通过在训练中建模量化对模型的影响,降低量化误差。 diff --git a/docs/zh_cn/quick_start/dygraph_quant_post_tutorial.md b/docs/zh_cn/quick_start/dygraph/dygraph_quant_post_tutorial.md similarity index 98% rename from docs/zh_cn/quick_start/dygraph_quant_post_tutorial.md rename to docs/zh_cn/quick_start/dygraph/dygraph_quant_post_tutorial.md index a6f7e5ce9cbf62c7834e695541f3b6738b88a075..2f3b13de7e39c5269ce635bc7dd329e140a41151 100644 --- a/docs/zh_cn/quick_start/dygraph_quant_post_tutorial.md +++ b/docs/zh_cn/quick_start/dygraph/dygraph_quant_post_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类模型离线量化-快速开始 +# 离线量化 离线量化又称为训练后量化,仅需要使用少量校准数据,确定最佳的量化参数降低量化误差。这种方法需要的数据量较少,但量化模型精度相比在线量化稍逊。 diff --git a/docs/zh_cn/quick_start/dygraph/index.rst b/docs/zh_cn/quick_start/dygraph/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..637ed8931b26d0b30110952e8e0021fa625e3d27 --- /dev/null +++ b/docs/zh_cn/quick_start/dygraph/index.rst @@ -0,0 +1,10 @@ + +动态图 +============== + +.. toctree:: + :maxdepth: 1 + + dygraph_pruning_tutorial.md + dygraph_quant_aware_training_tutorial.md + dygraph_quant_post_tutorial.md diff --git a/docs/zh_cn/quick_start/index.rst b/docs/zh_cn/quick_start/index.rst index f934bb21398abdbb42b7a5054757a7bdad2ab1eb..6602c10fa93bd4b821832e0faa2dd583db75de26 100644 --- a/docs/zh_cn/quick_start/index.rst +++ b/docs/zh_cn/quick_start/index.rst @@ -4,8 +4,7 @@ .. toctree:: :maxdepth: 1 + static/index.rst - dygraph_pruning_tutorial.md - dygraph_quant_aware_training_tutorial.md - dygraph_quant_post_tutorial.md + dygraph/index.rst diff --git a/docs/zh_cn/quick_start/static/distillation_tutorial.md b/docs/zh_cn/quick_start/static/distillation_tutorial.md index 6a55a1574718e90d7d3a839427b9aaa8dcef986a..17d5341dd288371810eee94d4c8199553f87dfa1 100755 --- a/docs/zh_cn/quick_start/static/distillation_tutorial.md +++ b/docs/zh_cn/quick_start/static/distillation_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类模型知识蒸馏-快速开始 +# 知识蒸馏 该教程以图像分类模型MobileNetV1为例,说明如何快速使用[PaddleSlim的知识蒸馏接口](https://paddlepaddle.github.io/PaddleSlim/api/single_distiller_api/)。 该示例包含以下步骤: diff --git a/docs/zh_cn/quick_start/static/index.rst b/docs/zh_cn/quick_start/static/index.rst index e1c5369766c7b5bb42fa6e63e9b0a4a0a3d8fc38..0380c9918f968e81d031de442f75ab3c95c749de 100644 --- a/docs/zh_cn/quick_start/static/index.rst +++ b/docs/zh_cn/quick_start/static/index.rst @@ -1,5 +1,5 @@ -静态图快速开始 +静态图 ============== .. toctree:: diff --git a/docs/zh_cn/quick_start/static/nas_tutorial.md b/docs/zh_cn/quick_start/static/nas_tutorial.md index a7225c75fbc988a7e47ac1b3fdf088da3c3ea2bb..c1d07ab5e8d3810c54da007452950cd36eb7e150 100644 --- a/docs/zh_cn/quick_start/static/nas_tutorial.md +++ b/docs/zh_cn/quick_start/static/nas_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类网络结构搜索-快速开始 +# 网络结构搜索 该教程以图像分类模型MobileNetV2为例,说明如何在cifar10数据集上快速使用[网络结构搜索接口](../api/nas_api.md)。 该示例包含以下步骤: diff --git a/docs/zh_cn/quick_start/static/pruning_tutorial.md b/docs/zh_cn/quick_start/static/pruning_tutorial.md index 38d7af804fc77a12e9f30df2df924afcbf513579..c4b47ea86edec9e2a340496358415129d4c33482 100755 --- a/docs/zh_cn/quick_start/static/pruning_tutorial.md +++ b/docs/zh_cn/quick_start/static/pruning_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类模型通道剪裁-快速开始 +# 卷积Filter剪裁 该教程以图像分类模型MobileNetV1为例,说明如何快速使用[PaddleSlim的卷积通道剪裁接口]()。 该示例包含以下步骤: diff --git a/docs/zh_cn/quick_start/static/quant_aware_tutorial.md b/docs/zh_cn/quick_start/static/quant_aware_tutorial.md index 8c87e6f88ea33c1ae824f2f0eee574468118fa28..3826a7d192f0131c5c97f6e9c0b4053e17059eba 100644 --- a/docs/zh_cn/quick_start/static/quant_aware_tutorial.md +++ b/docs/zh_cn/quick_start/static/quant_aware_tutorial.md @@ -1,6 +1,6 @@ -# 图像分类模型量化训练-快速开始 +# 量化训练 -该教程以图像分类模型MobileNetV1为例,说明如何快速使用PaddleSlim的[量化训练接口](../api_cn/quantization_api.html)。 该示例包含以下步骤: +该教程以图像分类模型MobileNetV1为例,说明如何快速使用PaddleSlim的量化训练接口。 该示例包含以下步骤: 1. 导入依赖 2. 构建模型 @@ -128,7 +128,7 @@ test(val_program) ## 4. 量化 -按照[默认配置](https://paddlepaddle.github.io/PaddleSlim/api_cn/quantization_api.html#id2)在``train_program``和``val_program``中加入量化和反量化op. +按照[默认配置]()在``train_program``和``val_program``中加入量化和反量化op. ```python @@ -156,7 +156,7 @@ test(val_quant_program) ## 6. 保存量化后的模型 -在``4. 量化``中使用接口``slim.quant.quant_aware``接口得到的模型只适合训练时使用,为了得到最终使用时的模型,需要使用[slim.quant.convert](https://paddlepaddle.github.io/PaddleSlim/api_cn/quantization_api.html#convert)接口,然后使用[fluid.io.save_inference_model](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/io_cn/save_inference_model_cn.html#save-inference-model)保存模型。``float_prog``的参数数据类型是float32,但是数据范围是int8, 保存之后可使用fluid或者paddle-lite加载使用,paddle-lite在使用时,会先将类型转换为int8。``int8_prog``的参数数据类型是int8, 保存后可看到量化后模型大小,不可加载使用。 +在``4. 量化``中使用接口``slim.quant.quant_aware``接口得到的模型只适合训练时使用,为了得到最终使用时的模型,需要使用[slim.quant.convert]()接口,然后使用[fluid.io.save_inference_model]()保存模型。``float_prog``的参数数据类型是float32,但是数据范围是int8, 保存之后可使用fluid或者paddle-lite加载使用,paddle-lite在使用时,会先将类型转换为int8。``int8_prog``的参数数据类型是int8, 保存后可看到量化后模型大小,不可加载使用。 ```python diff --git a/docs/zh_cn/quick_start/static/quant_post_static_tutorial.md b/docs/zh_cn/quick_start/static/quant_post_static_tutorial.md index 7658ac0e5b94ab7a9f1b129b38766923c6b8d19a..0144b9986c11176a3fcfa118874194baa5eedd33 100755 --- a/docs/zh_cn/quick_start/static/quant_post_static_tutorial.md +++ b/docs/zh_cn/quick_start/static/quant_post_static_tutorial.md @@ -1,6 +1,6 @@ - # 图像分类模型静态离线量化-快速开始 + # 离线量化 -该教程以图像分类模型MobileNetV1为例,说明如何快速使用PaddleSlim的[静态离线量化接口](../api_cn/quantization_api.html#quant-post-static)。 该示例包含以下步骤: +该教程以图像分类模型MobileNetV1为例,说明如何快速使用PaddleSlim的[静态离线量化接口]()。 该示例包含以下步骤: 1. 导入依赖 2. 构建模型 diff --git a/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_nvidia_gpu.md b/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_nvidia_gpu.md deleted file mode 120000 index 2076017725ef5c736dc656b55f0186bdacd60e6c..0000000000000000000000000000000000000000 --- a/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_nvidia_gpu.md +++ /dev/null @@ -1 +0,0 @@ -../../../../demo/quant/deploy/TensorRT/README.md \ No newline at end of file diff --git a/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_x86_cpu.md b/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_x86_cpu.md deleted file mode 120000 index ce45d15f41ffe36400e31f5e8b92349ac1afb17a..0000000000000000000000000000000000000000 --- a/docs/zh_cn/tutorials/deploy/deploy_cls_model_on_x86_cpu.md +++ /dev/null @@ -1 +0,0 @@ -../../../../demo/mkldnn_quant/README.md \ No newline at end of file diff --git a/docs/zh_cn/tutorials/index.rst b/docs/zh_cn/tutorials/index.rst index 9d1ea074583532e0fb1bba4ee73cd226ea849d41..dfabe4ab22f67a3c3a93efc7870375cf81b94159 100644 --- a/docs/zh_cn/tutorials/index.rst +++ b/docs/zh_cn/tutorials/index.rst @@ -1,8 +1,12 @@ -压缩教程 +高阶教程 ============== +该部分包括各个策略的综述与详细教程。 + .. toctree:: :maxdepth: 1 - static/index.rst + pruning/index + nas/index + quant/index diff --git a/docs/zh_cn/tutorials/nas/dygraph/index.rst b/docs/zh_cn/tutorials/nas/dygraph/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..aa8026bdd87cb04a3cc4137621ced88fcbcc6f90 --- /dev/null +++ b/docs/zh_cn/tutorials/nas/dygraph/index.rst @@ -0,0 +1,8 @@ + +动态图 +============== + +.. toctree:: + :maxdepth: 1 + + nas_ofa.md diff --git a/docs/zh_cn/tutorials/nas/nas_ofa.md b/docs/zh_cn/tutorials/nas/dygraph/nas_ofa.md similarity index 99% rename from docs/zh_cn/tutorials/nas/nas_ofa.md rename to docs/zh_cn/tutorials/nas/dygraph/nas_ofa.md index 7df1d6f2af1eaaabf882a0e40dd9e1f834917772..2203dc7fa0a1f269e13b7beb46c868873e948a19 100644 --- a/docs/zh_cn/tutorials/nas/nas_ofa.md +++ b/docs/zh_cn/tutorials/nas/dygraph/nas_ofa.md @@ -1,4 +1,4 @@ -# Once-For-All +# OFA详细教程   [Once-For-All(以下简称OFA)](https://arxiv.org/abs/1908.09791)主要的目的是训练一个超网络,根据不同的硬件从超网络中选择满足时延要求和精度要求的小模型。可以基于已有的预训练模型进行压缩也是OFA一个很大的优势。   为了防止子网络之间互相干扰,本论文提出了一种Progressive Shrinking(PS)的模式进行超网络训练,逐步从大型子网络到小型子网络进行训练。首先是从最大的子网络开始训练,例如:超网络包含可变的卷积核大小 kernel_size = {3, 5, 7},可变的网络结构深度 depth = {2, 3, 4} 和可变的网络的宽度 expand_ratio = {2, 4, 6},则训练卷积核为7、深度为4,宽度为6的网络。之后逐步将其添加到搜索空间中来逐步调整网络以支持较小的子网络。具体来说,在训练了最大的网络之后,我们首先支持可变卷积核大小,可以在{3,5,7}中进行选择,而深度和宽度则保持最大值。然后,我们依次支持可变深度和可变宽度。 diff --git a/docs/zh_cn/tutorials/nas/index.rst b/docs/zh_cn/tutorials/nas/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..1fb0d80df2c31ca9336eafa211508909f593504e --- /dev/null +++ b/docs/zh_cn/tutorials/nas/index.rst @@ -0,0 +1,10 @@ + +NAS +============== + +.. toctree:: + :maxdepth: 1 + + overview.md + dygraph/index + static/index diff --git a/docs/zh_cn/tutorials/nas/nas_overview.md b/docs/zh_cn/tutorials/nas/overview.md similarity index 98% rename from docs/zh_cn/tutorials/nas/nas_overview.md rename to docs/zh_cn/tutorials/nas/overview.md index f4aea6da764c03374628fe865cccd37a72b377ad..828861619aef82ffdbd6426b49b4a2679cf52420 100644 --- a/docs/zh_cn/tutorials/nas/nas_overview.md +++ b/docs/zh_cn/tutorials/nas/overview.md @@ -1,4 +1,4 @@ -# PaddleSlim模型结构搜索总览 +# Overview PaddleSlim提供了4种网络结构搜索的方法:基于模拟退火进行网络结构搜索、基于强化学习进行网络结构搜索、基于梯度进行网络结构搜索和Once-For-All。 @@ -10,7 +10,7 @@ PaddleSlim提供了4种网络结构搜索的方法:基于模拟退火进行网 | [DARTS/PCDARTS](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/zh_cn/api_cn/dygraph/nas/darts.rst) | DARTS是基于梯度进行网络结构搜索,这种方式比较高效,大大减少了搜索时间和所需要的机器资源。 |DARTS、PCDARTS、ProxylessNAS| -# 参考文献 +## 参考文献 [1] H. Cai, C. Gan, T. Wang, Z. Zhang, and S. Han. Once for all: Train one network and specialize it for efficient deployment. In International Conference on Learning Representations, 2020. [2] Pham, H.; Guan, M. Y.; Zoph, B.; Le, Q. V.; and Dean, J. 2018. Efficient neural architecture search via parameter sharing. arXiv preprint arXiv:1802.03268. [3] Zoph B, Vasudevan V, Shlens J, et al. Learning transferable architectures for scalable image recognition[J]. arXiv preprint arXiv:1707.07012, 2017, 2(6). diff --git a/docs/zh_cn/tutorials/nas/static/index.rst b/docs/zh_cn/tutorials/nas/static/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..f1136899bbaecd263992e1322dd7ed2c990ed417 --- /dev/null +++ b/docs/zh_cn/tutorials/nas/static/index.rst @@ -0,0 +1,8 @@ + +静态图 +============== + +.. toctree:: + :maxdepth: 1 + + sanas_darts_space.md diff --git a/docs/zh_cn/tutorials/static/sanas_darts_space.md b/docs/zh_cn/tutorials/nas/static/sanas_darts_space.md similarity index 100% rename from docs/zh_cn/tutorials/static/sanas_darts_space.md rename to docs/zh_cn/tutorials/nas/static/sanas_darts_space.md diff --git a/docs/zh_cn/tutorials/pruning/FPGM/weight_dist.png b/docs/zh_cn/tutorials/pruning/dygraph/FPGM/weight_dist.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/FPGM/weight_dist.png rename to docs/zh_cn/tutorials/pruning/dygraph/FPGM/weight_dist.png diff --git a/docs/zh_cn/tutorials/pruning/filter_pruning.md b/docs/zh_cn/tutorials/pruning/dygraph/filter_pruning.md similarity index 99% rename from docs/zh_cn/tutorials/pruning/filter_pruning.md rename to docs/zh_cn/tutorials/pruning/dygraph/filter_pruning.md index f5a8a72480b44c23737d8a8f2ab891fa3129fb80..f266ecb2ca761298c118b559af4abdbfdafcca19 100644 --- a/docs/zh_cn/tutorials/pruning/filter_pruning.md +++ b/docs/zh_cn/tutorials/pruning/dygraph/filter_pruning.md @@ -1,4 +1,4 @@ -# Paddle动态图卷积模型Filter剪裁教程 +# Filter剪裁详细教程 该教程以MobileNetV1模型和Cifar10分类任务为例,介绍如何使用PaddleSlim对动态图卷积模型进行filter剪裁。 diff --git a/docs/zh_cn/tutorials/pruning/filter_pruning/4-1.png b/docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-1.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/filter_pruning/4-1.png rename to docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-1.png diff --git a/docs/zh_cn/tutorials/pruning/filter_pruning/4-2.png b/docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-2.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/filter_pruning/4-2.png rename to docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-2.png diff --git a/docs/zh_cn/tutorials/pruning/filter_pruning/4-3.png b/docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-3.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/filter_pruning/4-3.png rename to docs/zh_cn/tutorials/pruning/dygraph/filter_pruning/4-3.png diff --git a/docs/zh_cn/tutorials/pruning/dygraph/index.rst b/docs/zh_cn/tutorials/pruning/dygraph/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..86b4b17dd97179fb29d2f09fe74da3bc8507d430 --- /dev/null +++ b/docs/zh_cn/tutorials/pruning/dygraph/index.rst @@ -0,0 +1,9 @@ + +动态图 +============== + +.. toctree:: + :maxdepth: 1 + + filter_pruning.md + self_defined_filter_pruning.md diff --git a/docs/zh_cn/tutorials/pruning/self_define_filter_pruning/1-1.png b/docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/1-1.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/self_define_filter_pruning/1-1.png rename to docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/1-1.png diff --git a/docs/zh_cn/tutorials/pruning/self_define_filter_pruning/1-2.png b/docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/1-2.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/self_define_filter_pruning/1-2.png rename to docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/1-2.png diff --git a/docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-1.png b/docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-1.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-1.png rename to docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-1.png diff --git a/docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-2.png b/docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-2.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-2.png rename to docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-2.png diff --git a/docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-3.png b/docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-3.png similarity index 100% rename from docs/zh_cn/tutorials/pruning/self_define_filter_pruning/4-3.png rename to docs/zh_cn/tutorials/pruning/dygraph/self_define_filter_pruning/4-3.png diff --git a/docs/zh_cn/tutorials/pruning/self_defined_filter_pruning.md b/docs/zh_cn/tutorials/pruning/dygraph/self_defined_filter_pruning.md similarity index 99% rename from docs/zh_cn/tutorials/pruning/self_defined_filter_pruning.md rename to docs/zh_cn/tutorials/pruning/dygraph/self_defined_filter_pruning.md index cd64dffb875a2c1972065a39cf31341a4771f82e..895bc067211a3a7bf0add03ce014d2dc7aa2ed42 100644 --- a/docs/zh_cn/tutorials/pruning/self_defined_filter_pruning.md +++ b/docs/zh_cn/tutorials/pruning/dygraph/self_defined_filter_pruning.md @@ -1,4 +1,4 @@ -# Paddle动态图自定义剪裁策略教程 +# 自定义剪裁 ## 1. 概述 diff --git a/docs/zh_cn/tutorials/pruning/index.rst b/docs/zh_cn/tutorials/pruning/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..ce89f1a6db6d0390bebc74e16113f1d755efc1b4 --- /dev/null +++ b/docs/zh_cn/tutorials/pruning/index.rst @@ -0,0 +1,10 @@ + +剪裁 +============== + +.. toctree:: + :maxdepth: 1 + + overview.md + dygraph/index + static/index diff --git a/docs/zh_cn/tutorials/pruning/overeview.md b/docs/zh_cn/tutorials/pruning/overeview.md deleted file mode 100644 index e972d61c7d5eb7b554bac1756c976aa3fab0d525..0000000000000000000000000000000000000000 --- a/docs/zh_cn/tutorials/pruning/overeview.md +++ /dev/null @@ -1,126 +0,0 @@ -# PaddleSlim模型裁剪方法总览 - -PaddleSlim裁剪模块针对动态图目前实现了两种裁剪相关算法,并提供对应的接口给用户来实现自身的裁剪算法。 - -## 1. 基于敏感度的模型分析算法 - -本节内容分为两部分:卷积层敏感度分析和基于敏感度的`Filters`剪裁,其中『卷积层敏感度分析』也可以被称作『卷积层重要度分析』。我们定义越重要的卷积层越敏感。 -PaddleSlim提供了工具类`Pruner`来进行重要性分析和剪裁操作,不同的`Pruner`的子类对应不同的分析和剪裁策略,本示例以`L1NormFilterPruner`为例说明。首先我们声明一个`L1NormFilterPruner`对象,如下所示: - -```python -from paddleslim.dygraph import L1NormFilterPruner -pruner = L1NormFilterPruner(net, [1, 3, 224, 224]) -``` - -如果本地文件系统已有一个存储敏感度信息(见1.1节)的文件,声明`L1NormFilterPruner`对象时,可以通过指定`sen_file`选项加载计算好的敏感度信息,如下: - -```python -#pruner = L1NormFilterPruner(net, [1, 3, 224, 224]), sen_file="./sen.pickle") -``` - -### 1.1 卷积重要性分析 - -在对卷积网络中的filters进行剪裁时,我们需要判断哪些`filters`不重要,然后优先剪掉不重要的`filters`。 -在一个卷积内,我们使用`filter`的`L1 Norm`来代表重要性,`L1 Norm`越大的`filters`越重要。在多个卷积间,我们通过敏感度代表卷积的重要性,越敏感的卷积越重要,重要的卷积会被剪掉相对较少的`filters`。 -单个卷积内的filters重要性计算会在剪裁时进行,无需用户关注。本小节,我们只介绍多个卷积间如何分析重要性,即『敏感度分析』。 - -#### 敏感度定义 - -如图4-1所示,某个卷积网络包含K个卷积层,每个卷积层有4个`filters`,原始网络精度为90。 - -第一步:从『卷积1』中剪裁掉25%的filters,也就是『卷积1』中第2个Filters,然后直接在测试集上评估精度结果为85,得到左边坐标图的第二个红点。恢复模型到初始状态。 -第二步:从『卷积1』中裁掉2个卷积,然后在测试集上评估精度为70,得到坐标图的第3个红点。恢复模型到初始状态。 -第三步:同理得到第4个红点。把『卷积1』对应的4个红点链接成曲线,即为『卷积1』的敏感度曲线。 -第四步:同理得到『卷积K』的敏感度曲线。 - -
- -
-
-图1-1 敏感度计算过程示意图 -
- -如图1-2所示,为VGG-16在CIFAR10分类任务上的敏感度曲线示意图: - -
- -
-
-图1-2 VGG-16敏感度示例 -
- - -考虑到不同的模型在不同的任务上的精度数值差别较大,甚至不在同一个量级,所以,PaddleSlim在计算和存储卷积层敏感度时,使用的是精度的损失比例。如图1-3所示,为PaddleSlim计算出的MobileNetV1-YOLOv3在VOC检测任务上的敏感度示意图,其中,纵轴为精度损失: - -
- -
-
-图1-3 用精度损失表示的敏感度 -
- - -#### 敏感度计算 - -调用`pruner`对象的`sensitive`方法进行敏感度分析,在调用`sensitive`之前,我们简单对`model.evaluate`进行包装,使其符合`sensitive`接口的规范。执行如下代码,会进行敏感度计算,并将计算结果存入本地文件系统: - -```python -def eval_fn(): - result = model.evaluate( - val_dataset, - batch_size=128) - return result['acc_top1'] -pruner.sensitive(eval_func=eval_fn, sen_file="./sen.pickle") -``` - -上述代码执行完毕后,敏感度信息会存放在pruner对象中,可以通过以下方式查看敏感度信息内容: - -```python -print(pruner.sensitive()) -``` - -### 1.2 根据敏感度数据对模型进行裁剪 - -选定模型的裁剪比例和需要跳过不裁剪的网络层,根据敏感度分析的数据对模型进行裁剪。 -```python -plan = pruner.sensitive_prune(pruned_flops=0.4, skip_vars=["conv2d_26.w_0"]) -``` - -### 2 基于几何中心(FPGM)的剪裁算法 - -在第1节中,我们采用了L1NormFilterPruner,在对一个卷积层进行裁剪的时候通过不同`filters`的`L1 Norm`来判定`filter`的重要性。然而这种方法基于两个前提: -1. 处于同一卷积网络层中的不同卷积核L1范数的标准差足够大,从而容易找到划分重要卷积核和非重要卷积核的阈值。 -2. 每一个卷积层中均存在部分卷积核的L1范数足够小,使得这些卷积核可以被安全的移除而不损害模型的表现。 -然而在很多情况下,网络模型的参数分布往往不满足上述两个前提: -
- -
-
- 卷积层中卷积核的参数分布 -
-针对这一问题PaddleSlim中提供了基于卷积层中卷积核的几何中心的判定方式(Filter Pruning via Geometric Median, FPGM)。通过同一卷积层中不同卷积核的权重向量与这些卷积核所构成高维空间几何中心的距离来判断其自身在所处卷积层中的重要程度。一个卷积核的权重向量与几何中心越近,说明其所含信息与其他卷积核的信息越近似,该卷积核的可替代性也就越强,因此可以被安全的从模型中移除。 -基于FPGM的裁剪算法可以与第1节中的敏感度分析算法共同使用,只需将第一节中的 - -```python -from paddleslim.dygraph import L1NormFilterPruner -pruner = L1NormFilterPruner(net, [1, 3, 224, 224]) -``` -更改为 - -```python -from paddleslim.dygraph import FPGMFilterPruner -pruner = FPGMFilterPruner(net, [1, 3, 224, 224]) -``` - -### 3 自定义裁剪方法 - -除了FPGM以外,PaddleSlim也提供了接口给用户来实现自己的裁剪算法。详细可参见:[自定义结构化裁剪](self_defined_filter_pruning.md) - -## 裁剪结果 -| 模型 | 压缩方法 | Top-1/Top-5 Acc | 模型体积(MB) | GFLOPs |PaddleLite推理耗时| 下载 | -|:--:|:---:|:--:|:--:|:--:|:--:|:--:| -| MobileNetV1 | Baseline | 70.99%/89.68% | 17 | 1.11 |66.052\35.8014\19.5762|[下载链接](http://paddle-imagenet-models-name.bj.bcebos.com/MobileNetV1_pretrained.tar) | -| MobileNetV1 | uniform -50% | 69.4%/88.66% (-1.59%/-1.02%) | 9 | 0.56 | 33.5636\18.6834\10.5076|[下载链接](https://paddlemodels.bj.bcebos.com/PaddleSlim/MobileNetV1_uniform-50.tar) | -| MobileNetV1 | sensitive -30% | 70.4%/89.3% (-0.59%/-0.38%) | 12 | 0.74 | 46.5958\25.3098\13.6982|[下载链接](https://paddlemodels.bj.bcebos.com/PaddleSlim/MobileNetV1_sensitive-30.tar) | -| MobileNetV1 | sensitive -50% | 69.8% / 88.9% (-1.19%/-0.78%) | 9 | 0.56 |37.9892\20.7882\11.3144|[下载链接](https://paddlemodels.bj.bcebos.com/PaddleSlim/MobileNetV1_sensitive-50.tar) | -| MobileNetV1 | uniform+FPGM -50% | 69.56% / 89.14% (-1.43%/-0.53%) | 9 | 0.56 |33.5636\18.6834\10.5076|[下载链接](https://paddlemodels.bj.bcebos.com/PaddleSlim/MobileNetV1_sensitive-50.tar) | diff --git a/docs/zh_cn/tutorials/pruning/overview.md b/docs/zh_cn/tutorials/pruning/overview.md new file mode 100644 index 0000000000000000000000000000000000000000..7406181f94adb59613c89c3b099f5a91f59a5d40 --- /dev/null +++ b/docs/zh_cn/tutorials/pruning/overview.md @@ -0,0 +1,145 @@ +# Overview + +PaddleSlim提供以下内置剪裁方法。 + + +| 序号 | 剪裁方法 | 支持静态图 | 支持动态图 | 支持敏感度分析 | 支持自定义各层剪裁率| +|:----:|:------------------:|:----------:|:----------:|:--------------:|:-------------------:| +|1 |FPGMFilterPruner |是 | 是 | 是 |是 | +|2 |L1NormFilterPruner |是 | 是 | 是 |是 | +|3 |L2NormFilterPruner |否 | 是 | 是 |是 | +|4 |SlimFilterPruner |是 | 否 | 是 |是 | +|5 |OptSlimFilterPruner |是 | 否 | 是 |是 | + +注: + +- 支持敏感度分支:意为是否支持通过各个层的敏感度分析来确定各个卷积层的剪裁率。 + +- 支持自定义各层剪裁率:意为是否支持手动指定各个卷积层的剪裁率。 + + +除了以上内置策略,PaddleSlim还支持用户自定义卷积通道剪裁策略,请参考:[自定义卷积通道剪裁教程]() + +## 各类方法效果对比 + +| 模型 | 压缩方法 | 精度(Top-1/Top-5) | 模型体积(MB) | GFLOPs |PaddleLite推理耗时| +|:--:|:---:|:--:|:--:|:--:|:--:| +| MobileNetV1 |Baseline |70.99%/89.68% |17|1.11 |66.052\35.8014\19.5762| +| MobileNetV1 |uniform + L1NormFilterPruner |69.40%/88.66% (-1.59%/-1.02%) |9 |0.56(-50%)|33.5636\18.6834\10.5076| +| MobileNetV1 |sensitive + L1NormFilterPruner|70.4%/89.3% (-0.59%/-0.38%) |12|0.74(-30%)| 46.5958\25.3098\13.6982| +| MobileNetV1 |sensitive + L1NormFilterPruner|69.8%/88.9% (-1.19%/-0.78%) |9 |0.56(50%) |37.9892\20.7882\11.3144| +| MobileNetV1 |uniform + FPGMFilterPruner |69.56%/89.14% (-1.43%/-0.53%) |9 |0.56(-50%)|33.5636\18.6834\10.5076| + +注: +- uniform: 各层剪裁率保持一样。 +- sensitive: 根据各层敏感度确定每层的剪裁率。 + + +## 策略介绍 + +### L1NormFilterPruner + +paper: https://arxiv.org/abs/1608.08710 + +该策略使用`l1-norm`统计量来表示一个卷积层内各个`Filters`的重要性,`l1-norm`越大的`Filter`越重要。 + +使用方法如下: + +#### 动态图 + +``` +pruner =paddleslim. L1NormFilterPruner(net, [1, 3, 128, 128]) +pruner.prune_vars({"conv2d_0.w_0": 0.3}) +``` + +[API文档](../../api_cn/dygraph/pruners/l1norm_filter_pruner.html) | [完整示例](../../quick_start/dygraph/dygraph_pruning_tutorial.html) + +#### 静态图 + +``` +pruner = paddleslim.prune.Pruner(criterion='l1_norm') +pruned_program, _, _ = pruner.prune( + train_program, + fluid.global_scope(), + params=["conv2d_0.w_0"], + ratios=[0.3], + place=fluid.CPUPlace()) +``` + +[API文档](../../api_cn/static/prune/prune_api.html) | [完整示例](../../quick_start/static/pruning_tutorial.html) + + +### FPGMFilterPruner + +论文: https://arxiv.org/abs/1811.00250 + +该策略通过统计`Filters`两两之间的几何距离来评估单个卷积内的`Filters`的重要性。直觉上理解,离其它`Filters`平均距离越远的`Filter`越重要。 + +使用方法如下: + +#### 动态图 + +``` +pruner =paddleslim.FPGMFilterPruner(net, [1, 3, 128, 128]) +pruner.prune_vars({"conv2d_0.w_0": 0.3}) +``` + +[API文档](../../api_cn/dygraph/pruners/fpgm_filter_pruner.html) | [完整示例](../../quick_start/dygraph/dygraph_pruning_tutorial.html) + +#### 静态图 + +``` +pruner = paddleslim.prune.Pruner(criterion='geometry_median') +pruned_program, _, _ = pruner.prune( + train_program, + fluid.global_scope(), + params=["conv2d_0.w_0"], + ratios=[0.3], + place=fluid.CPUPlace()) +``` + +[API文档](../../api_cn/static/prune/prune_api.html) | [完整示例](../../quick_start/static/pruning_tutorial.html) + + +### SlimFilterPruner + +论文: https://arxiv.org/pdf/1708.06519.pdf + +该策略根据卷积之后的`batch_norm`的`scales`来评估当前卷积内各个`Filters`的重要性。`scale`越大,对应的`Filter`越重要。 + +使用方法如下: + +#### 静态图 + +``` +pruner = paddleslim.prune.Pruner(criterion='bn_scale') +pruned_program, _, _ = pruner.prune( + train_program, + fluid.global_scope(), + params=["conv2d_0.w_0"], + ratios=[0.3], + place=fluid.CPUPlace()) +``` + +[API文档](../../api_cn/static/prune/prune_api.html) | [完整示例](../../quick_start/static/pruning_tutorial.html) + + +### OptSlimFilterPruner + +论文: https://arxiv.org/pdf/1708.06519.pdf + +使用方法如下: + +#### 静态图 + +``` +pruner = paddleslim.prune.Pruner(criterion='bn_scale', idx_selector="optimal_threshold") +pruned_program, _, _ = pruner.prune( + train_program, + fluid.global_scope(), + params=["conv2d_0.w_0"], + ratios=[0.3], + place=fluid.CPUPlace()) +``` + +[API文档](../../api_cn/static/prune/prune_api.html) | [完整示例](../../quick_start/static/pruning_tutorial.html) diff --git a/docs/zh_cn/tutorials/static/image_classification_sensitivity_analysis_tutorial.md b/docs/zh_cn/tutorials/pruning/static/image_classification_sensitivity_analysis_tutorial.md similarity index 99% rename from docs/zh_cn/tutorials/static/image_classification_sensitivity_analysis_tutorial.md rename to docs/zh_cn/tutorials/pruning/static/image_classification_sensitivity_analysis_tutorial.md index 571d4af48aafb25a065d0a19e07f063c57bf4359..4eda8dfd7a5ee9bade5565b215a81ef86f80528b 100644 --- a/docs/zh_cn/tutorials/static/image_classification_sensitivity_analysis_tutorial.md +++ b/docs/zh_cn/tutorials/pruning/static/image_classification_sensitivity_analysis_tutorial.md @@ -1,4 +1,4 @@ -# 图像分类模型通道剪裁-敏感度分析 +# 敏感度分析 该教程以图像分类模型MobileNetV1为例,说明如何快速使用[PaddleSlim的敏感度分析接口](https://paddlepaddle.github.io/PaddleSlim/api/prune_api/#sensitivity)。 该示例包含以下步骤: diff --git a/docs/zh_cn/tutorials/pruning/static/index.rst b/docs/zh_cn/tutorials/pruning/static/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..058e8b50bcae1833e61526ebce321858d11c2ffa --- /dev/null +++ b/docs/zh_cn/tutorials/pruning/static/index.rst @@ -0,0 +1,8 @@ + +静态图 +============== + +.. toctree:: + :maxdepth: 1 + + image_classification_sensitivity_analysis_tutorial.md diff --git a/docs/zh_cn/tutorials/quant/dygraph/dygraph_quant_post_tutorial.md b/docs/zh_cn/tutorials/quant/dygraph/dygraph_quant_post_tutorial.md new file mode 120000 index 0000000000000000000000000000000000000000..ddd24f04c0b0db18602d8b56e20d7521547592f4 --- /dev/null +++ b/docs/zh_cn/tutorials/quant/dygraph/dygraph_quant_post_tutorial.md @@ -0,0 +1 @@ +../../../quick_start/dygraph/dygraph_quant_post_tutorial.md \ No newline at end of file diff --git a/docs/zh_cn/tutorials/quant/dygraph/index.rst b/docs/zh_cn/tutorials/quant/dygraph/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..e45cca35cc33eaee2d81cdc11129dd39ca166270 --- /dev/null +++ b/docs/zh_cn/tutorials/quant/dygraph/index.rst @@ -0,0 +1,8 @@ + +动态图 +============== + +.. toctree:: + :maxdepth: 1 + + quant_aware_training_tutorial.md diff --git a/docs/zh_cn/tutorials/quant/quant_aware_training_tutorial.md b/docs/zh_cn/tutorials/quant/dygraph/quant_aware_training_tutorial.md similarity index 99% rename from docs/zh_cn/tutorials/quant/quant_aware_training_tutorial.md rename to docs/zh_cn/tutorials/quant/dygraph/quant_aware_training_tutorial.md index 24bf8167faaeb3a3bbdb47adaadde0bc1e3cf35e..10da4d052d4acd0a480484a536a55a29855f2182 100755 --- a/docs/zh_cn/tutorials/quant/quant_aware_training_tutorial.md +++ b/docs/zh_cn/tutorials/quant/dygraph/quant_aware_training_tutorial.md @@ -1,4 +1,4 @@ -# 量化训练 +# 量化训练详细教程 在线量化是在模型训练的过程中建模定点量化对模型的影响,通过在模型计算图中插入量化节点,在训练建模量化对模型精度的影响降低量化损失。 diff --git a/docs/zh_cn/tutorials/quant/index.rst b/docs/zh_cn/tutorials/quant/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..1f6cbd23a34cac308134c792533dbfb74146ec64 --- /dev/null +++ b/docs/zh_cn/tutorials/quant/index.rst @@ -0,0 +1,10 @@ + +量化 +============== + +.. toctree:: + :maxdepth: 1 + + overview.md + dygraph/index + static/index diff --git a/docs/zh_cn/tutorials/quant/paddleslim_quantization_overview.md b/docs/zh_cn/tutorials/quant/overview.md similarity index 96% rename from docs/zh_cn/tutorials/quant/paddleslim_quantization_overview.md rename to docs/zh_cn/tutorials/quant/overview.md index 8084ca8566713e009bff1e68f49bb6021a6fa4b9..7802d446983521126df3765f68ae3a52e02a1f88 100755 --- a/docs/zh_cn/tutorials/quant/paddleslim_quantization_overview.md +++ b/docs/zh_cn/tutorials/quant/overview.md @@ -1,6 +1,6 @@ -# PaddleSlim模型量化方法总览 +# Overview -# 图像分类INT8量化模型在CPU上的部署和预测 +## 图像分类INT8量化模型在CPU上的部署和预测 PaddleSlim主要包含三种量化方法:量化训练(Quant Aware Training, QAT)、动态离线量化(Post Training Quantization Dynamic, PTQ Dynamic)、静态离线量化(Post Training Quantization Static, PTQ Static)。 - [量化训练](quant_aware_training_tutorial.md) 量化训练让模型感知量化运算对模型精度带来的影响,通过finetune训练降低量化误差。 diff --git a/docs/zh_cn/tutorials/quant/quant_post_dynamic_tutorial.md b/docs/zh_cn/tutorials/quant/quant_post_dynamic_tutorial.md deleted file mode 100755 index fde968a6dfb9605392832e2aaaeea14643f13a96..0000000000000000000000000000000000000000 --- a/docs/zh_cn/tutorials/quant/quant_post_dynamic_tutorial.md +++ /dev/null @@ -1,27 +0,0 @@ -# 动态离线量化 - -动态离线量化,将模型中特定OP的权重从FP32类型量化成INT8/16类型。 - -量化前需要有训练好的预测模型,可以根据需要将模型转化为INT8或INT16类型,目前只支持反量化预测方式,主要可以减小模型大小,对特定加载权重费时的模型可以起到一定加速效果。 - -- 权重量化成INT16类型,模型精度不受影响,模型大小为原始的1/2。 -- 权重量化成INT8类型,模型精度会受到影响,模型大小为原始的1/4。 - -## 使用方法 - -- 准备预测模型:先保存好FP32的预测模型,用于量化压缩。 -- 产出量化模型:使用PaddlePaddle调用动态离线量化离线量化接口,产出量化模型。 - -主要代码实现如下: - -```python -import paddleslim -model_dir = path/to/fp32_model_params -save_model_dir = path/to/save_model_path -paddleslim.quant.quant_post_dynamic(model_dir=model_dir, - save_model_dir=save_model_dir, - weight_bits=8, - quantizable_op_type=['conv2d', 'mul'], - weight_quantize_type="channel_wise_abs_max", - generate_test_model=False) -``` diff --git a/docs/zh_cn/tutorials/static/embedding_quant_tutorial.md b/docs/zh_cn/tutorials/quant/static/embedding_quant_tutorial.md similarity index 100% rename from docs/zh_cn/tutorials/static/embedding_quant_tutorial.md rename to docs/zh_cn/tutorials/quant/static/embedding_quant_tutorial.md diff --git a/docs/zh_cn/tutorials/quant/static/index.rst b/docs/zh_cn/tutorials/quant/static/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..4aff6d7bef5efa5c2a76afa1b178a323106f6943 --- /dev/null +++ b/docs/zh_cn/tutorials/quant/static/index.rst @@ -0,0 +1,11 @@ + +静态图 +============== + +.. toctree:: + :maxdepth: 1 + + quant_aware_tutorial.md + quant_post_tutorial.md + mkldnn_quant_tutorial.md + embedding_quant_tutorial.md diff --git a/docs/zh_cn/tutorials/static/image_classification_mkldnn_quant_tutorial.md b/docs/zh_cn/tutorials/quant/static/mkldnn_quant_tutorial.md similarity index 98% rename from docs/zh_cn/tutorials/static/image_classification_mkldnn_quant_tutorial.md rename to docs/zh_cn/tutorials/quant/static/mkldnn_quant_tutorial.md index 2a8eaa2e269cbe1a8a949ce14fa871b878d9d5dc..e8c39628d70fb1f2f69dc5630f27de43f4d2f8aa 100644 --- a/docs/zh_cn/tutorials/static/image_classification_mkldnn_quant_tutorial.md +++ b/docs/zh_cn/tutorials/quant/static/mkldnn_quant_tutorial.md @@ -1,4 +1,4 @@ -# Intel CPU上部署量化模型教程 +# Intel CPU量化训练 在Intel Casecade Lake机器上(如:Intel(R) Xeon(R) Gold 6271),经过量化和DNNL加速,INT8模型在单线程上性能为FP32模型的3~3.7倍;在Intel SkyLake机器上(如:Intel(R) Xeon(R) Gold 6148),单线程性能为FP32模型的1.5倍,而精度仅有极小下降。图像分类量化的样例教程请参考[图像分类INT8模型在CPU优化部署和预测](https://github.com/PaddlePaddle/PaddleSlim/tree/develop/demo/mkldnn_quant/)。自然语言处理模型的量化请参考[ERNIE INT8 模型精度与性能复现](https://github.com/PaddlePaddle/benchmark/tree/master/Inference/c%2B%2B/ernie/mkldnn) diff --git a/docs/zh_cn/tutorials/quant/static/quant_aware_tutorial.md b/docs/zh_cn/tutorials/quant/static/quant_aware_tutorial.md new file mode 120000 index 0000000000000000000000000000000000000000..e80dbb5d2cca584653a484ce3031b1cb92f00a8c --- /dev/null +++ b/docs/zh_cn/tutorials/quant/static/quant_aware_tutorial.md @@ -0,0 +1 @@ +../../../quick_start/static/quant_aware_tutorial.md \ No newline at end of file diff --git a/docs/zh_cn/tutorials/quant/quant_post_static_tutorial.md b/docs/zh_cn/tutorials/quant/static/quant_post_tutorial.md similarity index 63% rename from docs/zh_cn/tutorials/quant/quant_post_static_tutorial.md rename to docs/zh_cn/tutorials/quant/static/quant_post_tutorial.md index 58f257a84264731e91fbeb56750da52dba4cf428..f32850f6ad4f885286f4550c7e57d973fe76168a 100755 --- a/docs/zh_cn/tutorials/quant/quant_post_static_tutorial.md +++ b/docs/zh_cn/tutorials/quant/static/quant_post_tutorial.md @@ -1,10 +1,40 @@ -# 静态离线量化 +# 低比特离线量化 + +## 动态模式 + +动态离线量化,将模型中特定OP的权重从FP32类型量化成INT8/16类型。 + +量化前需要有训练好的预测模型,可以根据需要将模型转化为INT8或INT16类型,目前只支持反量化预测方式,主要可以减小模型大小,对特定加载权重费时的模型可以起到一定加速效果。 + +- 权重量化成INT16类型,模型精度不受影响,模型大小为原始的1/2。 +- 权重量化成INT8类型,模型精度会受到影响,模型大小为原始的1/4。 + +### 使用方法 + +- 准备预测模型:先保存好FP32的预测模型,用于量化压缩。 +- 产出量化模型:使用PaddlePaddle调用动态离线量化离线量化接口,产出量化模型。 + +主要代码实现如下: + +```python +import paddleslim +model_dir = path/to/fp32_model_params +save_model_dir = path/to/save_model_path +paddleslim.quant.quant_post_dynamic(model_dir=model_dir, + save_model_dir=save_model_dir, + weight_bits=8, + quantizable_op_type=['conv2d', 'mul'], + weight_quantize_type="channel_wise_abs_max", + generate_test_model=False) +``` + +## 静态离线量化 静态离线量化是基于采样数据,采用KL散度等方法计算量化比例因子的方法。相比量化训练,静态离线量化不需要重新训练,可以快速得到量化模型。 静态离线量化的目标是求取量化比例因子,主要有两种方法:非饱和量化方法 ( No Saturation) 和饱和量化方法 (Saturation)。非饱和量化方法计算FP32类型Tensor中绝对值的最大值`abs_max`,将其映射为127,则量化比例因子等于`abs_max/127`。饱和量化方法使用KL散度计算一个合适的阈值`T` (`0索到一个网络结构训练7个epoch。" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2020-02-07 08:45:06,927-INFO: current tokens: [4, 4, 5, 1, 0, 4, 4, 2, 0, 4, 4, 3, 1, 4, 5, 2, 0, 4, 7, 2, 0, 4, 9, 0, 0]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TRAIN: loss: [2.6932292], acc1: [0.08203125], acc5:[0.51953125]\n", - "TRAIN: loss: [42.387478], acc1: [0.078125], acc5:[0.47265625]\n" - ] - } - ], - "source": [ - "for step in range(3):\n", - " archs = sanas.next_archs()[0]\n", - " exe, train_program, eval_progarm, inputs, avg_cost, acc_top1, acc_top5 = build_program(archs)\n", - " train_reader, train_feeder, eval_reader, eval_feeder = input_data(inputs)\n", - "\n", - " current_flops = slim.analysis.flops(train_program)\n", - " if current_flops > 321208544:\n", - " continue\n", - "\n", - " for epoch in range(7):\n", - " start_train(train_program, train_reader, train_feeder)\n", - "\n", - " finally_reward = start_eval(eval_program, eval_reader, eval_feeder)\n", - "\n", - " sanas.reward(float(finally_reward[1]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/zh_cn/tutorials/static/sanas_darts_space.ipynb b/docs/zh_cn/tutorials/static/sanas_darts_space.ipynb deleted file mode 100644 index 658124b5ceea1b0e48fe488faffd2fbfa9b6584e..0000000000000000000000000000000000000000 --- a/docs/zh_cn/tutorials/static/sanas_darts_space.ipynb +++ /dev/null @@ -1,324 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "import paddle\n", - "import paddle.fluid as fluid\n", - "from paddleslim.nas import SANAS\n", - "import numpy as np\n", - "\n", - "BATCH_SIZE=96\n", - "SERVER_ADDRESS = \"\"\n", - "PORT = 8377\n", - "SEARCH_STEPS = 300\n", - "RETAIN_EPOCH=30\n", - "MAX_PARAMS=3.77\n", - "IMAGE_SHAPE=[3, 32, 32]\n", - "AUXILIARY = True\n", - "AUXILIARY_WEIGHT= 0.4\n", - "TRAINSET_NUM = 50000\n", - "LR = 0.025\n", - "MOMENTUM = 0.9\n", - "WEIGHT_DECAY = 0.0003\n", - "DROP_PATH_PROBILITY = 0.2" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2020-02-23 12:28:09,752-INFO: range table: ([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14])\n", - "2020-02-23 12:28:09,754-INFO: ControllerServer - listen on: [127.0.0.1:8377]\n", - "2020-02-23 12:28:09,756-INFO: Controller Server run...\n" - ] - } - ], - "source": [ - "config = [('DartsSpace')]\n", - "sa_nas = SANAS(config, server_addr=(SERVER_ADDRESS, PORT), search_steps=SEARCH_STEPS, is_server=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "def count_parameters_in_MB(all_params, prefix='model'):\n", - " parameters_number = 0\n", - " for param in all_params:\n", - " if param.name.startswith(\n", - " prefix) and param.trainable and 'aux' not in param.name:\n", - " parameters_number += np.prod(param.shape)\n", - " return parameters_number / 1e6" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "def create_data_loader(IMAGE_SHAPE, is_train):\n", - " image = fluid.data(\n", - " name=\"image\", shape=[None] + IMAGE_SHAPE, dtype=\"float32\")\n", - " label = fluid.data(name=\"label\", shape=[None, 1], dtype=\"int64\")\n", - " data_loader = fluid.io.DataLoader.from_generator(\n", - " feed_list=[image, label],\n", - " capacity=64,\n", - " use_double_buffer=True,\n", - " iterable=True)\n", - " drop_path_prob = ''\n", - " drop_path_mask = ''\n", - " if is_train:\n", - " drop_path_prob = fluid.data(\n", - " name=\"drop_path_prob\", shape=[BATCH_SIZE, 1], dtype=\"float32\")\n", - " drop_path_mask = fluid.data(\n", - " name=\"drop_path_mask\",\n", - " shape=[BATCH_SIZE, 20, 4, 2],\n", - " dtype=\"float32\")\n", - "\n", - " return data_loader, image, label, drop_path_prob, drop_path_mask" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "def build_program(main_program, startup_program, IMAGE_SHAPE, archs, is_train):\n", - " with fluid.program_guard(main_program, startup_program):\n", - " data_loader, data, label, drop_path_prob, drop_path_mask = create_data_loader(\n", - " IMAGE_SHAPE, is_train)\n", - " logits, logits_aux = archs(data, drop_path_prob, drop_path_mask,\n", - " is_train, 10)\n", - " top1 = fluid.layers.accuracy(input=logits, label=label, k=1)\n", - " top5 = fluid.layers.accuracy(input=logits, label=label, k=5)\n", - " loss = fluid.layers.reduce_mean(\n", - " fluid.layers.softmax_with_cross_entropy(logits, label))\n", - "\n", - " if is_train:\n", - " if AUXILIARY:\n", - " loss_aux = fluid.layers.reduce_mean(\n", - " fluid.layers.softmax_with_cross_entropy(logits_aux, label))\n", - " loss = loss + AUXILIARY_WEIGHT * loss_aux\n", - " step_per_epoch = int(TRAINSET_NUM / BATCH_SIZE)\n", - " learning_rate = fluid.layers.cosine_decay(LR, step_per_epoch, RETAIN_EPOCH)\n", - " fluid.clip.set_gradient_clip(\n", - " clip=fluid.clip.GradientClipByGlobalNorm(clip_norm=5.0))\n", - " optimizer = fluid.optimizer.MomentumOptimizer(\n", - " learning_rate,\n", - " MOMENTUM,\n", - " regularization=fluid.regularizer.L2DecayRegularizer(\n", - " WEIGHT_DECAY))\n", - " optimizer.minimize(loss)\n", - " outs = [loss, top1, top5, learning_rate]\n", - " else:\n", - " outs = [loss, top1, top5]\n", - " return outs, data_loader" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "def train(main_prog, exe, epoch_id, train_loader, fetch_list):\n", - " loss = []\n", - " top1 = []\n", - " top5 = []\n", - " for step_id, data in enumerate(train_loader()):\n", - " devices_num = len(data)\n", - " if DROP_PATH_PROBILITY > 0:\n", - " feed = []\n", - " for device_id in range(devices_num):\n", - " image = data[device_id]['image']\n", - " label = data[device_id]['label']\n", - " drop_path_prob = np.array(\n", - " [[DROP_PATH_PROBILITY * epoch_id / RETAIN_EPOCH]\n", - " for i in range(BATCH_SIZE)]).astype(np.float32)\n", - " drop_path_mask = 1 - np.random.binomial(\n", - " 1, drop_path_prob[0],\n", - " size=[BATCH_SIZE, 20, 4, 2]).astype(np.float32)\n", - " feed.append({\n", - " \"image\": image,\n", - " \"label\": label,\n", - " \"drop_path_prob\": drop_path_prob,\n", - " \"drop_path_mask\": drop_path_mask\n", - " })\n", - " else:\n", - " feed = data\n", - " loss_v, top1_v, top5_v, lr = exe.run(\n", - " main_prog, feed=feed, fetch_list=[v.name for v in fetch_list])\n", - " loss.append(loss_v)\n", - " top1.append(top1_v)\n", - " top5.append(top5_v)\n", - " if step_id % 10 == 0:\n", - " print(\n", - " \"Train Epoch {}, Step {}, Lr {:.8f}, loss {:.6f}, acc_1 {:.6f}, acc_5 {:.6f}\".\n", - " format(epoch_id, step_id, lr[0], np.mean(loss), np.mean(top1), np.mean(top5)))\n", - " return np.mean(top1)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "def valid(main_prog, exe, epoch_id, valid_loader, fetch_list):\n", - " loss = []\n", - " top1 = []\n", - " top5 = []\n", - " for step_id, data in enumerate(valid_loader()):\n", - " loss_v, top1_v, top5_v = exe.run(\n", - " main_prog, feed=data, fetch_list=[v.name for v in fetch_list])\n", - " loss.append(loss_v)\n", - " top1.append(top1_v)\n", - " top5.append(top5_v)\n", - " if step_id % 10 == 0:\n", - " print(\n", - " \"Valid Epoch {}, Step {}, loss {:.6f}, acc_1 {:.6f}, acc_5 {:.6f}\".\n", - " format(epoch_id, step_id, np.mean(loss), np.mean(top1), np.mean(top5)))\n", - " return np.mean(top1)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2020-02-23 12:28:57,462-INFO: current tokens: [5, 5, 5, 5, 5, 12, 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10, 10, 10]\n" - ] - } - ], - "source": [ - "archs = sa_nas.next_archs()[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "train_program = fluid.Program()\n", - "test_program = fluid.Program()\n", - "startup_program = fluid.Program()\n", - "train_fetch_list, train_loader = build_program(train_program, startup_program, IMAGE_SHAPE, archs, is_train=True)\n", - "test_fetch_list, test_loader = build_program(test_program, startup_program, IMAGE_SHAPE, archs, is_train=False)\n", - "test_program = test_program.clone(for_test=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "place = fluid.CPUPlace()\n", - "exe = fluid.Executor(place)\n", - "exe.run(startup_program)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "train_reader = paddle.fluid.io.batch(paddle.reader.shuffle(paddle.dataset.cifar.train10(cycle=False), buf_size=1024), batch_size=BATCH_SIZE, drop_last=True)\n", - "test_reader = paddle.fluid.io.batch(paddle.dataset.cifar.test10(cycle=False), batch_size=BATCH_SIZE, drop_last=False)\n", - "train_loader.set_sample_list_generator(train_reader, places=place)\n", - "test_loader.set_sample_list_generator(test_reader, places=place)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Train Epoch 0, Step 0, Lr 0.02500000, loss 3.310467, acc_1 0.062500, acc_5 0.468750\n" - ] - } - ], - "source": [ - "for epoch_id in range(RETAIN_EPOCH):\n", - " train_top1 = train(train_program, exe, epoch_id, train_loader, train_fetch_list)\n", - " print(\"TRAIN: Epoch {}, train_acc {:.6f}\".format(epoch_id, train_top1))\n", - " valid_top1 = valid(test_program, exe, epoch_id, test_loader, test_fetch_list)\n", - " print(\"TEST: Epoch {}, valid_acc {:.6f}\".format(epoch_id, valid_top1))\n", - " valid_top1_list.append(valid_top1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}