本文为笔者个人见解,如有不同意见欢迎评论
1.引言
为了节省端侧计算资源以及简化部署工作,目前智驾方案中多采用动静态任务融合网络,地平线也释放了 Lidar-Camera 融合多任务BEVFusion参考算法。这种多任务融合网络的浮点训练策略可以简述为:
首先在大量数据的条件下完成多任务模型backbone部分的浮点训练;
然后,固定 backbone的权重,分别接多个 task head进行单独的训练。
在这种浮点训练策略下,QAT(量化感知训练)里的 calibration(校准)和量化训练策略跟常规的单 task 模型差别较大。常规的单 task 模型一般就是用那种比较固定、普遍适用的训练办法,不过碰到复杂多变又有特定需求的情况,它的局限性就慢慢显现出来了。
这篇文章会结合具体的场景,对 calibration 和量化训练策略进行分析,然后提出一些笔者个人独特的看法,希望相关领域的研究和实践提供点有用的参考和启发。
2.量化训练策略
本文将以具有两个任务头 task_head1 和 task_head_2 的多任务模型为例进行描述。
2.1 步骤描述
此步骤的前提是模型已完成浮点训练。
在进行后续操作之前,必须确保模型已经成功地完成了浮点训练。只有在这个前提条件得到满足的情况下,才能保证后续的工作能够顺利进行,并且得到准确和可靠的结果。
step1:
首先对骨干网络(backbone)进行校准/量化感知训练(calibration/qat),在满足量化精度要求后,保存校准/量化感知训练的权重(calib/qat 权重)。
step2:
验证 step1 中 backbone 在部署 head 上的精度,具体操作是对 backbone 进行伪量化处理,而task_head1 和task_head2保持浮点计算,然后在验证集上测试这两个 head 的精度。
step3:
对部署的 task_head1和 task_head2做finetune,从而使得task_head1和 task_head2去适应 backbone,直到浮点精度符合预期;
固定backbone,对 task_head1做calib和QAT(backbone 的weight和scale不更新)
固定backbone,对 task_hea2做calib和QAT(backbone 的weight和scale不更新)
固定backbone 的weight和scale的方式见下文。
step4:
固定backbone的weight和scale,然后分别对 task_head1和 task_head2做calib/qat;
2.2 固定weight的方式
固定weight采用pytorch的方法,包括固定bn和stop梯度更新这两个操作,如下所示:
2.3 Fix weight和activation scale的方式
2.4 示意图
本节将会针对上述步骤展开详尽且全面的图文阐释,通过清晰直观的图片和详细准确的文字说明,为您逐步剖析每个步骤的关键要点和操作细节。
2.4.1 验证 backbone变化对 head的影响
此步骤的验证前提是backbone已经完成了 calib/qat,并且伪量化精度已经满足预期,这里建议backbone的伪量化精度要达到浮点精度的 90% 以上。
模型改造:在backbone的forward代码的输入端插入 Quanstub,输出端插入 Dequanstub;
加载权重:在prepare之前加载 task_head1 或者 task_head2 的浮点权重, 在prepare之后加载backbone的 calib/qat权重,这里要特别注意加载权重的顺序;
calibration:配置模型状态(如下图),注意这里模型的状态要配置为 VALIDATION,然后进行伪量化的精度的验证;
如果某个 head的精度较差,那么将固定 backbone的权重,对此 head的权重进行微调。



