Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于QuantizationStates.PASSIVE_INIT量化配置探讨 #87

Closed
Menace-Dragon opened this issue May 4, 2022 · 2 comments
Closed

关于QuantizationStates.PASSIVE_INIT量化配置探讨 #87

Menace-Dragon opened this issue May 4, 2022 · 2 comments

Comments

@Menace-Dragon
Copy link

想叨扰问一下这个配置是干什么用的:base_quant_config.input_quantization_config[-1].state = QuantizationStates.PASSIVE_INIT

当执行这个语句时,也就是PASSIVE_INIT生效时,最后量化引入的量化噪声非常严重;但不使用这个语句时,量化噪声就几乎没有了。这是为什么呢,,

@ZhangZhiPku
Copy link
Collaborator

ZhangZhiPku commented May 5, 2022

PPQ 使用 QuantizationState 控制量化逻辑,该字段是 TensorQuantizationConfig 中最重要的内容,我们目前支持 12 种量化状态:

  • INITIAL = 1 # 量化参数刚刚被初始化,当前 config 不生效,数据不能被使用
  • BAKED = 2 # 只针对参数量化,表示参数已经被静态量化,当前 config 不生效,数据可以直接使用
  • OVERLAPPED = 3 # 只针对activation量化,表示数据流的量化由其他 config 管理,当前 config 不生效
  • SLAVE = 4 # 只针对activation量化,表示当前数据流处于强制联合定点,当前 config 生效
  • DEACTIVATED = 5 # 表示当前 config 不生效
  • ACTIVATED = 6 # 表示当前 config 生效
  • DEQUANTIZED = 7 # 表示当前 config 处于解量化状态,解量化是 PPQ 的一个系统操作
  • SOI = 8 # 表示这一路输入与 Shape or index 相关,不量化
  • PASSIVE = 9 # 表示这一路输入被动量化,如 bias, clip value 等
  • PASSIVE_INIT = 10 # 表示这一路输入被动量化,并且刚刚初始化不能被使用
  • PASSIVE_BAKED = 11 # 被动量化且静态量化,当前config不生效,数据可以直接使用
  • FP32 = 12 # 表示这一路输入直接为FP32浮点数

其中最常见的量化状态是 INITIAL -> ACTIVATED -> BAKED,大部分量化都遵循这样的状态变迁。在一开始,Quantizer负责为所有 TensorQuantizationConfig 初始化状态,即全部初始化为 INITIAL。而后 Quantizer 负责将 Conv, Gemm 中的 bias 修改为 PASSIVE_INIT 状态,这表明需要 PPQ 对 bias 展开被动定点逻辑,只有bias的量化处于 PASSIVE_INIT 时它的量化参数才会被 input scale * weight scale覆盖,否则bias将执行主动定点逻辑,生成自己的量化参数。

当你修改了此处的状态初始化,如果你将其修改为 INITIAL,则 bias 执行主动定点,会通过 observer 给自己确定一个独立的scale 和 offset,你的推理框架可能会向你报告错误。如果你将其修改为 FP32,则会直接撤销 bias 的定点过程。修改为其他状态可能会造成执行错误。

在 PPQ 中量化是这样发生的:

  1. 由 Quantizer 负责初始化状态,写明位宽,截断值等基本信息。
  2. 由 QuantizeReducePass 负责关闭一些多余的量化信息,被关闭的量化信息状态为 OVERLAPPED,同时建立父子连接。
  3. 由 QuantizeRefinePass 负责修正量化错误,即强制要求 'Reshape', 'Slice', 'Gather', 'Resize', 'Split' 的部分输入不可量化,状态置为 SOI。
  4. 由 QuantizeRefinePass 负责修正量化错误,即强制要求 'Clip', 'Pad' 的部分输入状态为 PASSIVE_INIT。
  5. 由 RuntimeCalibrationPass 或者 ParameterQuantizePass 负责处理状态为INITIAL的量化信息,寻找合适的 scale 与 offset,并将量化状态置为ACTIVATED。
  6. 由 PassiveParameterQuantizePass 负责处理状态为 PASSIVE_INIT 的量化信息,并将这些它们的状态设置为 PASSIVE。
  7. 如果开启了PPQ的训练功能,则由 ppq/quantization/optim/training.py 中的一系列 pass 对 scale 和 offset 进行微调
  8. 如果开启了parameter_baking,则由 ParameterBakingPass 负责处理所有状态为 ACTIVATED 或 PASSIVE 的参数,对他们执行量化烘焙,直接将其数值替换成量化后的值,同时将状态转换为 BAKED 或者 PASSIVE_BAKED

@Menace-Dragon
Copy link
Author

原来是这样,感谢😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants