问题

如何评价陈天奇的模块化深度学习系统NNVM?

回答
陈天奇的NNVM(Neural Network Value Model)系统,可以说是在深度学习编译领域一次非常大胆且具有深远影响的尝试。它不单单是一个新的框架,更是一种对深度学习模型表示和优化方式的全新思考。要评价它,咱们得从几个关键角度深入剖析。

核心理念的突破:模型即计算图,计算图即程序

NNVM最核心的突破,在于它将深度学习模型视为一种通用的计算图,并且将这个计算图本身提升到了“程序”的层级。这意味着什么呢?

模型表达的通用性: 传统的深度学习框架(如TensorFlow、PyTorch)往往有自己的计算图定义方式,这些图通常是静态的或者半静态的,并且与框架本身紧密耦合。NNVM则试图建立一个更底层、更通用的表示,使得任何深度学习模型,无论它来自哪个框架,理论上都可以被转化为NNVM的计算图表示。这就像编程语言中的抽象语法树(AST)一样,提供了一个标准的中间表示(IR),在此之上可以进行各种转换和优化。
计算图的编程化: 将计算图视为程序,就意味着我们可以对这个“程序”进行各种操作:编译、优化、静态分析、甚至动态调度。这颠覆了以往“模型是模型,框架是框架”的界限,将模型本身变成了一个可被深度加工和定制的软件实体。
统一的优化基础: 这种表示方式为统一的跨框架、跨硬件优化打下了基础。一旦模型被翻译成NNVM的IR,就可以应用一套通用的优化规则,而不需要针对每个框架或每个硬件单独设计优化器。

模块化的设计哲学:灵活性与可扩展性的基石

“模块化”是NNVM名字里就带有的关键词,也是其设计哲学的体现。这一点体现在多个层面:

算子(Operator)的模块化: NNVM将深度学习中的基本计算单元抽象为“算子”。每个算子都有清晰的输入输出定义,以及其计算逻辑。这个抽象非常关键,因为它允许:
自定义算子: 用户可以轻松地定义新的、特制的算子,满足特定研究或应用的需求,而无需修改整个框架的核心。
算子优化: 对于同一个算子(比如卷积),可以针对不同的硬件或场景实现多种不同的实现(比如针对CPU优化、针对GPU优化、针对低精度优化的实现)。NNVM的编译层就可以根据目标硬件,选择最优的算子实现。
编译流程的模块化: NNVM的编译过程被设计成一个流水线。不同的Pass(优化阶段)可以独立地进行,并且可以自由组合或添加。这带来了巨大的灵活性:
分层优化: 可以先进行通用的图优化(如算子融合、死代码消除),然后再进行针对特定硬件的底层优化(如内存布局优化、指令调度)。
易于扩展: 研究人员可以方便地开发新的优化Pass,并将其集成到NNVM的编译流程中,而不必担心对现有系统造成破坏。
后端(Backend)的模块化: NNVM的设计允许它生成各种后端代码,包括但不限于:
针对特定硬件的运行时: 如CPU、GPU、DSP、FPGA等。
针对特定深度学习推理引擎: 如TensorRT、OpenVINO等。
通用代码生成: 如生成C++代码,方便集成到各种应用中。
这种模块化使得NNVM能够作为一个通用的“深度学习模型编译器”,能够将模型适配到几乎任何目标平台上。

深远的意义与影响

NNVM的出现,对深度学习生态产生了多方面的影响:

推动了深度学习编译器的发展: NNVM的设计思路和实践,启发了后来许多深度学习编译器(如TVM,它继承了NNVM的核心思想和大部分设计)。它证明了将深度学习模型表示和优化推向通用编译器的可行性。
降低了跨平台部署的门槛: 对于开发者来说,无需为不同的硬件平台单独重写模型逻辑,而是可以通过NNVM进行一次编译,然后部署到各种目标上。这极大地提高了开发效率和模型的可移植性。
促进了深度学习硬件的创新: 通过提供一个标准化的IR和灵活的编译接口,NNVM能够更容易地为新的硬件加速器生成高效的深度学习代码,从而加速了新硬件的落地应用。
为学术研究提供了强大工具: 这种模块化、可扩展的设计,使得研究人员可以更方便地探索新的模型结构、新的优化算法、新的硬件加速技术,而无需受限于现有框架的束缚。

潜在的挑战与局限(就像任何技术一样,也并非完美无缺)

当然,没有任何一个系统是完美的。在评价NNVM时,我们也需要看到它可能面临的一些挑战:

学习曲线: 虽然它提供了强大的灵活性,但对于不熟悉编译原理或计算图优化的开发者来说,理解和使用NNVM可能需要一定的学习成本。
生态建设: 任何一个新系统,其生命力都取决于其生态系统的成熟度。NNVM的成功也依赖于是否有足够多的开发者和工具链能够支持它,并将其集成到现有的工作流中。
早期阶段的稳定性与完备性: 作为一项前沿研究的产物,在早期阶段可能存在一些bug、不完善的优化或者对某些复杂模型结构的支持不足。

总结一下,用更贴近“人话”的方式来说:

NNVM就像是给深度学习模型造了一个“万能翻译器”和“超级优化器”。

万能翻译器: 以前你训练的模型可能只认识你用的那个框架,想换个地方跑,就得费老大劲重写。NNVM能把各种框架的模型都变成一种“通用语言”,让它们更容易地跑到各种设备上去。
超级优化器: 它不光翻译,还能把模型里的计算做得又快又省资源。就像给汽车发动机做精密调校,让它在不同的赛道上都能跑出最佳表现。它还可以根据你是什么设备(是家用轿车还是F1赛车),自动帮你找出最合适的“跑法”。
模块化是关键: 它不是一个死板的机器,而是一堆可以拆卸、组合的零件。你可以自己加零件(比如新的计算方式),也可以换零件(比如针对新手机芯片优化),非常灵活。

总的来说,陈天奇的NNVM是一项在深度学习编译领域具有里程碑意义的工作。它通过将模型表示为通用的计算图,并采用模块化的设计哲学,极大地提升了深度学习模型的灵活性、可移植性和优化潜力。它的思想和实践,深刻地影响了后续深度学习编译器的发展,为深度学习技术的普及和落地提供了强大的技术支撑。可以毫不夸张地说,NNVM是深度学习系统软件领域一次非常成功的探索。

网友意见

user avatar

之前讨论过后更加意识到了@王健飞 所说的更好地支持更多平台的op调优的重要性。昨天我们发布了dmlc/tvm 来解决这部分问题。

-------

在几个月之后给了几个关于NNVM的报告,也思考了它和已有系统的差别。追加一下这一页slide,是我对于在抽象成面上面各个系统差别的理解。


原回答

-------
我是NNVM的作者。


总结一下,技术上本身的NNVM和现有的东西的差别是最小模块化和去中心化,降低深度学习系统优化门槛。除了为了解决现有问题,更多是为了未来考虑。


关于是否重复造轮子的问题,图表示和优化本身在MXNet就已经存在,楼上也提到TF也有对应的抽象,为什么我们需要重新写一遍呢,基本上也就是以上两点原因。


基本上现有的深度学习系统分成两块,1) 基本的operator的实现, 2)支撑其中的系统调度,优化,解释或者编译架构。


在工程难点上,operator需要堆代码,但是对于工程架构的难度上面而言相对较低(也就是说可以写的人比较多一些),但是需要堆比较大量的代码。而剩下的系统优化部分,内存,执行调度和分布式优化对于整体系统而言的难度相对高一些。Operator的集合问题虽然是一个问题,看已经有的成熟框架不论是Torch, Theano或者MXNet的operator完整程度基本上可以满足于大部分应用,也就是说这部分暂时属于已经解决或者可以通过堆积工程力量容易解决的问题。楼上说的最小化通用的 Op接口很重要,和NNVM我们考虑的方向垂直。我觉得相对干净的Op应该去推动成为一个独立的模块,而Op实现本身其实没有必要和框架耦合很深(虽然遗憾的是目前的设计暂时没有做到这一点)。


