精华内容
下载资源
问答
  • 作者丨田子宸@知乎(已授权)来源丨https://zhuanlan.zhihu.com/p/411522457编辑丨极市平台导读本文对衡量深度学习模型大小的一些常用指标,如计算量、参数量...

    作者丨田子宸@知乎(已授权)

    来源丨https://zhuanlan.zhihu.com/p/411522457

    编辑丨极市平台

    导读

     

    本文对衡量深度学习模型大小的一些常用指标,如计算量、参数量、访存量、内存占用等进行探讨,分析这些指标对模型部署推理的影响,尤其是计算量与访存量对模型推理速度的影响,并给出在不同硬件架构下设计网络结构的一些建议。

    0、前言

    当年头一次实习做算法的时候,主管给的第一个任务就是“把一个大的分割模型砍成一个小的”。当时并不理解模型“大”、“小”的真正含义,就简单的选取计算量作为评价指标,疯狂砍计算量(backbone 换 MobileNet/ShuffleNet、Conv 换成 DepthWise Conv、以及一些奇奇怪怪的融合结构等等),把模型计算量砍了将近 10 倍,结果一部署发现速度并没有快多少,反而是把最初的 ResNet 简单砍掉几个 block 效果更好。

    也是从那时起接触了访存量、流水线、RoofLine 模型等概念,对模型推理速度的问题产生了兴趣,从此踏上了深度学习推理优化的不归路(划掉)。

    如今做推理优化和 HPC 已经有一段时间了,还是偶尔能回想起当年不懂推理时设计的与硬件严重不匹配的模型。此外在工作中跟研究员沟通时,也会发现部分研究员对模型大小和模型推理速度的关系不太了解,设计出一些很难发挥硬件计算能力的模型结构。因此在这里对一些用于评价模型大小的指标——计算量、参数量、访存量、内存占用等指标进行详细探讨,分析这些指标会对模型的部署推理产生何种影响,详细讨论计算量和访存量对模型推理速度的影响,并给出不同硬件架构下设计高效网络结构的一些建议。

    本文不仅仅是为了给出网络的设计建议,更是希望能够有效传达性能优化的基础理论知识,以及性能分析的基本思路,帮助各位同学减少网络设计与部署之间的 gap,更高效的完成网络设计与部署工作。非常希望本文能够对大家的工作有所帮助,也非常欢迎大家在评论区留言探讨。

    一、常用的模型大小评估指标

    目前常用于评价模型大小的指标有:计算量、参数量、访存量、内存占用等,这些指标从不同维度评价了模型的大小。本节仅作简单介绍,熟悉的小伙伴可以跳过此节,直接看后面的分析与探讨。

    1. 计算量

    计算量可以说是评价模型大小最常用的指标了,很多论文在跟 baseline 进行比较时,都会把计算量作为重要的比较依据。

    计算量是模型所需的计算次数,反映了模型对硬件计算单元的需求。计算量一般用 OPs (Operations) ,即计算次数来表示。由于最常用的数据格式为 float32,因此也常常被写作 FLOPs (Floating Point Operations),即浮点计算次数。(这里为了跟传统习惯保持一致,下文就统一采用 FLOPs 啦)

    模型的整体计算量等于模型中每个算子的计算量之和。而每个算子的计算量计算方法各不一致。例如对于 Eltwise Sum 来讲,两个大小均为 (N, C, H, W) 的 Tensor 相加,计算量就是 N x C x H x W;而对于卷积来说,计算量公式为(乘加各算一次):

    PyTorch 有不少工具可以模型计算量,但需要注意的是这些工具有可能会遗漏一些算子的计算量,将其计算量算成 0,从而导致统计的计算量跟实际计算量有轻微的偏差,不过大多数情况下这些偏差影响不大。

    2. 参数量

    早期的论文也很喜欢用参数量来评价模型大小。

    参数量是模型中的参数的总和,跟模型在磁盘中所需的空间大小直接相关。对于 CNN 来说参数主要由 Conv/FC 层的 Weight 构成,当然其他的一些算子也有参数,不过一般忽略不计了。

    参数量往往是被算作访存量的一部分,因此参数量不直接影响模型推理性能。但是参数量一方面会影响内存占用,另一方面也会影响程序初始化的时间。

    参数量会直接影响软件包的大小。当软件包大小是很重要的指标时,参数量至关重要,例如手机 APP 场景,往往对 APK 包的大小有比较严格的限制;此外有些嵌入式设备的 Flash 空间很小,如果模型磁盘所需空间很大的话,可能会放不下,因此也会对参数量有所要求。

    除了在设计模型时减少参数量外,还可以通过压缩模型的方式降低软件包大小。例如 Caffe 和 ONNX 采用的 Protobuf 就会对模型进行高效的编码压缩。不过压缩模型会带来解压缩开销,会一定程度增加程序初始化的时间。

    3. 访存量

    访存量往往是最容易忽视的评价指标,但其实是现在的计算架构中对性能影响极大的指标。

    访存量是指模型计算时所需访问存储单元的字节大小,反映了模型对存储单元带宽的需求。访存量一般用 Bytes(或者 KB/MB/GB)来表示,即模型计算到底需要存/取多少 Bytes 的数据。

    和计算量一样,模型整体访存量等于模型各个算子的访存量之和。对于 Eltwise Sum 来讲,两个大小均为 (N, C, H, W) 的 Tensor 相加,访存量是 (2 + 1) x N x C x H x W x sizeof(data_type),其中 2 代表读两个 Tensor,1 代表写一个 Tensor;而对于卷积来说,访存量公式为:

    93918e9eefb5cd7f8ff89fa7607a170e.png

    访存量对模型的推理速度至关重要,设计模型时需要予以关注。

    4. 内存占用

    内存占用是指模型运行时,所占用的内存/显存大小。一般有工程意义的是最大内存占用,当然有的场景下会使用平均内存占用。这里要注意的是,内存占用 ≠ 访存量。

    内存占用在论文里不常用,主要原因是其大小除了受模型本身影响外,还受软件实现的影响。例如有的框架为了保证推理速度,会将模型中每一个 Tensor 所需的内存都提前分配好,因此内存占用为网络所有 Tensor 大小的总和;但更多的框架会提供 lite 内存模式,即动态为 Tensor 分配内存,以最大程度节省内存占用(当然可能会牺牲一部分性能)。

    和参数量一样,内存占用不会直接影响推理速度,往往算作访存量的一部分。但在同一平台上有多个任务并发的环境下,如推理服务器、车载平台、手机 APP,往往要求内存占用可控。可控一方面是指内存/显存占用量,如果占用太多,其他任务就无法在平台上运行;另一方面是指内存/显存的占用量不会大幅波动,影响其他任务的可用性。

    5. 小结

    计算量、参数量、访存量、内存占用从不同维度定义了模型的大小,应根据不同的场合选用合适的指标进行评价。

    模型推理速度不单单受模型计算量的影响,也与访存量和一些其他因素息息相关。下文将详细讨论影响模型推理速度的因素。

    二、计算量越小,模型推理就越快吗

    答案是否定的。

    实际上计算量和实际的推理速度之间没有直接的因果关系。计算量仅能作为模型推理速度的一个参考依据。

    模型在特定硬件上的推理速度,除了受计算量影响外,还会受访存量、硬件特性、软件实现、系统环境等诸多因素影响,呈现出复杂的特性。因此,在手头有硬件且测试方便的情况下,实测是最准确的性能评估方式

    在设计网络结构时,如果有实测的条件,建议在模型迭代早期对性能也进行测试。一些 NAS 的方法也会对搜索出来的网络结构进行测速,或者干脆对硬件速度进行了建模,也作为初期搜索的重要参数。这种方法设计出来的网络在后期部署时,会极大减少因性能问题迭代优化的时间和人力开销。

    这里我将讨论影响模型在硬件上推理速度的一些因素,一方面希望可以帮助手动/自动设计网络结构的同学更快的设计更高效的网络结构,另一方面希望当模型部署时性能出现问题时能够为大家提供分析原因的思路。

    这一问题我将从如下 3 个点进行讨论:

    • 计算密度与 RoofLine 模型

    • 计算密集型算子与访存密集型算子

    • 推理时间

    1. 计算密度与 RoofLine 模型

    计算密度是指一个程序在单位访存量下所需的计算量,单位是 FLOPs/Byte。其计算公式很简单,很多教材、资料里也称之为计算访存比,用于反映一个程序相对于访存来说计算的密集程度:

    RoofLine 模型是一个用于评估程序在硬件上能达到的性能上界的模型,可用下图表示:

    2e2700452414ae7756f36f187f5220fa.png

    RoofLine 模型

    用公式描述:

    当程序的计算密度I较小时,程序访存多而计算少,性能受内存带宽限制,称为访存密集型程序,即图中橙色区域。在此区域的程序性能上界=计算密度×内存带宽,表现为图中的斜线,其中斜率为内存带宽的大小。计算密度越大,程序所能达到的速度上界越高,但使用的内存带宽始终为最大值。

    反之如果计算密度I较大,程序性能受硬件最大计算峰值(下文简称为算力)限制,称为计算密集型程序,即图中蓝色区域。此时性能上界=硬件算力,表现为图中的横线。此时计算速度不受计算密度影响,但计算密度越大,所需内存带宽就越少。

    在两条线的交点处,计算速度和内存带宽同时到达最大值。

    d68f2d1e1d077fd5d5b47d3774375c1a.png

    在不同设备上,同一个程序的性质可能发生变化

    在不同设备上,同一个程序的性质可能发生变化。例如上图中的程序2,在算力稍弱的设备2上属于计算密集型程序,而在算力较强的设备1上就属于访存密集型程序了(感谢评论区指正)。如果想要充分发挥设备1的性能,应当适当加大程序的计算密度(比如到程序3的位置)。

    2. 计算密集型算子与访存密集型算子

    网络中的算子可以根据计算密度进行分类。一般来讲,Conv、FC、Deconv 算子属于计算密集型算子;ReLU、EltWise Add、Concat 等属于访存密集型算子。

    同一个算子也会因参数的不同而导致计算密度变化,甚至改变性质,比如在其他参数不变的前提下,增大 Conv 的 group,或者减小 Conv 的 input channel 都会减小计算密度。

    举个栗子,对于不同参数的卷积,计算密度如下:

    01d1849464309567b324c9449765065e.png

    可以看到,不同参数下卷积算子的计算密度有很大的差异。第 4 个算子 Depthwise Conv 计算密度仅有 2.346,在当下的很多设备上都属于访存密集型算子。

    算子的计算密度越大,约有可能提升硬件的计算效率,充分发挥硬件性能。我们以一个 Intel X86 服务器平台为例(10980 XE)。该平台 CPU 频率为 4.5 GHz,我们以 16 核为例,其理论 FP32 算力为 4.608 TFLOPs/s,内存带宽理论值为 96 GB/s。在此平台上的 RoofLine 模型为:

    6dabb9ed8d932e5810cea22599564805.png

    Intel 10980 XE 16 核 RoofLine 模型,以及各个算子的计算密度与性能

    该平台“拐点”的计算密度为 48,计算较为密集的 OP1 和 OP2 处在计算密集区,能够达到平台的算力峰值;而 OP3 和 OP4 处在访存密集区,受内存带宽限制不能到达算力峰值,尤其是 OP4,由于计算访存比过低,计算效率仅有可怜的 4.9%,计算效率并不高。

    3. 推理时间

    这里涉及到一个 gap,很多部署的同学们更喜欢谈“计算效率”,而实际上算法同学真正关心的点是“推理时间”,导致两者在对接的时候经常会出现一些 misleading。因此我这里单独开一节来探讨一下“推理时间”的评估方法。

    其实也很简单,按照 RoofLine 模型,我们很容易就能得到算子实际的执行时间:

    计算时间计算量计算速度计算量计算量访存量带宽理论算力

    这是一个分段函数,拆开来可得:

    计算时间访存量带宽访存密集区计算量理论算力计算密集区

    一句话总结:对于访存密集型算子,推理时间跟访存量呈线性关系,而对于计算密集型算子,推理时间跟计算量呈线性关系

    讲到这里,我们就能初步回答本章一开始的问题了:按照 RoofLine 模型,在计算密集区,计算量越小,确实推理时间越小。但是在访存密集区,计算量与推理时间没关系,真正起作用的是访存量,访存量越小,推理的时间才越快。在全局上,计算量和推理时间并非具有线性关系。

    上一节中,OP4 虽然计算效率很低,但由于访存量也很低,因此其实推理速度还是快于其他几个 OP 的。但是我们可以观察到,其计算量虽然只有 OP1 的 1/130,但是推理时间仅降低到了 1/6,两者并非是线性关系(也是当年我把模型减到 1/10 计算量,但其实没快多少的原因)。

    再举两个例子强化一下,首先看这两个卷积,他们的计算量差不多,但是因为都在访存密集区,OP3 的访存量远低于 OP5,其推理也更快:

    a399617592edba6d4f8b9c74c391514d.png

    下面这个栗子更明显,OP5 和 OP6 的区别仅仅是一个是 DepthWise Conv,一个是普通 Conv,其他参数没有变化。按照我们之前的直观感受,Conv 换成 DepthWise Conv 应该会更快,但实际上两者的推理时间是差不多的(这组参数也是当年我用过的【手动捂脸):

    fb096f3becbc721cec88e7f4230c5a71.png

    4. 小结

    从上面的讨论中我们可以看出:计算量并不能单独用来评估模型的推理时间,还必须结合硬件特性(算力&带宽),以及访存量来进行综合评估。并非是计算量越低模型推理越快。在评价模型大小时,也建议加上访存量作为重要的评价指标

    需要强调的一点是,不同的硬件平台峰值算力和内存带宽不同,导致同一个模型在平台 1 上可能是计算密集的,在平台 2 上可能就变成了访存密集的。例如上文提到的 Intel X86 平台,“拐点”值为 48,而 NVIDIA V100“拐点”值为 173.6,上文举的例子在 V100 平台上仅有 OP2 落在了计算密集区,剩下的全部是访存密集的。因此,同样的模型在不同平台上性质可能会发生改变,需要具体情况具体分析。

    我们很难给出一个通用性的结论,究其原因是 RoofLine 模型本身是一个非线性模型。这里必须要强调一点的是,除了峰值算力和内存带宽之外,还有硬件限制、系统环境、软件实现等诸多因素会影响程序的实际性能,使得其非线性特性更加严重。因此 RoofLine 模型仅仅只能提供一个性能上界的评估方式,并不代表能够达到的实际性能。实际性能最准确的测量方式只有真机实测

    RoofLine 模型更重要的是提供了一种分析性能的思想,即计算密集型程序更多的受限于硬件算力,而访存密集型程序更多的受限于硬件内存带宽。在理解这一点的基础上设计网络结构,并分析网络的性能,将更有理论参考。不会再对”计算量减半,为啥推理时间没变“这种问题抱有疑问了(说的就是我【流泪)

    下文将对 RoofLine 模型的一些限制进行讨论,分析哪些因素将以何种方式影响程序,使得其到达不了 RoofLine 模型估计的性能上界。

    (下文要开始难度升级了,建议没看懂 RoofLine 模型的同学们再把这一章看一遍,不然后面会看的有点懵)

    三、影响模型推理性能的其他因素

    RoofLine 模型可以用来评估程序的性能上界,但是实际能达到的性能还会受到硬件限制、系统环境、软件实现等诸多因素的影响,距离性能上界有一定距离。本章将对这些影响因素进行分析。

    1. 硬件限制对性能上界的影响

    前面 RoofLine 模型使用的峰值算力及内存带宽,是根据纸面数据计算得到的,是理论上的最大值。但在实际情况下,硬件会因为种种原因,无法达到这个理论值。因此建议大家对硬件进行micro-benchmark,以获取硬件的真实性能上限

    以上文的 Intel X86 CPU 为例,我们之前计算的 avx512 理论算力为 4.608 TFLOPs/s,但这个数值的前提是频率能维持在 4.5 GHz。然而实际上在使用 16 核跑 avx512 指令时,CPU 频率会下降到约 2.9 GHz,此时理论算力仅剩下 2.96 TFLOPs/s,而实测值仅有 2.86 TFLOPs/s。

    除了频率之外,有些芯片可能会因为一些设计上或实现上的原因,导致在实际使用时达不到理论峰值。比如一些低端芯片不支持多发射、不支持乱序执行、采用了阻塞式 Cache 等等,一些芯片甚至会有一些性能 bug,导致在实际使用时几乎到达不了理论峰值(这里我个人倾向于把这些原因归结为硬件限制带来的损失)。

    内存同理,该平台理论带宽为 96GB/s,但实测下来最高读带宽仅有 74 GB/s,仅能到达理论带宽的 77%。

    我们可以得到修正后的 RoofLine 模型,图中蓝色填充部分反映了因实际算力和内存带宽达到不了理论值而造成的损失:

    16165acbef82f052d30761612e682b7a.png

    修正了实测峰值算力和内存带宽后的 RoofLine 模型,蓝色填充部分为硬件限制带来的损失

    修正后的模型“拐点”发生了变化,因此算子的性质也会发生变化。建议拿到硬件后对硬件进行 micro-benchmark,这里推荐两个测试工具:

    一个是高叔叔写的浮点峰值测试方法的文章,最后有 github 链接,大家可以 clone 下来测试硬件峰值:

    还有一个是 stream 测试工具,可以用于测试内存带宽:

    2. 系统环境对性能的影响

    除非程序运行在裸机中,否则操作系统一定会对性能上界产生一定影响,比如操作系统在多核间的调度损失、操作系统的内存管理带来的损失、操作系统本身占用的运算资源等等。

    对于一般的深度学习推理任务而言,现代操作系统对性能的影响并不是特别明显。但是在一些特殊情况下,也会带来严重的性能损失。我这里将会举两个例子:

    一个是 Android 系统在大小核上的调度,一旦程序在 CPU 上的占用率不足(比如是周期工作的任务),则有可能被 Android 调度到小核上,带来性能损失。

    另一个例子是内存缺页。在 Linux 系统上,当向系统申请内存页后,系统只是返回了虚拟页,等到程序实际使用虚拟页时,才会通过触发缺页异常的方式,进入操作系统内核分配物理页,这一过程会严重降低性能。

    好在这些问题可以通过软件进行一部分弥补,例如调度问题可以使用绑核来解决,缺页问题可以通过绑定物理页(需要内核态)或内存池来解决。因此操作系统带来的影响是可控的。

    除了操作系统带来的影响,系统中运行的其他进程也会对当前进程造成影响。比如一个系统中运行了多个深度学习实例,或者系统后台一些 APP 自启动了等等。这些进程都会占用核心算力和内存带宽,造成当前进程性能损失。

    这往往会导致在工程测试环境下性能达标的模型,在实际部署时性能下降。因此,必须关注工程测试环境和实际部署系统环境的差异。如有条件,最好在实际部署环境下进行测试。

    3. 软件实现对性能的影响

    除了硬件限制和系统环境外,一个任务的软件实现好坏对性能有着重大的影响

    例如对于同样的矩阵操作任务,使用 python 写的多重 for 循环,和用 numpy 高度优化过的矩阵操作函数,性能可以差出 1~2 个数量级。

    对于深度学习模型推理而言,推理框架对模型性能的影响主要体现在:是否充分利用了硬件的流水线资源、是否高效利用了硬件中的缓存、是否采用了时间复杂度更低的算法、是否解决了操作系统带来的性能损失(如上文的调度问题和内存缺页问题)、是否进行了正确高效的图优化等等。

    由于影响因素很多,因此软件对性能的影响往往呈现出很强的非线性,导致在评估性能时很难给出一些普适性的结论,很多时候只能具体情况具体分析。(有的时候甚至有点玄学【捂脸)

    例如同样计算量的向量四则运算和超越函数,后者往往会慢于前者的原因是很多硬件不支持超越函数的 SIMD 指令;再比如空洞卷积(dilated Conv)性能会弱于普通卷积的原因是前者对访存的利用不如后者高效等等。

    在软件实现的影响下,RoofLine 模型的上界再次下降,达到图中的红线(真实的非线性可能会比我随手画的要复杂的多):

    86c7778c4d13c8eda0a47cdcd3df33af.png

    RoofLine 模型各种性能损失示意图,图中曲线不代表真实比例

    因此,在评估或分析深度学习推理性能时,简单的计算量/访存量指标是完全不够的,只能做个性能上界参考。实际能达到的性能其实还要关注很多很多因素,例如算子的访存模式、数据排布、是否能够进行图融合、是否有精度可接受的低时间复杂度算法、算法并行度是否充足、各种运算的比例等等因素。

    这些因素对于算法同学而言可能过于复杂,并不需要掌握。但如果所在的公司/部门有交流的机会的话,可以跟部署/优化的同学针对模型结构和算子进行探讨,以获取性能优化的建议。

    这里可以一些一般性的结论,仅供参考:

    • 对于一些访存非常密集且访存 pattern 连续的算子,如 Concat、Eltwise Sum、ReLU、LeakyReLU、ReflectionPad 等,在 Tensor 数据量很大的情况下,软件实现的损失会非常小,正常情况下基本都能达到内存带宽实测上限;如果框架采用了融合策略的话,基本可以达到 0 开销。

    • 对于 Conv/FC/Deconv 等算子,在计算密度很高的情况下,大多数框架是能够很接近算力峰值的。但对于计算密度不是特别高的 case,不同框架的表现不一,需要实测才能确定。不过从大趋势而言,都是计算密度越高,硬件的利用率越高的。

    • 尽量使用常用的算子参数,例如 Conv 尽量使用 3x3_s1/s2,1x1___s1/s2 等,这些常用参数往往会被特殊优化,性能更好。

    4. 小结

    RoofLine 模型仅能用于估计模型所能达到的性能上界,而实际部署时,还会受硬件限制、系统环境、软件实现等因素的影响,导致无法达到 RoofLine 模型所定义的性能上界。

    此外,由于这些因素往往会导致性能曲线有较强的非线性,理论分析和实测会有一定差距,有时这些因素会严重影响性能曲线,甚至会导致算子的性质发生变化。因此本节讨论的内容只是提供一些分析的思路与技巧,实测始终是最准确的性能评估方式

    四、面向推理速度的模型设计建议

    前面讨论了一大堆,其实最实用的还是“怎么设计模型能够达到更快的推理速度”。

    在给出我的个人建议之前,首先要先声明的是:由于不同硬件、不同环境、不同框架的差异会很大,这些建议可能并不是在所有条件下都适用。在设计算法或性能测试遇到疑问时,建议咨询部署/优化的同学。

    好了,废话不多说(其实已经说了很多了),给出我的一些个人建议:

    方法论建议

    • 了解目标硬件的峰值算力和内存带宽,最好是实测值,用于指导网络设计和算子参数选择。

    • 明确测试环境和实际部署环境的差异,最好能够在实际部署环境下测试性能,或者在测试环境下模拟实际部署环境。

    • 针对不同的硬件平台,可以设计不同计算密度的网络,以在各个平台上充分发挥硬件计算能力(虽然工作量可能会翻好几倍【捂脸)。

    • 除了使用计算量来表示/对比模型大小外,建议引入访存量、特定平台执行时间,来综合反映模型大小。

    • 实测是最准确的性能评估方式,如果有条件快速实测的话,建议以实测与理论分析相结合的方式设计并迭代网络。

    • 遇到性能问题时,可以逐层 profiling,并与部署/优化同学保持紧密沟通,具体问题具体分析(适当了解一下计算相关理论的话,可以更高效的沟通)。

    网络设计建议

    • 对于低算力平台(CPU、低端 GPU 等),模型很容易受限于硬件计算能力,因此可以采用计算量低的网络来降低推理时间。

    • 对于高算力平台(GPU、DSP 等),一味降低计算量来降低推理时间就并不可取了,往往更需要关注访存量。单纯降低计算量,很容易导致网络落到硬件的访存密集区,导致推理时间与计算量不成线性关系,反而跟访存量呈强相关(而这类硬件往往内存弱于计算)。相对于低计算密度网络而言,高计算密度网络有可能因为硬件效率更高,耗时不变乃至于更短。

    • 面向推理性能设计网络结构时,尽量采用经典结构,大部分框架会对这类结构进行图优化,能够有效减少计算量与访存量。例如 Conv->BN->ReLU 就会融合成一个算子,但 Conv->ReLU->BN 就无法直接融合 BN 层

    • 算子的参数尽量使用常用配置,如 Conv 尽量使用 3x3_s1/s2、1x1___s1/s2 等,软件会对这些特殊参数做特殊优化。

    • CNN 网络 channel 数尽量选择 4/8/16/32 的幂次,很多框架的很多算子实现在这样的 channel 数下效果更好(具体用多少不同平台不同框架不太一样)。

    • 框架除了计算耗时外,也处理网络拓扑、内存池、线程池等开销,这些开销跟网络层数成正比。因此相比于“大而浅”的网络,“小而深”的网络这部分开销更大。一般情况下这部分开销占比不大。但在网络算子非常碎、层数非常多的时候,这部分开销有可能会影响多线程的扩展性,乃至于成为不可忽视的耗时因素。

    一些其他建议

    • 除了优化网络结构、推理框架性能外,还可以考虑通过一些其他工程技巧来提升系统整体的性能。例如:对推理服务流水化,并行数据读取与计算的过程,掩盖 IO 延时。

    本文介绍了评估模型大小的四个常用指标——计算量、参数量、访存量、内存占用,从 RoofLine 模型入手详细讨论了影响模型推理速度的影响因素,并给出了面向推理速度的模型设计方法论与建议。

    撰写本文的目的,不仅仅是给算法同学提供有效的网络设计建议,更多的还是希望能够传达性能优化的基础知识与分析思路,减少算法设计到部署之间的 gap,更快速高效的设计推理友好的网络模型。希望能对大家的工作有所帮助。

    由于本人知识水平有限,如有错误和不详尽的地方,望大家不吝指出,非常欢迎大家在评论区留言探讨。

    本文亮点总结

    1.模型在特定硬件上的推理速度,除了受计算量影响外,还会受访存量、硬件特性、软件实现、系统环境等诸多因素影响,呈现出复杂的特性。因此,在手头有硬件且测试方便的情况下,实测是最准确的性能评估方式。

    2.除了峰值算力和内存带宽之外,还有硬件限制、系统环境、软件实现等诸多因素会影响程序的实际性能,使得其非线性特性更加严重。因此 RoofLine 模型仅仅只能提供一个性能上界的评估方式,并不代表能够达到的实际性能。实际性能最准确的测量方式只有真机实测。

    本文仅做学术分享,如有侵权,请联系删文。

    下载1

    在「计算机视觉工坊」公众号后台回复:深度学习,即可下载深度学习算法、3D深度学习、深度学习框架、目标检测、GAN等相关内容近30本pdf书籍。

    下载2

    在「计算机视觉工坊」公众号后台回复:计算机视觉,即可下载计算机视觉相关17本pdf书籍,包含计算机视觉算法、Python视觉实战、Opencv3.0学习等。

    下载3

    在「计算机视觉工坊」公众号后台回复:SLAM,即可下载独家SLAM相关视频课程,包含视觉SLAM、激光SLAM精品课程。

    重磅!计算机视觉工坊-学习交流群已成立

    扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。

    同时也可申请加入我们的细分方向交流群,目前主要有ORB-SLAM系列源码学习、3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、深度估计、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

    9f129aee26ff5ca783a8a62f66ca7f35.png

    ▲长按加微信群或投稿

    13b63b1e45928d2c3afea4dd18bb81af.png

    ▲长按关注公众号

    3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列三维点云系列结构光系列手眼标定相机标定orb-slam3知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近2000星球成员为创造更好的AI世界共同进步,知识星球入口:

    学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

    58ca06631626c204ed42b30e2a33c96f.png

     圈里有高质量教程资料、答疑解惑、助你高效解决问题

    觉得有用,麻烦给个赞和在看~  f0727b1ba14e3882984eae4df9148b87.gif

    展开全文
  • 计算量 计算量可以说是评价模型大小最常用的指标了,很多论文在跟 baseline 进行比较时,都会把计算量作为重要的比较依据。 计算量是模型所需的计算次数,反映了模型对硬件计算单元的需求。计算量一般用 OPs ...

    点上方计算机视觉联盟获取更多干货

    仅作学术分享,不代表本公众号立场,侵权联系删除

    转载于:作者:田子宸@知乎    编辑:CV技术指南

    原文:https://zhuanlan.zhihu.com/p/411522457

    985人工智能博士笔记推荐

    周志华《机器学习》手推笔记正式开源!附pdf下载链接,Github2500星!

    前言


    当年头一次实习做算法的时候,主管给的第一个任务就是“把一个大的分割模型砍成一个小的”。当时并不理解模型“大”、“小”的真正含义,就简单的选取计算量作为评价指标,疯狂砍计算量(backbone 换 MobileNet/ShuffleNet、Conv 换成 DepthWise Conv、以及一些奇奇怪怪的融合结构等等),把模型计算量砍了将近 10 倍,结果一部署发现速度并没有快多少,反而是把最初的 ResNet 简单砍掉几个 block 效果更好。

    也是从那时起接触了访存量、流水线、RoofLine 模型等概念,对模型推理速度的问题产生了兴趣,从此踏上了深度学习推理优化的不归路(划掉)。

    如今做推理优化和 HPC 已经有一段时间了,还是偶尔能回想起当年不懂推理时设计的与硬件严重不匹配的模型。此外在工作中跟研究员沟通时,也会发现部分研究员对模型大小和模型推理速度的关系不太了解,设计出一些很难发挥硬件计算能力的模型结构。因此在这里对一些用于评价模型大小的指标——计算量、参数量、访存量、内存占用等指标进行详细探讨,分析这些指标会对模型的部署推理产生何种影响,详细讨论计算量和访存量对模型推理速度的影响,并给出不同硬件架构下设计高效网络结构的一些建议。

    本文不仅仅是为了给出网络的设计建议,更是希望能够有效传达性能优化的基础理论知识,以及性能分析的基本思路,帮助各位同学减少网络设计与部署之间的 gap,更高效的完成网络设计与部署工作。非常希望本文能够对大家的工作有所帮助,也非常欢迎大家在评论区留言探讨。

    一、常用的模型大小评估指标


    目前常用于评价模型大小的指标有:计算量、参数量、访存量、内存占用等,这些指标从不同维度评价了模型的大小。本节仅作简单介绍,熟悉的小伙伴可以跳过此节,直接看后面的分析与探讨。

    1. 计算量

    计算量可以说是评价模型大小最常用的指标了,很多论文在跟 baseline 进行比较时,都会把计算量作为重要的比较依据。

    计算量是模型所需的计算次数,反映了模型对硬件计算单元的需求。计算量一般用 OPs (Operations) ,即计算次数来表示。由于最常用的数据格式为 float32,因此也常常被写作 FLOPs (Floating Point Operations),即浮点计算次数。(这里为了跟传统习惯保持一致,下文就统一采用 FLOPs 啦)

    模型的整体计算量等于模型中每个算子的计算量之和。而每个算子的计算量计算方法各不一致。例如对于 Eltwise Sum 来讲,两个大小均为 (N, C, H, W) 的 Tensor 相加,计算量就是 N x C x H x W;而对于卷积来说,计算量公式为(乘加各算一次):

    d450eec5c0c1514c59b063df7777b445.png

    PyTorch 有不少工具可以模型计算量,但需要注意的是这些工具有可能会遗漏一些算子的计算量,将其计算量算成 0,从而导致统计的计算量跟实际计算量有轻微的偏差,不过大多数情况下这些偏差影响不大。

    2. 参数量

    早期的论文也很喜欢用参数量来评价模型大小。

    参数量是模型中的参数的总和,跟模型在磁盘中所需的空间大小直接相关。对于 CNN 来说参数主要由 Conv/FC 层的 Weight 构成,当然其他的一些算子也有参数,不过一般忽略不计了。

    参数量往往是被算作访存量的一部分,因此参数量不直接影响模型推理性能。但是参数量一方面会影响内存占用,另一方面也会影响程序初始化的时间。

    参数量会直接影响软件包的大小。当软件包大小是很重要的指标时,参数量至关重要,例如手机 APP 场景,往往对 APK 包的大小有比较严格的限制;此外有些嵌入式设备的 Flash 空间很小,如果模型磁盘所需空间很大的话,可能会放不下,因此也会对参数量有所要求。

    除了在设计模型时减少参数量外,还可以通过压缩模型的方式降低软件包大小。例如 Caffe 和 ONNX 采用的 Protobuf 就会对模型进行高效的编码压缩。不过压缩模型会带来解压缩开销,会一定程度增加程序初始化的时间。

    3. 访存量

    访存量往往是最容易忽视的评价指标,但其实是现在的计算架构中对性能影响极大的指标。

    访存量是指模型计算时所需访问存储单元的字节大小,反映了模型对存储单元带宽的需求。访存量一般用 Bytes(或者 KB/MB/GB)来表示,即模型计算到底需要存/取多少 Bytes 的数据。

    和计算量一样,模型整体访存量等于模型各个算子的访存量之和。对于 Eltwise Sum 来讲,两个大小均为 (N, C, H, W) 的 Tensor 相加,访存量是 (2 + 1) x N x C x H x W x sizeof(data_type),其中 2 代表读两个 Tensor,1 代表写一个 Tensor;而对于卷积来说,访存量公式为:

    8f20a3d62bb4b44cbed949cbb464fd01.png

    访存量对模型的推理速度至关重要,设计模型时需要予以关注。

    4. 内存占用

    内存占用是指模型运行时,所占用的内存/显存大小。一般有工程意义的是最大内存占用,当然有的场景下会使用平均内存占用。这里要注意的是,内存占用 ≠ 访存量。

    内存占用在论文里不常用,主要原因是其大小除了受模型本身影响外,还受软件实现的影响。例如有的框架为了保证推理速度,会将模型中每一个 Tensor 所需的内存都提前分配好,因此内存占用为网络所有 Tensor 大小的总和;但更多的框架会提供 lite 内存模式,即动态为 Tensor 分配内存,以最大程度节省内存占用(当然可能会牺牲一部分性能)。

    和参数量一样,内存占用不会直接影响推理速度,往往算作访存量的一部分。但在同一平台上有多个任务并发的环境下,如推理服务器、车载平台、手机 APP,往往要求内存占用可控。可控一方面是指内存/显存占用量,如果占用太多,其他任务就无法在平台上运行;另一方面是指内存/显存的占用量不会大幅波动,影响其他任务的可用性。

    5. 小结

    计算量、参数量、访存量、内存占用从不同维度定义了模型的大小,应根据不同的场合选用合适的指标进行评价。

    模型推理速度不单单受模型计算量的影响,也与访存量和一些其他因素息息相关。下文将详细讨论影响模型推理速度的因素。

    二、计算量越小,模型推理就越快吗


    答案是否定的。

    实际上计算量和实际的推理速度之间没有直接的因果关系。计算量仅能作为模型推理速度的一个参考依据。

    模型在特定硬件上的推理速度,除了受计算量影响外,还会受访存量、硬件特性、软件实现、系统环境等诸多因素影响,呈现出复杂的特性。因此,在手头有硬件且测试方便的情况下,实测是最准确的性能评估方式

    在设计网络结构时,如果有实测的条件,建议在模型迭代早期对性能也进行测试。一些 NAS 的方法也会对搜索出来的网络结构进行测速,或者干脆对硬件速度进行了建模,也作为初期搜索的重要参数。这种方法设计出来的网络在后期部署时,会极大减少因性能问题迭代优化的时间和人力开销。

    这里我将讨论影响模型在硬件上推理速度的一些因素,一方面希望可以帮助手动/自动设计网络结构的同学更快的设计更高效的网络结构,另一方面希望当模型部署时性能出现问题时能够为大家提供分析原因的思路。

    这一问题我将从如下 3 个点进行讨论:

    • 计算密度与 RoofLine 模型

    • 计算密集型算子与访存密集型算子

    • 推理时间

    1. 计算密度与 RoofLine 模型

    计算密度是指一个程序在单位访存量下所需的计算量,单位是 FLOPs/Byte。其计算公式很简单,很多教材、资料里也称之为计算访存比,用于反映一个程序相对于访存来说计算的密集程度:

    045e88a8bfec3f52b9f53f3d86da70aa.png

    RoofLine 模型是一个用于评估程序在硬件上能达到的性能上界的模型,可用下图表示:

    1c7cffd6d9a26a1b4032e627d816ca6e.png

    RoofLine 模型

    用公式描述:

    debd6d7b93c59256f576ae51b9992f34.png

    当程序的计算密度I较小时,程序访存多而计算少,性能受内存带宽限制,称为访存密集型程序,即图中橙色区域。在此区域的程序性能上界=计算密度×内存带宽,表现为图中的斜线,其中斜率为内存带宽的大小。计算密度越大,程序所能达到的速度上界越高,但使用的内存带宽始终为最大值。

    反之如果计算密度I较大,程序性能受硬件最大计算峰值(下文简称为算力)限制,称为计算密集型程序,即图中蓝色区域。此时性能上界=硬件算力,表现为图中的横线。此时计算速度不受计算密度影响,但计算密度越大,所需内存带宽就越少。

    在两条线的交点处,计算速度和内存带宽同时到达最大值。

    a52998f2e9cbed16128780e6195d684e.png

    在不同设备上,同一个程序的性质可能发生变化

    在不同设备上,同一个程序的性质可能发生变化。例如上图中的程序2,在算力稍弱的设备2上属于计算密集型程序,而在算力较强的设备1上就属于访存密集型程序了(感谢评论区指正)。如果想要充分发挥设备1的性能,应当适当加大程序的计算密度(比如到程序3的位置)。

    2. 计算密集型算子与访存密集型算子

    网络中的算子可以根据计算密度进行分类。一般来讲,Conv、FC、Deconv 算子属于计算密集型算子;ReLU、EltWise Add、Concat 等属于访存密集型算子

    同一个算子也会因参数的不同而导致计算密度变化甚至改变性质,比如在其他参数不变的前提下,增大 Conv 的 group,或者减小 Conv 的 input channel 都会减小计算密度。

    举个栗子,对于不同参数的卷积,计算密度如下:

    a4f5ff0016f8de4ed12c39d667f3e1b7.png

    可以看到,不同参数下卷积算子的计算密度有很大的差异。第 4 个算子 Depthwise Conv 计算密度仅有 2.346,在当下的很多设备上都属于访存密集型算子。

    算子的计算密度越大,约有可能提升硬件的计算效率,充分发挥硬件性能。我们以一个 Intel X86 服务器平台为例(10980 XE)。该平台 CPU 频率为 4.5 GHz,我们以 16 核为例,其理论 FP32 算力为 4.608 TFLOPs/s,内存带宽理论值为 96 GB/s。在此平台上的 RoofLine 模型为:

    44bd319cd02fbfd71a1da4707c914a8d.png

    Intel 10980 XE 16 核 RoofLine 模型,以及各个算子的计算密度与性能

    该平台“拐点”的计算密度为 48,计算较为密集的 OP1 和 OP2 处在计算密集区,能够达到平台的算力峰值;而 OP3 和 OP4 处在访存密集区,受内存带宽限制不能到达算力峰值,尤其是 OP4,由于计算访存比过低,计算效率仅有可怜的 4.9%,计算效率并不高。

    3. 推理时间

    这里涉及到一个 gap,很多部署的同学们更喜欢谈“计算效率”,而实际上算法同学真正关心的点是“推理时间”,导致两者在对接的时候经常会出现一些 misleading。因此我这里单独开一节来探讨一下“推理时间”的评估方法。

    其实也很简单,按照 RoofLine 模型,我们很容易就能得到算子实际的执行时间:

    计算时间计算量计算速度计算量计算量访存量带宽理论算力

    这是一个分段函数,拆开来可得:

    计算时间访存量带宽访存密集区计算量理论算力计算密集区

    一句话总结:对于访存密集型算子,推理时间跟访存量呈线性关系,而对于计算密集型算子,推理时间跟计算量呈线性关系

    讲到这里,我们就能初步回答本章一开始的问题了:按照 RoofLine 模型,在计算密集区,计算量越小,确实推理时间越小。但是在访存密集区,计算量与推理时间没关系,真正起作用的是访存量,访存量越小,推理的时间才越快。在全局上,计算量和推理时间并非具有线性关系。

    上一节中,OP4 虽然计算效率很低,但由于访存量也很低,因此其实推理速度还是快于其他几个 OP 的。但是我们可以观察到,其计算量虽然只有 OP1 的 1/130,但是推理时间仅降低到了 1/6,两者并非是线性关系(也是当年我把模型减到 1/10 计算量,但其实没快多少的原因)。

    再举两个例子强化一下,首先看这两个卷积,他们的计算量差不多,但是因为都在访存密集区,OP3 的访存量远低于 OP5,其推理也更快:

    7de85c105f574e0bad2ce5743d9481a5.png

    下面这个栗子更明显,OP5 和 OP6 的区别仅仅是一个是 DepthWise Conv,一个是普通 Conv,其他参数没有变化。按照我们之前的直观感受,Conv 换成 DepthWise Conv 应该会更快,但实际上两者的推理时间是差不多的(这组参数也是当年我用过的【手动捂脸):

    faf9c858919dd2c16d7d7ba5643db17a.png


    4. 小结

    从上面的讨论中我们可以看出:计算量并不能单独用来评估模型的推理时间,还必须结合硬件特性(算力&带宽),以及访存量来进行综合评估。并非是计算量越低模型推理越快。在评价模型大小时,也建议加上访存量作为重要的评价指标

    需要强调的一点是,不同的硬件平台峰值算力和内存带宽不同,导致同一个模型在平台 1 上可能是计算密集的,在平台 2 上可能就变成了访存密集的。例如上文提到的 Intel X86 平台,“拐点”值为 48,而 NVIDIA V100“拐点”值为 173.6,上文举的例子在 V100 平台上仅有 OP2 落在了计算密集区,剩下的全部是访存密集的。因此,同样的模型在不同平台上性质可能会发生改变,需要具体情况具体分析

    我们很难给出一个通用性的结论,究其原因是 RoofLine 模型本身是一个非线性模型。这里必须要强调一点的是,除了峰值算力和内存带宽之外,还有硬件限制、系统环境、软件实现等诸多因素会影响程序的实际性能,使得其非线性特性更加严重。因此 RoofLine 模型仅仅只能提供一个性能上界的评估方式,并不代表能够达到的实际性能。实际性能最准确的测量方式只有真机实测

    RoofLine 模型更重要的是提供了一种分析性能的思想,即计算密集型程序更多的受限于硬件算力,而访存密集型程序更多的受限于硬件内存带宽。在理解这一点的基础上设计网络结构,并分析网络的性能,将更有理论参考。不会再对”计算量减半,为啥推理时间没变“这种问题抱有疑问了(说的就是我【流泪)

    下文将对 RoofLine 模型的一些限制进行讨论,分析哪些因素将以何种方式影响程序,使得其到达不了 RoofLine 模型估计的性能上界。

    (下文要开始难度升级了,建议没看懂 RoofLine 模型的同学们再把这一章看一遍,不然后面会看的有点懵)

    三、影响模型推理性能的其他因素


    RoofLine 模型可以用来评估程序的性能上界,但是实际能达到的性能还会受到硬件限制、系统环境、软件实现等诸多因素的影响,距离性能上界有一定距离。本章将对这些影响因素进行分析。

    1. 硬件限制对性能上界的影响

    前面 RoofLine 模型使用的峰值算力及内存带宽,是根据纸面数据计算得到的,是理论上的最大值。但在实际情况下,硬件会因为种种原因,无法达到这个理论值。因此建议大家对硬件进行micro-benchmark,以获取硬件的真实性能上限。

    以上文的 Intel X86 CPU 为例,我们之前计算的 avx512 理论算力为 4.608 TFLOPs/s,但这个数值的前提是频率能维持在 4.5 GHz。然而实际上在使用 16 核跑 avx512 指令时,CPU 频率会下降到约 2.9 GHz,此时理论算力仅剩下 2.96 TFLOPs/s,而实测值仅有 2.86 TFLOPs/s。

    除了频率之外,有些芯片可能会因为一些设计上或实现上的原因,导致在实际使用时达不到理论峰值。比如一些低端芯片不支持多发射、不支持乱序执行、采用了阻塞式 Cache 等等,一些芯片甚至会有一些性能 bug,导致在实际使用时几乎到达不了理论峰值(这里我个人倾向于把这些原因归结为硬件限制带来的损失)。

    内存同理,该平台理论带宽为 96GB/s,但实测下来最高读带宽仅有 74 GB/s,仅能到达理论带宽的 77%。

    我们可以得到修正后的 RoofLine 模型,图中蓝色填充部分反映了因实际算力和内存带宽达到不了理论值而造成的损失:

    8f92fbc91c9d4d5e2965148b9bc479b6.png

    修正了实测峰值算力和内存带宽后的 RoofLine 模型,蓝色填充部分为硬件限制带来的损失

    修正后的模型“拐点”发生了变化,因此算子的性质也会发生变化。建议拿到硬件后对硬件进行 micro-benchmark,这里推荐两个测试工具:

    一个是高叔叔写的浮点峰值测试方法的文章,最后有 github 链接,大家可以 clone 下来测试硬件峰值:

    https://zhuanlan.zhihu.com/p/28226956

    还有一个是 stream 测试工具,可以用于测试内存带宽:

    https://www.cs.virginia.edu/stream/

    2. 系统环境对性能的影响

    除非程序运行在裸机中,否则操作系统一定会对性能上界产生一定影响,比如操作系统在多核间的调度损失、操作系统的内存管理带来的损失、操作系统本身占用的运算资源等等。

    对于一般的深度学习推理任务而言,现代操作系统对性能的影响并不是特别明显。但是在一些特殊情况下,也会带来严重的性能损失。我这里将会举两个例子:

    一个是 Android 系统在大小核上的调度,一旦程序在 CPU 上的占用率不足(比如是周期工作的任务),则有可能被 Android 调度到小核上,带来性能损失。

    另一个例子是内存缺页。在 Linux 系统上,当向系统申请内存页后,系统只是返回了虚拟页,等到程序实际使用虚拟页时,才会通过触发缺页异常的方式,进入操作系统内核分配物理页,这一过程会严重降低性能。

    好在这些问题可以通过软件进行一部分弥补,例如调度问题可以使用绑核来解决,缺页问题可以通过绑定物理页(需要内核态)或内存池来解决。因此操作系统带来的影响是可控的。

    除了操作系统带来的影响,系统中运行的其他进程也会对当前进程造成影响。比如一个系统中运行了多个深度学习实例,或者系统后台一些 APP 自启动了等等。这些进程都会占用核心算力和内存带宽,造成当前进程性能损失。

    这往往会导致在工程测试环境下性能达标的模型,在实际部署时性能下降。因此,必须关注工程测试环境和实际部署系统环境的差异。如有条件,最好在实际部署环境下进行测试。

    3. 软件实现对性能的影响

    除了硬件限制和系统环境外,一个任务的软件实现好坏对性能有着重大的影响

    例如对于同样的矩阵操作任务,使用 python 写的多重 for 循环,和用 numpy 高度优化过的矩阵操作函数,性能可以差出 1~2 个数量级。

    对于深度学习模型推理而言,推理框架对模型性能的影响主要体现在:是否充分利用了硬件的流水线资源、是否高效利用了硬件中的缓存、是否采用了时间复杂度更低的算法、是否解决了操作系统带来的性能损失(如上文的调度问题和内存缺页问题)、是否进行了正确高效的图优化等等。

    由于影响因素很多,因此软件对性能的影响往往呈现出很强的非线性,导致在评估性能时很难给出一些普适性的结论,很多时候只能具体情况具体分析。(有的时候甚至有点玄学【捂脸)

    例如同样计算量的向量四则运算和超越函数,后者往往会慢于前者的原因是很多硬件不支持超越函数的 SIMD 指令;再比如空洞卷积(dilated Conv)性能会弱于普通卷积的原因是前者对访存的利用不如后者高效等等。

    在软件实现的影响下,RoofLine 模型的上界再次下降,达到图中的红线(真实的非线性可能会比我随手画的要复杂的多):

    8cb94e7030dffaabc3d9f76193c5caaf.png

    RoofLine 模型各种性能损失示意图,图中曲线不代表真实比例

    因此,在评估或分析深度学习推理性能时,简单的计算量/访存量指标是完全不够的,只能做个性能上界参考。实际能达到的性能其实还要关注很多很多因素,例如算子的访存模式、数据排布、是否能够进行图融合、是否有精度可接受的低时间复杂度算法、算法并行度是否充足、各种运算的比例等等因素。

    这些因素对于算法同学而言可能过于复杂,并不需要掌握。但如果所在的公司/部门有交流的机会的话,可以跟部署/优化的同学针对模型结构和算子进行探讨,以获取性能优化的建议。

    这里可以一些一般性的结论,仅供参考:

    • 对于一些访存非常密集且访存 pattern 连续的算子,如 Concat、Eltwise Sum、ReLU、LeakyReLU、ReflectionPad 等,在 Tensor 数据量很大的情况下,软件实现的损失会非常小,正常情况下基本都能达到内存带宽实测上限;如果框架采用了融合策略的话,基本可以达到 0 开销。

    • 对于 Conv/FC/Deconv 等算子,在计算密度很高的情况下,大多数框架是能够很接近算力峰值的。但对于计算密度不是特别高的 case,不同框架的表现不一,需要实测才能确定。不过从大趋势而言,都是计算密度越高,硬件的利用率越高的。

    • 尽量使用常用的算子参数,例如 Conv 尽量使用 3x3_s1/s2,1x1___s1/s2 等,这些常用参数往往会被特殊优化,性能更好。

    4. 小结

    RoofLine 模型仅能用于估计模型所能达到的性能上界,而实际部署时,还会受硬件限制、系统环境、软件实现等因素的影响,导致无法达到 RoofLine 模型所定义的性能上界。

    此外,由于这些因素往往会导致性能曲线有较强的非线性,理论分析和实测会有一定差距,有时这些因素会严重影响性能曲线,甚至会导致算子的性质发生变化。因此本节讨论的内容只是提供一些分析的思路与技巧,实测始终是最准确的性能评估方式

    四、面向推理速度的模型设计建议


    前面讨论了一大堆,其实最实用的还是“怎么设计模型能够达到更快的推理速度”。

    在给出我的个人建议之前,首先要先声明的是:由于不同硬件、不同环境、不同框架的差异会很大,这些建议可能并不是在所有条件下都适用。在设计算法或性能测试遇到疑问时,建议咨询部署/优化的同学。

    好了,废话不多说(其实已经说了很多了),给出我的一些个人建议:

    方法论建议

    • 了解目标硬件的峰值算力和内存带宽,最好是实测值,用于指导网络设计和算子参数选择。

    • 明确测试环境和实际部署环境的差异,最好能够在实际部署环境下测试性能,或者在测试环境下模拟实际部署环境。

    • 针对不同的硬件平台,可以设计不同计算密度的网络,以在各个平台上充分发挥硬件计算能力(虽然工作量可能会翻好几倍【捂脸)。

    • 除了使用计算量来表示/对比模型大小外,建议引入访存量、特定平台执行时间,来综合反映模型大小。

    • 实测是最准确的性能评估方式,如果有条件快速实测的话,建议以实测与理论分析相结合的方式设计并迭代网络。

    • 遇到性能问题时,可以逐层 profiling,并与部署/优化同学保持紧密沟通,具体问题具体分析(适当了解一下计算相关理论的话,可以更高效的沟通)。

    网络设计建议

    • 对于低算力平台(CPU、低端 GPU 等),模型很容易受限于硬件计算能力,因此可以采用计算量低的网络来降低推理时间。

    • 对于高算力平台(GPU、DSP 等),一味降低计算量来降低推理时间就并不可取了,往往更需要关注访存量。单纯降低计算量,很容易导致网络落到硬件的访存密集区,导致推理时间与计算量不成线性关系,反而跟访存量呈强相关(而这类硬件往往内存弱于计算)。相对于低计算密度网络而言,高计算密度网络有可能因为硬件效率更高,耗时不变乃至于更短。

    • 面向推理性能设计网络结构时,尽量采用经典结构,大部分框架会对这类结构进行图优化,能够有效减少计算量与访存量。例如 Conv->BN->ReLU 就会融合成一个算子,但 Conv->ReLU->BN 就无法直接融合 BN 层

    • 算子的参数尽量使用常用配置,如 Conv 尽量使用 3x3_s1/s2、1x1___s1/s2 等,软件会对这些特殊参数做特殊优化。

    • CNN 网络 channel 数尽量选择 4/8/16/32 的幂次,很多框架的很多算子实现在这样的 channel 数下效果更好(具体用多少不同平台不同框架不太一样)。

    • 框架除了计算耗时外,也处理网络拓扑、内存池、线程池等开销,这些开销跟网络层数成正比。因此相比于“大而浅”的网络,“小而深”的网络这部分开销更大。一般情况下这部分开销占比不大。但在网络算子非常碎、层数非常多的时候,这部分开销有可能会影响多线程的扩展性,乃至于成为不可忽视的耗时因素。

    一些其他建议

    • 除了优化网络结构、推理框架性能外,还可以考虑通过一些其他工程技巧来提升系统整体的性能。例如:对推理服务流水化,并行数据读取与计算的过程,掩盖 IO 延时。

    本文介绍了评估模型大小的四个常用指标——计算量、参数量、访存量、内存占用,从 RoofLine 模型入手详细讨论了影响模型推理速度的影响因素,并给出了面向推理速度的模型设计方法论与建议。

    撰写本文的目的,不仅仅是给算法同学提供有效的网络设计建议,更多的还是希望能够传达性能优化的基础知识与分析思路,减少算法设计到部署之间的 gap,更快速高效的设计推理友好的网络模型。希望能对大家的工作有所帮助。

    由于本人知识水平有限,如有错误和不详尽的地方,望大家不吝指出,非常欢迎大家在评论区留言探讨。

    -------------------

    END

    --------------------

    我是王博Kings,985AI博士,华为云专家、CSDN博客专家(人工智能领域优质作者)。单个AI开源项目现在已经获得了2100+标星。现在在做AI相关内容,欢迎一起交流学习、生活各方面的问题,一起加油进步!

    我们微信交流群涵盖以下方向(但并不局限于以下内容):人工智能,计算机视觉,自然语言处理,目标检测,语义分割,自动驾驶,GAN,强化学习,SLAM,人脸检测,最新算法,最新论文,OpenCV,TensorFlow,PyTorch,开源框架,学习方法...

    这是我的私人微信,位置有限,一起进步!

    58bae242ddf7c2ffd99fc4caf1459933.png

    王博的公众号,欢迎关注,干货多多

    手推笔记:

    思维导图  |  “模型评估与选择”  |  “线性模型”  |  “决策树”  |  “神经网络”  |  支持向量机(上)  |  支持向量机(下)  |  贝叶斯分类(上)  |  贝叶斯分类(下)  |  集成学习(上)  |  集成学习(下)  |  聚类  |  降维与度量学习  |  稀疏学习  |  计算学习理论  |  半监督学习  |  概率图模型  |  规则学习

    增长见识:

    博士毕业去高校难度大吗?  |  研读论文有哪些经验之谈?  |  聊聊跳槽这件事儿  |  聊聊互联网工资收入的组成  |  机器学习硕士、博士如何自救?  |  聊聊Top2计算机博士2021年就业选择  |  非科班出身怎么转行计算机?  |  有哪些相见恨晚的科研经验?  |  经验 | 计算机专业科班出身如何提高自己编程能力?  |  博士如何高效率阅读文献  |  有哪些越早知道越好的人生经验?  |  

    其他学习笔记:

    PyTorch张量Tensor  |  卷积神经网络CNN的架构  |  深度学习语义分割  |  深入理解Transformer  |  Scaled-YOLOv4!  |  PyTorch安装及入门  |  PyTorch神经网络箱  |  Numpy基础  |  10篇图像分类  |  CVPR 2020目标检测  |  神经网络的可视化解释  |  YOLOv4全文解读与翻译总结  | 

    99bd0c43494c5907d35ee47894b5e08c.gif

    点分享

    d63e3bb200119859fe7f972699b15bbe.gif

    点收藏

    6ce24447f97fa06cad35bd4cf1b9ee5b.gif

    点点赞

    85527cfd74b361cc5246a6bce3294f94.gif

    点在看

    展开全文
  • 一篇基于复杂网络模型的计算机网络拓扑结构研究论文第卷期第年月计算机科学基于复杂网络模型的计算机网络拓扑结构研究杜彩凤中国石油大学摘,东营,要,随着计算机网络的快速发展网络结构日益复杂传统的随机网络模型已...

    一篇基于复杂网络模型的计算机网络拓扑结构研究论文

    期第年月

    计算

    基于复杂网络模型的计算机网络拓扑结构研究

    杜彩凤

    中国石油大学

    ,

    东营

    ,

    ,

    随着计算机网络的快速发展网络结构日益复杂传统的随机网络模型已很难对其拓扑特性作出客观的描

    ,

    .

    述因此复杂网络理论为计算机网络拓扑的研究提供了一个新的视野和思路

    给出了一种新的复杂网络模型来描述

    ,

    .

    计算机网络这个网络模型的平稳度分布

    关键词

    ,

    .

    另外证明了当网络规模趋于无限大时这个新模型具有高聚团性

    ,

    复杂网络平稳度分布聚系数

    ,,

    ,

    地名外

    ,

    ,

    ,

    ,

    ,

    ,

    ,

    引言

    ,

    ,

    其它众多的路由器相连

    ,

    .

    例如

    ,,

    ,

    .

    等这些门户网站

    分布

    有上百万甚至几十亿个链接这说明当用随机网络模型来描述计算机网络的拓扑结构时认为其点度服从的观点是不符合事实的

    . .

    网络已成为各学科领域重要的分析工具和研究手段事

    实上客观世界中复杂系统都可用网络进行直观刻画

    ,,

    ,

    网络

    这使人们相信复杂系统如计算机

    ,

    ,

    是由许多节点与连接两个节点的一些边组成的其中节点代表系统中不同的个体边则表示个体间的关系两个节点之间

    具有特定的关系则连一条边有边相连的两个节点被看作是

    ,

    网络一定存在某些特定的组织原则它背离随机图的随机化

    规则

    .

    由此人们开始开发工具运用新方法建立新模型以量

    ,

    .

    化的方式去捕捉隐含的组织原则 '〕

    在计算机网络方面的应用

    ,

    .

    相邻的

    .

    比如计算机网络可以看作是自主工作的计算机通过

    .

    本文的主要工作是研究随机复杂网络的平稳性质及其首先提出了一个新的反

    模型一致即

    ,

    ,

    各种物理介质与通信协议相互连接所得到的网络

    ,

    不依赖于节点的具体位置和边的具体形态就能表现出来的性质称为网络的拓扑性质相应的结构被称为网络的拓扑

    的网络模型其边际分布及边界条件与顶点

    ,

    在时刻

    ,

    连接的概率边际分布

    结构

    .

    大量研究表明网络所具有的特性在很大程度上是由

    ,

    ,

    . .

    阴走

    网络拓扑来决定的不同的拓扑结构会导致网络性能的差异

    ,

    一一

    ,

    随机复杂网络研究传统上属于图论范畴

    ,

    自从

    世纪

    ,

    ,

    在时刻顶点

    的度边界条件

    年代起无明确设计原理的大规模

    网络被描述为随机图

    这是最简单的复杂网络

    .

    随机图首先由匈牙利数学家

    ,

    然后我们证明了这个网络模型就有平稳度分布和高聚团系

    进行研究他们建立的度分布是模型〔〕

    ,

    数符合计算机网络的实际特征

    ,

    .

    我们也做了一些模拟结果

    .

    分布的

    一,

    '

    .

    年压

    指出真

    ,

    的新模型及其度分布

    我们考虑无向边连接的增长模型假设初始时刻是一个具有每单位时间有一个带有

    .

    实网络的另一个重要统计特征是网络的点度服从幂律分布幕律分布的参数

    ,

    与网络大小无关因此将具

    .

    有这种特性的网络称为无标度网络

    ,

    无标度网络的节点度分

    ,,

    个顶点的完全图条边的新点加人网络

    ,

    布从直观上看具有这样的特征大多数节点只有少量的连接

    而极少数节点却有大量的连接拥有的连接点可能高达数百

    ,,

    新点的第一条边以偏好概率连接即新点连接到某点

    的概率正比于点的度

    '

    ,

    数千甚至数百万是一个无标度网络少数主干节点路由器与

    本文受中国石油大学人才引进博士基金资助

    杜彩凤

    ,

    ,

    , .

    ,

    新点的其余的

    条边

    女博士主要研究领域为随机图复杂网络

    ,

    .

    '

    1994-2009 China Academic Journal Electronic Publishing House. All rights reserved.

    http://doc.xuehai.net

    1-3439-png_6_0_0_45_45_868_1237_979.5_1353-2412-0-779-2412.jpg

    展开全文
  • 但是理论过于抽象,而图灵就可以认为是该理论的模型,即 计算模型 。图灵可以等价于任何有限逻辑数学过程的终极强大逻辑机器。除了图灵之外,还有其他的计算模型,比如寄存器。 关于此处的内容,参见维基...

    实际上关于本文所要探讨的内容,早在19年就在 关于可计算、图灵机及CPU性能 中进行了梳理。所以本文简要串联下逻辑,其余内容可以参见之前的这篇文章。

    计算机和操作系统的核心自然是为 计算 服务的,那么什么问题是可被计算的呢?这就是可计算理论探讨的问题。

    但是理论过于抽象,而图灵机就可以认为是该理论的模型,即 计算模型 。图灵机可以等价于任何有限逻辑数学过程的终极强大逻辑机器。除了图灵机之外,还有其他的计算模型,比如寄存器机

    关于此处的内容,参见维基百科的定义。可以在维基百科上顺着图灵机找到很多相关的概念索引,值得试试看。

    那么 计算模型 如何变成现实呢?冯·诺伊曼结构

    该结构思想和我们之前学过的知识点有非常大的联系,主要是:

    • 存储和计算分离:plusar消息队列可还记得?当然了,plusar的存储和计算分离是消息队列历史演进中产生的思想。
    • 更进一步的是,逻辑和控制分离:各种设计模式、编程思想,重点就是控制流程和业务逻辑的分离。

    该结构五大件:控制器、运算器、存储器、输入、输出。算法都讲究空间复杂度和时间复杂度,为什么呢?和五大件一对比,很自然得出推论:

    • 存储器:对应空间
    • 控制器和运算器组成的执行单元:对应时间

    一个程序占用执行单元时间长了,自然时间复杂度就高。你用的多了,其他程序不就用的少了?一个程序占用存储器的空间越多,空间复杂度越高。虽然有虚拟内存机制,好像内存(存储单元)大小是相对无限的,但是过大内存占用,会导致频繁的缺页,拉高磁盘负载,进而又反过来影响执行单元的执行。

    假设: 执行单元不再是晶体管实现,而是变成了量子计算机,且量子计算器的计算能力无穷。那么请问,到那时,时间复杂度还是重要的标准吗?


    再回到 计算 上,现阶段计算的重要指标就是速度,如何评估速度呢?两个维度:

    1. 响应时间:单位任务完成的时间
    2. 吞吐量:单位时间完成的任务

    这两个维度太棒了,响应时间偏向于个体,吞吐量偏向于整体。

    那么单个任务的执行时间,在这里就是CPU的执行时间,CPU执行时间 = CPU时钟周期数 * 周期时间。

    当CPU当做是一个需要口号121 121来指挥的机器,喊口号时工作(喊得越快跑的越快),不喊口号时停止。那么这个机器完成一项任务的总时间,自然就等于喊口号的数量 * 喊口号的频率。

    这里更建议阅读一下《编码:隐匿在计算机软硬件背后的语言》,可以理解为什么CPU需要时钟周期,也即底层硬件结构:实际上就是 组合逻辑电路和时序逻辑电路组成,需要统一的口号(心跳)来协调工作。

    同时,建议阅读《计算机组成》第一章。

    CPU执行时间 = CPU时钟周期数 * 周期时间,而CPU时钟周期数 = 指令数 * 平均每条指令的执行时间。

    所以:CPU执行时间(响应时间) = 指令数 * 平均每条指令的执行时间 * 周期时间。

    这里你可能会想问,为什么是 平均每条指令的执行时间呢? 其实答案也在《编码》中,不同指令对应操作不同的硬件单元,不同的硬件单元对应的电路组成不一样,所以总的执行时间也不相同。类似的,电脑上打开文本文档和打开IDEA哪个快呢?

    为什么要推算响应时间的公式呢?答案还是 计算 的重要指标:速度,也即缩短响应时间,加快执行。

    所以我们看到计算机的主频相比之前变高不少,对应就是降低了周期时间,但也受着约束,这块内容请参加之前的文章。

    而指令数的下降一方面是程序本身优化,另一方面是引入新硬件结构支持更复杂的指令。

    最后 平均每条指令执行时间(CPI),对应如下方面:

    1. 流水线技术:单个CPU上采用多级流水线同时执行多条指令,使得CPI降低,增大吞吐量
    2. 并行技术:多个CPU同时执行多条指令,使得CPU降低,增大吞吐量
    3. 缓存技术:通过在内存和CPU之间加入多级缓存,降低CPI

    关于计算抽象就说到这里。通过本文的分析,也就引出了下文的指令集,指令集是对CPU整体硬件的抽象,并且流水线技术是对指令执行重要的优化。

    其他内容参见: 关于可计算、图灵机及CPU性能 ,与本文相互补充。

    展开全文
  • 一、数据仓库 与 传统数据库 区别、 二、数据仓库系统体系结构、 三、多维数据模型、 1、星型模式、 2、雪片模式、 3、事实星座、 四、在线分析处理、 五、多维数据分析操作
  • 本文介绍简化模型构建和评估过程。 caret包的train函数可用于 使用重采样评估模型调整参数对性能的影响 在这些参数中选择“最佳”模型 从训练集估计模型性能 首先,必须选择特定的模型。 调整模型的第一步是...
  • Redis 多线程网络模型全面揭秘

    千次阅读 多人点赞 2021-02-21 15:31:18
    导语一文带你完全吃透 Redis 整个核心网络模型的原理和源码。 目录 导言 Redis 有多快? Redis 为什么快? Redis 为何选择单线程? 避免过多的上下文切换开销 避免同步机制的开销 简单可维护 Redis 真的...
  • 聊聊多线程的代价是否应该使用多线程程序更复杂上下文切换的开销增加资源消耗 是否应该使用多线程 从一个单线程的应用到一个多线程的应用并不仅仅带来好处,它也会有一些代价。不要仅仅为了使用多线程而使用多线程。...
  • 点上方蓝字人工智能算法与Python大数据获取更多干货在右上方···设为星标★,第一时间获取资源仅做学术分享,如有侵权,联系删除转载于 :AI科技评论Bert模型自18年10月推出,...
  • 本章中,该研究讨论并开始理解基础模型社会影响的复杂性。本章讨论了不公平带来的危害和滥用的危害;基础模型对经济和环境的影响;基础模型在法律和道德方面影响。 不平等与平等:本小节主要描述了内在偏差,即间接...
  • PaddleOCR算法主要包含三个部分,分别是文本检测模型(detection)、文本识别模型(recognition)、方向分类器(classification)。 文本检测模型(detection) 模型介绍 PaddleOCR开源的文本检测算法列表: DB(paper) [2]...
  • 哪张是做成的模型的截图? 1号 2号 下面就来分享下用手机来玩转ContextCapture(Smart3D)建模 1.拍照技巧(捕获对象) ContextCapture(Smart3D)作为一个自动化建模不需过多人工干预的软件,照.
  • v_rep教程----构建纯净模型构建可见形状:建立关节模型定义 本教程将指导您逐步建立一个纯净的模拟模型,一个机器人,或任何其他项目。得到一个美观、快速显示、快速仿真和稳定的仿真模型,这是一个非常重要的课题,...
  • 在这篇文章我们将介绍因式分解机模型(FM),为行文方便后文均以FM表示。FM模型结合了支持向量与因子分解模型的优点,并且能够用了回归、二分类以及排序任务,速度快,是推荐算法中召回与排序的利器。FM算法和前面...
  • 召回模型

    千次阅读 2021-01-21 10:22:43
    如果比较熟悉的读者,可以直接跳到“用FM/FFM模型做召回意味着什么”部分看起。 这个召回模型系列文章的缘起,来自于我对下列两个不太符合常规做法的推荐技术问题的思考,下面再次复述一遍: 第一个问题:我...
  • 这些blockwise或chunking的方法可作为许多更复杂模型的基础。 Strided patterns是另一种方法,即仅按固定间隔参与。诸如Sparse Transformer和/或Longformer之类的模型,采用“跨越式”或“膨胀式“视窗。 Compressed...
  • Segmentation Model Architecture:分割模型架构 图7展示了分割网络的架构,该架构由编码器和解码器组成。它是基于U-Net的改进的对称网络。特征图的大小在编码器和解码器的pipline中或多或少对称。该网络由3×3和5...
  • △ 人物分割可以让人们直接在移动设备上为视频创建AR效果 最初开发这些模型时,它们的大小复杂性意味着为特定效果部署一个模型可能需要长达三天的时间,这还不包括调试模型修复任何错误的时间。 然后还有跨设备的...
  • 本博客为(系列四)的笔记,对应的视频是:【(系列四) 线性分类1-背景】、【(系列四) 线性分类2-感知(Perceptron)】、【(系列四) 线性分类3-线性判别分析(Fisher)-模型定义】、【(系列四) 线性分类4-线性判别...
  • 这种局限性,很大一部分原因就是自编码相对是简单任务,很难学习到更深层次的表示,而机器翻译需要更复杂的语义转化,这种预训练目标和下游任务之间的差异,导致模型很难最大程度利用好预训练数据。如何克服着两个...
  • 也就是说,如何确定机器学习模型预测的结果是符合常理的,进而确定所选择的机器学习模型是可信的。关于这个问题,我将通过两个篇幅向大家介绍机器学习模型的可信性,即机器学习预测结果的解释,以及 MATLAB 如何支持...
  • 前言假如你想尝试一下不用表格来排版网页,而是用CSS来排版...这就是DIV排版的核心所在,传统的表格排版是通过大小不一的表格和表格嵌套来定位排版网页内容,改用CSS排版后,就是通过由CSS定义的大小不一的盒子和盒...
  • 黑箱模型

    千次阅读 2021-02-14 13:38:57
    但由于因素众多、关系复杂,也可简化为灰箱模型来研究。 黑箱模型:该模型是环境预测工作中应用较多的一类模型,它是根据输入—输出关系建立起来的,反映了有关因素间的一种笼统的直接因果关系。用于环境预测的黑箱...
  • 本文转载自:机器之心 | 作者:力元深度学习的灵活性恰好适合于复杂的 CAD 设计,DeepMind 的研究者基于 CAD 草图与自然语言建模的相似性,提出了自动生成 CAD 草图的...
  • 点上方人工智能算法与Python大数据获取更多干货在右上方···设为星标★,第一时间获取资源仅做学术分享,如有侵权,联系删除转载于 :机器之心千亿参数量的中文大规模预训练语言模型时代...
  • https://github.com/ParikaGoel/KinectFusion 演示: 2.Kintinuous 上述 KinectFusion 算法使用固定体积的网格模型(如256×256×256)表示重建的三维场景,从而只能重建固定大小的场景;另外当重建体积较大,或者...
  • Zookeeper 为 HBase 集群提供协调服务,它管理着HMaster和HRegionServer的状态(available/alive等),并且会在它们宕时通知给HMaster,从而HMaster可以实现HMaster之间的failover(故障转移),或对宕的...
  • MLP多层感知 数据获取、预处理 模型搭建 训练与评估 卷积神经网络 高效建模 Keras Sequential高效建模 Functional API建模 经典网络调用 高效训练 当模型建立完成后,通过 tf.keras.Model 的 compile 方法配置训练...
  • 计算机网络-参考模型

    2021-07-02 13:23:02
    按网络大小和规模分类覆盖范围并非绝对,关键在于是否使用了如局域网的技术,是否具备了如局域网的技术特征。覆盖范围 1m:个域网 PAN (Personal Area Networks)覆盖范围 1Km:局域网 LAN (Local Area Networks)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 139,043
精华内容 55,617
关键字:

复杂模型机比较大小