ppq icon indicating copy to clipboard operation
ppq copied to clipboard

混合精度量化支持吗?会结合考虑实际板上推理速度吗?能否推荐一些确实work且好用的论文或方法~?

Open 666DZY666 opened this issue 1 year ago • 12 comments

666DZY666 avatar Aug 10 '22 13:08 666DZY666

你是说int 8/fp 16那种混合还是int 1/2/3/4/5/6/7/8那种混合?

ZhangZhiPku avatar Aug 10 '22 13:08 ZhangZhiPku

int 1/2/3/4/5/6/7/8

666DZY666 avatar Aug 11 '22 09:08 666DZY666

从量化这个角度来看,PPQ支持去模拟1/2/3/4/5/6/7/8比特的混合精度推理,基础的优化过程都已经针对这类量化做了准备,应该只需要改一下quantizer和调度器就可以了。 然而从部署角度看,我的看法是这种混合比特完全没有实际意义与部署价值,理由大概有几条:

首先,大部分芯片是没有2/3/5/6/7比特运算器的,这几乎从根本上就否决了方案的可行性,它们几乎不会带来任何加速效果:一个6bit的加法,你仍然需要把它当作8bit去加,只可能在访存上稍微占点优势。于此同时你会引入一个额外的内存拆包封包的开销,因为我们没办法给你去做3 bit寻址,只能是pack到32,64,128bit去处理,这写起来会很麻烦。而且搞不好我有些算子比如softmax, sigmoid这种,我1/2/3/4/5/6/7/8比特对应8个不同的实现。

其次,不同位宽的混合对图融合逻辑会带来挑战。我们举例来说一个add算子,输入两个卷积conv1(4bit)与conv2(3bit),那么这个时候我到底融不融conv-add,融了的话这个add我是fp32算,还是可以直接上int16的累加器?抑或是说因为我前面两个conv不同精度,我根本就融不了?gpu, npu 这类器件吞吐能力极强,图融合对他们来说是尤为重要的,如果这里你的混合精度导致他有些图融合不能做,运行效率就会成倍的下降。那么为了模型能运行的快,我们需要把所有图融合策略全部拿过来研究一遍,探讨各种情况。

再举一例,对于concat这个算子,假设他有5个输入。你不可能concat 5个不同位宽的东西,这里必须要精度转换,这一次精度转换的代价很可能让你前面的量化全部白干。也就是我们必须首先在调度的时候就把concat的输入分支调度到同一个精度上,split的输出分支调度到同一个精度上,与之类似的算子还有 add, mul, div, sum, sub...

前面这几个因素放在一起,我的结论很明确:混合精度的性能优势微乎其微。而这几乎可以忽略不计的速度优势,却要算子实现、调度、图融合的三方支持才可能做到,任何一个环节出了问题,性能就会非常糟糕。

ZhangZhiPku avatar Aug 11 '22 14:08 ZhangZhiPku

谢谢回复。 有没有比较好的混合精度搜索论文推荐?HAWQ? 之前ppq里的这部分似乎去掉了?

666DZY666 avatar Aug 11 '22 14:08 666DZY666

啊你一直在关注ppq吗,去掉的原因主要是因为我们发现HAWQ算半天(30分钟)的效果还不如直接跑一下layerwise_analyse(1分钟),然后调损失较大的层送上高精度平台即可...屡试不爽。而且部署上也没人会用这个混合精度部署,我们的调度策略更多是去满足部署侧的需求,比如精度不够我送几个层回fp32,比如复杂网络结构我要探测那些算子可以量化那些不行。

而且你知道我们不希望PPQ变成一个方法大杂烩,PPQ已经是目前最为复杂的量化框架之一了,0.6.5版本以及后续的更新都不会轻易地添加优化过程或者调度逻辑到标准流程中来。我们更希望提供足够可靠实用方法,比如精度方面我们推荐用户以算法+调度相结合的方式解决问题;性能方面我们推荐用户多去profile自己的网络,理解图融合,运算-访存比等概念,从而设计出更合理的网络结构。

与此同时我们也陆续开放了 operation forward, quantizer, parser, exporter 的自定义接口,并即将推出完整的使用样例。这是我们所希望看到的,PPQ在一个稳定统一的框架之下描述量化的每一个细节,生成符合硬件约束条件的量化信息,同时让用户自由实现定制化的开发,针对自己的硬件书写量化规则。

而我们将尽最大努力保证PPQ的稳定性、可用性、以及执行效率。

ZhangZhiPku avatar Aug 11 '22 15:08 ZhangZhiPku

okok,这种屡试不爽的方法有完整example或test吗(误差分析+bits 分配)? 误差用哪种最好('cosine', 'snr', and 'mse')?有啥经验吗?

666DZY666 avatar Aug 12 '22 02:08 666DZY666

容我晚些时候写一个例子给你,误差我会用snr,因为有数学依据啊...

ZhangZhiPku avatar Aug 12 '22 04:08 ZhangZhiPku

okok~

666DZY666 avatar Aug 12 '22 08:08 666DZY666

关于误差,ppq里是看qt_output和fp_output的差距, 是否有实验过:1、qt_output和label的loss;2、qt_output和fp_output与label的loss的差距~?

666DZY666 avatar Aug 12 '22 09:08 666DZY666

关于误差,ppq里是看qt_output和fp_output的差距, 是否有实验过:1、qt_output和label的loss;2、qt_output和fp_output与label的loss的差距~?

不同网络loss计算方式不同,构建起来很“麻烦”,有时甚至不知道loss的设计,qat中需考虑任务loss,ptq的话直接衡量cos就行,常规模型cos(fp, int8)>0.99精度都满足,画质类要求更高一些

Jzz24 avatar Aug 12 '22 10:08 Jzz24

okok~

666DZY666 avatar Aug 12 '22 10:08 666DZY666

@666DZY666 你可以尝试下面这个文件中的内容,为了使得它能成功运行,你可能需要切换到我的开发分支上。

https://github.com/openppl-public/ppq/pull/207/files#diff-550e5d58f4eb3955decf84a9bdd7bdc7a7311843193260d12a240fd626390be7

ZhangZhiPku avatar Aug 15 '22 14:08 ZhangZhiPku

okok,多谢~

666DZY666 avatar Aug 16 '22 08:08 666DZY666

@666DZY666 开发分支已经合并到主分支,现在你可以使用主分支上的内容完成测试了

ZhangZhiPku avatar Aug 17 '22 08:08 ZhangZhiPku

好的~

666DZY666 avatar Aug 17 '22 11:08 666DZY666

demo中的bits是[4, 8]可选,若是[1, 4, 8, 16]呢?

666DZY666 avatar Aug 18 '22 04:08 666DZY666

那怕是你要自己写int1, int16平台quantizer对应的逻辑... 额可能还得自己在ppq.core.quant里面写个平台叫INT1, INT16...

ZhangZhiPku avatar Aug 18 '22 06:08 ZhangZhiPku