Dive into TensorFlow系列(1)-静态图运行原理
接触过TensorFlow v1的朋友都知道,训练一个TF模型有三个步骤:定义输入和模型结构,创建tf.Session实例sess,执行sess.run()启动训练。不管是因为历史遗留代码或是团队保守的建模规范,其实很多算法团队仍在大量使用TF v1进行日常建模。我相信很多算法工程师执行sess.run()不下100遍,但背后的运行原理大家是否清楚呢?不管你的回答是yes or no,今天让我们一起来探个究竟。
学习静态图运行原理能干什么?掌握它对我们TF实践中的错误排查、程序定制、性能优化至关重要,是必备的前置知识。
一、何为静态图?
众所周知,TensorFlow程序有两种运行选择,即静态图模式与动态图模式。
1.1 静态图
静态图采用声明式编程范式(先编译后执行),根据前端语言(如python)描述的神经网络结构和参数信息构建固定的静成计算图,静态图在执行期间不依赖前端语言,而是由TF框架负责调度执行,因此非常适合做神经网络模型的部署。用户定义的静态图经序列化后用GraphDef表达,其包含的信息有:网络连接、参数设置、损失函数、优化器等。
有了完整的静态图定义后,TF编译器将计算图转化成IR(中间表示)。初始IR会经TF编译器一系列的转换和优化策略生成等价的计算图。编译器前端转换和优化包括:自动微分、常量折叠、公共子表达式消除;编译器后端与硬件相关,其转换和优化包括:代码指令生成和编译、算子选择、内存分配、内存复用等。
综上所述,静态图的生成过程可用下图简要概适:

1.2 动态图
动态图采用命令式编程范式,即编译与执行同时发生。动态图采用前端语言的解释器对用户代码进行解析,然后利用TF框架的算子分发功能,使得算子立即执行并向前端返回计算结果。当模型接收输入数据后,TF开始动态生成图拓扑结构,添加输入节点并将数据传输给后续节点。如果动态图中含有条件控制逻辑,会立即计算逻辑判断结果并确定后续数据流向,因此动态图完整的拓扑结构在执行前是未知的。另外,当模型根据新的batch训练时,原有的图结构则失效,必须根据输入和控制条件重新生成图结构。
综上所述,动态图生成过程可用下图简要概括:

1.3 比较
为了方便大家深入理解动/静态图原理及异同点,梳理相关信息如下表:
| 静态图 | 动态图 | |
|---|---|---|
| 即时获取中间结果 | 否 | 是 |
| 代码调试难度 | 难 | 易 |
| 控制流实现方式 | TF特定语法 | 可采用前端语言语法 |
| 性能 | 多种优化策略,性能好 | 优化受限,性能差 |
| 内存占用 | 内存占用少 | 内存占用多 |
| 部署情况 | 可直接部署 | 不可直接部署 |
二、Session是干啥的?
2.1 Session定义
tf.Session代表用户程序和C++运行时之间的连接。一个Session类对象session可以用来访问本机计算设备,也可访问TF分布式运行时环境中的远程设备。session也能缓存tf.Graph信息,使得相同计算逻辑的多次执行得以高效实现。
tf.Session的构造方法定义如下:
def __init__(self, target='', graph=None, config=None):
"""Creates a new TensorFlow session.
If no `graph` argument is specified when constructing the session,
the default graph will be launched in the session. If you are
using more than one graph (created with `tf.Graph()` in the same
process, you will have to use different sessions for each graph,
but each graph can be used in multiple sessions. In this case, it
is often clearer to pass the graph to be launched explicitly to
the session constructor.
Args:
target: (Optional.) The execution engine to connect to.
Defaults to using an in-process engine. See
@{$distributed$Distributed TensorFlow}
for more examples.
graph: (Optional.) The `Graph` to be launched (described above).
config: (Optional.) A [`ConfigProto`](https://www.tensorflow.org/code/tensorflow/core/protobuf/config.proto)
protocol buffer with configuration options for the session.
"""
super(Session, self).__init__(target, graph, config=config)
# NOTE(mrry): Create these on first `__enter__` to avoid a reference cycle.
self._default_graph_context_manager = None
self._default_session_context_manager = None
我们来看一下__init__()方法的三个参数:
2.2 Session.run()
tf.Session.run()实际是调用tf.BaseSession.run()方法,其函数签名如下:
def run(self, fetches, feed_dict=None, options=None, run_metadata=None):
run()方法的参数说明如下:
当Session指定fetches后,根据要获取的结果决定tf.Graph实际执行的subgraph(并非整个tf.Graph都要执行)。执行静态图还有三个要点:
2.3 Session类前后端设计
首先我们看一下和用户直接打交道的前端Session,具体分为普通Session和交互式InteractiveSession。前者全称为tf.Session,需要在启动之前先构建完整的计算图;后者全称为tf.InteractiveSession,它是先构建一个session,然后再定义各种操作,适用于shell和IPython等交互式环境。这两个类均继承自BaseSession,这个基类实现了整个生命周期的所有会话逻辑(相关代码在tensorflow/python/client/session.py中)。前端Session类的继承关系如下图:

