关于美团:通用目标检测开源框架YOLOv6在美团的量化部署实战

40次阅读

共计 7205 个字符,预计需要花费 19 分钟才能阅读完成。

基于美团指标检测模型开源框架 YOLOv6,本文提供了一种通用的量化部署计划,在放弃精度的同时大幅晋升了检测的速度,为通用检测的工业化部署摸索出一条可行之路,心愿能给大家带来一些启发或者帮忙。

1. 背景和难点

YOLOv6 是美团公布的一款开源的面向工业利用的 2D 指标检测模型 [1],次要特点是速度快、精度高、部署敌对,在美团泛滥视觉业务场景中都有着宽泛的利用。通过量化(Quantization)晋升推理速度是理论工业利用中的基本操作,但因为 YOLOv6 系列模型采纳了大量的重参数化模块,如何针对 YOLOv6 进行高效和高精度的量化成为一个亟待解决的问题。本文旨在解决 YOLOv6 量化方面的难题,并以 YOLOv6s 模型为例,从训练后量化(Post-Training Quantization, PTQ)和量化感知训练(Quantization-Aware Training, QAT)两个方面进行剖析,摸索出了一条切实可行的量化计划。

YOLOv6 采纳了多分支的重参数化构造 [2](如图 1A 所示),通过在网络结构层面退出人工先验能够在训练阶段让模型更好收敛。在推理阶段,多分支能够等价合并为单路,从而晋升运行速度。但现有的训练后量化办法,不能很好应答多分支构造带来的激烈变动的数值范畴,导致量化后产生重大的精度损失 [3]。另外,如何针对多分支结构设计量化感知训练(QAT)办法也面临着较大的挑战。蒸馏常被用来辅助 QAT 晋升性能,但如何利用 2D 指标检测的蒸馏办法来辅助 YOLOv6 模型的量化,也须要设计正当的计划在理论利用中进行测验。

![图 1 多分支构造重参数化过程(A)构造变动(B)参数变动(起源:[2])](https://p0.meituan.net/travel…)

2. 量化计划实战

2.1 重参数化优化器

YOLOv6 网络中大量应用重参数化构造,在进步模型训练精度的同时可能显著升高模型部署推理延时,但也带来了模型量化部署方面的难题。对重参数化网络的间接量化个别会带来不可承受的精度损失,例如 RepVGG-B1 [2] 网络在 ImageNet 数据集上的浮点精度为 78.42%,采纳 TensorRT 后量化(PTQ)的量化模型精度则升高为 54.55%。

此外,因为重参数化构造在训练和部署时构造不同,因而无奈间接适配现有的量化感知训练(QAT)办法,如何应用 QAT 办法来进步 YOLOv6 量化模型的精度,同样存在着挑战。近期,一篇重参数化优化器的工作 RepOpt [3] 较好地解决了重参数化构造的量化问题。

2.1.1 RepOpt

RepOpt [3] 对重参数化构造量化艰难的问题进行了钻研,发现重参数构造的分支交融操作,显著放大了权重参数散布的标准差。异样的权重散布产生了过大的网络激活层数值散布,进一步导致该层量化损失过大,因而模型精度损失重大。

鉴于此,咱们统计了基于 RepVGG 构造的 YOLOv6 模型(YOLOv6s_repvgg)各层的权重及激活数值散布,剖析了 YOLOv6 中的重参数化层的数据分布。下图 2 以“Rep_p4.block.0.rbr_reparam”层为例,给出其特色图数值散布直方图,咱们发现其数值宽泛散布在 [0, 57] 的区间内。显然,采纳现有的 INT8 量化办法,无论怎样抉择量化缩放参数(scale),都会产生较大的量化误差。

为解决这一问题,RepOpt 提出了一种基于优化器的重参数化设计(如下图 3 所示),通过梯度掩码(Gradient Mask)的形式在网络训练反向流传的过程中退出先验,保障了训练精度可达到 RepVGG 相近的程度,而网络结构则在训练和推理阶段始终保持一般的 VGG 构造,这种训练方法请参考 RepOpt [3]。该工作中提出的 RepOpt-B1 网络模型,在浮点精度与 RepVGG-B1 基本一致的状况下,量化模型精度晋升超过 20%,极大地改善了重参数化网络的量化掉点问题。此外,RepOpt 模型的训练速度快,内存占用也比拟低。

2.1.2 RepOpt 版本的 PTQ

咱们实现了 RepOpt 版本的 YOLOv6s 网络(YOLOv6s_repopt),达到了与 YOLOv6s_repvgg 统一的浮点精度 42.4%(300 epochs),两个版本的网络结构在部署阶段保持一致。咱们首先剖析了 YOLOv6s_repopt 模型的数据分布特色。

如图 2 所示,给出了“Rep_p4.block.0.rbr_reparam”层的特色图数值散布直方图,能够看到数值严密散布在 [0, 10] 的区间内,相比 YOLOv6s_repvgg 的数值散布对于量化操作更加敌对。进一步采纳 TRT 的后量化办法进行模型量化部署,能够看到 YOLOv6s_repvgg 的量化网络精度升高了 7.4%,在理论工程中根本不可用。而 YOLOv6s_repopt 网络的量化模型精度为 40.9%,精度损失仅为 1.5%,相比原版模型有了极大的改善。

2.1.3 RepOpt 版本的 QAT

此外,应用 RepOpt 构造解决了本来的 RepVGG 网络无奈间接应用现有量化感知训练的问题。对于构造重参数化的 RepVGG 网络,如何应用 QAT 来复原量化模型精度,咱们始终存有困扰。如下图 4(左)所示,如果对重参数化操作之前的多分支网络进行 QAT,对每个分支别离增加伪量化算子进行量化感知训练,因为每个分支的量化参数不同,导致多分支构造无奈等效交融进行高性能部署;如果对重参数化操作之后的单分支网络进行 QAT,因为网络中不再有 BN 层,应用 QAT 办法进行微调并不容易复原到浮点精度。而对于 RepOpt 构造网络则不存在这一问题,因为 RepOpt 在训练和部署中网络结构是保持一致的。

如图 4(右)所示,对 RepOpt 的卷积等算子退出伪量化节点进行量化感知训练,晋升量化模型精度,而后间接部署该量化模型,而不须要再进行模型交融的操作。后文,咱们将给出具体的 QAT 算法及对模型精度的晋升后果。

2.2 基于量化敏感度剖析的局部量化

YOLOv6s_repopt 在 PTQ 后的 mAP 达到了 40.9%,尽管比之前的 35.0% 有了很大的改善,但依然有 1.5% 的精度损失,还无奈满足业务需要。因而,咱们采纳了局部量化(Partial PTQ),一种使网络中的局部量化敏感层复原浮点计算,来疾速复原量化模型精度的办法。首先须要对网络中的每一层都进行量化敏感度剖析。

咱们在 YOLOv6s-repopt 网络上对罕用的敏感度分析方法均方误差(MSE)、信噪比(SNR)、余弦类似度(Cosine Similarity)进行了比照测试。量化校准(calibration)测试应用 4 个 batch 的数据,敏感度计算用 1 个 batch,batch 大小设置为 32。

测试时,每次只对一层进行量化,获取该层的激活数据后计算敏感度数值,代表了该层的量化敏感度。作为比照,咱们能够间接计算网络在 COCO val 数据集上的 mAP,应用检测精度作为该层的量化敏感度,即检测精度越高,该层敏感度越低(下文称为 mAP 办法)。

测试后果如下图 5 所示,咱们对测试后果进行归一化后,从不同敏感度剖析后果中抉择敏感性最高的 6 层跳过,计算局部量化精度。

局部量化精度如下表 3 所示,能够看到:mAP 办法获得了最好的成果,可能无效代表 YOLOv6 敏感度剖析后果。但因为 mAP 办法须要频繁地计算验证集精度,耗时太久且容易过拟合验证集,因而在理论我的项目中为了谋求效率,咱们倡议应用 MSE 办法。

2.3 基于通道蒸馏的量化感知训练

至此,咱们优化后的 PTQ 的精度达到了 42.0%,进一步提高模型精度须要引入量化感知训练(QAT)。量化感知训练(Quantization Aware Training, QAT)能够改善 PTQ 量化精度损失,通过在训练过程中对卷积等算子退出伪量化操作(如图 4 所示),使得网络参数能更好地适应量化带来的信息损失,从而显著升高量化后的精度损失。

模型蒸馏作为一种无效的晋升小模型精度的办法,在 QAT 过程中被宽泛应用,来晋升量化模型的精度。以下,咱们将摸索针对 YOLOv6 网络的量化感知训练方法。

2.3.1 通道蒸馏

传统的分类网络在蒸馏时,往往对最初一层输入的 logits 进行蒸馏;然而在检测网络中个别采纳“特色图”蒸馏的办法,间接让学生网络(student)输入的特色图拟合老师网络(teacher)输入的特色图(个别不会选取整个特色图,而是一些感兴趣区域)。

这种办法的缺点是特色图中的每个 pixel 对蒸馏的损失奉献雷同。咱们采纳了每通道散布蒸馏 [6],即让 student 输入的每个通道的散布拟合 teacher 输入的每个通道的散布。两种办法的区别如下图 6 所示:

2.3.2 YOLOv6 量化感知蒸馏框架

针对 YOLOv6s,咱们抉择对 Neck(Rep-PAN)输入的特色图进行通道蒸馏(channel-wise distillation, CW)。另外,咱们采纳“自蒸馏”的办法,老师模型是 FP32 精度的 YOLOv6s,学生模型是 INT8 精度的 YOLOv6s。下图 7 是一个简化示意图,只画出了 Neck 的一个分支:

如下表 4 所示,在 Partial QAT 中引入通道蒸馏计划(CW),量化精度进一步晋升了 0.3%。

3. 部署时优化

3.1 图优化

量化部署时,能够间接利用 TensorRT 的 PTQ 接口进行生成量化引擎,然而这种办法往往精度损失较大。因而,个别要先进行 QAT,使量化模型精度满足业务需要,而后导出带有“Quant”、“DeQuant”节点的 ONNX,最初再利用 TensorRT 构建量化引擎。咱们发现这两种计划最终生成的图构造并不相同,导致部署模型的理论运行效率存在很大的差别,通常 QAT 办法生成的模型效率更低。

咱们在 NVIDIA T4 机器上对量化模型进行了比照测试(见下表 5)。只管 QAT INT8 模型的 QPS 比 FP16 高了~27%,然而离 PTQ INT8 还有较大差距。咱们对此景象进行了粗疏的剖析,发现起因是 QAT 引入的“Quant”,“DeQuant”节点突破了原有 TensorRT 的交融策略,导致了很多算子无奈交融,从而影响了最终量化引擎的性能。在这一节中,咱们以 YOLOv6s_repopt 为例,展现一种定位具体瓶颈的图优化办法。在量化实际中,图优化是一个很实用的伎俩,咱们能够依法炮制,晋升模型的 QPS。

3.1.1 性能剖析

首先,咱们利用 nsys 工具 [5] 对 QAT INT8 的模型和 PTQ INT8 模型进行了性能剖析,如下表所示:

从中咱们发现,QAT INT8 有 10.8% 的 kernel 执行了 permutationKernelPLC3 操作,这些操作对应 quantize_scale_node 节点,如下图 8 所示:

3.1.2 图构造剖析

为什么 QAT INT8 会有大量的 permutationKernelPLC3 操作?咱们利用 trtexec 和 pltEngine 工具,画出了 PTQ INT8 和 QAT INT8 的计算图,并进行了认真的剖析。下图 9 是其中一个子图的比照:

QAT INT8 计算图中 neck.reduce_layer1.conv 交融节点输出精度是 FP32,并且跟了 2 个 quantize_scale_node 节点,而 PTQ INT8 图中的 neck.reduce_layer1.conv 交融节点输入的是 INT8。很显然,QAT 图中 FP32 和 INT8 之间的转换会带来额定的开销。咱们又利用 Netron 来剖析 QAT INT8 的 ONNX 图构造,找到了 neck.reduce_layer1.conv 这个地位,图 10 给出该节点示意。

通过剖析 ONNX 图构造,咱们发现了 QAT INT8 引擎中 neck.reduce_layer1.conv 输入为 FP32,并且为两个分支保留了 quantize_scale_node 的起因。因为 neck.upsample1.upsample_transpose 分支的输出量化 scale 为 0.083,而 neck.Rep_n3.conv1 分支的输出量化 scale 为 0.105,这两个节点输出尺度是不同的,导致 neck.reduce_layer1.conv 无奈间接输入为 INT8。

能够看出,对于同一个输入,输出到多路分支后为何 scale 不同的,起因是左边的分支通过了 concat 操作,会导致输入的数据分布发生变化,再进行激活校准(Activation Calibration)时,会失去的不同的最佳截断值 (Activaition Max)。

3.1.3 图构造优化

依据下面的剖析,如果一个节点的输入,输出到不同的分支节点中,并且分支节点的量化 scale 不同,则 quantize_scale_node 节点无奈交融,进而导致了额定的开销。如何解决这个问题?咱们应用了一个简略的办法,就是强制使所有分支节点的量化 scale 雷同(依据教训,在同一数量级上的 scale 能够平安合并),即间接批改 QAT 网络中的 Quantizer 节点的参数。

咱们整顿了 YOLOv6s_repopt 中所有须要进行 scale 交融的节点(如表 7 所示),因为 TensorRT 的 8 bit 的量化范畴是[-127,127],所以只须要将多路分支的 Activation Amax 设为同一个值,个别取多路分支中的最大值。

3.1.4 性能测试

通过以上的多路分支的 scale 交融后,咱们再次利用 trtexec 和 pltEngine 工具,画出了 QAT INT8 进行优化前后的图构造。能够发现,quantize_scale_node 节点曾经全副被交融。

咱们测试了通过图优化的 QAT 模型,QPS 达到了 528,性能十分靠近 PTQ 的 556,而且 mAP 仍然放弃优化前的 42.1%。

3.2 线上服务优化

咱们在 NVIDIA T4 服务器上进行了端到端的吞吐测试,利用“多实例”并发解决的技术,YOLOv6s_repopt INT8 QPS 达到了 552,相较 FP16 晋升了~40%。咱们对服务器的各项指标进行了监测,发现此时 T4 GPU 的利用率只有 95%,还有压迫空间,而 16 核 CPU 利用率曾经超过了 1500%,简直满负荷运行。咱们揣测整个线上服务的“瓶颈”可能在 CPU,而图片预处理会应用大量 CPU 资源。

3.2.1 DALI 预处理

为了解决 CPU 预处理带来的“瓶颈”,咱们采纳了 NVIDIA 的 DALI 库,将预处理间接放到 GPU 中运算。该库能够在 GPU 上对二进制图片进行解码和预处理,极大的缓解 CPU 瓶颈,下图 12 为 DALI 的经典流程。

3.2.2 吞吐测试

如下图 13 所示,INT8 + DALI 的吞吐达到了 1182 imgs/s,比 INT8 吞吐晋升了 1.14 倍。引入 DALI 预处理后,T4 GPU 利用率达到了 100%,而 16 核 CPU 的利用率则降落到了 1100% 左右,局部 CPU 资源失去了“解放”。另外,咱们也测试 FP16 + DALI 的吞吐,反而有稍微的降落。咱们揣测是 DALI 抢占了局部 GPU 计算资源,而 FP16 服务的瓶颈在 GPU,所以对整体性能产生了负面影响。

4. 总结

综上所述,本文基于 YOLOv6 V1.0 版本,以 YOLOv6s 为例探讨了基于重参数化结构设计的 2D 检测模型的量化难点和具体计划,在模型精度根本放弃的前提下,通过量化减速,晋升了约 40% 的 QPS。部署时的预处理优化则额定晋升了 214%,极大地晋升了工业部署吞吐能力。下表列出了本文尝试的办法及叠加成果。

本文应用的速度测试环境见表 11, 测试输出 batch size 为 1,尺寸为 640×640。

YOLOv6 版本更新

近日,YOLOv6 曾经更新了 V2.0 版本,并新增了中大型网络,对轻量级和小网络的性能进行了全面降级,进一步晋升综合性能,量化成果也失去大幅晋升,其中 YOLOv6-S 量化模型达到了 43.3mAP 和 869 FPS(TensorRT 8.4)。更多具体内容请关注官网出品的技术报告 [7]。

咱们心愿通过分享本文的实际,进一步推动最新通用指标检测算法的落地。将来,咱们会和业界同行一道,摸索更优的量化计划,继续晋升量化精度和推理速度,助力降本增效,深入业务价值。

5. 参考文献

  • [1]YOLOv6:又快又准的指标检测框架开源啦
  • [2] RepVGG: Making VGG-style ConvNets Great Again,https://arxiv.org/abs/2101.03697
  • [3] ReOpt: Re-parameterizing Your Optimizers rather than Architectures
  • [4] SNR: https://github.com/openppl-pu…
  • [5] Nsight-systems: https://docs.nvidia.com/nsigh…
  • [6] Channel-wise Knowledge Distillation for Dense Prediction, https://arxiv.org/abs/2011.13256
  • [7] YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications, https://arxiv.org/abs/2209.02976

6. 本文作者

庆源、李亮、奕铎、张勃、王新、祥祥等,来自美团根底研发平台数据迷信与平台部和视觉智能部。

浏览美团技术团队更多技术文章合集

前端 | 算法 | 后端 | 数据 | 平安 | 运维 | iOS | Android | 测试

| 在公众号菜单栏对话框回复【2021 年货】、【2020 年货】、【2019 年货】、【2018 年货】、【2017 年货】等关键词,可查看美团技术团队历年技术文章合集。

| 本文系美团技术团队出品,著作权归属美团。欢送出于分享和交换等非商业目标转载或应用本文内容,敬请注明“内容转载自美团技术团队”。本文未经许可,不得进行商业性转载或者应用。任何商用行为,请发送邮件至 [email protected] 申请受权。

正文完
 0