为了提高人脸识别的实时性,我们团队将传统的推理使用神经网络框架升级为统一的TensorRT加速推理。经过实验对比,通过TensorRTFP16模式推理加速的人脸识别不仅准确率几乎没有损失,甚至在部分场景下准确率有所提升,识别速度提升了2.3倍。统一的人脸识别加速推理,不仅可以为客户提供高质量、高响应的服务,还可以提高AI服务器资源的利用率,降低服务成本,有利于各种模型推理的融合统一。一、目的与背景首先,量化推理的出现,为提高人脸识别服务的响应速度,为客户提供更好的服务体验提供了更多的选择。其次,可以在不同的神经网络框架下训练生成针对不同业务需求的神经网络模型。比如TensorFlow用于人脸检测,MxNet用于人脸识别,PyTorch用于人像生成。如果在线服务使用深度学习框架进行推理,则需要在服务器上部署多个框架。与统一推理引擎相比,多个框架不利于结构优化和数据间的通信,会增加升级和维护。的代价。最后,面对日益增长的AI服务需求,为保证服务质量,企业需要采购更多的服务器资源,尤其是GPU服务器。如何提高服务器资源的利用率,降低相应的服务成本也成为迫切需要。模型的量化推理减少了计算和存储资源的占用,推理加速也可以减少服务器资源的占用。基于以上背景,我们团队对现有的定量推理和深度学习推理服务进行了研究和实验。二、相关技术1、TensorRT什么是TensorRT?TensorRT是Nvidia开发的用于高性能深度学习推理的SDK。它包括一个高性能神经网络推理优化器和一个用于生产部署的运行时引擎。借助TensorRT,可以优化在所有主要深度学习框架中训练的神经网络模型,并针对低精度进行高精度校准,并最终部署到超大规模数据中心、嵌入式设备或汽车产品平台。如图1所示:TensorRT通过融合层和优化内核来优化网络,以改善延迟、吞吐量、能效和内存消耗。如果应用程序指定,它还会优化网络以降低精度运行,进一步提高性能并减少内存需求。如图2所示:TensorRT为视频流、语音识别、推荐和自然语言处理等深度学习推理应用的生产部署提供INT8和FP16优化。降低精度的推理可以显着减少应用程序延迟,这是许多实时服务、自动驾驶和嵌入式应用程序的要求。①低精度推理MxNet、TensorFlow、PyTorch等现有深度学习框架在训练模型时一般使用Float32(简称FP32)精度来表示权重、偏差、激活值等。数量逐渐加深,其参数的计算量极其庞大,比如像ResNet、VGG这样的网络。如此大的计算量,在推理过程中以FP32精度进行计算会非常耗时耗资源。如果是移动设备或者是计算资源有限的嵌入式设备,这么大的计算量根本无法想象,甚至根本无法运行。在部署推理时使用低精度数据,如INT8、FP16等,是解决计算量大、提高推理速度的一种方式。当然,有办法解决计算量大的问题,比如模型压缩。但是我们的方法侧重于模型推理阶段的优化。那么问题来了,使用较低精度的数值表示会不会降低原始模型的精度。毕竟如表1所示,不同精度的动态范围还是相差很大的。对于精度损失这个问题,很多学者都在实证层面进行了分析。例如,为什么深度神经网络的八位就足够了?[1]和LowPrecisionInferencewithTensorRT[2]这两篇博文提出即使使用低精度数据进行推理,在提高推理速度的同时也不会影响推理速度。准确性会产生太大的影响。博文作者认为,神经网络学习了数据样本的模式可分性,同时由于数据中存在噪声,网络具有很强的鲁棒性,这意味着输入样本的微小变化都会不会太大影响最终的性能。甚至有研究发现,在某些场景下,低精度推理可以提高结果的准确性。此外,在CPU上提高神经网络的速度[3]和TrainingDeepNeuralNetworkswithLowPrecisionMultiplications[4]进行了理论分析和论证。由于INT8的存储占用率低,通过率高,但是因为它的表达范围和FP32还是相差太多,所以FP32的精度实际上降到了INT8精度,也就是用8bit来表示原本32bit表示的tensor,这实际上相当于对信息重新编码的过程,没有明显的精度损失,还是相当具有挑战性的。转换过程需要将每一层的输入张量(Tensor)和网络学习到的参数从原来的FP32表示转换为INT8表示。因此,需要尽量减少转换过程中的信息损失,转换方法应该简单且计算效率高。TensorRT采用简单有效的线性量化转换方式。即式(1):FP32Tensor(T)=FP32scalefactor*8-bitTensor(t)+FP32_bias(b)(1)Nvidia研究人员已经证明可以去除偏置项,即公式(2):FP32Tensor(T)=FP32scalefactor*8-bitTensor(t)(2)然后转换过程中最重要的就是确定比例因子,最简单的方法就是直接Map–|max|和|最大|FP32中的张量值到INT8对应的-127和127,中间值按照线性关系进行映射。这种方法也称为无饱和(Nosaturation)映射。但是,实验表明这种方法有明显的精度损失。因此,TensorRT的开发者采用了一种称为饱和(saturate)映射的方法,如图3右侧所示:与不饱和映射相比,它不再直接映射±|max|。两端的值都为±127,但选择A阈值|T|,映射±|T|到±127,其中|T|<|最大值|。[-|T|,|T|之外的值]区间直接映射为±127,例如图3中红色的三个x点直接映射为-127,而在[-|T|,|T|]在区间内,遵循线性映射的方法。TensorRT开发者对网络推理过程中涉及的权重(weights)和激活值(activation)进行了实验,发现权重的饱和映射与非饱和方法相比并没有提高精度,而饱和映射的激活值在准确率上有明显的提升。因此,在TensorRT中,权重采用不饱和映射法,激活值采用饱和映射法。那么为什么非饱和映射会提高饱和映射的精度呢?另外,在不饱和映射中如何选择T?先看下图右侧。这张图是resnet-152网络模型中间层的激活值统计。横坐标是激活值,纵坐标是统计的归一化表示。可以看出图4中白线左侧的激活值分布比较集中且重合,而白线右侧(对应阈值T线)的激活值,即红框内,比较分散,红框内激活值在整个层中所占的比例比较小,所以这部分在映射关系上可以不考虑,如右图数字。研究发现,大多数网络都具有大部分激活值集中、少数激活值分散的特点。T值需要满足FP32模式到INT8模式转换的最小信息损失,信息损失可以用KL散度(也叫相对熵)来衡量,如公式(3)所示:KL_divergence(P,Q):=SUM(P[i]*log(P[i]/Q[i]),i)(3)其中P和Q分别代表FP32和INT8模式下的分布,以及每一层对应的T值张量的不同,决定T值的过程称为标定(Calibration),如图5所示,标定示意图。首先需要对校准数据集(CalibrationDataset)进行FP32推理,然后得到各层激活值的直方图,使用不同的量化阈值生成对应的量化分布。其中,量化阈值如上图激活值直方图中,等距虚线对应的激活值就是量化阈值,而我们需要的T值就是这些虚线中能够最小化KL散度的激活值.这个标定需要一定的时间,所以每次量化时,标定得到的T值都会保存到对应的文件中,下次推理模式从FP32转INT8时直接读取保存。层T值,这在整个过程中节省了时间。很明显,校准数据集(CalibrationDataset)会直接影响激活值的分布,进而影响T值的选取。校准数据集应该具有代表性和多样性。例如,在图像分类应用中,校准数据集应该能够代表所有分类目标。验证数据集的子集是理想的校准集。当然,可能有人会问,是不是所有的数据都用来标定才能最好的反映原始数据的分布呢?但这也会增加整个过程的时间,研究和实验表明校准集只需要1000个样本。TensorRTINT8量化的性能和精度,图6和图7来自Nvidia官方PPT。从上面的图6和图7可以看出,经过校准的INT8推理相比于FP32推理在精度上有轻微的损失,同时也可以看出在某些情况下(图6表格中绿色部分所示)INT8推理阶段与FP32相比,推理精度略有提高。此外,还可以看出一个趋势。随着Calibration数据集中图片数量的增加,INT8相对于FP32的精度损失在逐渐减小。从Performance图中可以看出,在不同的inferenceBatchSizes(注意实际的inferenceBatchSize和Calibration过程中的BatchSize不需要保持一致)设置下,INT8inference相对于FP32inference的加速比.从图中可以看出,BatchSize越大,加速效果越好。当BatchSize为128时,加速比约为3.5倍。当然,实际加速比还与硬件平台和神经网络本身有关。除了速度上的提升,低精度推理相比FP32在存储消耗方面也进行了优化,如图8所示:图8中,INT8onP40表示在P40显卡上进行INT8推理。可以看出,相比FP32推理模式内存占用减少了3倍以上,而速度提升了3倍以上。FP16模式还减少了30%的内存使用,速度几乎翻了一番。当然,上述实验对比测试均来自Nvidia官方。对于我们实际的深度学习场景,需要通过实验来比较精度的损失和速度的提升。在第三章中,我们将总结我们团队使用TensorRT加速人脸识别的实验过程和效果,以及在实现中遇到的一些问题和解决方案。②神经网络优化TensorRT不仅通过支持FP16和INT8两种低精度模式的推理来提高速度,还根据底层GPU的特点对神经网络进行了重构和优化。首先是它会删除一些不使用输出的层,以避免不必要的计算。那么神经网络中可以合并的一些操作就会被合并。例如,在图9所示的原始网络中,TensorRT会将conv、bias、relu这三层融合为一层,即图10所示的CBR层,这种合并操作也称为verticallayerfusion。进一步,还有水平层融合,即图10到图11所示的过程,将1x1CBR在同一水平层进行融合。2.InferenceServerInferenceServer是一个高性能的模型服务系统,为机器学习模型提供一站式的管理、推理服务、集成等功能。下面简单介绍几种常见的InferenceServer。①TensorFlowServingTensorFlowServing是谷歌TensorFlow团队开发的一种灵活、高性能的机器学习模型服务系统,专为生产环境设计。在机器学习推理方面,它可以管理训练模型的生命周期,并通过高性能、引用计数的查找表为客户端提供版本化访问。它提供了与TensorFlow模型的开箱即用集成,也可以扩展到其他模型。如果模型是通过TensorFlow训练生成的,使用TensorFlowServing最方便。有关详细信息,请参阅https://github.com/tensorflow/serving。②MMS(MultiModelServer)MultiModelServer(MMS)是一种灵活易用的工具,可为使用任何ML/DL框架训练的深度学习模型提供推理服务。这是亚马逊的AWSlab开发的模型推理工具,原名MxNetModelServer。由于Amazon主要支持MxNet,所以MMS对MxNet的优化比较好,对MxNet的特性支持也比较积极。有关详细信息,请参阅https://github.com/awslabs/multi-model-server。③TensorRTInferenceServer中较早介绍的TensorFlowServing和MMS都是深度学习框架厂商推出的,相应的对各自深度学习框架的支持会更好。TensorRTInferenceServer(最新版本称为NvidiaTritonInferenceServer)是显卡厂商Nvidia开发的深度学习模型推理服务器。它针对NvidiaGPU进行了更深入的优化,Server可以通过HTTP或GRPC端点提供推理服务。它最大的特点是支持多种框架。它不仅支持TensorRT本身生成的模型,还支持TensorFlow、Caffe2、ONNX和PyTorch的模型。它还支持混合模型的推理,以及不同框架模型的同时推理。这非常符合将推理服务与神经网络框架解耦的业务需求。有关详细信息,请参阅https://github.com/NVIDIA/triton-inference-server。这里简单介绍一下常见的InferenceServers,当然还有其他厂商的InferenceServers,比如TorchServe,见https://github.com/pytorch/serve。三、TensorRT加速人脸识别1、典型的TensorRTINT8工作流程:首先,我们需要FP32模式训练的模型文件和标定数据集。Next:①TensorRT会对校准集进行FP32推理。②获取各网络层对应的激活值统计。③执行标定算法得到各层对应的最优阈值T,得到最优量化因子。④将FP32的权重量化为INT8模式。⑤生成对应的校准表(CalibrationTable)和INT8执行引擎。2.TensorRT加速需要注意的问题:①深度学习框架与TensorRT的集成度不同。要实现上述TensorRT推理加速,首先需要一个FP32模式训练的神经网络模型。如果要进行INT8推理,还需要校准数据集(CalibrationDataset),通常是验证集的一个子集。由于各个深度学习框架与TensorRT的集成和支持程度不同,除了TensorFlow和MATLAB已经集成了TensorRT之外,大部分深度学习框架生成的模型都必须通过ONNX格式导入到TensorRT中。如图12所示:由于在TensorFlow中实现了与TensorRT集成的API,因此可以从TensorFlow代码中指定TensorRT作为Inference的后端,在TensorRT中也实现了一个TensorFlowParser来解析TensorFlow生成的模型文件。PyTorch和MXNET在训练时需要将模型文件保存为ONNX格式,或者将原始模型文件导入到框架中保存为ONNX格式。当然,这些深度学习框架也在跟进对TensorRT的支持和整合。比如MXNET新的1.60版本已经实现了调用TensorRT加速推理,但是目前的版本只支持FP16推理,不支持INT8推理。当然使用框架中提供的TensorRT接口来加速有其优势,当然也会带来相应的问题。好处是在框架内提供比较方便,减少转换等中间过程,但还是离不开框架本身。引擎违背了脱离深度学习框架本身的出发点。②TensorRT对神经网络中operator和layers的支持由于我们目前业务中的人脸识别是在mxnet框架上实现的,为了实现和比较其accuracyloss和Acceleration效果。我们先将原始的mxnet格式(.params+.json)模型文件导入到mxnet中,然后使用mxnet内部的onnx接口将模型文件转换为onnx格式。这里需要注意一点,将Mxnet模型导出为onnx格式,需要安装mxnet1.3.0或更高版本,对应的onnx组件也需要1.2.1版本,不过我们测试过onnx1.3.0版本。具体可以参考MxNet官方教程:ExportingtoONNXformat[5]。onnx-1.2.1版本在onnx文件中生成默认的V7版本的onnx算子,而1.3.0版本的onnx生成的onnx文件支持V8版本的onnx算子。不同版本的onnx算子支持不同的算子,即使是同一个算子,不同的版本也可能有不同的内部实现方式。不同版本的TensorRT对onnx算子的支持不同。mxnet对onnx算子的支持请参考:ONNXOperatorCoverage[6]。TensorRT对onnx运算符的支持可以在:SupportedONNXOperators[7]和TensorRT-Support-Matrix-Guide[8]中找到。我们团队在使用TensorRT将人脸识别onnx模型转换为TensorRT对应的模型文件(.trt)时,遇到了算子支持的问题。mxnet生成的onnx模型文件导入TensorRT后,无法正常导出TRT文件。后来通过研究发现TensorRT是支持Prelu算子的。通过Netron(一种神经网络可视化工具)可以清楚地看到两种Prelu模式之间的区别。如图13所示:绿色粗线左边的PRelu是mxnet中支持的模式,是mxnet默认导出onnx的PRelu模式。绿色粗线右侧带有Reshape的PRelu是TensorRT中支持的一种模式。为此,我们手动修改了mxnet的onnx转换对应的源码,将导出的onnx文件的Prelu修改为图中右边的模式。此外,团队中的其他深度学习任务在转换为onnx格式时也遇到了softmaxactivation、upsampling、crop等算子的支持问题。除了修改mxnet源码的解决方案,还可以修改原有的神经网络结构支持TensorRT,然后重新训练模型,但是在某些业务中重新调整训练模型的时间和精力成本场景比较大。您也可以使用TensorRT提供的插件功能来实现对一些不支持的算子和网络层的分析。③不同显卡对计算模式的支持不同。由于架构和功能的差异,不同的显卡支持FP16、INT8、INT4,与FP32相比实际获得的加速效果是不同的。有关详细信息,请参见图14中的表格。显示:图14中,N/A表示不支持,2x、4x、8x分别表示该模式下的加速比是FP32模式的2倍、4倍、8倍。例如,从表中可以看出,TeslaP100支持FP32和FP16,但不支持INT8和INT4加速。TeslaP40支持INT8但不支持FP16。在nvidia新的Turing架构中(芯片为表中的tu102和tu104)显卡已经全面支持FP16、INT8、INT4。为了保证TensorRT加速人脸识别的公平性,我们团队在TeslaT4上进行了FP32、FP16、INT8实验。还有一点需要说明的是,在不同类型的显卡上生成的TensorRT推理引擎文件(TRT)并不通用。例如,在TeslaP40上生成的TRT文件无法在TeslaP100上运行,反之亦然。3、TensorRT加速后人脸识别测试集:客流云系统前端摄像头采集的员工照片506张;校准集:LFW、INT8模式需要校准,FP16模式不需要校准;测试平台:NvidiaTeslaT4;相关设置:校准批次大小设置为64;inferencebatchsize设置为1,和我们实际业务场景一样,要求一个处理一个,保证处理结果实时返回。上图15是我们团队使用TensorRT加速人脸识别的推理效果,其中MX表示使用MXNET框架进行推理,TR表示使用TensorRT进行推理,FP32、FP16、INT8分别代表对应的推理模式。先看蓝色柱子。基于MXFP32,TensorRT以FP32精度执行推理。推理速度是MXFP32模式的1.557倍。相应地融合和优化层和运算符。在FP16和INT8模式下,使用TensorRT获得的加速分别为2.296倍和3.185倍。看橙色柱子,TRFP16和TRINT8相对于TRFP32的1.475倍加速,主要是因为FP16和INT8相比FP32计算效率更高,通过率更高。INT8加速的效果非常喜人。不仅速度提高了,内存占用率也降低了。其效果不仅提升了服务,还降低了相应的资源成本。我们的目标是在尽可能保持原有精度的同时提高速度。经过后续的精度对比实验,FP16模式几乎没有精度损失,甚至在某些情况下精度略有提升,而INT8模式的精度损失略大。一些。为此,经过综合考虑,团队部署了TensorRTFP16模式来加速在线推理。FP16模式精度几乎无损,加速效果好,使用更方便(无需标定)。另外,FP16模式也是NVIDIA何坤老师推荐的。4.总结为了提高客流云的服务速度,降低相应的服务成本,我们团队在调研和试验相关量化推理加速方案后,使用TensorRT将人脸识别服务的推理速度提升到原来的水平.的2.3倍。统一的推理后台为TensorRT,也带来了后续集成各种神经网络框架模型的可能,相应的减少了业务部署的成本和麻烦。主要需要注意的是神经网络框架、ONNX、TensorRT都支持算子。另外,我们还要结合自己的业务场景,通过量化推理进行实验,在不影响准确率的情况下获得相应的加速。这也将加快未来的其他操作。人工智能服务提供了宝贵的经验。