TensorFlow后端会根据前端tf.Session(target='', graph=None, config=None)创建时指定的target来创建不同的后端Session。target是要连接的TF后端执行引擎,默认为空字符串。后端Session的创建采用抽象工厂模式,如果为空字符串,则创建本地DirectionSession;如果是grpc://开头的URL串,则创建分布式GrpcSession。DirectSession只能利用本地设备,将任务调度到本地的CPU/GPU设备上;GrpcSession可利用远程设备,将任务分发到不同机器的CPU/GPU上,然后机器之间通过gRPC进行通信。显而易见,DirectionSession的定义应在core/common_runtime/direction_session.h中;GrpcSession的定义在core/distributed_runtime/rpc/grpc_session.h中。后端Session的类图关系如下所示:

三、静态图执行过程
3.1 执行框架
为便于大家理解,我们先给出粗粒度的静态图执行原理如下:

3.2 若干执行细节
静态图的实际执行过程要比3.1节描述的复杂得多。由于本篇的初衷不是做源码的完整剖析,因此我们仅就Client向Master的处理过程做详细说明,旨在让读者亲身体会一下交互过程的复杂性。
Client创建GrpcSession,控制Client会话的生命周期;Master运行时被MasterSession控制。GrpcSession通过抽象工厂模式得到,首先得到工厂类GrpcSessionFactory的对象,并用SessionFactory句柄factory存储。然后通过factory的多态方法生成GrpcSession,如果target为grpc://的话。Master本质上是一个Server,每个Server均有一个MasterService和一个WorkerService。
Client通过GrpcSession调用Master节点的MasterService,这个过程需借助MasterInterface才可完成。MasterInterface用来和MasterService进行通信,它有两种不同的场景实现:

如果读者想对上述过程做更为深入的了解,可以参考几个关键类的源码:
其实Client到Master的处理过程还涉及MasterSession的创建,以及GrpcSession与MasterSession的交互与标识问题。篇幅所限,不展开了。
四、总结
作为Dive into TensorFlow系列第一讲,本文由浅入深、系统讲解了静态图及其运行原理,以及支撑这些功能的架构设计与部分源码解析。回到文章开头提到的用户读懂全文能有什么收益?(尝试提几点)
参考资料
1.Graphs and Sessions: https://github.com/tensorflow/docs/blob/master/site/en/r1/guide/graphs.md
2.《机器学习系统:设计与实现》: https://openmlsys.github.io/chapter_computational_graph/index.html
3.前后端连接的桥梁Session: https://www.likecs.com/show-306440850.html
4.TensorFlow v1.15.5源码: https://github.com/tensorflow/tensorflow/tree/v1.15.5/tensorflow/core/graph
5.TensorFlow Architecture: https://github.com/tensorflow/docs/blob/master/site/en/r1/guide/extend/architecture.md
6.TensorFlow分布式环境Session: https://www.cnblogs.com/rossiXYZ/p/16065124.html
Dive into TensorFlow系列(1)-静态图运行原理的更多相关文章
- StarUML 系列,静态图与动态图,用例图,类图【ps:熟悉一下starUML】
大部分: 静态图部分,即静态不动的图 1.用例图, Use case diagram 1.展示系统核心功能及与其交互的用户ACTOR 表示:椭圆
- StarUML 系列,静态图与动态图,用例图,类图
大部分: 静态图部分,即静态不动的图 1.用例图, Use case diagram 1.展示系统核心功能及与其交互的用户ACTOR 表示:椭圆
- Spark核心技术原理透视一(Spark运行原理)
在大数据领域,只有深挖数据科学领域,走在学术前沿,才能在底层算法和模型方面走在前面,从而占据领先地位. Spark的这种学术基因,使得它从一开始就在大数据领域建立了一定优势.无论是性能,还是方案的统一 ...
- tensorflow 升级到1.9-rc0,生成静态图frozen graph.pb本地测试正常, 在其他版本(eg1.4版本)或者android下运行出错NodeDef mentions attr 'dilations' not in Op<name=Conv2D; signature=input:T, filter:T -> output:T; attr=T:type,allowed=[DT_
这时节点定义找不到NodeDef attr 'dilations' not in,说明执行版本的NodeDef不在节点定义上,两个不一致,分别是执行inference的代码和生成静态图节点不一致(当然 ...
- 『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程
https://www.cnblogs.com/hellcat/p/9084894.html 目录 一.符号式编程 1.命令式编程和符号式编程 2.MXNet的符号式编程 二.惰性计算 用同步函数实际 ...
- 小白学PyTorch 动态图与静态图的浅显理解
文章来自公众号[机器学习炼丹术],回复"炼丹"即可获得海量学习资料哦! 目录 1 动态图的初步推导 2 动态图的叶子节点 3. grad_fn 4 静态图 本章节缕一缕PyTorc ...
- 【UML 建模】UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
- WCF开发实战系列三:自运行WCF服务
WCF开发实战系列三:自运行WCF服务 (原创:灰灰虫的家 http://hi.baidu.com/grayworm)上一篇文章中我们建立了一个WCF服务站点,为WCF服务库运行提供WEB支持,我们把 ...
- UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
随机推荐
- vivo前端智能化实践:机器学习在自动网页布局中的应用
作者:vivo 互联网前端团队- Su Ning 在设计稿转网页中运用基于self-attention机制设计的机器学习模型进行设计稿的布局,能够结合dom节点的上下文得出合理的方案. 一.背景 切图 ...
- 如何结合整洁架构和MVP模式提升前端开发体验(三) - 项目工程化配置、规范篇
工程化配置 还是开发体验的问题,跟开发体验有关的项目配置无非就是使用 eslint.prettier.stylelint 统一代码风格. formatting and lint eslint.pret ...
- 操作服务器的神奇工具Tmux
Tmux 是什么? 会话与进程 命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称"窗口"),在里面输入命令.用户与计算机的这种临时的交互,称为一次 ...
- 走进Redis-扯扯集群
集群 为什么需要切片集群 已经有了管理主从集群的哨兵,为什么还需要推出切片集群呢?我认为有两个比较重要的原因: 当 Redis 上的数据一直累积的话,Redis 占用的内存会越来越大,如果开启了持久化 ...
- 快Key:按一下鼠标【滚轮】,帮你自动填写用户名密码,快速登录,可制作U盘随身(开源免费-附安装文件和源代码)
* 代码以本文所附下载文件包为准,安装文件和源文件包均在本文尾部可下载. * 快Key及本文所有内容仅供交流使用,使用者责任自负,由快Key对使用者及其相关人员或组织造成的任何损失均由使用者自负,与本 ...
- Windows LDAP加固之替换LDAP加密证书
之前两篇文章介绍了LDAP的安全加固,其中提到了TLS加密LDAP通信.对于通常的网页加密,RDP加密都可以在对应的管理界面中选择使用哪个证书来加密.那么对于LDAP服务,怎么确定当前使用的是哪张证书 ...
- 《Java基础——继承》
Java基础--继承 一.类的继承: 规则: 1.一个子类只能有一个父类,但一个父类可以有多个子类,每个子类都可以作为父类使用. 2.若一个类没有声明父类,则默认其父类为Object. 3.父 ...
- SQL注入篇——sqli-labs各关卡方法介绍|1-65
主要是记下来了每关通过可以采用的注入方式,可能部分关卡的通关方式写的不全面,欢迎指出,具体的获取数据库信息请手动操作一下. 环境初始界面如下: sql注入流程语句: order by 3--+ #判断 ...
- 【学习笔记】前馈神经网络(ANN)
前言 最近跟着<神经网络与深度学习>把机器学习的内容简单回顾了一遍,并进行了一定的查缺补漏,比如SVM的一些理解,one-hot向量,softmax回归等等. 然后我将继续跟着这本书,开始 ...
- 在 CentOS 8/RHEL 8 上安装和使用 Cockpit
Cockpit 是一个基于 Web 的服务器管理工具,可用于 CentOS 和 RHEL 系统.最近发布的 CentOS 8 和 RHEL 8,其中 cockpit 是默认的服务器管理工具.它的软件包 ...