前言
GPU 和人工智能越来越火,引起了大批投资者和开发者的注意。百度前首席科学家 Andrew Ng 提到,人工智能的春天已经到来,其重要因素之一是 GPU 处理能力,能让神经网络的智能可以随数据增加而继续提升,突破了过去的人工智能所能达到的平台,训练饱和极限(智力容量)大大上移。
最近 Google 在 ISCA2017 上披露了 TPU(Tensor Processing Unit)的细节,继 Haswell CPU, Tesla K80GPU 之后,又增加了一种专门用于机器学习和神经网络的高性能武器。因此,我想借 Tim Dettmers 的博客《哪种GPU 适合Deep learning:我的经验和建议》来介绍一下GPU 的选择。
最开始读到他的文章,是为了找如何用多GPU 集群处理大表JOIN 偶然遇到的。他分享的内容很适合刚开始涉入GPU 开发领域的朋友参考,比如参加Kaggle 比赛,用多套数据并行运行于同一个模型,或者用同一套数据并行运行于多个不同模型等。其正文后面的讨论也有很多干货。
数据分析和GPU
GPU 不仅能实现数据库的许多功能,而且其强大的计算能力,能实现 **实时** 分析。MapD 和 Kinetica 是这方面比较有名的两家公司。MapD 用 NVIDIA Tesla K40/K80 实现了基于 SQL 和列式存储的数据库,无需索引,擅长任意多组合的条件查询 (Where)、聚合 (Groupby) 等,实现传统关系型数据库的 BI 功能,方便用户自由地进行多条件查询。性能优势也很明显(尤其是响应时间)。
比如,MapD 将 1987-2008 年全美国进出港航班的数据扩大 10 倍后,执行全表扫描的报表任务,如"SELECT … GROUP BY …”。一台带有 8 张 Tesla K40 显卡的服务器 (8 核 /384G RAM/SSD) 比 3 台服务器(32 核 /244G RAM/SSD)组成的内存数据库集群快 50-100 倍(请参见 MapD 技术白皮书 MapD Technical Whitepaper Summer 2016)。
GPU 数据库的另一大特色是可视化渲染和绘制。将 OpenGL 等的 缓冲区直接映射成 GPU CUDA 里的显存空间,原地渲染,无需将结果从内存拷到 GPU,可以实现高帧频的动画。也可以原地绘制成 PNG 或视频 stream,再发给客户端,大大减少网络传输的数据量。这些优势吸引了很多开发者。
在实时分析上比较有名的一家公司是 Kinetica。他们开始时为美国情报机构实时分析 250 个数据流。现在能用 10 个节点,基于 20 万个传感器,为美国邮政服务(USPS)提供 15000 个并行的实时分析、物流路由计算和调度等。
我国用 GPU 进行分析和挖掘的用户也越来越多,想深入学习的朋友也不少。最快速的入门办法是重复前人的实验。弗吉尼亚大学的 Accelerating SQL Database Operations on a GPU with CUDA 里的开发环境和实验,值得借鉴。他们用一张 4G 显存的 NVIDIA Tesla C1060, 在一台低配的服务器上(Xeon X5550(2.66GHz/4 核),5G RAM),用 5 百万行的表做查询和汇总,响应时间 30-60 毫秒。
我们测过的最低配置是 NVidia GTX 780,一千多块,适合用来尝试查询和聚合。先用 SQLite 将 SQL 解析成多个 OpCode 步骤, 然后在 CUDA 上实现一个虚机,来逐一实现每个步骤,直至将整个表逐行遍历完。其中一些步骤可以并行,因此可用 CUDA 起几万个线程,每个线程处理一行。
深度学习和 GPU
深度需要较高的计算能力,所以对 GPU 的选择会极大地影响使用者体验。在 GPU 出现之前,一个实验可能需要等几个月,或者跑了一天才发现某个试验的参数不好。好的 GPU 可以在深度学习网络上快速迭代,几天跑完几个月的试验,或者几小时代替几天,几分钟代替几小时。
快速的 GPU 可以帮助刚开始学习的朋友快速地积累实践经验,并用深度学习解决实际问题。如果不能快速得到结果,不能快速地从失误中汲取教训,学起来会比较让人灰心。Tim Dettmers 利用 GPU,在一系列 Kaggle 比赛里应用了 deep learning,并在 Partly Sunny with a chance of Hashtags 比赛中获了亚军。他用了两个较大的两层深度神经网络,采用了 ReLU 激活函数,用 Dropout 来实现正则化(避免过拟合)。这个网络勉强能加载到 6GB 的 GPU 显存里。
是否需要多个 GPU?
Tim 曾用 40G bit/s 的 InfiniBand 搭建了一个小 GPU 集群,但他发现很难在多个 GPU 上实现并行的神经网络,而且在密集的神经网络上,速度提升也不明显。小网络可以通过数据并行更有效地并行,但对比赛里所用的这个大网络,几乎没有提速。
后来又开发了一个 8-bit 压缩方法,按理说,能比 32-bit 更有效地并行处理密集或全互联的网络层。但是结果也不理想。即使对并行算法进行优化,自己专门写代码在多颗 GPU 上并行执行,效果和付出的努力相比仍然得不偿失。要非常了解深度学习算法和硬件之间具体如何互动,才能判断是否能从并行里真的得到好处。
图 1. 3 套 GXT Titan GPU 卡和一张 InfiniBand 卡,是好的 deep learning 配置吗?
对 GPU 的并行支持越来越常见,但还远未普及,效果也未必很好。仅有 CNTK 这一种深度学习库通过 Microsoft 特殊的 1-bit 量化并行算法(效率较高)和块动量算法(效率很高),能在多个 GPU 和多台计算机上高效地执行算法。(参见 CNTK Parallel 1-bit SGD , 需要安装微软 MPI 或 OpenMPI。)
在 96 颗 GPU 的集群上用 CNTK,可以获得 90-95 倍的速度提升。下一个能高效地多机并行的库可能是 Pytorch,但还没完全做好。如果想在单机上并行,可以用 CNTK,Torch 或 Pytorch。速度可提升 3.6-3.8 倍。这些库包含了一些算法,能在 4 颗 GPU 的单机上并行执行。 其他支持并行的库,要么慢(比如 TensorFlow 能加速 2-3 倍),要么在多 GPU 上不好用(比如 Theano),要么这两个问题都有。
如果并行很重要,那可以用 Python 或 CNTK。
多 GPU,非并行
用多个 GPU 的另一个好处是,即使不并行执行算法,也可以在每个 GPU 上分别运行多个算法或实验。虽然不能提速,但可以一次性了解多个算法或参数的性能。当科研人员需要尽快地积累深度学习经验,尝试一个算法的不同版本时,这很有用。
这对深度学习的过程也很有好处。任务执行得越快,越能更快地得到反馈,脑子就从这些记忆片段里总结出完整的结论。在不同的 GPU 上用小数据集训练两个卷积网络,可以更快地摸索到如何能执行得更好。也能更顺地找到交叉验证误差(Cross validation error)的规律,并正确地解读它们。还能发现某种规律,来找到需要增加、移除或调整的参数或层。
总的来说,单 GPU 几乎对所有的任务都够了,不过用多个 GPU 来加速深度学习模型变得越来越重要。多颗便宜的 GPU 也能用来更快地学习深度学习。因此,建议用多个小 GPU,而不是一个大的。
选哪种? NVIDIA GPU,AMD GPU 还是 Intel Xeon Phi?
用 NVIDIA 的标准库很容易搭建起 CUDA 的深度学习库,而 AMD 的 OpenCL 的标准库没这么强大。而且 CUDA 的 GPU 计算或通用 GPU 社区很大,而 OpenCL 的社区较小。从 CUDA 社区找到好的开源办法和可靠的编程建议更方便。
而且,NVIDIA 从深度学习的起步时就开始投入,回报颇丰。虽然别的公司现在也对深度学习投入资金和精力,但起步较晚,落后较多。如果在深度学习上采用 NVIDIA-CUDA 之外的其他软硬件,会走弯路。
据称,Intel 的 Xeon Phi 上支持标准 C 代码,而且要在 Xeon Phi 上加速,也很容易修改这些代码。这个功能听起来有意思。但实际上只支持很少一部分 C 代码,并不实用。即使支持,执行起来也很慢。Tim 曾用过 500 颗 Xeon Phi 的集群,遇到一个接一个的坑,比如 Xeon Phi MKL 和 Python Numpy 不兼容,所以没法做单元测试。因为 Intel Xeon Phi 编译器无法正确地对模板进行代码精简,比如对 switch 语句,很大一部分代码需要重构。因为 Xeon Phi 编译器不支持一些 C++11 功能,所以要修改程序的 C 接口。既麻烦,又花时间,让人抓狂。
执行也很慢。当 tensor 大小连续变化时,不知道是 bug,还是线程调度影响了性能。举个例子,如果全连接层(FC)或剔除层(Dropout)的大小不一样,Xeon Phi 比 CPU 慢。
预算内的最快 GPU
结论
用于深度学习的 GPU 的高速取决于什么? 是 CUDA 核? 时钟速度?还是 RAM 大小?这些都不是。影响深度学习性能的最重要的因素是显存带宽。
GPU 的显存带宽经过优化,而牺牲了访问时间(延迟)。CPU 恰恰相反,所用内存较小的计算速度快,比如几个数的乘法(3*6*9);所用内存较大的计算慢,比如矩阵乘法(A*B*C)。 GPU 凭借其显存带宽,擅长解决需要大内存的问题。当然,GPU 和 CPU 之间还有更复杂的区别,可以参见 Tim 在 Quora 上的回答。
所以,购买快速 GPU 的时候,先看看带宽。
图 2. 对比 CPU 和 GPU 的带宽发展
芯片架构相同时,带宽可以直接对比。比如,Pascal 显卡 GTX 1080 和 1070 的性能对比,只需看显存带宽。GTX 1080(320GB/s)比 GTX 1070(256GB/s)快 25%。不过如果芯片架构不同,不能直接对比。比如 Pascal 和 Maxwell (GTX 1080 和 Titan X),不同的生产工艺对同样带宽的使用不一样。不过带宽还是可以大概体现 GPU 有多快。
另外,需要看其架构是否兼容 cnDNN。绝大多数深度学习库要用 cuDNN 来做卷积,因此要用 Kepler 或更好的 GPU,即 GTX 600 系列或以上。一般来说,Kepler 比较慢,所以从性能角度,应考虑 900 或 1000 系列。
为了比较不同显卡在深度学习任务上的性能,Tim 做了个图。比如 GTX 980 和 0.35 个 Titan X Pascal 一样快,或者说 Titan X Pascal 比 GTX 快了差不多 3 倍。
这些结果并不来自于每张卡的深度学习 benchmark 测试,而是从显卡参数和计算型 benchmark(在计算方面,一些加密货币挖掘任务和深度学习差不多)。所以这只是粗略估计。真实数字会有些不同,不过差距不大,显卡排名应该是对的。 同时,采用没有用足 GPU 的小网络会让大 GPU 看上去不够好。比如 128 个隐藏单元的 LSTM(批处理 >64)在 GTX 1080 Ti 上跑的速度不比 GTX 1070 快多少。要得到性能区别,需要用 1024 个隐藏单元的 LSTM(批处理 >64)。
一般来说,Tim 建议用 GTX 1080 Ti 或 GTX 1070。这两者都不错。如果预算够的话,可以用 GTX 1080 Ti。GTX 1070 便宜一点,比普通 GTX Titan X(Maxwell) 更快。两者都比 GTX 980 Ti 更适合,因为显存更大——11GB 和 8GB,而不是 6GB。
8GB 有点小,但对很多任务都足够了,比如足够应付 Kaggle 比赛里大多数图像数据集合自然语言理解(NLP)的任务。
刚开始接触深度学习时,GTX 1060 是最好的选择,也可以偶尔用于 Kaggle 比赛。3GB 太少,6GB 有时不太够,不过能应付很多应用了。GTX 1060 比普通 Titan X 慢,但性能和二手价格都和 GTX 980 差不多。
从性价比来看,10 系列设计很好。GTX 1060, 1070 和 1080 Ti 更好。GTX 1060 适合初学者, GTX 1070 的用途多,适合初创公司和某些科研和工业应用,GTX 1080 Ti 是不折不扣的全能高端产品。
Tim 不太建议 NVIDIA Titan X (Pascal),因为性价比不太好。它更适合计算机视觉的大数据集,或视频数据的科研。显存大小对这些领域的影响非常大,而 Titan X 比 GTX 1080 Ti 大 1GB,因此更适合。 不过,从 eBay 上买 GTX Titan X(Maxwell) 更划算——慢一点,但 12GB 的显存够大。
GTX 1080Ti 对大多数科研人员够用了。额外多 1GB 的显存对很多科研和应用的用处不大。
在科研上,Tim 个人会选多张 GTX 1070. 他宁可多做几次实验,稍微慢一点,而不是跑一次实验,快一点。NLP 对显存的要求不像计算机视觉那么紧,因此 GTX 1070 足够了。他现在处理的任务和方式决定了最合适的选择——GTX 1070。
选择 GPU 时可以用类似的思路。先想清楚所执行的任务和实验方法,再找满足要求的 GPU。现在 AWS 上的 GPU 实例比较贵且慢。GTX 970 比较慢,而且二手的也比较贵(eBay 上卖 $150)而且启动时显卡有内存问题。可以多花点钱买 GTX 1060,速度更快,显存更大,而且没有显存问题。如果 GTX 1060 太贵,可以用 4G 显存的 GTX 1050 Ti。4GB 有点小,但也深度学习的起步也够了。如果在某些型号上做调整,可以得到较好性能。GTX 1050 Ti 适合于大多数 Kaggle 比赛,不过可能在一些比赛里发挥不出选手优势。
AWS(Amazon Web Services)的 GPU 实例
现在 AWS 上的 GPU 比较慢(GTX 1080 速度是 AWS GPU 的四倍),而且价格最近几个月涨了很多。购买自己的 GPU 更明智。
结论
采购 GPU 时,需要平衡所需的显存大小、带宽(GB/s)和价格。目前,预算够的话,可用 GTX 1080 Ti 或 GTX 1070; 如果刚开始或预算有限,可选 GTX 1060; 如果钱很少,尽量买 GTX 1050 Ti; 如果用于计算机视觉科研,可考虑 Titan X Pascal (或者手上现有的 GTX Titan X)。
TL;DR 一言以蔽之
数据库 GPU
最常用的生产级 GPU:Tesla K40/80
起步:GTX 780
深度学习 GPU
综合最好的 GPU: Titan X Pascal 和 GTX 1080 Ti
划算,较贵:GTX 1080 Ti, GTX 1070
划算,较便宜: GTX 1060
Tim 用于 250GB 以上的数据集: 普通 GTX Titan X 或 Titan X Pascal
预算很少: GTX 1060
预算少得可怜: GTX 1050 Ti
Tim 参加 Kaggle 竞赛: 普通竞赛用 GTX 1060,深度学习类用 GTX 1080 Ti
追求性能的计算机视觉科研: Titan X Pascal 或普通 GTX Titan X
普通科研人员: GTX 1080 Ti,而某些情况,比如自然语言处理,GTX 1070 也够可靠,具体要看所用模型对显存的要求;
GPU 集群: 参见此处
刚开始接触深度学习而且比较认真: 从GTX 1060 开始,根据日后情况(比如创业、参加Kaggle 竞赛、科研或深度学习应用)换成更合适的GPU。
感谢杜小芳对本文的策划和审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论