在英特尔收购 Nervana 之后,终于宣布了自己的新的Intel® Nervana™ 平台,本文介绍了 Intel® Nervana™ Graph 的预览版本。
深度学习领域正在快速发展。从业者需要足够灵活的工具才能跟得上节奏。Theano 使得计算图(computational graph)作为强大抽象(abstraction)的概念越来越流行,TensorFlow 在此概念上进行了迭代。最终,他们证明了解锁深度学习潜力的第一步,但现在我们需要工具带来更多的下一代复杂的网络拓扑。
结合我们来自医疗、金融、农业和汽车业的客户的需求,我们知道现代化的数据科学家需要:
能自由选择正确的前端接口,以在所需的粒度(granularity)水平上特定模型
能够融合、匹配各框架上建立的模型,以实现更复杂的拓扑
能够依赖执行运行时间(execution runtime)来默认执行代数简化、自动张量布局和内存/记忆共享优化,这样我们就不必做这样的事了
这些优化是现成的,但仍然会在你需要的时候提供编译机制
能在跨种类繁多的硬件平台(如 CPU、GPU 和/或 Nervana Silicon Technology 的异构混合结构)上有效地执行这些模型
为了实现这些能力,作为工具开发者,我们需要:
轻松编写新的前端的能力,让其可以利用已有的后端硬件指标和优化;
尝试新的编译器技术的能力,所有的前端用户都可以尝试,且只需要单次配置切换;
这些新的编译模块应该能利用已有后端所使用的共享的优化机制来实现高性能;
通过接入到一个装备了电池的已有系统,以使其能在无需从头开始编写新的库的情况下使用上新的硬件、网络、存储和数据处理系统。
从我们保持着最高速的深度学习库的多年经验以及在基于图(graph)的设计上的一年迭代来看,我们现在希望分享 Nervana Graph (ngraph) 的一个预览版来解决这些目标。这个版本由三个部分组成:
一个用于创建计算 ngraph 的 API
两个更高层面的前端 API(TensorFlow 和 Neon),它们使用了 ngraph API 来处理常见的深度学习工作流
一个变换器(transformer)API,用于在 GPU 和 CPU 上编译和执行这些图
下面让我们逐一介绍它们以及它们助力用户的方式。
Nervana Graph
该Theano和TensorFlow的计算图要求用户在建构图的同时推算出其潜在的张量形状。这个事情对用户来说很乏味而且容易出错,同时取消编译器的功能重新进行轴排序(reorder axes),以此来匹配特定硬件平台的假设。
然而,ngraph API能让用户来定义一组命名轴(named axes),并在图建构过程中将这些轴附加到张量上,需要时可以通过名字(而不是位置)来指定。这些轴可以根据眼下问题的特定领域来命名,来帮助用户处理这些任务。这种灵活性可以在执行前让必要的reshaping/shuffling通过转换器推断出来。此外,之后这些推断出的张量轴排序能在通过整个计算图的过程中优化,以此为潜在的runtime/硬件平台的偏好排序,这样可以优化缓存局部性和runtime执行时间。
这些能力强调了ngraph的原则:在一个足够高的抽象层上操作,这样一来,转换器就能在无需一个“非常聪明的编译器”的情况下高效的执行任务,同时还能让用户和前端更轻松的将这些构建模块组合在一起。
前端
大多数应用和用户不需要ngraph API提供充分的灵活性,所以我们也在引进一个更高层的 neon API,它能为用户提供一个带有常见构建模块的可组合的接口,来构建深度学习模型。这包括的对象有常见的优化器、指标、和多种层类型,如线性的、批处理规范的、卷积的和RNN。我们用在MNIST 数字、CIFAR-10图像库和Penn Treebank文本库中训练的案例模型来给大家做展示。
下一代的神经深度学习API( neon deep learning API)与ngraph后端机器将最终替换我们现有的神经库(neon library),并且仍然保持与之前同样的世界领先水平,也将保留广泛的开放目录(https://github.com/NervanaSystems/ModelZoo ) 。在其性能、稳定性和可用模型和工具情况能与当前可用的相比时,我们就会进行这一次转变。我们期望能在未来几个月内达到这一目标。
我们还意识到用户今天已经在使用已有的框架了,而且可能想要继续使用/结合在其它框架中编写的模型。为了这个目的,我们表明我们可以将已有的 TensorFlow 模型转换成 ngraph,并且使用 ngraph 转换器来(ngraph transformer)执行它们。这个 importer 今天已经支持很多常见的运算类型了,并且未来的版本还会进行更多扩展。我们还计划在未来实现与其它框架的兼容。所以,请保持关注。
此外,我们还要强调,因为 ngraph 提供了深度学习计算的核心构建模块和多个高性能的后端,所以增加前端是一件很直接的事情,而且后端(或新的后端)可以通过被已有的和未来的前端自动利用来获得提升。所以用户可以继续使用他们最喜欢的句法,同时也能从该共享的编译机制中获益。
转换器(Transformers)
考虑到现在最佳的模型也有数百万甚至数十亿的参数以及长达数周的训练时间,那么确保模型在最小内存开销上高速地执行是很关键的。在我们开发和维护最高速的深度学习库的经验的帮助下,我们鉴定出了现代深度学习性能的复杂性因素:
Kernel fusion/compounding(核融合/混合)
Efficient buffer allocation(有效的缓存分配)
Training vs. inference optimizations(训练 vs. 推理优化)
Heterogeneous backends(异构后端)
Distributed training(分布式训练)
Multiple data layouts(多个数据布局)
New hardware advancements (新的硬件进步,如:Nervana Silicon Technology)
考虑到这些现实情况,我们设计了ngraph转换器,通过API自动化和抽象细节,允许强大的用户控件同时调整所有事物,同时对模型创建的抽象灵活性没有限制。
对于ngraph而言,我们相信成功的关键在于站在巨人的肩膀上——现代编译器设计,以提高灵活性,在实验中选择合适的编译器,优化设置和顺序,以使转换器能够为人所用。这种原则使我们的工具提高了灵活性,同时降低了复杂性。这些特性使得开发者能够更容易添加后端代码以支持外来模型,而不需要理解或修改系统中其它部分的定义。
每个ngraph转换器(或LLVM后端)都针对特定的硬件后端,并可用于将ngraph编译为函数句柄评估的计算的接口。目前,ngraph带有GPU和CPU任务的转换器,在未来我们计划实现在分布式训练中进行异构设备转换的支持。
例子
这里给出了一个构建和执行 ngraph 的例子,请查看我们文档中 walkthrough(https://ngraph.nervanasys.com/docs/latest/walk_throughs.html ),我们会在这里给出一个入门级的例子,它会 print 数字 1 到 5.
import ngraph as ng import ngraph.transformers as ngt # Build a graph x = ng.placeholder(()) x_plus_one = x + 1 # Construct a transformer transformer = ngt.make_transformer() # Define a computation plus_one = transformer.computation(x_plus_one, x) # Run the computation for i in range ( 5 ): print (plus_one(i)) |
地位和未来工作
由于这是一个预览,我们还有大量的工作要做。目前我们包括的样本有:
使用 MNIST 和 CIFAR-10 的 MLP 网络
使用 MNIST 和 CIFAR-10 的CNN
使用 Penn Treebank的基于字符的 RNN
随着 Nervana 被英特尔收购,我们有了世界一流的专家团队来为编译器、分布式系统、系统软件和深度学习提供贡献。我们现在正在研究的方向有:
对性能的改进:
在 fusion/compounding 和存储共享上的进一步研究
并发指令执行
数据加载流程(pipelining)
图序列化/反序列化(Graph serialization/deserialization)
对可用性/优化的图可组合性的进一步改进
对更多流行的前端的额外的支持
分布式、异类后端目标支持
互通性的 C API 从而满足其他创造/执行图的语言
现代化的基于云的模型部署策略
对强化学习友好的网络建造前端