1. 背景简介
当发现使用plugin 精度debug工具定位到是某个linear敏感时,示例如下:
可以发现,model.linear2 weight排在了前面,且是int8量化。
接下来看下baseline_statistic.txt与analysis_statistic.txt,其中有model.linear2的input、weight、output的数值分布范围,示例如下:
解决方案:使用int16来量化这个敏感linear的weight。
如果必须要求linear input weight output都是int16量化,怎么办呢?
2. 知识基础
在J6E/M上,地平线BPU对linear支持的情况如下:
本文发布时是这样的

可以看到:input和weight不能同时为int16。
3. Linear input weight both int16
对于linear input和weight均需要int16量化的情况,可使用broadcast mul sum来替代验证,无需重训float。
异同简介:broadcast_mul_sum_replace_linear在float层面可以等价替换linear,但在量化方式上存在区别:Linear weight是per channel量化,weight作为mul输入时,是per tensor量化。一般情况下:weight int8 perchannel变成 per tensor int16,精度是正向优化。
替换方案:在float训练完成后替换,然后进行calib+qat。
broadcast mul sum替换方案,均支持int16。
注意事项:如果mul的输出 绝大多数 数值都在0附近 -> MSE校准受异常值影响较大 -> 输出scale非常大 -> 0附近的大量小数值被舍入成0 -> sum和发生巨大偏差。
影响范围:mul后面跟着sigmoid 或 add+sigmoid时影响很大。
解决方案:mul输出设置fixed scale为7/32767,因为sigmoid并不需要太大的输入,而mul的输出分布需要小scale。
4. 全流程示例
从表中可以看到,在linear需要int16量化的场景,input/output int16对应的latency最短,其次是weight output int16 input int8,最差的是三者都需要int16,针对这三种情况,下面分别提供完整的例子供参考。

注意:非完全等价,仅作为参考
4.1 示例代码
4.2 比较替代方案的输出一致性
linear2 weight input output int16
broadcast mul sum int16

