Skip to content

Commit

Permalink
fix quantization api and tutorial doc (PaddlePaddle#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
slf12 authored Feb 20, 2020
1 parent 145963b commit d6d5b25
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 41 deletions.
6 changes: 3 additions & 3 deletions docs/en/quick_start/quant_aware_tutorial_en.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Training-aware Quantization of image classification model - quick start

This tutorial shows how to do training-aware quantization using [API](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/docs/api/quantization_api.md) in PaddleSlim. We use MobileNetV1 to train image classification model as example. The tutorial contains follow sections:
This tutorial shows how to do training-aware quantization using [API](https://paddlepaddle.github.io/PaddleSlim/api_en/paddleslim.quant.html#paddleslim.quant.quanter.quant_aware) in PaddleSlim. We use MobileNetV1 to train image classification model as example. The tutorial contains follow sections:

1. Necessary imports
2. Model architecture
Expand Down Expand Up @@ -89,7 +89,7 @@ test(val_program)

## 4. Quantization

We call ``quant_aware`` API to add quantization and dequantization operators in ``train_program`` and ``val_program`` according to [default configuration](https://paddlepaddle.github.io/PaddleSlim/api/quantization_api/#_1).
We call ``quant_aware`` API to add quantization and dequantization operators in ``train_program`` and ``val_program`` according to [default configuration](https://paddlepaddle.github.io/PaddleSlim/api_cn/quantization_api.html#id2).

```python
quant_program = slim.quant.quant_aware(train_program, exe.place, for_test=False)
Expand All @@ -114,7 +114,7 @@ test(val_quant_program)

## 6. Save model after quantization

The model in ``4. Quantization`` after calling ``slim.quant.quant_aware`` API is only suitable to train. To get the inference model, we should use [slim.quant.convert](https://paddlepaddle.github.io/PaddleSlim/api/quantization_api/#convert) API to change model architecture and use [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) to save model. ``float_prog``'s parameters are float32 dtype but in int8's range which can be used in ``fluid`` or ``paddle-lite``. ``paddle-lite`` will change the parameters' dtype from float32 to int8 first when loading the inference model. ``int8_prog``'s parameters are int8 dtype and we can get model size after quantization by saving it. ``int8_prog`` cannot be used in ``fluid`` or ``paddle-lite``.
The model in ``4. Quantization`` after calling ``slim.quant.quant_aware`` API is only suitable to train. To get the inference model, we should use [slim.quant.convert](https://paddlepaddle.github.io/PaddleSlim/api_en/paddleslim.quant.html#paddleslim.quant.quanter.convert) API to change model architecture and use [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) to save model. ``float_prog``'s parameters are float32 dtype but in int8's range which can be used in ``fluid`` or ``paddle-lite``. ``paddle-lite`` will change the parameters' dtype from float32 to int8 first when loading the inference model. ``int8_prog``'s parameters are int8 dtype and we can get model size after quantization by saving it. ``int8_prog`` cannot be used in ``fluid`` or ``paddle-lite``.


```python
Expand Down
2 changes: 1 addition & 1 deletion docs/en/quick_start/quant_post_tutorial_en.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Post-training Quantization of image classification model - quick start

This tutorial shows how to do post training quantization using [API](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/docs/api/quantization_api.md) in PaddleSlim. We use MobileNetV1 to train image classification model as example. The tutorial contains follow sections:
This tutorial shows how to do post training quantization using [API](https://paddlepaddle.github.io/PaddleSlim/api_en/paddleslim.quant.html#paddleslim.quant.quanter.quant_post) in PaddleSlim. We use MobileNetV1 to train image classification model as example. The tutorial contains follow sections:

1. Necessary imports
2. Model architecture
Expand Down
62 changes: 32 additions & 30 deletions docs/zh_cn/api_cn/quantization_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
- **activation_quantize_type(str)** - 激活量化方式,可选 ``'abs_max'`` , ``'range_abs_max'`` , ``'moving_average_abs_max'`` 。如果使用 ``TensorRT`` 加载量化后的模型来预测,请使用 ``'range_abs_max', 'moving_average_abs_max'`` 。,默认 ``'moving_average_abs_max'`` 。
- **weight_bits(int)** - 参数量化bit数,默认8, 推荐设为8。
- **activation_bits(int)** - 激活量化bit数,默认8, 推荐设为8。
- **not_quant_pattern(str | list[str])** - 所有 ``name_scope`` 包含 ``'not_quant_pattern'`` 字符串的 ``op`` ,都不量化, 设置方式请参考 `fluid.name_scope <https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/name_scope_cn.html#name-scope>`_ 。
- **quantize_op_types(list[str])** - 需要进行量化的 ``op`` 类型,目前支持 ``'conv2d', 'depthwise_conv2d', 'mul'`` 。
- **not_quant_pattern(str | list[str])** - 所有 ``name_scope`` 包含 ``'not_quant_pattern'`` 字符串的 op ,都不量化, 设置方式请参考 `fluid.name_scope <https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/name_scope_cn.html#name-scope>`_ 。
- **quantize_op_types(list[str])** - 需要进行量化的 op 类型,目前支持 ``'conv2d', 'depthwise_conv2d', 'mul'`` 。
- **dtype(int8)** - 量化后的参数类型,默认 ``int8`` , 目前仅支持 ``int8`` 。
- **window_size(int)** - ``'range_abs_max'`` 量化方式的 ``window size`` ,默认10000。
- **moving_rate(int)** - ``'moving_average_abs_max'`` 量化方式的衰减系数,默认 0.9。
Expand All @@ -69,22 +69,24 @@
quant_aware
------------

.. py:function:: paddleslim.quant.quant_aware(program, place, config, scope=None, for_test=False)[[源代码]](https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/quant/quanter.py)
.. py:function:: paddleslim.quant.quant_aware(program, place, config, scope=None, for_test=False)
在 ``program`` 中加入量化和反量化 ``op``, 用于量化训练。
`源代码 <https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/quant/quanter.py>`_

在 program 中加入量化和反量化op, 用于量化训练。


**参数:**

- **program (fluid.Program)** - 传入训练或测试 ``program``
- **program (fluid.Program)** - 传入训练或测试program
- **place(fluid.CPUPlace | fluid.CUDAPlace)** - 该参数表示 ``Executor`` 执行所在的设备。
- **config(dict)** - 量化配置表。
- **scope(fluid.Scope, optional)** - 传入用于存储 ``Variable`` 的 ``scope`` ,需要传入 ``program`` 所使用的 ``scope`` ,一般情况下,是 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ 。设置为 ``None`` 时将使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ ,默认值为 ``None`` 。
- **for_test(bool)** - 如果 ``program`` 参数是一个测试 ``program`` , ``for_test`` 应设为 ``True`` ,否则设为 ``False``
- **for_test(bool)** - 如果 ``program`` 参数是一个测试 ``program`` , ``for_test`` 应设为True,否则设为False

**返回**

含有量化和反量化 ``operator````program``
含有量化和反量化 operator 的 program 。

**返回类型**

Expand All @@ -93,10 +95,10 @@ quant_aware

.. note::

- 此接口会改变 ``program`` 结构,并且可能增加一些``persistable``的变量,所以加载模型参数时请注意和相应的``program``对应。
- 此接口底层经历了``fluid.Program``-> ``fluid.framework.IrGraph``->``fluid.Program``的转变,在``fluid.framework.IrGraph``中没有``Parameter``的概念,``Variable``只有``persistable``和``not persistable``的区别,所以在保存和加载参数时,请使用``fluid.io.save_persistables````fluid.io.load_persistables``接口。
- 由于此接口会根据``program``的结构和量化配置来对``program``添加op,所以``Paddle``中一些通过``fuse op``来加速训练的策略不能使用。已知以下策略在使用量化时必须设为``False``: ``fuse_all_reduce_ops, sync_batch_norm``。
- 如果传入的 ``program`` 中存在和任何op都没有连接的 ``Variable`` ,则会在量化的过程中被优化掉。
- 此接口会改变program 结构,并且可能增加一些persistable的变量,所以加载模型参数时请注意和相应的 program 对应。
- 此接口底层经历了 fluid.Program -> fluid.framework.IrGraph -> fluid.Program 的转变,在 ``fluid.framework.IrGraph`` 中没有 ``Parameter`` 的概念,``Variable`` 只有 persistable 和not persistable的区别,所以在保存和加载参数时,请使用 ``fluid.io.save_persistables````fluid.io.load_persistables`` 接口。
- 由于此接口会根据 program 的结构和量化配置来对program 添加op,所以 ``Paddle`` 中一些通过 ``fuse op`` 来加速训练的策略不能使用。已知以下策略在使用量化时必须设为False : ``fuse_all_reduce_ops, sync_batch_norm``
- 如果传入的 program 中存在和任何op都没有连接的 ``Variable`` ,则会在量化的过程中被优化掉。



Expand All @@ -108,24 +110,24 @@ convert
`源代码 <https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/quant/quanter.py>`_


把训练好的量化 ``program`` ,转换为可用于保存 ``inference model`` 的 ``program``
把训练好的量化 program ,转换为可用于保存 ``inference model`` 的 program 。

**参数:**

- **program (fluid.Program)** - 传入测试``program``
- **place(fluid.CPUPlace | fluid.CUDAPlace)** - 该参数表示``Executor``执行所在的设备。
- **program (fluid.Program)** - 传入测试 program
- **place(fluid.CPUPlace | fluid.CUDAPlace)** - 该参数表示 ``Executor`` 执行所在的设备。
- **config(dict)** - 量化配置表。
- **scope(fluid.Scope)** - 传入用于存储``Variable````scope``,需要传入``program``所使用的``scope``,一般情况下,是 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ 。设置为 ``None`` 时将使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ ,默认值为 ``None`` 。
- **save_int8(bool)** - 是否需要返回参数为 ``int8`` 的 ``program`` 。该功能目前只能用于确认模型大小。默认值为 ``False`` 。
- **scope(fluid.Scope)** - 传入用于存储 ``Variable````scope`` ,需要传入 ``program`` 所使用的 ``scope`` ,一般情况下,是 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ 。设置为 ``None`` 时将使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ ,默认值为 ``None`` 。
- **save_int8(bool)** - 是否需要返回参数为 ``int8`` 的 program 。该功能目前只能用于确认模型大小。默认值为 ``False`` 。

**返回**

- **program (fluid.Program)** - freezed program,可用于保存inference model,参数为``float32``类型,但其数值范围可用int8表示。
- **int8_program (fluid.Program)** - freezed program,可用于保存inference model,参数为``int8``类型。当``save_int8``为``False``时,不返回该值。
- **program (fluid.Program)** - freezed program,可用于保存inference model,参数为 ``float32`` 类型,但其数值范围可用int8表示。
- **int8_program (fluid.Program)** - freezed program,可用于保存inference model,参数为 ``int8`` 类型。当 ``save_int8`` 为False 时,不返回该值。

.. note::

因为该接口会对``op``和``Variable``做相应的删除和修改,所以此接口只能在训练完成之后调用。如果想转化训练的中间模型,可加载相应的参数之后再使用此接口。
因为该接口会对 op 和 Variable 做相应的删除和修改,所以此接口只能在训练完成之后调用。如果想转化训练的中间模型,可加载相应的参数之后再使用此接口。

**代码示例**

Expand Down Expand Up @@ -186,13 +188,13 @@ quant_post
- **model_dir(str)** - 需要量化的模型所在的文件夹。
- **quantize_model_path(str)** - 保存量化后的模型的路径
- **sample_generator(python generator)** - 读取数据样本,每次返回一个样本。
- **model_filename(str, optional)** - 模型文件名,如果需要量化的模型的参数存在一个文件中,则需要设置``model_filename``为模型文件的名称,否则设置为``None``即可。默认值是``None``。
- **params_filename(str)** - 参数文件名,如果需要量化的模型的参数存在一个文件中,则需要设置``params_filename``为参数文件的名称,否则设置为``None``即可。默认值是``None``。
- **model_filename(str, optional)** - 模型文件名,如果需要量化的模型的参数存在一个文件中,则需要设置 ``model_filename`` 为模型文件的名称,否则设置为 ``None`` 即可。默认值是 ``None``
- **params_filename(str)** - 参数文件名,如果需要量化的模型的参数存在一个文件中,则需要设置 ``params_filename`` 为参数文件的名称,否则设置为 ``None`` 即可。默认值是 ``None``
- **batch_size(int)** - 每个batch的图片数量。默认值为16 。
- **batch_nums(int, optional)** - 迭代次数。如果设置为``None``,则会一直运行到``sample_generator`` 迭代结束, 否则,迭代次数为``batch_nums``, 也就是说参与对 ``Scale`` 进行校正的样本个数为 ``'batch_nums' * 'batch_size'`` .
- **scope(fluid.Scope, optional)** - 用来获取和写入 ``Variable`` , 如果设置为 ``None`` ,则使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ . 默认值是``None``.
- **batch_nums(int, optional)** - 迭代次数。如果设置为 ``None`` ,则会一直运行到 ``sample_generator`` 迭代结束, 否则,迭代次数为 ``batch_nums``, 也就是说参与对 ``Scale`` 进行校正的样本个数为 ``'batch_nums' * 'batch_size'`` .
- **scope(fluid.Scope, optional)** - 用来获取和写入 ``Variable`` , 如果设置为 ``None`` ,则使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ . 默认值是 ``None`` .
- **algo(str)** - 量化时使用的算法名称,可为 ``'KL'`` 或者 ``'direct'`` 。该参数仅针对激活值的量化,因为参数值的量化使用的方式为 ``'channel_wise_abs_max'`` . 当 ``algo`` 设置为 ``'direct'`` 时,使用校正数据的激活值的绝对值的最大值当作 ``Scale`` 值,当设置为 ``'KL'`` 时,则使用KL散度的方法来计算 ``Scale`` 值。默认值为 ``'KL'`` 。
- **quantizable_op_type(list[str])** - 需要量化的 ``op`` 类型列表。默认值为 ``["conv2d", "depthwise_conv2d", "mul"]`` 。
- **quantizable_op_type(list[str])** - 需要量化的 op 类型列表。默认值为 ``["conv2d", "depthwise_conv2d", "mul"]`` 。
- **is_full_quantize(bool)** - 是否量化所有可支持的op类型。如果设置为False, 则按照 ``'quantizable_op_type'`` 的设置进行量化。
- **weight_bits(int)** - weight的量化比特位数。
- **activation_bits(int)** - 激活值的量化比特位数。
Expand All @@ -205,14 +207,14 @@ quant_post

.. note::

- 因为该接口会收集校正数据的所有的激活值,当校正图片比较多时,请设置``'is_use_cache_file'``为True, 将中间结果存储在硬盘中。另外,``'KL'``散度的计算比较耗时。
- 目前``Paddle-Lite``有int8 kernel来加速的op只有 ``['conv2d', 'depthwise_conv2d', 'mul']``, 其他op的int8 kernel将陆续支持。
- 因为该接口会收集校正数据的所有的激活值,当校正图片比较多时,请设置 ``'is_use_cache_file'`` 为True, 将中间结果存储在硬盘中。另外,``'KL'`` 散度的计算比较耗时。
- 目前 ``Paddle-Lite`` 有int8 kernel来加速的op只有 ``['conv2d', 'depthwise_conv2d', 'mul']`` , 其他op的int8 kernel将陆续支持。

**代码示例**

.. warning::

此示例不能直接运行,因为需要加载``${model_dir}``下的模型,所以不能直接运行。
此示例不能直接运行,因为需要加载 ``${model_dir}`` 下的模型,所以不能直接运行。

.. code-block:: python
Expand Down Expand Up @@ -249,12 +251,12 @@ quant_embedding
**参数:**

- **program(fluid.Program)** - 需要量化的program
- **scope(fluid.Scope, optional)** - 用来获取和写入``Variable``, 如果设置为``None``,则使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ .
- **scope(fluid.Scope, optional)** - 用来获取和写入 ``Variable``, 如果设置为 ``None``,则使用 `fluid.global_scope() <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/executor_cn/global_scope_cn.html>`_ .
- **place(fluid.CPUPlace | fluid.CUDAPlace)** - 运行program的设备
- **config(dict)** - 定义量化的配置。可以配置的参数有:
- ``'params_name'`` (str, required): 需要进行量化的参数名称,此参数必须设置。
- ``'quantize_type'`` (str, optional): 量化的类型,目前支持的类型是 ``'abs_max'``, 待支持的类型有 ``'log', 'product_quantization'`` 。 默认值是``'abs_max'`` .
- ``'quantize_bits'`` (int, optional): 量化的 ``bit`` 数,目前支持的 ``bit`` 数为8。默认值是8.
- ``'quantize_type'`` (str, optional): 量化的类型,目前支持的类型是 ``'abs_max'``, 待支持的类型有 ``'log', 'product_quantization'`` 。 默认值是 ``'abs_max'`` .
- ``'quantize_bits'`` (int, optional): 量化的bit数,目前支持的bit数为8。默认值是8.
- ``'dtype'`` (str, optional): 量化之后的数据类型, 目前支持的是 ``'int8'``. 默认值是 ``int8`` 。
- ``'threshold'`` (float, optional): 量化之前将根据此阈值对需要量化的参数值进行 ``clip``. 如果不设置,则跳过 ``clip`` 过程直接量化。

Expand Down
Loading

0 comments on commit d6d5b25

Please sign in to comment.