在运算资源有限制的机器上部署深度学习模型,需要了解模型大小和模型推理速度的关系,设计能发挥硬件计算能力的模型结构。而衡量模型大小和模型推理速度关系往往跟计算量、参数量、访存量、内存占用等指标密切相关。因此本博客对这些指标进行分析,介绍这些指标对模型部署推理的影响。本篇博客主要参考:深度学习模型大小与模型推理速度的探讨
计算量是模型所需的计算次数,反映了模型对硬件计算单元的需求。计算量一般用FLOPs
(Floating Point Operations)即浮点次数表示。模型的整体计算量等于模型中每个算子的计算量之和。对于卷积而言,计算量公式为: F L O P s C o n v = N × O C × O H × O W × K H × K W × I C × 2 FLOPs_{Conv}= N\times OC\times OH\times OW\times KH\times KW\times IC\times 2 FLOPsConv=N×OC×OH×OW×KH×KW×IC×2
参数量是模型中参数的总和,与模型占用磁盘空间大小直接相关。对于卷积神经网络而言,参数量主要与卷积层和全连接层的权重组成。参数量往往是被算作访存量的一部分,因此参数量不直接影响模型推理性能。但是参数量一方面会影响内存占用,另一方面也会影响程序初始化时间。另一方面参数量对软件包大小也会有影响。减少软件包大小可以通过设计一些高效简单模型,另一方面可以通过模型压缩方式,如Protobuf对模型进行高效编码进行压缩。
参数量在Tensorflow里面通过model.summary()
即可打印出参数量信息。
访存量是指模型计算时所需访问存储单元的字节大小,反映了模型对存储单元带宽的需求。访存量一般用 Bytes(或者 KB/MB/GB)来表示,即模型计算到底需要存/取多少 Bytes 的数据。和计算量一样,模型整体访存量等于模型各个算子的访存量之和。
内存占用是指模型运行时,所占用的内存/显存大小。一般有工程意义的是最大内存占用,当然有的场景下会使用平均内存占用。和参数量一样,内存占用不会直接影响推理速度,往往算作访存量的一部分。但在同一平台上有多个任务并发的环境下,如推理服务器、车载平台、手机 APP,往往要求内存占用可控。可控一方面是指内存/显存占用量,如果占用太多,其他任务就无法在平台上运行;另一方面是指内存/显存的占用量不会大幅波动,影响其他任务的可用性。
计算量、参数量、访存量、内存占用从不同维度定义了模型的大小,应根据不同的场合选用合适的指标进行评价。模型推理速度不单单受模型计算量的影响,也与访存量和一些其他因素息息相关。
模型在特定硬件上的推理速度,除了受计算量影响外,还会受访存量、硬件特性、软件实现、系统环境等诸多因素影响,呈现出复杂的特性。因此,在手头有硬件且测试方便的情况下,实测是最准确的性能评估方式。
计算密度是指一个程序在单位访存量下所需的计算量,单位是 FLOPs/Byte。其计算公式很简单,很多教材、资料里也称之为计算访存比,用于反映一个程序相对于访存来说计算的密集程度: 计 算 密 度 I = 计 算 量 ( F L O P s ) 访 存 量 ( B y t e s ) 计算密度I = \frac{计算量(FLOPs)}{访存量(Bytes)} 计算密度I=访存量(Bytes)计算量(FLOPs)当程序的计算密度I较小时,程序访存多而计算少,性能受内存带宽限制,称为访存密集型程序。反之如果计算密度I较大,程序性能受硬件最大计算峰值(下文简称为算力)限制,称为计算密集型程序。
网络中的算子可以根据计算密度进行分类。一般来讲,Conv、FC、Deconv 算子属于计算密集型算子;ReLU、EltWise Add、Concat 等属于访存密集型算子。同一个算子也会因参数的不同而导致计算密度变化,甚至改变性质,比如在其他参数不变的前提下,增大 Conv 的 group,或者减小 Conv 的 input channel 都会减小计算密度。
在不同参数下卷积算子的计算密度有很大的差异。第 4 个算子 Depthwise Conv 计算密度仅有 2.346,在当下的很多设备上都属于访存密集型算子。算子的计算密度越大,约有可能提升硬件的计算效率,充分发挥硬件性能。
按照 RoofLine 模型,算子的实际执行时间:
则有:
对于访存密集型算子,推理时间跟访存量呈线性关系,而对于计算密集型算子,推理时间跟计算量呈线性关系。按照 RoofLine 模型,在计算密集区,计算量越小,确实推理时间越小。但是在访存密集区,计算量与推理时间没关系,真正起作用的是访存量,访存量越小,推理的时间才越快。在全局上,计算量和推理时间并非具有线性关系。
前面 RoofLine 模型使用的峰值算力及内存带宽,是根据纸面数据计算得到的,是理论上的最大值。但在实际情况下,硬件会因为种种原因,无法达到这个理论值。因此建议大家对硬件进行micro-benchmark,以获取硬件的真实性能上限。
计算量并不能单独用来评估模型的推理时间,还必须结合硬件特性(算力&带宽),以及访存量来进行综合评估。并非是计算量越低模型推理越快。在评价模型大小时,也建议加上访存量作为重要的评价指标。
除了峰值算力和内存带宽之外,还有硬件限制、系统环境、软件实现等诸多因素会影响程序的实际性能,使得其非线性特性更加严重。因此 RoofLine 模型仅仅只能提供一个性能上界的评估方式,并不代表能够达到的实际性能。实际性能最准确的测量方式只有真机实测。RoofLine 模型仅能用于估计模型所能达到的性能上界,而实际部署时,还会受硬件限制、系统环境、软件实现等因素的影响,导致无法达到 RoofLine 模型所定义的性能上界。
以下建议摘自:深度学习模型大小与模型推理速度的探讨。
关于实际工程部署,有一些技巧/注意的点可以保证不浪费访存量: