第 1 章 TensorFlow系统概述

第 1 章 TensorFlow系统概述

人工智能和深度学习的热潮将TensorFlow推向了很高的地位,媒体的追捧和业界的宣传也为这一源自Google的开源软件增添了传奇的色彩。对于技术从业者或爱好者而言,我们初识TensorFlow时有必要拨开表象看本质。本章作为引子,首先从技术视角概括性地介绍TensorFlow的产生背景、独特价值、版本变迁,以及它与其他主流深度学习框架的异同。同时,本章从灵活通用性、异构支持性和性能高效性三个视角解析TensorFlow的设计目标,展示TensorFlow作为一款兼具深度学习库、人工智能引擎和基础平台软件身份的开源产品的优势所在。最后,我们将简单介绍TensorFlow的工作形态和组件结构,帮助读者快速建立对TensorFlow软件架构的第一印象。

1.1 简介

当今,人工智能领域最受欢迎的深度学习和机器学习框架非Google开源的TensorFlow莫属。本节我们将依次介绍TensorFlow的产生背景、独特价值和版本变迁,并横向对比目前主流机器学习和深度学习框架各自的特点和优劣。

1.1.1 产生背景

随着近年来深度学习模型在图像、视觉和语音领域不断取得突破,相关研究热潮持续高涨,开源深度学习框架出现百花齐放之势,其中具有代表性的框架包括XGBoost、Theano、Torch、Caffe和MXNet等。它们有的计算速度快,有的可移植性好,有的内存占用少,有的易于上手。在Google推出TensorFlow之前,大家仍处于“你方唱罢我登场”的百家争鸣状态。然而,Google推出深度学习框架TensorFlow之后,江湖巨变。

2015年10月,Google旗下的DeepMind公司研发的AlphaGo击败樊麾,成为第一个无须让子即可在19路棋盘上击败职业围棋选手的电脑程序。这一壮举不仅打破了人工智能无法在围棋领域战胜人类顶尖棋手的诅咒,而且吸引了全球各界对人工智能研究的高度关注。2016年1月,AlphaGo的研究成果发表在知名学术期刊《自然》上,这一事件也将人工智能热潮推向了新的高度。2017年5月,强化后的AlphaGo与世界围棋三甲之一的柯洁对弈,获得3∶0全胜战绩。这再一次笃定了人们对于Google在人工智能领域遥遥领先的信念。

AlphaGo的后期版本使用了基于TensorFlow编写的算法模型。但事实上,AlphaGo只是让TensorFlow走进公众视野的一个契机,TensorFlow的原始动机则是Google在高速发展的信息化应用背景下,发展感知、预测等人工智能技术的需求。移动互联网、物联网、共享经济、增强实现……这些热词的背后无一不需要海量数据与智能处理能力的支撑。作为行业的引领者,Google公司内部很早便有自研的机器学习平台。TensorFlow是既有平台的多年技术积累在新的时代背景下蜕变升华的成果。

TensorFlow推出后短短一个月,就成为了机器学习和深度学习项目中最受欢迎的开源框架。究其原因,离不开Google在人工智能与数据处理领域的深厚积淀及其在业界的强大号召力。同时,Google已经成功领导了多个开源项目,典型的有移动操作系统Android、容器编排引擎Kubernetes、编程语言Go等,它们充分体现了Google的工程水准与协作精神。因此,在内因与外因的合力之下,TensorFlow的横空出世也就不难理解了。

1.1.2 独特价值

