PaddlePaddle / PaddleDetection

Object Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection.
Apache License 2.0
12.38k stars 2.84k forks source link

Bug of quant-aware training of tinypose ! #6365

Closed 2050airobert closed 1 year ago

2050airobert commented 2 years ago

问题确认 Search before asking

bug描述 Describe the Bug

@yghstill TinyPose模型的自动化压缩代码整理完成了:https://github.com/PaddlePaddle/PaddleSlim/tree/develop/demo/auto_compression/detection 配置文件是:configs/tinypose_qat_dis.yaml,启动方式和readme中完全一致,如果全量化的话可以先使用这个 上面是你说的话,可是出现了几个问题。 1 你给出的这个链接 404打不开了,于是我找到了其他的位置,找到你说的yml,运行程序 2 python3 -m paddle.distributed.launch --log_dir=log0705 --gpus 0,1 run.py --config_path=./configs/tinypose_qat_dis.yaml --save_dir='./output0705/'
python3 run.py --config_path=./configs/tinypose_qat_dis.yaml --save_dir='./output0705/'
以上两种方式都尝试了,可是报错如下 image image 请大佬能认真帮忙看下吗? 3 是否有真正的可复现而且无bug的版本发出来,是否可以进行自测再发出来,多谢

BR

复现环境 Environment

       paddle-gpu 2.23 以上
       paddledet release/2.4
       paddleslim develop
       cuda 11.3
      pytorch 跟cuda配套

是否愿意提交PR Are you willing to submit a PR?

yghstill commented 2 years ago

@2050airobert Paddleslim已经发布2.3.0版本,之前的代码位置有所改动,请使用正式版代码再试下吧:https://github.com/PaddlePaddle/PaddleSlim/tree/release/2.3/example/auto_compression/detection 请安装PaddleSlim 2.3.0版本再试下:

pip insyall paddleslim==2.3.0

如有问题,请再将报错详细log发出来~

2050airobert commented 2 years ago

hi, 1 我已经在这个分支上了,您仔细看下 image 2 另外, 您仔细看 weight_quantize_type: 'channel_wise_abs_max' # 'abs_max' is layer wise quant 这里只是实验了perchannel 量化,但是我们需要的应该是perlayer 全量化,这个这版能训练起来了么? image 3 另外您再仔细看下我上面的过程和问题,帮忙check下到底是哪里的问题,或许您合入的时候没有做回归还是? BR

yghstill commented 2 years ago

@2050airobert 你的问题没有复现,重新安装下paddleslim2.3.0,然后代码也更新下试下呢? 如果评估精度的话,PaddleDet安装需要手动编译安装最新的release 2.4或develop分支,因为依赖这个PR:https://github.com/PaddlePaddle/PaddleDetection/pull/6223

2050airobert commented 2 years ago

1 我理解您说的,可问题是我确实满足您说的条件,也是按照您说的来的,上面的证据再加一个下面的截图证据 image 2 我的建议是能不能就事论事,看下这个问题,为啥不支持这些参数呢? 这些参数明显是你的auto compression里面的,而且我确定的是之前不用auto compression框架,直接quant config里面的方式是可以训练起来的,只是当时精度不行,您这版没有延续发布在quant config里面的方式,而是非要采用auto compression的方式,产生了相应问题,是否可以解释下? 3 您还需要什么信息我可以提供,或者弄好反馈给您? 多谢

2050airobert commented 2 years ago

@yghstill 1 确实是因为版本更新导致的,依赖有点。。。 我再试试 看结果如何? 别急 大佬 2 另外, 您仔细看 weight_quantize_type: 'channel_wise_abs_max' # 'abs_max' is layer wise quant 这里只是实验了perchannel 量化,但是我们需要的应该是perlayer 全量化,这个这版能训练起来了么? 3 这个qat训练需要输入模型吗? 还是下面的模型是qat训练的输出呢?大佬 image 4 我可以直接用这个qat训练 训练 coco train 所有的数据集,然后一次性训练出来最优map的网络模型而且输出就是qat 量化模型吗? 我的意思是输入不用给coco train训练好的模型 直接用这个qat边训练边量化 出一个最优map的模型?大佬 BR

yghstill commented 2 years ago

perlayer是支持的,加载的模型是fp32训好的模型,需要先训好fp32模型再进行量化蒸馏,如果想要QAT训练,目前只支持部分量化,不支持全量化。

2050airobert commented 2 years ago

非常感谢您的准确回答,期待不错的结果,只是还有点问题 1 qat 部分量化的最优结果跟您这版本的 qat离线全量化的结果 ,tinypose关键点的位置精度哪个更好,差别大概有多少? 包括ap掉点 2 qat在线训练全量化大概什么时候可以支持tinypose? 3 为啥这个auto compression 一定要加上蒸馏操作呢? 可以注释掉吗? 如果注释掉会掉点多少呢? image 期待您的答复,再次感谢

yghstill commented 2 years ago

部分量化和auto compression精度相差多少还没对比,先提供了全量化的auto compression的这个配置。 QAT支持全量化是功能性的开发,我们下个Q会开始规划支持。 node的参数可以删除,会默认增加蒸馏节点,无需手动设置。

2050airobert commented 2 years ago

tks,还有个小问题 1 目前来看应该qat跑起来了,截图如下 image image 但是由于一直卡在这里,估计有几个小时了,我的batchsize给从16改为128了,为啥一直没有log出来,不像大多数training可以不断地有batch的log出现。 2 如何判断我的qat训练正常,是否可以打开log设置,查看中间过程? 3 据我所知,部分量化的偏差还是蛮大的,之前我跟lite同事一起试过,不知道lite是否跟你们反馈过,不太可用。所以才做了全量化的你这个版本,所以训练完后我会评估下最终的map有多少,对比下,到时候给您反馈,好吧? 4 你刚发布的qat全量化版本运行后中间结果会带有eval 这个结果可信吗?如果可信为什么总是接近于0的map ,是哪里我搞错了吗? 请帮忙check下 好么? image 5 对于上面的问题4 ,如果暂时在训练过程中答应map指标等,我可以最后评估,于是按照readme的指示,结果如下 1657102826063 确实生成了新模型 image 请问下为何无法评估,是目前还不支持吗? BR

yghstill commented 2 years ago

@2050airobert fp32模型评估精度正常吗?

2050airobert commented 2 years ago

不正常啊! 麻烦您看下我上面几个问题,多谢

yghstill commented 2 years ago

@2050airobert 先验证正确fp32模型再进行压缩吧,确认下输入shape、预处理过程是否一致?https://github.com/PaddlePaddle/PaddleSlim/blob/develop/example/auto_compression/detection/configs/tinypose_reader.yml#L37

2050airobert commented 2 years ago

hi,guanghua 您理解的跟我说的不一致,我再重复一遍哈,就是我的意思是我的fp32模型是非常专业而且准确的,我们之前项目都用过测试过。更重要的是这是官方paddle亲自发出的版本,如果有问题,不可能一直半年保持在上面不动的。tinypose128x96模型的官方版本,您可以复测下。所以还是麻烦您关注下我的提问,和实测遇到的问题,而不是停留在纸面,拜托详细分析下我遇到的问题。上面的问题您几乎都可以复现,有问题我可以帮助的话,尽管说就好, 全力支持

yghstill commented 2 years ago

@2050airobert 确认了下,是normalize加不加进网络的区别,

image

已经提交PR适配了下,参考修改下就可以了:https://github.com/PaddlePaddle/PaddleSlim/pull/1267

2050airobert commented 2 years ago

非常专业, 1 可是还是有问题,log如下: image 2 我的配置文件如下 麻烦您看下是不是哪里配置有问题,我的coco数据集在其他目录,我的配置里面都体现了位置,是不是还有特殊的要求? image 3 您这个bug fixed 代码就是这个read yml代码改动吧,我只要合入这个改动,正常评估eval就行? 还是我必须重新 train qat量化才行?

yghstill commented 2 years ago

@2050airobert

  1. 看你的报错,是数据集的问题,img_path索引错误
  2. image_dir和anno_path设置成dataset_dir的相对路径试下呢?TrainDataset也设置下?
  3. 正常eval就行,自动压缩时加载fp32训好的模型即可,不用加载qat之后的模型。
2050airobert commented 2 years ago

很感谢, 1我更改为绝对路径,然后上面两个设置为相对路径,按照您的意思 具体rux如下 image 上面的部分没有改动。 2 另外我的另一个文件配置如下 image 我确保coco数据集的路径都是有的,图片和标注都有,没问题,但是还是哪里填写错了呢? 3 备注 我非常确定的是之前三个都用绝对路径的配置,qat 训练是可以跑起来了的,看起来前半部分是蒸馏后面是逐步的训练量化,还有中间log,直到最终迭代结束。qat训练training跑通没问题,但中间结果都是 map ap recall几乎都是0,显然也不对,不知道问题到底在哪呢? 劳烦大佬能帮忙分析下问题?多谢

yghstill commented 2 years ago

根据你的报错代码位置打印下为什么索引不到,是不是路径有误等

image

也可以使用coco数据集验证下官方demo是否能跑起来。

2050airobert commented 2 years ago

@yghstill exactly ,你说的很对 第一,问题是我确实路径设置对了,coco数据集也是正常的,都有图像在,不应该一张jpg都加载不进来。 于是我做了下实验,假如我故意把路径设置错误,于是会出现warning并且程序会尝试自动下载coco数据集,我马上停止。 当我改为正确的img jpg路径的时候,就不会出现warning了,接下来会出现的error就是上面你看到的。这里,到底隐藏了一个什么大的bug呢? 问题在哪呢? 能细心分析下root cause吗?

[07/07 08:20:24] ppdet.utils.download WARNING: Config image_dir /app_lcl/paddle_test/HRNet-Human-Pose-Estimation/data/coco/val2017 is not a directory, dataset config is not valid [07/07 08:20:24] ppdet.utils.download INFO: Dataset /app_lcl/paddle_test/HRNet-Human-Pose-Estimation/data/coco is not valid for reason above, try searching /root/.cache/paddle/dataset or downloading dataset... 第二,在同样的路径配置下,确实可以qat 训练起来,只是结果map 等中间指标都不正常。 我怀疑是不是detection2.4版本哪里的接口配置不对导致的,您那边没遇到该问题吗? 或者说您用的是? 您仔细看下这个log 里面 调用了paddledetection 这很奇怪。。 File "/usr/local/lib/python3.8/dist-packages/paddledet-2.4.0-py3.8.egg/ppdet/metrics/keypoint_metrics.py", line 191, in accumulate self.get_final_results(self.results['all_preds'], File "/usr/local/lib/python3.8/dist-packages/paddledet-2.4.0-py3.8.egg/ppdet/metrics/keypoint_metrics.py", line 152, in get_final_results 'image': int(img_path[idx]) 第三,假如一定要下载 coco数据,那指定的位置在哪才对呢? 我可以直接拷贝过去啊。 然而,以我的经验来看,这不是一个好的release 设计,不应该出现在release版本中吧?麻烦大佬建议下如何修改? image

2050airobert commented 2 years ago

hi, 1 评估正常了,但是评估后发现全量化之前的map很高,但是全量化训练后的model,map指标为接近0,明显异常。 这个worknum必须设置为2吗? 推荐设置是? image

2 具体训练过程的log如下,会在开始的时候卡住一会,不知道在干嘛,后面会逐个batch出log,麻烦大佬解释下呗? image 3 需要专门加一个 is_full_quantize = true 吗?

yghstill commented 2 years ago

@2050airobert

  1. 目前动态图量化训练QAT可以完成模型部分量化,但不支持全量化,这个功能有待完善,具体支持的时间也不能确定。所以你的任务有两种方案:(1)使用自动化压缩工具做量化,每个op会保存一个out_threshold属性,lite端就可以完成全量化推理。is_full_quantize这个可不加。(2)QAT+PTQ方案:先动态图量化训练导出模型,然后使用离线量化,将https://github.com/PaddlePaddle/PaddleSlim/blob/cf8bbf3ce1c50f9e5f83720d4a1b5d477767056a/paddleslim/quant/quanter.py#L368 将quantizable_op_type设置为[], 这样可以保证动态图QAT量化过的op不再量化,未量化的op执行校准scale的过程,最终的模型可以用lite在npu上部署。
  2. 开源的配置文件在coco数据集上表现还可以,但不确保在自定义数据集上可行,可以weight_quantize_type设置成'channel_wise_abs_max'看下精度是否正常。如果正常,那么pre layer的量化方式不太适合这个模型,请咨询下lite目前是否支持了最新的pre channel量化,或者重新技术选型,试下其他模型。
  3. 由于人力有限,但tinypose后续还会继续完善npu部署,感谢持续关注~
2050airobert commented 2 years ago

感谢您准确的归纳总结。 但最重要的是我上面采用了方案一“(1)使用自动化压缩工具做量化。。。”,发现了在qat 全量化的时候,中间会带有eval指标log,如下 image 从图中可以看出,很明显的问题就是您发布的这个qat量化导致本来map很高的模型逐渐变成一个不能用的map几乎为0的模型 这是怎么回事能解释下吗? 我甚至用最后结束训练后的模型试了一下,python eval.py --- 之后还是map几乎为零。这明显不对啊! 是哪里的问题呢?大佬 能帮忙分析下吗? 您那边可以把log 截图过来 看下是否正常吗? BR

yghstill commented 2 years ago

@2050airobert 你试过coco上官方发布的模型吗?我这边测试自动化压缩这个demo,AP可以到48左右

2050airobert commented 2 years ago

是的呀 我确实用的就是你官方发布的模型,你看下他原始的map非常高 998ac486b15441a1627e05681ca1f81 我的训练集配置不是发给你了 也是coco的 不过我的qat训练采用的是 coco的 eval数据,你的配置应该也是如此吧?

yghstill commented 2 years ago

@2050airobert 配置文件改了哪些地方?weight_quantize_type保持channel_wise_abs_max不变吗?abs_max这个没有验证调试

2050airobert commented 2 years ago

其实为了复现你的结果,我基本没动,除非数据目录不同,我稍微改下 image

yghstill commented 2 years ago

is_full_quantize这个删掉试下吧

2050airobert commented 2 years ago

其实这是我试过你原始的不行才加上的,结果一样错 您好需要什么配置信息 我发你,实际上我开始git clone下来基本没变的话,都是这种结果,我试过很多改动,从来没出现过一次不是0的。。。 我的配置都是按照你说的 pdet 版本 和pslim版本都对齐了 还有地方可能不同?

2050airobert commented 2 years ago

实在不行,可以把您的版本打包发下呗? 我验证下 可以吗?

yghstill commented 2 years ago

@2050airobert https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.4/configs/keypoint/tiny_pose/tinypose_128x96.yml#L147 你将fuse_normalize设为False,然后Reader还是保持修改PR之前的设置再试下吧,我这边复现,fuse_normalize=Ture的是会有问题

2050airobert commented 2 years ago

不对啊,你这个改动的是paddle detection里面的文件,可是我用的slim采用的是你的方法一,qat全量化方式,我应该改动的文件是 tinypose_qat_dis.yaml 和 tinypose_reader.yml ?

2050airobert commented 2 years ago

如果你怀疑输入的模型有问题,您可以给我一个你那边验证没问题的模型 pdiparam 和pdmode info.yml infoxxx四个文件打包给我下就好

2050airobert commented 2 years ago

另外我能提个建议吗? image 你看你这个程序执行的时候也不知道在做什么,开始有很长一段时间都卡在这,当然过了几个小时之后会出一些迭代的log,这个能解释下吗? 或者可以中间出一些log提示,如果有问题就停掉了。 另外这个程序正常全量化 2X 3090两个卡上需要几个小时呢?