quantization_FAQ.md 4.6 KB
Newer Older
L
Liufang Sang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
## 量化FAQ

1. 量化训练或者离线量化后的模型体积为什么没有变小?
2. 量化训练或者离线量化后的模型使用fluid加载为什么没有加速?怎样才能加速?
3. 该怎么设置适合的量化配置?
4. 离线量化出现'KeyError: '报错
5. 离线量化或者量化训练时出现CUDNN或者CUDA错误
6. 量化训练时loss是nan
7. cpu上跑量化后的模型出nan

#### 1. 量化训练或者离线量化后的模型体积为什么没有变小?

答:这是因为量化后保存的参数是虽然是int8范围,但是类型是float。这是由于fluid没有int8 kernel, 为了方便量化后验证量化精度,必须能让fluid能够加载。

#### 2. 量化训练或者离线量化后的模型使用fluid加载为什么没有加速?怎样才能加速?

答:这是因为量化后保存的参数是虽然是int8范围,但是类型是float。fluid并不具备加速量化模型的能力。量化模型必须配合使用预测库才能加速。

- 如果量化模型在ARM上线,则需要使用[Paddle-Lite](https://paddle-lite.readthedocs.io/zh/latest/index.html).

    -  Paddle-Lite会对量化模型进行模型转化和优化,转化方法见[链接](https://paddle-lite.readthedocs.io/zh/latest/user_guides/model_quantization.html#paddle-lite)。

    - 转化之后可以像非量化模型一样使用[Paddle-Lite API](https://paddle-lite.readthedocs.io/zh/latest/user_guides/tutorial.html#lite)进行加载预测。

- 如果量化模型在GPU上线,则需要使用[Paddle-TensorRT 预测接口](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/performance_improving/inference_improving/paddle_tensorrt_infer.html).

    - 和非量化模型的区别在于以下参数设置:

```python
config->EnableTensorRtEngine(1 << 20      /* workspace_size*/,  
                        batch_size        /* max_batch_size*/,  
                        3                 /* min_subgraph_size*/,
                        AnalysisConfig::Precision::kInt8 /* precision*/,
                        false             /* use_static*/,
                        false             /* use_calib_mode*/);
```

-  如果量化模型在x86上线,需要使用[INT8 MKL-DNN](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/fluid/contrib/slim/tests/QAT_mkldnn_int8_readme.md)

    - 首先对模型进行转化,可以参考[脚本](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/fluid/contrib/slim/tests/save_qat_model.py)

    - 转化之后可使用预测部署API进行加载。比如[c++ API](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/advanced_guide/inference_deployment/inference/native_infer.html)


#### 3. 该怎么设置适合的量化配置?

- 首先需要考虑量化模型上线的平台

   | 平台             | 支持weight量化方式             | 支持activation量化方式                | 支持量化的OP                                                 |
   | ---------------- | ------------------------------ | ------------------------------------- | ------------------------------------------------------------ |
   | ARM(Paddle-Lite) | channel_wise_abs_max, abs_max | moving_average_abs_max,range_abs_max | conv2d, depthwise_conv2d, mul                                |
   | x86(MKL-DNN)     | abs_max                        | moving_average_abs_max,range_abs_max | conv2d, depthwise_conv2d, mul, matmul                        |
   | GPU(TensorRT)    | channel_wise_abs_max           | moving_average_abs_max,range_abs_max | mul, conv2d, pool2d, depthwise_conv2d, elementwise_add, leaky_relu |

- 部分层跳过量化

   如果量化后精度损失较大,可以考虑跳过部分对量化敏感的计算不量化,比如最后一层或者attention计算。



#### 4. 离线量化出现'KeyError: '报错



答: 一般是reader没写对,导致离线量化是前向一次没跑,没有收集到中间的激活值。



#### 5. 离线量化或者量化训练时出现CUDNN或者CUDA错误



答:因为离线量化或者量化训练并没有涉及到对cuda或者cudnn做修改, 因此这个错误一般是机器上的cuda或者cudnn版本和Paddle所需的cuda或者cudnn版本不一致。



#### 6. 量化训练时loss是nan



答:需要适当调小学习率。如果小学习率依然不能解决问题,则需要考虑是否某些层对量化敏感,需要跳过量化,比如attention.



#### 7. cpu上跑量化后的模型出nan



答:可查看使用的paddle版本是否包含[pr](https://github.com/PaddlePaddle/Paddle/pull/22966), 该pr修复了在对几乎是0的tensor进行量化时的bug。