Created by: slf12
Required(必填, multiple choices, two at most)
-
PR type(PR 类型) is ( A): A. New features(新功能)---------------- D. Performance optimization(性能优化) B. Bug fixes(问题修复)------------------ E. Breaking changes(向后不兼容的改变) C. Function optimization(功能优化)------F. Others(其它)
-
PR changes(改动点)is ( B): A. OPs(operators)---------------------- C. Docs(文档) B. APIs(接口)--------------------------- D. Others(其它)
-
Use one sentence to describe what this PR does.(简述本次PR的目的和改动)
support user defined quantization func and preprocess 在不影响原有量化功能的使用下添加用户自定义的量化方法或者自定义的在量化前对activation或者weight做预处理的方法。
自定义预处理方法: 比如activation在量化前可以做一些clip再进行量化,虽然activation一些量化方式是滑动平均,仍然不能解决activation离群点比较多的问题。比如有的activation的最大值在150左右,但是大部分的分布在-10到10之间,这样直接量化容易出现nan并且效果低。 解决离群点的一个函数pact定义:
def pact(x, name=None):
helper = LayerHelper("pact", **locals())
dtype = 'float32'
init_thres = 20
u_param_attr = fluid.ParamAttr(
name=x.name + '_pact',
initializer=fluid.initializer.ConstantInitializer(value=init_thres),
regularizer=fluid.regularizer.L2Decay(0.0001),
learning_rate=1)
u_param = helper.create_parameter(attr=u_param_attr, shape=[1], dtype=dtype)
x = fluid.layers.elementwise_sub(
x, fluid.layers.relu(fluid.layers.elementwise_sub(x, u_param)))
x = fluid.layers.elementwise_add(
x, fluid.layers.relu(fluid.layers.elementwise_sub(-u_param, x)))
return x
在activation量化前插入这个函数可将activation的绝对值大于u_param的点变成u_param,使量化更稳定。
对weight预处理思想类似。
自定义量化方法: 将fp32均匀映射成int8是量化的基本方法,量化有很多方式(在不考虑预测的情况下,这里加的功能只能快速验证量化方法是否可行,如果验证可行之后,还需要实现op来实现这种量化功能), 如果可以用paddle的op像上述pact这样在函数中组出来,那么会将这个函数(输入是待量化的值,输出是反量化之后的值)替换默认的量化反量化op。
所以如果用户自定义了weight的自定义量化方式,那么将使用自定义的量化方式代替默认的量化反量化op, activation类似。