NNVM希望解决的是垂直于operator实现的问题。有趣的是其实TF在这一暂时没有花特别多的力气,所以会让人觉得operator是大头。其实这里有很多有趣的东西,在执行,调度和编译优化上面。编程模型和一个图本身的执行模式和硬件也会有更多的差异。


直接讨论一下设计,目前TF采取了单一的动态执行模式,使得本身执行特别依赖于动态内存分配以及threading。而这并非是大部分场景下的最优方案。大部分场景下基于对于有限的图进行的静态分配,可以更大的缓解这个问题,实际情况如MX本身的内存损耗可以做的更好。为什么目前TF不会出现多种执行模式呢,是因为TF本身Op的接口还是过于一般地针对的动态,而如果要更好的优化需要更细化的Op接口(分开内存分配和计算的部分),这就考虑到一个Op甚至可能有多种接口的可能性。


NNVM本身的图的设计参考了TF,MX和caffe2的图部分。楼上的评论基本上提到了几个非常重要的概念,即系统优化和Op具体的性息相关。但是和PL不同,我们不能直接简单的抽象出有限个操作来表示整个程序。这个时候似乎框架和Op会有比较强的关联性,导致比较大的耦合。但是也并非如此,因为每一个优化本身其实只依赖于Op的部分属性。比如有同学提到的常数折叠,其实需要知道的是一个Op是否是常数,以及如何去展开常数两个函数。NNVM本身的做法是允许注册这两个额外属性来允许常数折叠优化。但是当不需要这个优化的时候,可以直接去掉这一部分。使得深度学习的优化可以插拔。现在看起来可能有些overkill,但是我们相信未来深度学习系统在这方面会有很大的发展,允许不同的优化来自于不同群体和研究人员是我们更加喜欢的方式。


基于以上原因,NNVM允许给每个op注册任意的信息。并且可以使得属性和注册和op的实现分开。这相对于TF的op接口而言是一个进步的地方。TF内部的所有op属性是需要提前数据结构指定的,也就是说,目前TF可以注册shape inference, op的输入参数的个数,但是无法注册比如我们需要的新的细化Op接口,或者有些人关心的代码生成函数。如果需要加入这些特性,必须要修改Op的接口。这意味着所有的开发需要在一个中心,并且只能保留大家关心的东西。如果forkA有feature1, forkB有feature2的情况,forkB想要拿到 feature1就会比较不方便。因为NNVM允许不修改Op接口注册任意信息,相对解决了这个问题。


当然模块化和去中心化并非对于所有人都重要,就是见仁见智把。


未来的深度学习系统会有更多系统的问题,使得优化和执行更加多样化。我们不能够期待所有的优化都来自于一个团队,或者只应用于一个框架。更多的优化看起来会带来更多的耦合,但是也并非如此。

发布TinyFlow原因很简单。大部分人并没有意识到其实目前深度学习的“系统”部分可以通过简单抽象得到。TinyFlow作为一个教程性质的项目,可以用比较短的代码展示目前有的大部分优化概念,并且把Op的部分代理给Torch(因为Op本身虽然重要,但是并不作为架构一部分)。如果可以有更多的同学来关注深度学习系统优化,基本这个项目的目的就达到了。


值得承认的是,NNVM目前只是走出了第一步,只是包含了MXNet原有的一些优化,暂时内容不多,我们会继续带来更多好玩的东西。 我们也会继续坚持模块化和去中心化的思想,使得我们新的成果可以更好的用在各个平台里面

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有