Py学习  »  机器学习算法

不止显卡!这些硬件因素也影响着你的深度学习模型性能

极市平台 • 4 年前 • 718 次点击  

加入极市专业CV交流群,与6000+来自腾讯,华为,百度,北大,清华,中科院等名企名校视觉开发者互动交流!更有机会与李开复老师等大牛群内互动!

同时提供每月大咖直播分享、真实项目需求对接、干货资讯汇总,行业技术交流。关注 极市平台 公众号 ,回复 加群,立刻申请入群~


作者:

来源:


程序员之于计算机就相当于赛车手对待跑车一样,必须十分熟悉它的每一个部件,明白各自的用途,然后在每一次调教当中充分发挥各部分的潜力,最终才能爆发出最大的性能。本次分享以图像任务训练为例,将从cpu、内存、硬盘、显卡这些方面对算法性能的影响进行逐一分析,配合相应的实验,给出相应的优化建议。笔者为图像算法工程师,因此下面均以图像数据为例,但无需任何图像算法的前置知识,大概只要写过代码的都能理解(首先感谢 老狼 的技术支持,给出了宝贵的建议)

  • 老狼 链接:

    https://www.zhihu.com/people/mikewolfwoo/activities



数据流动路径


假设我们现在有一批图片集放在硬盘当中,待读取进内存送入GPU运算,那么一般会经历以下流程:


  1. cpu发出读取指令,从硬盘中找到图片数据,并存到内存中;

  2. cpu从内存中取出一批数据,转化为numpy array,并作数据预处理/增强操作,如翻转、平移、颜色变换等。处理完毕后送回内存。

  3. cpu内存(后面简称内存)和gpu内存(后面简称显存)各开辟一块缓冲区,内存中的一个batch的数据通过PCIe通道传输到显存当中。

  4. GPU核心从显存中获取数据进行并行计算,计算结果返回至显存中。

  5. 计算好的结果将从显存经过PCIe通道返回到内存。


这5个步骤涉及到几个影响数据传输速度的环节:


  1. 硬盘读取速度;

  2. PCIe传输速度;

  3. 内存读写速度;

  4. cpu频率。


我们首先来说说硬盘。



硬盘


intel 900P


在深度学习模型进行训练前,往往需要从本地硬盘读取数据到内存,并做一些预处理,硬盘读取速度会极大影响训练的效率。如果读取速度快,送进GPU的数据多,GPU的利用率就越高。当然提高数据传送效率除了有硬件的部分也有软件的部分,我们先来讨论硬件方面的影响。而目前市售硬盘有机械硬盘和固态硬盘两种,固态硬盘根据接口分为sata、M.2 NVME、PCIe三种。笔者个人电脑上有两种硬盘,分别是希捷酷鱼2T机械硬盘和三星860evo 500GB固态硬盘,我们使用kaggle著名数据集dogs_cats_redux,从两个硬盘中分别测试数据读取的速度。


测试条件:


cpu:i7 8700k (6C 12T @4.7GHz)


内存:64GB


固态:三星860evo 500GB


机械:希捷酷鱼2T


显卡:1080ti


系统:ubuntu 18.04



从代码里面可以看到,先用opencv读取图片,然后统一进行resize到(224, 224)的操作,固态硬盘的读取速度差不多是机械硬盘的7倍!然后笔者为了皮一下,用mxnet的API来测试一下在固态上的读取速度:



每秒3565张!为什么mxnet能如此快?是因为API内部是实现了多线程读图的操作,这也就是影响读图速度的软件的方面,后面再详细讲。



PCIe


内存中的数据通过PCIe总线传输到GPU显存当中,具体PCIe的介绍请参考 老狼 的深入PCI与PCIe之一:硬件篇。如果是单显卡的机器,大部分都能工作在PCIe 3.0 x16带宽下,此时的带宽为15.754GB/s。PCIe各代速率对比如下图,来自百度百科

  • 深入PCI与PCIe之一:硬件篇 链接:

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


当一个batch的数据(假设tensor shape: (32, 224, 224, 3))通过PCIe (3.0 x16)传输至GPU时,理论上所需时间为:2.44ms。(float 32的tensor的size为32×224×224×3×8≈0.0385GB)。