TensorFlow能够在众多开源框架中杀出重围,除了Google的背书以外,一定有其自身的独特价值。下面重点介绍TensorFlow相比其他开源框架的亮点和优势。

  • 运算性能强劲。在构建和部署机器学习系统时,性能是至关重要的。TensorFlow 1.0加入的线性代数编译器XLA全方位地提升了计算性能。XLA可以帮助TensorFlow在CPU、GPU、TPU、嵌入式设备等平台上更快速地运行机器学习模型的训练与推理任务。同时,TensorFlow提供了大量针对不同软硬件环境的优化配置参数。用户可以根据自身的需求和应用的特点,进一步提升计算性能。
  • 框架设计通用。TensorFlow并非只是纯粹的神经网络库。TensorFlow最初由Google Brain小组(隶属于Google机器智能研究机构)的研究员和工程师们开发出来,用于机器学习和深度神经网络方面的研究,但其灵活的设计也可广泛用于其他计算领域。同时,TensorFlow既提供高层封装API(如Slim、Keras、TF Layers等),能够帮助用户快速实现算法原型;又提供底层原生API,可以实现更灵活且高效的分布式并行模式。
  • 支持生产环境部署。TensorFlow支持使用同一套API实现探索环境和生产环境的部署。曾经,科研人员将算法原型推广到生产环境中使用的过程非常痛苦,因为这涉及大量的模型重写和脚本适配工作。现在,使用TensorFlow的算法研发人员既可以快速地将想法和原型运用到生产环境的产品中,也可以在学术圈更方便地分享自己的研究成果。
  • 语言接口丰富。TensorFlow核心层由C++ 实现,应用层使用SWIG等技术封装,提供了多语言API的支持。目前,官方支持的语言有Python、C、C++、Java、Go等。除此之外,TensorFlow的社区贡献者们也提供了非官方的应用层API,如Node.js(https://github.com/node-tensorflow/node-tensorflow)、Julia(https://github.com/malmaud/TensorFlow.jl)、R(https://github.com/rstudio/tensorflow)。
  • 端云协同计算。TensorFlow同时支持在云侧(服务器端)和端侧(移动设备等终端)运行,有效结合了云侧和端侧的各自优势。在云侧方面,TensorFlow提供多种并行模式和编译优化等技术,尽可能提升算法模型的运算性能;在端侧方面,TensorFlow提供轻量级部署和8比特压缩等技术,尽可能提升计算和存储资源利用效率。

除以上列举的优势外,TensorFlow丰富的算子库和教学资料也是其独有的竞争优势。同时,TensorFlow社区的活跃度遥遥领先其他竞争者,每个月都会有上万行的代码合入主分支,这使得TensorFlow的新特性能够快速实现,bug也能快速修复。我们相信在业界众多人工智能开发者和Google工程师的共同努力下,TensorFlow能够计算得越来越快、发展得越来越好。

1.1.3 版本变迁

TensorFlow自2015年11月开源以来,已经发布了30多个版本。本节从TensorFlow的发展历程入手,考查其关键特性的发布和对应版本的变迁。图1-1展示了这一变化过程。

图1-1 TensorFlow关键特性发布和对应版本变迁

在TensorFlow开源后第9天,Google带来了第一个正式发布版——TensorFlow 0.5.0,不过该版本仅支持在Linux系统上运行单机模型。随着TensorFlow贡献者和用户对分布式的呼声越来越高,2016年4月发布的TensorFlow 0.8.0开始初步支持分布式计算。两个月后,TensorFlow 0.9.0增加了对多平台的支持。自此,用户可以将TensorFlow部署在iOS和树莓派(Raspberry Pi)上。同时,该版本还支持在macOS上使用GPU运行算法模型。

2016年9月,0.10.0版本的发布解决了TensorFlow学习成本高和上手难的问题。尤其对于非计算机背景的算法研究人员,使用该版本提供的高层API——TF-Slim能够快速实现图像和视觉领域的算法模型。TF-Slim的发布有效扩大了TensorFlow用户群体,使得高校和科研院所的研究者们也能够享受TensorFlow带来的便利。

随着TensorFlow开源一周年而到来的0.11.0版本,新增了对HDFS和cuDNN 5的支持。HDFS作为Hadoop生态中的分布式文件系统,广泛地应用于大数据系统,这一特性标志着大数据生态和TensorFlow开始相互合作和共赢发展;cuDNN是NVIDIA公司开发的深度神经网络库,cuDNN 5能够进一步提升神经网络任务在GPU硬件上的计算速度。紧接着发布的TensorFlow 0.12.0开始为Windows平台提供支持,同时提供了实验性的Go语言应用层API。

2017年2月,Google在山景城(Mountain View)召开了TensorFlow Dev Summit 2017大会。大会全面介绍了TensorFlow的进展和取得的成就,并于隔天发布了TensorFlow 1.0.0。这也成为了TensorFlow发展的一个重大里程碑事件,标志着TensorFlow已经初步成熟并能够支持生产环境部署。事实上,当时京东、小米、Uber等国内外公司也确实在生产环境中使用了TensorFlow。作为TensorFlow的第一个正式版,TensorFlow 1.0.0带来了诸多提升性能和易用性的关键特性,比如:线性代数编译器XLA,部分解决了内存消耗大和计算速度慢的问题;命令行调测工具TensorFlow Debugger,初步解决了算法模型调测困难的问题。同时,该版本还新增了对Android的友好支持,使得用户能够更快速地将TensorFlow编写的模型部署到移动设备上运行。

2017年4月,TensorFlow 1.1.0将Keras 2合并到了项目主分支的tf.contrib.keras目录中。从此以后,用户再也不需要独立安装Keras软件包,TensorFlow将自带Keras API。Keras是一套类似于TF-Slim的高层API,它良好的封装性和对模型的高度抽象使之收获了一大批算法开发者。但是,Keras并不等于TensorFlow,诸如分布式运行和更灵活的计算模式等还得使用TensorFlow原生API实现。同时,该版本还支持用户在Windows上使用Java语言的应用层API。

2017年7月,TensorFlow 1.2.0正式合入了Yahoo! 提供的面向InfiniBand等高性能网络的RDMA通信方案。早在TensorFlow白皮书中,Google就表示TensorFlow支持RDMA。但可能出于商业考虑或其他原因,一直没有将RDMA方案发布到TensorFlow开源版本中。直到TensorFlow 1.2.0发布,用户终于可以在高性能网络设备上享受RDMA带来的效率提升,这有效解决了分布式训练大模型时的通信瓶颈问题。经测试,在VGG等大模型的分布式训练场景下,相比TCP/IP,RDMA能够减少一半左右的网络通信开销。

2017年8月,TensorFlow 1.3.0发布。它允许用户使用新增的Estimator库,以开箱即用方式快速实现深度神经网络分类器(DNNClassifier)、深度神经网络回归器(DNNRegressor)、线性分类器(LinearClassifier),以及深度神经网络和线性混合分类器(DNNLinearCombinedClassifier)。同时,从TensorFlow 1.3.0开始的所有二进制发布包都默认使用cuDNN 6,这将进一步提升TensorFlow在GPU上的运算性能。

2017年11月,TensorFlow 1.4.0发布。该版本新增了tf.data模块,为数据读入和处理提供了便捷高效的解决方案。该版本还增强了Estimator的能力,使其能够支持简单的分布式模型训练和评估。同时,Google还开源了GANEstimator库,以回应越来越多的用户对生成对抗网络(GAN)的需求。

回望TensorFlow的发展历程,我们不难发现Google在TensorFlow项目的推进上投入了不小的资源。在TensorFlow项目组成员和贡献者的共同努力下,TensorFlow正一步步走向成熟。

1.1.4 与其他主流深度学习框架的对比

放眼全球,诸如Google、Facebook、Amazon和Microsoft等国际巨头均在深度学习领域着手布局。一时间,江湖风云四起,各大门派争相斗法。Google坐拥TensorFlow,捍卫江湖地位;Facebook携手Caffe2和PyTorch,以图三分天下;Amazon拥抱MXNet,不甘落于人后;Microsoft坚守Cognitive Toolkit(CNTK),寻求单点突破。除此之外,还有Caffe、Torch7、Theano等老一辈深度学习框架参与竞争。可谓是乱花渐欲迷人眼,用户不知如何选。本节将为用户客观分析各大主流深度学习框架的特点与优劣。

下面我们从社区活跃度、多语言支持、教学资源、运算性能等多个维度全方位对比主流的深度学习框架。考虑到Keras的广大用户基础,我们也将其单独列出来进行比较。表1-1对比了2017年12月各个深度学习框架在GitHub上的统计数据。不难发现,TensorFlow在各项指标中均遥遥领先。排名第二的Keras由于接口简单易用而受到广泛关注,目前Keras官方已经支持使用TensorFlow、Theano和CNTK作为后端计算引擎。紧随其后的是老牌深度学习框架Caffe,其创始人是加州大学伯克利分校的贾扬清博士,他同时也参与了TensorFlow项目的早期设计和实现。

表1-1 主流深度学习框架在GitHub的上统计数据

框架名称

所属机构

多语言支持

Star数量

Fork数量

贡献者数量

TensorFlow

Google

Python/C/C++/Java/Go

84132

41072

1226

Keras

keras-team

Python

23530

8582

590

Caffe

BVLC

Python/C++/Matlab/Cmd-line

22024

13509

253

CNTK

Microsoft

Python/C++/C#

13488

3522

158

MXNet

Amazon

Python/C++/R/Scala/Julia

12594

4641

465

PyTorch

Facebook

Python

10737

2225

375

Torch7

Facebook

Lua

7575

2222

133

Theano

蒙特利尔大学

Python

7515

2370

326

Caffe2

Facebook

Python/C++

6665

1510

140

从目前局势来看,TensorFlow是最受欢迎的深度学习框架。那么,抛开Google在行业的巨大影响力,TensorFlow自身的硬实力如何呢?我们参考了多种公开基准测评,以及我们在图像和视觉领域实际测试得到的数据,给出了表1-2这组相对客观的横向对比。表中各评价指标均为5分制。因为部分框架未能找到测试数据,所以表中仅列出了指标相对确定的深度学习框架。

表1-2 主流深度学习框架在各个维度的横向对比

框架名称

教学资源

多语言接口

模型设计

运算性能

易用性

TensorFlow

5

5

5

4

5

MXNet

3

5

4

5

4

Caffe

2

5

3

5

3

Theano

3

2

5

3

2

Torch7

2

2

5

3

3

CNTK

2

3

2

5

3

对于深度学习框架的初学者来说,教学资源是一个非常重要的参考指标。借助Google的强大影响力和执行力,TensorFlow在这方面具有显著优势。不论是基础的指导手册,抑或是花样百出的最佳实践,初学者都有大量资料可以查询。同时,人工智能相关的会议和期刊论文中发布的新模型和新算法,几乎都会有人第一时间使用TensorFlow实现,并在GitHub上开源出来。

从多语言接口的角度来看,TensorFlow和MXNet共同占据领先地位。几乎所有框架都支持深度学习领域的“英语”——Python。TensorFlow对更多不同编程范式语言的支持使之对于不同背景的用户都具有一定的友好性,同时也扩展了框架潜在的应用领域。

从模型设计维度来看,TensorFlow采用了当前主流的基于数据流图的模型设计方式。其算子种类丰富,粒度较细,为用户提供的自由度高。相比于Caffe的配置式模型设计,TensorFlow显得更加灵活,能够适应更多的应用场景。同样使用数据流图定义模型的还有MXNet。不过,MXNet的分布式模型的约束较多,灵活性不足。

自TensorFlow发布以来,运算性能似乎一直是其弱项。在GitHub和Stack Overflow上的讨论帖中,我们也时常能够看到有人对TensorFlow的内存消耗和计算速度表示遗憾。但是,随着XLA和RDMA等特性的发布,TensorFlow的性能在绝大多数情况下都不输于其他深度学习框架。如果用户能够深入了解TensorFlow的API,那么就会发现它提供了大量提升性能的配置项。在启用这些性能优化选项后,TensorFlow的运算性能甚至能够超过MXNet和Caffe。

TensorFlow的灵活性是它的一大优势,但同时也因为API过于丰富而带来了学习成本高的问题。尤其是对于仅研究算法和模型的开发人员,在没有时间全面了解TensorFlow运行机制和编程接口的前提下,往往觉得无从下手。针对这类用户,社区的开发者们也提出了不少解决方案,那就是以Keras、TF Layers和TF Learn等为代表的高层API封装库。这些库隐藏了TensorFlow的大量细粒度接口,以简单易懂的接口取而代之,使得读者能够快速上手编程,并实现一些单机运行的算法模型。

综合对比当前主流的深度学习框架,TensorFlow在各个维度都具有比较明显的优势。同时,TensorFlow社区的活跃度也远超其他社区,这会使得越来越多的深度学习从业者参与贡献TensorFlow项目,最终形成越用越好用的良性循环。

1.2 设计目标

作为Google公司上一代深度学习平台DistBelief的继任者,TensorFlow的首要设计目标是满足公司内部的图像、语音、语义等感知和预测类应用的需求。这些应用的数据规模和模型复杂度日益增长,对提供计算能力的软硬件平台的功能和性能不断提出更高的要求。与此同时,新一波人工智能浪潮的兴起也促使在开源软件商业生态建设方面经验丰厚的Google公司敏锐嗅探信息化、智能化产业发展的新动向,并广泛吸收工业界、学术界和开源社区的前沿理念与最佳实践,将这些思想纳入TensorFlow的设计。种种迹象表明,TensorFlow的设计目标并非局限一套深度学习库,Google希望其成为一套面向多种应用场景和编程范式、支持异构计算平台、具备优异性能与可伸缩性的通用人工智能引擎。本节从中选取几个侧面,对TensorFlow的设计目标进行介绍和分析。

1.2.1 灵活通用的深度学习库

近几年来,随着海量数据的涌现、硬件计算能力的提升以及神经网络模型和机器学习算法的改进,深度学习技术得到了快速发展,已经成为学术界和工业界共同关注的热点。一方面,深度学习模型和算法的理论研究还未完全成熟,其发展空间巨大,吸引了大量科研人员参与其中。这几年深度学习席卷了各大顶级学术会议,模型设计、方法优化和应用创新的迭代更新速度极快。另一方面,深度学习在某些领域已经可以落地,比如人脸识别模型成功应用于安防系统,语音识别模型成功用于智能终端。除此之外,工业界正在积极探索深度学习更多潜在的商业应用场景。在人工智能的热潮中,很多开源的深度学习库应运而生,这对加速相关研究和工程化效率起到了非常重要的作用。为了应对上述研究与应用领域的诸多使用场景,深度学习库必须注重设计的灵活性与功能的通用性,才能在风起云涌的人工智能生态系统中得以立足。TensorFlow作为当前主流的深度学习库之一,其设计具有很高的灵活性和通用性,主要体现在以下几个方面。

  • 在算子定义方面,相比于其他深度学习库,TensorFlow提供的算子粒度更细、数量更多,能够支撑上层灵活多变的模型和算法。用户可以使用这些算子自由、灵活地开发各种深度学习模型。此外,很多传统的机器学习模型也可以基于TensorFlow实现,如支持向量机、决策树和随机森林等。TensorFlow亦支持深度学习和传统机器学习混合的模型,从而使得数据流水线式的应用创新成为可能。TensorFlow对新算子的支持也足够灵活,允许用户通过组合已有的细粒度算子来构造新的算子,以快速实现算法原型、验证一些新的想法。用户也可以使用C++ 语言和CUDA等底层函数库实现新的算子并在运行时动态加载使用,以便满足专用算法需求并保证计算性能。
  • 在编程范式方面,TensorFlow支持声明式编程,将模型的定义和执行解耦。模型以数据流图结构表示,经过编译和优化之后才会真正执行。以数据流图抽象为核心的设计在保证模型执行效率的同时,使得用户编程更加灵活。例如,在模型定义阶段,用户可以通过添加控制依赖边来指定算子的执行顺序,通过添加自定义变量自如地管理数据流图的输入和输出,还可以通过队列控制多设备之间的数据传输和子图执行时序。在数据流图的运行态,用户可以指定数据流图中待执行的子图,从而避免不必要的算子计算开销。除了模型之外,数据读取、数据预处理等其他操作都可以被添加到数据流图中,用户可以通过编辑数据流图实现对具体应用的端到端灵活控制。
  • 在运行时框架方面,TensorFlow在具备隐式并行计算能力的同时,也提供了细粒度的显式控制接口,允许灵活地控制模型在多节点异构设备上的分布式执行方式。用户在编写深度学习模型时,可以自由地将模型中的每个算子绑定在任意的计算设备上。TensorFlow运行时框架负责将模型对应的数据流图按照设备进行切分,并自动插入必要的通信操作,对用户屏蔽了底层复杂的数据传输与时序同步机制。用户可以结合具体模型和应用的特点,通过手工指定或者以强化学习等方式找出模型在多节点异构硬件上的最优布局与执行方式(如数据并行、模型并行等),这使得模型的训练和推理都有更多的优化空间。
  • 在多语言支持方面,TensorFlow提供Python、C、C++、Java、Go等主流语言的编程接口。虽然Python是当前深度学习和人工智能领域使用最为广泛的编程语言,但是其他语言也有各自的语法优势、适用场景以及拥趸,它们能够满足科研、商用等不同应用领域及服务器、终端等不同目标设备的开发需求。另外,社区开源贡献者在TensorFlow C API基础上扩展开发了Node.js、Julia、R等其他语言的编程接口,这在体现TensorFlow内核设计灵活性的同时,也进一步扩大了其作为通用深度学习库的场景覆盖范围。

总而言之,TensorFlow通过丰富的算子、灵活的编程范式、自由的运行时框架以及多语言API支持,对用户展现了高度的灵活性和通用性。TensorFlow在其设计之初就被定义为灵活通用的深度学习平台。Google公司将它开源的目的正是要以其作为基石,构筑深度学习乃至整个人工智能的生态圈。

1.2.2 端云结合的人工智能引擎

“端云结合”是当今信息化、智能化技术发展的普遍趋势。一方面,随着信息技术在生产、生活中各个应用领域愈发深入的集成,对海量数据的高效处理成为IT服务商与决策部门的迫切需求。在传统数据中心基础上发展起来的云计算和大数据技术以集约化的资源管理、动态弹性的资源供给为持续膨胀的应用提供了高水平、可伸缩的计算能力,同时降低了服务提供者的准入门槛。这就要求传统服务器端软件必须适应云化部署场景,以水平扩展(scale-out)、无状态、微服务等方式构建高内聚、低耦合的系统架构。另一方面,随着以智能手机为代表的移动终端技术的高速普及,以及物联网、机器人等智能化技术在传统行业的不断渗透,用户对于数据私密性、安全性的重视程度逐渐增强,应用场景对服务实时性与可用性的要求也更加严格。在这一背景下,计算能力的边缘化成为与云化并驾齐驱的演进方向。这就要求提供服务的软件能够适应体系结构多样、计算资源有限、功耗受到制约的终端硬件环境,并具备一定的自治与协同工作能力。

在人工智能领域野心勃勃的Google公司自然准确地把握并积极地引领着这一趋势。在云侧,Google既是一家公有云提供商,需要通过具有核心竞争力的PaaS层产品吸引企业级用户和二次开发者;又是一家业务高度依赖于智能算法与海量数据的创新型公司,需要开发高效、灵活的基础平台软件满足自身业务快速发展的需要。在端侧,Google公司不但需要为日新月异的应用开发提供强有力的智能化支撑能力,从而使其Android生态系统得以抗衡强大的竞争对手;而且需要借助实时且可靠的智能计算引擎进军物联网、可穿戴设备、增强实现、无人驾驶等新兴领域,以寻求“后移动互联网时代”的新增长点。TensorFlow等平台层软件的设计因此也兼顾了云侧与端侧的需求。

TensorFlow对云计算场景的支持是其竞争力的基础,主要体现在以下方面。

  • 提供多种标准化的安装包、构建脚本及容器化封装,支持在不同Linux发行版以及Windows Server等其他服务器操作系统上部署,既允许以二进制包方式快速安装,也允许针对特定环境定制化编译高效的目标代码,从而极大地扩展了软件的适用范围,增强了适配能力。
  • 支持对接多种常见的公有云和私有云服务,如Google Cloud Storage、Amazon S3、HDFS,并为对接其他类似服务预留可扩展设计,从而能够与既有的互联网、大数据生态系统无缝交互,实现资源复用与服务组合。
  • 兼容若干种常见的高性能计算与通信硬件,能够有效利用云环境的既有投资并提升应用软件对高端硬件资源的利用率。例如,支持NVIDIA和OpenCL GPU,能够充分挖掘众核设备的并行计算能力;支持RDMA网络协议,能够充分发挥InfiniBand等高速网络设备的带宽潜力。
  • 灵活的运行时框架设计,既提供标准且易用的PS-worker分布式模式,也允许用户自由开发针对特定环境需求的分布式框架。即使脱离Google公司的Borg等基础设施,以TensorFlowOnSpark、MaTEx-TensorFlow为代表的第三方工具也能够利用既有的分布式平台提升TensorFlow在数据中心和超算集群中的可伸缩性。

TensorFlow在端侧场景方面也毫不逊色,其主要设计体现在以下几个方面。

  • 推理(预测)态代码能够运行于多种主流的终端平台,包括Android、iOS,以及部署Linux操作系统的多类ARM与MIPS设备(如Raspberry Pi),从而为形态多样的终端设备集成AI认知与决策能力提供支撑。
  • 通过XLA AOT(ahead-of-time)编译技术及其他软硬件解耦设计,显著地简化底层异构计算设备的对接方式,实现对神经网络芯片等新型专用端侧硬件的快速支持能力。
  • 提供量化参数和低精度代数等算法层机制,适配算力、存储和功耗受限的终端,从而实现低端边缘设备的智能化。
  • 提供模型与框架一体化的精简版运行时平台,具备完全的离线工作能力,有助于实现端侧计算的私密性与实时性。

可以看出,TensorFlow作为一套人工智能引擎,不但致力于增强应用系统的“大脑”,同时也在帮助其完善“末梢神经”。可以预见,未来TensorFlow等人工智能引擎会像Linux操作系统内核一样,成为在端云两侧广泛支撑各类应用、助力实现智能化社会的幕后英雄。

1.2.3 高性能的基础平台软件

虽然如今的互联网、大数据计算平台软件层出不穷,核心技术变幻莫测,吸睛特性轮番登场,但是性能始终都能够超脱于名目繁多的噱头,成为几乎所有用户一致认可的硬指标。在半导体器件物理极限将至的情况下,摩尔定律的有效性已经存疑,软件轻松分享硬件发展红利的时代走向末路。硬件设计者正在广泛采纳新型器件、三维电路、应用定制、众核并行等多元化思路满足应用不断增长的算力需求,这为软件开发者提供机会的同时也带来了不小的挑战。如何将软件架构和算法有效适配到硬件体系结构、充分利用硬件资源发挥其设计性能,成为所有软件开发者,特别是基础平台层软件开发者面临的重要问题。

随着深度学习技术发展而兴起的一系列开源计算库长期处于激烈竞争的态势。在竞争过程中,一快遮百丑。这里的“快”字有两层含义:深度学习库的开发者不仅需要快速响应上层需求和下层技术的变化,及时发布新版本与新特性,而且需要通过苦修内功提升深度学习库本身的性能,加快算法模型的训练与推理速度。在第一个“快”字上,TensorFlow借助Google公司强大的号召力和坚决的执行力,长期保持领先地位。在第二个“快”字上,TensorFlow曾因权衡灵活性等原因一度落后于同类软件,但如今已经迎头赶上,在主流应用场景中取得了优异的测试成绩。这归功于众多核心研究者和开源贡献者在性能方面的深耕。

TensorFlow的高性能设计首先体现在它对高端和专用硬件的深入支持。同其他主流的深度学习库一样,TensorFlow将NVIDIA GPU作为训练态的硬件加速器,同时兼顾OpenCL GPU设备。不同于简单使用CUDA Runtime API的其他平台,Google的工程师基于CUDA Driver API实现了控制粒度更细、并行性能更优的StreamExecutor异构计算库,并对cuBLAS、cuDNN等库的函数变种进行了精确的适配。在推理态,尽管Google没有开源或销售TPU,然而TensorFlow开放性的设计已经促使多家芯片厂家实现了对接,这为定制化设备上的计算性能提升提供了保障。针对高性能计算环境中常用的InfiniBand、RoCE等高速网络设备,以及NVLink等片间高速互联技术,TensorFlow引入了RDMA、NCCL等协议,较好地解决了通信延迟问题,推进了分布式计算作业的加速比提升。

其次,系统层的优化技术是TensorFlow性能提升的重要杀手锏。相比来自于学术界的算法研究团队,Google科研与工程团队深厚的系统研发背景是TensorFlow构建性能竞争力的坚实后盾。XLA这种融合了编译器设计理论的优化框架就是一例。它引入的JIT(just-in-time)编译机制能够在数据流图运行过程中实时创建二进制代码,将其中大量细粒度的操作融合为少量粗粒度的专用核函数,从而减少图中操作执行时的内存分配和上下文切换开销,极大地提升计算速度。TensorFlow诸多模块设计中也存在着细节上的性能优化。例如,通信模块中具有若干种旁路(bypass)设计,可以避免不必要的网络访问和内存复制开销;数据流图构建时会执行常量折叠、公共子表达式消除、内联函数展开等多种语法树优化,能够消除无意义的计算开销。这些设计体现出开发者良好的软件工程素养与精益求精追求。

最后,算法层的优化设计也是TensorFlow实现优异性能不可或缺的组成部分。为了实现高性能的目标,TensorFlow的设计采纳了自顶向下、全栈优化的思路,而算子恰恰是贯穿上下层的核心要素。在深度学习的算法模型中,每种算子的逻辑都可以采用多种算法实现。为此,TensorFlow内置了多种优化后的基础算子和模型组件。以卷积算子为例,cuDNN提供了Winograd等8种算法。针对不同的输入数据大小、卷积计算超参以及内存等资源限制,TensorFlow会自动为每个卷积操作选择最快的实现算法。另外,针对递归神经网络等模型,TensorFlow也支持Fold解决方案,使得动态批处理成为可能,极大提高了这些模型的计算速度。

综上所述,性能是TensorFlow研发者重点关注的设计目标。虽然TensorFlow开源版本的性能优化起步稍晚,但是在Google团队和开源社区的共同努力下进步迅速。在这个“天下武功唯快不破”的时代,TensorFlow的高性能优势必将为Google插上腾飞的翅膀,使之引领人工智能研究与应用的高速发展。

1.3 基本架构

在展开介绍TensorFlow的使用方法和设计原理之前,我们有必要建立对TensorFlow基本架构的直观认识。本节从工作形态和组件结构这两个角度对TensorFlow进行概要性的说明。读者可以以此为切入点,逐步理顺学习TensorFlow的脉络。

1.3.1 工作形态

基础平台层软件的设计模式多种多样,它们对应用层开发者体现出的工作形态也有所差别。在众多平台设计模式中,存在两类基础而典型的模式,即图1-2所示的库模式和框架模式。在库模式下,平台层软件以静态或动态的开发库(如 .a、.so文件)形式存在,应用层开发者需要编写程序调用这些库提供的函数,实现计算逻辑。程序的入口(如main()函数)及整体流程控制权把握在应用层开发者手中。在框架模式下,平台层软件以可执行文件的形式存在,并以前端交互式程序或后端守护进程方式独立运行。应用层开发者需要遵从平台规定的接口约束,开发包含计算逻辑在内的子程序,交由框架性质的平台层软件调度执行。程序的入口及整体流程控制权由框架把握。

图1-2 平台层软件的典型设计模式

在高性能与大数据计算领域,典型的库模式软件有用于计算的Eigen、NumPy,以及用于通信的MPI、ZeroMQ等。基于这些库开发应用时,编程方式比较灵活,部署模式也相对轻量。应用开发者具有较大的自由度,但不得不编写业务逻辑之外的不少“脚手架”代码,以便将算法代码片段转变为完整可用的软件。典型的框架模式软件有大数据计算平台Hadoop、Spark,以及基于SQL和类SQL语言的数据库、数据仓库等。使用这些框架开发应用时,开发者的工作相对轻松,只需要编写与业务逻辑密切相关的算法代码,不用关心运行时机制的复杂性。不过,程序的灵活性将受制于框架的约束。

TensorFlow的设计采用了库模式。之所以如此,是出于灵活通用、端云结合及高性能等设计目标的考虑。库模式的平台层软件便于与各种既有的框架协同工作,不对软件的运行时组件添加新的约束,应用范围也不受制约。除了依赖最基本的编程语言库和操作系统调用,这类平台层软件同其他环境因素解耦,从而可以做到高度的可移植性。在单机和终端等场景下,由于没有守护进程和调度框架的开销,有效计算逻辑的资源利用率也会提高,进而有助于性能优化。

综上,TensorFlow的工作形态是由用户编写主程序代码,调用Python或其他语言函数库提供的接口以实现计算逻辑。用户部署和使用TensorFlow系统时,不需要启动专门的守护进程,也不需要调用特殊的启动工具,只需要像编写普通的本地应用程序那样即可上手。用户也不用担心库模式的开发所必需的那些“脚手架”代码,因为TensorFlow已经提供了多种高级抽象,尽可能地最小化了核心计算逻辑之外的开发工作。

1.3.2 组件结构

TensorFlow作为一套包含数十万行代码的大型软件,其组件结构较为复杂。不过,由于其代码组织合理,文档资料充分,我们很容易将它的软件结构进行不同抽象程度的宏观呈现。初识TensorFlow的新手只需要从最高层的抽象视角观察其组件构成。图1-3给出了一幅粗粒度的TensorFlow组件结构示意图,展示了TensorFlow的主要内部结构及其与周边环境的关系。

图1-3 TensorFlow的组件结构示意图

构成TensorFlow的主体是其运行时核心库。对于普通的Python应用层开发者而言,这个核心库就是指通过pip命令等方式安装TensorFlow之后,部署到site-packages或类似目录中的动态链接库文件。生成这个库的C++ 源代码大致分为3个层次:分布式运行时、公共运行时和算子核函数。其中,公共运行时实现了数据流图计算的基本逻辑,分布式运行时在此基础上实现了数据流图的跨进程协同计算逻辑,算子核函数则包含图上具体操作节点的算法实现代码。

TensorFlow运行时核心库导出的函数接口基于C和C++ 语言。为了使用其他语言进行应用开发,TensorFlow提供了多语言的API层。Python应用层开发者在代码中调用import tensorflow as tf时,导入的便是TensorFlow安装在Python第三方库目录下的API层模块(本书后面沿用这种Python包导入惯例,使用tf作为tensorflow命名空间的缩写)。API层对用户屏蔽了TensorFlow核心库的动态链接逻辑,使得用户可以使用自己熟悉的语言编写算法模型。

为了简化经典模型的开发,使得TensorFlow成为一套“开箱即用”的工具,Google官方团队及开源贡献者们在TensorFlow社区开设了若干算法模型库及人工智能应用程序项目。用户可以复用这些项目的成果,加快自己的项目开发进度;也可以学习它们的实现原理,提升自己的模型与应用设计水平。这些外围项目中的部分代码(如Keras)已被认为具有较高的共性价值,因此逐步被加入到TensorFlow主项目之中。

TensorFlow运行时核心库底层对接的是各种计算库和通信库。这些库有的是外部组件(如用于CPU代数计算的Eigen库),有的则作为TensorFlow源代码的一部分集成在核心库内部(如用于GPU并行计算的StreamExecutor库)。用户在开发应用程序时看不到这些库的细节,只需要按照软件文档安装好必要的外部依赖包即可。

上面所有组件均运行在本地操作系统和硬件基础设施之上。在服务器端运行场景,最常见的宿主操作系统是Linux,硬件一般为x86 CPU和NVIDIA GPU。在移动终端运行场景,宿主操作系统可以是Android、iOS等,硬件一般为ARM CPU和专用的人工智能芯片。TensorFlow不仅支持原生的物理环境,对虚拟机和容器也完全兼容,这构成了云计算环境下的最佳实践。

1.4 小结

作为一套优秀的深度学习计算库,TensorFlow在新一波人工智能浪潮中脱颖而出。它源于Google公司内部基于海量数据开展感知和预测类应用的需求,并通过围棋大战向公众一展雄姿。依托Google团队雄厚的科研实力,同时借助开源社区的集体智慧,TensorFlow已经成为了一套运算性能强劲、框架设计通用、语言接口丰富,并支持生产环境部署和端云协同计算的通用人工智能基础平台软件。TensorFlow的构架设计灵活而开放,有助于适应多样的应用场景并吸引第三方开发者贡献特性。我们相信,在当今人工智能理论进步与应用落地并举的时代,TensorFlow势必会引领相关研究与工程领域的高速发展。

目录