这也就是Jim Keller曾经提到的“domain-specific”针对具体场景的特定芯片。这个略具“时代革命”气质的判断,一般认为是以2012年AlexNet刷新图像识别正确率事件为分界线的:当时深度学习还不像如今这般普及,AlexNet极具突破性地选择GPU来加速整个图像识别过程,赢得了当年ImageNet视觉识别挑战赛冠军。很快,深度学习借助GPU高度并行、大存储的特性,开始应用于语音识别、机器翻译等领域。
毫无疑问,GPU成为了“专用处理器”的雏形,机器学习则推动了专用处理器“革命”的步伐。2013年,谷歌正式推出TPU,这是个窄化到仅针对卷积神经网络(CNN)做计算的ASIC,它能够体现针对特定领域“专用处理器”的优越性,并无视摩尔定律的放缓。从某种角度来看,TPU在做的就是“架构革命”,革的是通用处理器(或具有通用计算特性的芯片)的命。
OpenAI 2018年年终发布了一份名为《AI 与计算》的分析报告,其中的数据提到,自2012 年以来AI训练任务应用的算力需求每3.5个月就会翻倍;AI算力增长超过30万倍— 这就比摩尔定律快太多了。以AI领域为“专用计算”的典范,看起来ASIC即将成为拯救人类未来的英雄,因为针对特定场景的ASIC,才能够达到性能与能效比的极致,尤其是在摩尔定律放缓,以及登纳德比例缩放定律失效的当下。然而实际情况好像比我们想象得复杂。
GPU的那段往事
在MIT的语境中,“专用处理器”其实未必是指ASIC,FPGA也可以实现专用:数据中心加速卡即是其中一个例证;软件定义芯片(SDC)也能以“专用”的方式应用到工业领域;GPU应用在AI训练方面如今依然十分普遍。然而在众所周知的“计算引擎选择(Computing Engine Choices)”图上,ASIC的确在横轴的性能、能效、芯片面积这几个方面表现最优。
不过ASIC的问题也非常显著,即其灵活性或可编程性最差。具体反映到AI芯片上,一种算法只能应对一种应用;一颗AI芯片只能单一地解决一种问题;而算法在不断演变,每3~6个月就可能变一次;AI芯片或许尚未上市,算法就已经发生进化了。这是ASIC型AI芯片的尴尬之处。或许某些偏应用层的企业并不在意,比如谷歌TPU虽然只能做一件事,但它带来的创收依然是不可限量的。
在针对某些非常具体的应用场景里,灵活性也可能并没有那么重要,所以如今在AI专用加速方面的产品除了谷歌TPU以外,还有如NVIDIA DLA、Intel Nervana、特斯拉FSD等。谷歌TPU和特斯拉FSD采用的都是一种名为脉动阵列(Systolic Array)的“古老”技术。这是一种固化、专用的电路,通过内部连线、内部PE 整合、固定时钟周期输入数据,实现卷积操作。
所以不难发现,谷歌TPU和特斯拉FSD都能轻易做到相较GPU,性能和效率都高出一截的表现,即便这是以牺牲可编程性为代价的。到这里,处理器的通用与专用之争,似乎就快出结论了。
但在这个AI芯片发展的初级阶段,我们大致上或许能够找到另外一个参考:GPU的发展历史。狭义的GPU似乎就是用来做图形加速计算的,它很多时候被我们归类为专用处理器。
实际上,在上世纪90年代GPU发展的初级阶段,它的确是完完全全的ASIC。在那个时间点,技术和制程都远不如现在先进,图形渲染追求极致性能必须选择ASIC—彻头彻尾的专用硬件;而且从市场特点来看,也和当前的AI芯片市场一样,彼时涌现出了大量GPU初创公司。
但从本世纪初开始,GPU出现弱编程特性— 这是因为图形加速行业飞速发展,当时的图形渲染算法变化速度和现在的AI/ML算法迭代速度可类比,那些固化的“绝对专用”的GPU无法适应这种变化;而在近10年,英伟达的GPGPU(General Purpose GPU)概念已经成为一种常态,GPU中的shader通用核心变得很重要。GPU在某些领域内变得“通用”, 它不仅能玩游戏,还能加速视频渲染、做科学分析、实现AI加速。
当硬件更多的需要与软件生态挂钩时,市场大多数参与者便会倒下。在竞争清理过后,GPU形成了如今的双寡头市场,并且步入相当成熟的阶段。
当AI芯片走向“通用”
为什么GPU最终没有朝着性能和能效比更高的ASIC方向发展?除了前述图形渲染算法变迁带来GPU走向可编程甚至通用的必然,要知道GPU是享受摩尔定律最尖端技术的最大受益者之一。而最先进制程的成本攀升,要求GPU市场规模足够大,否则难以摊薄成本。
所以GPU走出图形计算的单一市场,开始跨界AI等更多领域,GPGPU编程也就十分常见了。ASIC本身的成本、灵活性缺失,以及应用范围很窄的特点,都导致它无法采用最先进制程: 即便它们具备性能和能效优势,一旦无法采用最先进制程,则这一优势也将不再明显。
这段GPU的发展史能否给予我们一些启示? 在AI芯片领域,除了前文提到的谷歌TPU、特斯拉FSD之外,实际已经有一些AI芯片产品具备了弱编程特性,典型的如华为腾、Graphcore的IPU;包括在边缘AI计算领域,Arm前不久推出的NPU IP,都强调一定的灵活性。
在我们采访Graphcore创始人兼CEO Nigel Toon时,他特别提到:“很多人认为,人工智能是场景驱动的,ASIC能够实现更高的效率。
但我不这么看:不管是什么样的神经网络,不管是何种应用,最后的底层都会表征成一个计算图(graphs),不管是处理图片也好,语言也好,最后就是个计算图。IPU就是用于处理计算图的。”
“对于AI,我认为有三类解决方案。第一类是比较简单的小型化加速产品,用于手机、摄像设备等产品中。”Toon告诉我们。这类产品典型如海思麒麟芯片内部的NPU单元。“第二类是ASIC,对一些超大规模的公司而言,有某一类具体的问题要解决,比如谷歌的TPU,它用数学加速器来解决具体的问题;第三类是可编程处理器,这个市场的主体如今仍是GPU, 但Graphcore未来也会有巨大的份额,我们做的也是非常灵活的处理器。”
Toon认为,IPU有机会替代GPU,形成截至目前最大的细分市场:“我们接触过的所有创新者都说,GPU正在阻碍他们创新。如果仔细看他们正在研究的模型类型,你会发现主要是卷积神经网络(CNN),而递归神经网络(RNN)和其他类型结构,比如强化学习,并不能很好地映射到GPU。他们需要足够好的硬件平台,这是我们将IPU推向市场的原因。”
Graphcore的CTO(首席技术官)Simon Knowles早前曾说过:“机器智能(machine intelligence,这是Graphcore的提法,亦即人工智能)毫无疑问是计算的未来,但它还很年轻, 发展也很快。所以将如今最流行的模型或学习算法放进固定硬件中、构建ASIC会是比较愚蠢的方式。支持潜在的智能新特性、当细节发生进化时也具备足够的弹性保证其可用性,是芯片架构必须考虑的。”
“ 我们刚开始构想加速智能处理的方案时,我们就很清楚不能只盯着深度神经网络。”Knowles说,“所以我们没有窄化到特定算法,而是考虑作为计算负载,机器智能的基本原则是什么。”
实际上,当前市场上的正在参与竞争的AI 芯片,包括具备一定可编程性的,也并非Graphcore一家。但Arm联合创始人Hermann Hauser先前曾经这样评价过Graphcore:“这在计算机历史上只发生过三次,第一次是70年代的CPU,第二次是9 0年代的GPU,而Graphcore就是第三次革命。他们的芯片是这个世界伟大新架构的一种。”
这所谓的“第三次革命”究竟是怎么做的? 如果我们只把眼光停留在AI芯片如今共有的“高度并行”计算能力上,大概并不能领会IPU在“开创”个芯片类型上究竟有何特殊。而且搞清楚这个问题,也更有助于我们去理解AI芯片的通用和专用之路究竟会怎么走,尤其Toon在访谈中提到的“计算图(graph)”究竟是什么?
图2:Nigel Toon从口袋中掏出的一枚IPU
IPU实现通用性的关窍
这个时代,AI芯片厂商都在强调GPU执行AI加速的低效问题,那么GPU究竟有什么问题呢? 我们知道,“机器智能”对高度并行有着先天的依赖,需要成百上千的核心一起并行。把大量核心(独立的指令流pipeline)放到同一块die上面,以现在的技术实现起来并不难。问题就在于这些核心如何获取指令和数据,核心之间如何连接,如何进行数据共享,最后一点最关键的就是如何易于编程—以实现“通用”,适应当前AI算法发展的速度,以及适配不同的应用场景。
应对这些问题,首先能想到极为适配的芯片恐怕就是GPU了。不过GPU存在的先天问题在于:GPU的“核心”,概念和CPU还是不一样的。将每个处理器指令流,发往GPU很宽(wide)的矢量数据路径(datapath)时,GPU的并行特性也就没有看起来那么美好了。
GPU毕竟还是为图形计算设计的,注重的是低维数据结构,是一种宽矢量处理器,对AI的高维数据处理相对低效。图形计算需要较高的精度,这种高精度对于AI加速而言是一种浪费。还有一个重点,GPU的核心间通讯依赖于共享存储,许多数据放在外部存储上,这会造成带宽和延迟的瓶颈:即便后续GPU也引入了多层级缓存(cache),以及加入HBM(High-Bandwidth Memory)这样昂贵的3D存储结构。但随运算单元增加,这些改良方式也终将捉襟见肘。
现有的AI芯片着手解决的,实际就是上述这两大问题。市面上许多AI芯片都开始采用低精度、更“窄”的核心,这样整体可以提供更高的计算密度,但它们并没有很好地解决数据存储和核心互联的问题。比如简单的南北、东西互联, 配合数据流执行。片上高并行所需的互联、存储带宽并不理想,另外还存在编程很难的问题。
Graphcore认为,解决这个问题应该参考人脑的网络结构。Toon在几年前的一篇文章中提到,剑桥大学的Edward Bullmore教授研究人脑的分形结构(fractal architecture)。人脑中约77%的组成都用于通讯。在哺乳动物大脑进化的过程中,用于通讯的部分体积增长,是快于“功能单元”的,两者比例符合幂次法则。上世纪60年代,IBM的研究人员E.F. Rent发现了电路中,逻辑单元和互联之间也存在类似这种关系。他发现,逻辑电路边缘的输入和输出端数量(T),与内部逻辑组件数量(C)之间有个恒定关系(t和p是常数)。
T = t · C p
互联方面的设计需要做出突破,来支持这个所谓的Rent定律,至少在大规模并行芯片中,GPU是没有做到的。在Graphcore看 来,1000个独立并行处理单元之间有效共享数据,是实现“机器智能”高性能和效率的必经之路;与此同时它必须具备简单可编程属性。
Graphcore的解决方案,针对存储的问题, 选择了大量芯片面积都用于片上SRAM,相比HBM2这样的片外存储系统,在带宽和延迟方面要快得多。而SRAM被切分成很多块,分布于负责高度并行计算的处理器核心(注:Graphcore并没有采用“核心”的说法,而是称作一个tile或processor,但本文不对此做出区分)之上,这样也能一定程度确保可接受的良率。
“虽然IPU的片上SRAM无法达到GPU DRAM那么大,但至少确保大型、复杂的机器学习模型能够整个跑在芯片上。”Toon表示,“所以单个IPU存储带宽能够达到45TB/s,比性能最快的HBM快50倍以上,相同算力的能耗也降低一半。”两颗IPU则达到了100倍的速度,如上图所示。
而在互联方面,IPU选择的是一种名为 BSP(Bulk Synchronous Parallel,整体同步并行计算)的方案。一颗IPU内部有1200多个核心,如前所述每个都有自己的本地存储—可通过无状态互联(stateless interconnect)来彼此收发message。这种互联方案,让IPU得以支持任意类型的知识模型(knowledge model)和推理算法,包括那些还没有出现在市场上的。
到这里,IPU的灵活性已经有所体现了。“计算图的这种静态性,让编译器能够将程序切分成独立的子程序,运行在很多处理器(核心)上。”在这套机制中,就要求有一个方案能够维护整体的程序队列,让子程序之间的message能够在正确的时候发出。这个时候就用到了BSP。
BSP最早是1990年由Leslie Valliant和Bill McColl发明的,其中有“计算阶段(compute phase)”和“交换阶段(exchange phase)”的概念,BSP就在两者间做切换。计算阶段,每颗处理器核心在本地存储中做计算;片上存储之间(memory-to-memory)收发message则在交换阶段进行。IPU有专门的硬件来保证全局同步,包括芯片,甚至是跨芯片的同步,据说有着极小的开销。
似乎从设计之初,IPU就预设好了性能与通讯的弹性扩展方案。Graphcore销售副总裁、中国区总经理卢涛告诉我们,不仅是芯片内部的核心通讯,“IPU-Link能够将多个IPU联结到一起,组成集群。所以All-to-All总线之间的BSP算法,不仅是同一个IPU芯片各个核之间,跨芯片的核之间也能通过这个协议总线做通信;更大规模的训练,例如通过以太网,我们有IPU-POD,借由IPU-Gateway芯片,通过IPUoF技术,把几千几万颗IPU连在一起。”亦即我们此前报道的ExaFLOPs级别算力扩展,虽然我们不清楚这中间的通讯效率会受到多大程度的影响。
简单地说,BSP在整个程序级别构建起了时序机,同时在每一步支持海量并行。而计算与交换阶段的这个序列,就来自于我们前面反复提到的计算图(graph),由编译器自动得到。所以对开发者来说,不需要关心BSP本身。IPU将计算图程序,映射到高效的高度并行计算中去。
做CPU、GPU之外的“第三类”芯片
到这里,我们就可以具体谈谈前文反复提到的、“Graphcore”这个词汇中的“graph(s)”究竟是什么了。Knowles早年在聊到机器智能工作负载的特殊性时,提过:“无论是人类的智能,还是机器的智能,都包含两个能力。第一是近似计算(approximate computing),也就是在不大可能有完美答案情况下,高效找出也许还不错的答案—一般是因为信息量、时间和能量都不够充足;第二个能力就是学习,根据经验,也就是先前的数据做出相应变化。”
“对人类和计算机而言,学习过程就是从以往的数据中提炼出概率分布(模型),这个模型随后就可用于预测可能的输出。”“从以前的数据来推理出知识模型,然后再通过更多的数据, 在现有已习得模型的基础上推理新的结果。”
“知识模型和算法最自然的呈现方式就是计算图(graphs)。计算图是由顶点(vertices)组成的,而顶点则通过边缘(edge)相连。顶点包含模型中可学习的(learnable)参数,以及定义如何更新这些参数的部分代码—也就是对新的输入的响应,还有提供给其他顶点的更多信息。而边缘则定义流经整个模型信息的关系通路。在深度神经网络中,边缘一般是传递张量,而在贝叶斯网络(Bayesian net)或者马尔可夫随机场(Markov random field)中,边缘则负责传递概率分布。”
Graphcore将自家的处理器称作“graph processor”。通过机器学习框架构建起计算图模型(computational graph models),而IPU在Graphcore眼中正是操纵这种计算图的理想处理器。下面这张图是完整的AlexNet深度神经网络训练回路(training loop),生成自TensorFlow的描述。这张图本身是Graphcore的软件团队对计算图的视觉化呈现。
图5:天体物理数据分析中的一个机器学习模型计算图
这种计算图实际拥有的基本特征有很多,这里说几个比较重要的。首先是通常计算图中的顶点会非常多,“经常有上万、上百万乃至更多的顶点”,大部分顶点只连接一小部分其他顶点,这样一来模型就是稀疏的(sparse)—这其实是AI芯片在架构实现上必备的能力,它对存储访问方式,以及核心间的通讯方式是有很大影响的。
计算图具备较高的“分形维数(fractal dimensionality)”,IPU的结构决定了它对计算图做处理时具备更细的粒度;而当高纬的计算图嵌入到低维存储的线性地址空间时,顶点相邻连接在内存上就会比较分散,这是GPU一类宽矢量机存在的问题。卢涛表示:“IPU芯片每个tile(核心)里面都有计算单元和片上存储,无论是计算还是待处理的张量(tensor),都在本地。这种结构,在做稀疏化应用场景时,性能自然会更好。”
其二是知识模型获取的是数据经验的统计近似值(statistical approximations)。模型通常对带有噪声和不完整的数据进行学习,那么个体的模型参数和激活状态就并不会十分准确。它们组成的整体协同工作,就能给出一个相对高分辨的输出。从运算的角度来看,这就是低精度数据的高性能计算— 这也是如今AI芯片的共同特点。
另外,计算图结构可以认为是静态的,至少在较长的一段时间里是这样。计算过程中不需要改变知识模型中的连接。对于构建有效的高度并行芯片来说,静态计算图还是非常重要的: 在将并行程序映射到芯片时,编译器更容易做到在核心之间平衡计算工作;分配存储;在核心之间调度message通信。
这部分内容看起来显得有些太过抽象和枯燥。实际上真正对上述整个过程做视觉化表征的,是Graphcore的软件框架Poplar。它是针对IPU系统的计算图编程框架。它对前面所说的这种基于计算图的机器学习开发流程做抽象, 对开发者隐藏了底层计算图IPU硬件的复杂性。这也是前面Toon提到,“不管是什么样的神经网络,不管是何种应用,最后的底层都会表征成一个计算图(graphs)”的原因,也是IPU做到通用的基础。
和当代的一些开发框架一样,Poplar支持TensorFlow、Pytorch等常见的高层框架编写的应用。Poplar内部有个计算图编译器(graph compiler),将这些高层机器学习框架所用的标准操作,转译为IPU自身的“高度优化”应用代码。编译器会构建计算图的I R中间层,而计算图如前所述,能够实现IPU核心或者多IPU之间的调度和部署。
“Poplar对算法模型、数据模型做处理后,将它映射或分配到处理器的不同位置,定义好什么时候需要交换、什么时候需要同步等。”Toon 表示,“BSP算法,加上Poplar软件栈协同工作,那么虽然每个IPU有1000多个处理器(核心),7000多个线程(每个核心跑至多6个线程),也不需要担心通信问题,这中间的通信效率是非常高的。”
前文已经简单提到了BSP整体同步并行计算。实际在核心的互联、调度上,BSP和Poplar内部的编译器会成为Graphcore宣传中多核“高效”互通,与任务调度的最核心环节。虽然我们并不清楚其中细节,及编译器的转译效率,不过至少Poplar对开发者比较友好,也就是Graphcore时常提到的AI芯片必须具备“易于编程”的特点。Toon甚至强调,这种易于使用的特性,相较FPGA这类型的芯片会非常显著,而且还有性能与效率的明显优势。
从Graphcore近期自己公布的数据来看, 以MCMC(马尔可夫链蒙特卡罗)模型为例— 这种模型可帮助基金经理预测回报点,发现股票汇报背后的驱动因素。Graphcore金融行业的客户“在IPU上仅用4.5分钟就可以训练他们专有的、优化的MCMC模型,而现有硬件则需要2小时以上。”这里的现有硬件应该是指GPU。
“即便使用未优化的、现成的TensorFlow代码,IPU仍能够在45分钟内训练概率模型,而次优选择为400分钟。”
那么到这里,虽然我们无法全局勾勒出IPU的微架构,但已经将IPU如何解决存储瓶颈、大量核心的互联与调度,以及如何实现一定程度的通用性、针对开发者的友好易编程性,做出了大方向的描述。而且实际上,我们也认为,IPU的这些方案代表了当前通用AI芯片的一种典型范例,其中的某些方案实施方向和当前的很多AI芯片也比较类似,这有助于我们未来去观察和理解更多的AI芯片产品。
我们所在意的AI芯片通用与专用之争,在Toon和Knowles看来似乎根本不成为一个值得多思的问题。Knowles说过:“我们如果将CPU看做主要执行标量控制任务的处理器,GPU主要是执行矢量图形任务的处理器,那么新一代的IPU,就是专为以计算图为中心的智能任务设计的处理器。”
所以在Graphcore眼中,IPU是自CPU、GPU之后的第三大类主流处理器,“通用”在这个路径中是个必选项,而毫无犹豫的必要。如果按照这个思路来行进,MIT认为专用计算将成为后摩尔定律时代新宠的预言,大概不会成真;因为IPU并不针对某个特定领域。
不过要培养起这么大型的目标,首先就需要建立属于IPU的生态系统,吸收足够多的开发者和应用场景。这对初创阶段的Graphcore而言或许也并不容易,即便如我们先前介绍的那样,Graphcore是“含着金汤匙”出生的。
前不久,Graphcore刚刚宣布与微软合作,Azure云上的I PU预览版已经开放供用户注册:主要针对的是BERT语言模型;除此之外,Graphcore现有合作客户还包括了戴尔,IPU应用到戴尔的企业服务器中;以及从Graphcore官方信息来看,其客户已涵盖了机器人技术领域、金融领域等。
和本世纪初的GPU市场一样,在AI芯片市场步入弱编程阶段,如今百家争鸣的局面预计也将很快结束,市场在一轮厮杀后会剩下为数不多的参与者做最终对决。在整理发展思路上,我们认为Graphcore大约可以代表未来。然而市场的发展速度也远超我们想象,即便是GPU实则也在针对AI计算做不断的优化,比如GPU早就出现了专门的张量核心。现在要看的是在发展初期的逐一击破阶段,Graphcore是否真有定义并主控第三类芯片的魄力了。
责编:Yvonne Geng