但目前市售的桌面级cpu(以英特尔酷睿系列的i7 cpu为例),CPU直连的PCIe通道一般只有16条,如果插了双GPU,那么只能工作在PCIe 3.0 x8带宽上(如果你的主板支持的话),那么理论延迟时间加倍。因此一般多卡机器如4卡、8卡、10卡,均最低使用双路工作站或服务器级别的cpu,如英特尔至强系列,此系列单U最低都能提供40条PCIe总线。

但这些延迟时间相比起GPU计算、IO等这些时间来说,其实影响甚微,加上还有软件层面的速度优化,这个延迟可以忽略不计,因此装机时不必太多纠结于PCIe通道数上(当然心里边还是觉得满血最舒服对吧)。


顺便一提,AMD在今年computeX大会上,发布了新款zen3系列的cpu和主板产品,支持PCIe 4.0,相比3.0的带宽直接翻一倍。但intel竟宣称4.0现在不是主流,对打游戏没多大帮助,所以近期没有推出支持PCIe 4.0的产品的打算(人人都打游戏???)



CPU频率


没错!CPU频率也会对数据读取速度有影响,这跟市面上大多装机分享所说的不同,这些文章宣称cpu频率对速度没多大影响,但实验证明频率也对读取速度有比较大的影响。


测试条件:


硬件同上,但cpu i7-8700k是可超频的u,因此通过bios的超频设置,分别设置为2.5GHz、3.0GHz、3.5GHz、4.7GHz四个不同的频率,分别测试opencv读取猫狗大战数据集(12500张狗狗图)的速度,结果对比如下:


实际上,由于所有数据预处理的操作都在cpu上执行,因此cpu频率越高,生成图片的速度就越快,这样的差距也在情理之中。当机器拥有多显卡时,cpu喂数据的速度可能会成为整个系统的瓶颈。



内存频率


我们来测试一下在不同内存频率下,opencv读图的速度。内存频率分别设为2133MHz、2400MHz、2666MHz、3000MHz,其它硬件参数同上。


可以看到,这几个内存频率下,读取速度几乎没差别,其实内存的带宽相对来说已经足够大,真正的短板在于硬盘。这里附上维基百科给出的内存频率-带宽对比表格:


图来自wikipedia

从表中看出,即使内存频率低至1866MHz,带宽已经达到15GB/s,已经接近PCIe 3.0 x16的带宽(15.75GB/s),也就是说内存传输数据到显存的时候也能跑满PCIe 3.0 x16的带宽,因此内存带宽远远不是瓶颈。



显卡


有钱就买最贵的就对了(误)。目前市面上许多深度学习装机教程已经对显卡的选择作了非常细致的解释,这里就不作推荐什么价位买什么显卡的重复劳动了,这里聊聊显卡的几项指标(如非特别说明,本文提到的显卡一律指Nvidia的显卡,目前几乎没人用AMD显卡做深度学习,或许未来有)。


  • CUDA核心数


CUDA核心数基本确定了一张显卡的算力,当前服务器级别算力最强的Tesla V100显卡拥有高达5120个cuda核心;工作站级别最强的RTX 8000显卡以及TITAN系列最强的RTX TITAN,CUDA数为4608个;而当前桌面级别最强的RTX2080ti,拥有4352个CUDA核心(很快这些当前最强就会变成老爷车了)。核心数越多意味着执行并行计算的量就更多。详细的显卡规格对比可以参考维基百科List of Nvidia graphics processing units



  • 内存颗粒


最新几代的显存颗粒类型分别有GDDR5X(1080ti)、GDDR6(2080ti)、HBM、HBM2(V100),对应的带宽如下表:



HBM2显存的带宽已经高达256GB/s,nvidia目前把这种显存只用在最高端的显卡上,而AMD这边则已经应用到桌面级显卡,老黄的刀法啧啧啧。(英伟达官方宣传其V100的HBM2显存拥有900GB/s的带宽,应该是拥有多个channel的结果)


  • TensorCore


tensor core最早出现在nvidia的volta架构,用于加速深度学习经常需要的矩阵运算。当使用tensor core时,我们需要从以往的单精度运算(float32)转换成为混合精度(float16+float32)计算,而tensor core正是能加速这些混合精度运算。所谓“混合精度-mix precision”,如下图,假设A和B是FP16精度的矩阵,矩阵相乘后再和一个FP16或者FP32精度的矩阵相加,会得到一个FP16或者FP32的矩阵(取决于你相加的矩阵是什么精度)。



由FP32转换成FP16计算,能够减少一半的显存使用量,运算时的吞吐量大大增加。实际上,拥有640个tensorcore的V100,吞吐量是P100的12倍(详见nvidia的tensor core介绍文档)。

  • nvidia的tensor core介绍文档 链接:

    https://images.nvidia.com/content/volta-architecture/pdf/volta-architecture-whitepaper.pdf


我们来看看几款显卡的tensor core数量:



在桌面级显卡中,2080ti拥有最多的544个tensor core,而RTX Titan则有576个tensor core。


  • 浮点算力


浮点算力是最能反映显卡性能的指标,对于深度学习来说,单精度(float32)的运算最常见,因此最受关注的是float32的算力。而近来混合精度计算越来越受欢迎,float16的算力也越来越重要。至于int8一般用在要求极端速度的推理任务上。而float64一般在HPC应用中常用,所以基本可以忽略这一项。我们来看看几款Volta、Turing架构的显卡详细参数表:


手动整理的表格,数据来自英伟达官网和GPU-L


当前单精度和半精度浮点算力最高的是RTX Titan,而算力紧追其后的是Tesla V100和Titan V,但这两款的核心数和显存均是最高。更大的显存意味着每次输入数据的batch size可以更大,以及在GAN应用中可以生成更大分辨率的图片。如果用于高精度的科学计算,Tesla V100和Titan V是最佳选择。如果要考虑性价比,那无疑是2080ti最佳。


为什么服务器级别的Tesla卡在算力上与桌面级、工作站级的显卡相差无几,价格却差这么大呢?除了上面的双精度算力最高之外,笔者认为还有以下因素——nvlink、nvswitch。


  • nvlink


nvlink是英伟达在2014年推出的GPU互联技术,由于以往的多卡环境中,GPU与其它GPU通信的时候,必须先通过PCIe把数据传输到CPU,再由CPU传输到其它GPU,整体计算速度受限于PCIe的速度(要知道HBM2显存的带宽已经达到了900GB/s),PCIe 3.0 x 16双向带宽最多只有30GB/s。nvlink的出现正是为了解决这个问题,看看下面nvlink的说明图:


来源于英伟达官网


先看左图,有了nvlink,GPU与GPU之间的通信不需要再通过CPU,直接通过nvlink通信,双向带宽高达100GB/s(nvlink 2.0)。右图是单服务器双路CPU及8路GPU的架构,两个CPU分别对应4个GPU,当其中一组GPU需要向另一组GPU进行通信时,以往同样只能先通过PCIe传输到CPU,然后再通过QPI通道(带宽为25.6GB/s)传输到另一个CPU,最后再通过PCIe送进另一组GPU。而nvlink支持跨CPU节点的直接通信,V100每个GPU有6条nvlink通道,总带宽高达300GB/s。


但从上图可以看到,即使每个GPU拥有6条nvlink通道,仍然无法做到“全连接”(即任意两个GPU之间存在双向通道)。这就引出了下一个更加疯狂的技术:nvswitch。


  • nvswitch

图来源于nvidia官网


图来源于nvidia官网


nvidia官网介绍视频的这两张图很好地介绍了两者之间的区别。下图一个主板上的8块GPU通过6块nvswitch芯片与另一块主板上的任意一块GPU进行通信,使得8对GPU能够同时以300GB/s的速度进行通信,实现16个GPU全连接。除此之外,nvswitch还能使得整个服务器作为一块拥有0.5TB显存、2PetaFLOPS算力的“大显卡”使用。


那么为什么V100敢卖这么贵(约8万RMB一张)?因为只有V100的nvlink和nvswitch是满血的 ,2080ti虽然也能使用nvlink,但速度被老黄砍了一刀。而且目前实现nvswitch的DGX2机器也只有V100的选项,因此这只能是土豪们的玩物。



-End-


*延伸阅读





CV细分方向交流群


添加极市小助手微信(ID : cv-mart),备注:研究方向-姓名-学校/公司-城市(如:目标检测-小极-北大-深圳),即可申请加入目标检测、目标跟踪、人脸、工业检测、医学影像、三维&SLAM、图像分割等极市技术交流群(已经添加小助手的好友直接私信),更有每月大咖直播分享、真实项目需求对接、干货资讯汇总,行业技术交流一起来让思想之光照的更远吧~



△长按添加极市小助手


△长按关注极市平台


觉得有用麻烦给个在看啦~  

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49597
 
718 次点击