深度学习利器: TensorFlow系统架构及高性能程序设计

2015年11月9日谷歌开源了人工智能平台TensorFlow,同时成为2015年最受关注的开源项目之一。经历了从v0.1到v0.12的12个版本迭代后,谷歌于2017年2月15日发布了TensorFlow 1.0 版本,并同时在美国加州山景城举办了首届TensorFlow Dev Summit会议。

\\

TensorFlow 1.0及Dev Summit(2017)回顾

\\

和以往版本相比,TensorFlow 1.0 的特性改进主要体现在以下几个方面:

\\
  • 速度更快:TensorFlow 1.0版本采用了XLA的编译技术,改进了TensorFlow的运行性能及内存利用。从Benchmark问题的测试结果来看,对单机Inception v3模型,实现了在单机8 GPUs上7.3倍的运算加速;对分布式Inception v3模型,实现了在多机64 GPUs上58倍的运算加速。\\t
  • 更加灵活:该版本除了支持tf.layers,tf.metrics及tf.losses模型的High-Level API外,实现了对keras(high-level neural networks library)API的全面兼容。\\t
  • 更产品化:TensorFlow Python API在v1.0版本中趋于稳定,为产品兼容性打下坚实基础。\

在TensorFlow 1.0版本发布的当天,谷歌公司还举办了TensorFlow 2017 DEV Summit。该日程主要包括以下几个方面的主题演讲:

\\
  • \\t

    XLA (TensorFlow, Compiled)编译技术 :介绍采用XLA技术最小化图计算执行时间和最大化利用计算资源,用于减少数据训练和模型结果推断时间。

    \\t\\t
  • \\t

    Hands-on TensorBoard可视化技术:介绍了如何使用TensorBoard,以及TensorFlow图模型、训练数据的可视化等。

    \\t\\t
  • \\t

    TensorFlow High-Level API:介绍了使用Layers, Estimators, and Canned Estimators High-Level API定义训练模型。

    \\t\\t
  • \\t

    Integrating Keras \u0026amp; TensorFlow: 介绍了如何在TensorFlow中使用Keras API进行模型定义及训练。

    \\t\\t
  • \\t

    TensorFlow at DeepMind:介绍了在DeepMind中使用TensorFlow平台的典型案例,包括AlphaGo等应用。

    \\t\\t
  • \\t

    Skin Cancer Image Classification:介绍了斯坦福医学院使用TensorFlow分类皮肤癌照片,用于医学诊断。

    \\t\\t
  • \\t

    Mobile and Embedded TensorFlow:介绍了如何把TensorFlow模型运行在移动终端、嵌入式设备,包括安卓,iOS等系统。

    \\t\\t
  • \\t

    Distributed TensorFlow:系统性地介绍了分布式TensorFlow的相关技术,以及如何应用于大规模模型训练。

    \\t\\t
  • \\t

    TensorFlow Ecosystem:讲解了TensorFlow的生态系统,包括生成训练数据,分布式运行TensorFlow和serving models的产品化流程。

    \\t\\t
  • \\t

    Serving Models in Production with TensorFlow Serving:系统性讲解了如何在生产环境中应用TensorFlow Serving模型。

    \\t\\t
  • \\t

    ML Toolkit:介绍了TensorFlow的机器学习库,如线性回归,KMeans等算法模型的使用。

    \\t\\t
  • \\t

    Sequence Models and the RNN API:介绍了如何构建高性能的sequence-to-sequence模型,以及相关API。

    \\t\\t
  • \\t

    Wide \u0026amp; Deep Learning: 介绍了如何结合Wide模型和Deep模型构建综合训练模型。

    \\t\\t
  • \\t

    Magenta,Music and Art Generation:使用增强型深度学习模型生成音乐声音和艺术图片。

    \\t\\t
  • \\t

    Case Study,TensorFlow in Medicine - Retinal Imaging:使用TensorFlow机器学习平台对医学视网膜图片进行分类,辅助医学诊断。

    \\t\

TensorFlow系统架构

\\

TensorFlow作为分布式机器学习平台,主要架构如下图所示。RPC和RDMA为网络层,主要负责传递神经网络算法参数。CPU和GPU为设备层,主要负责神经网络算法中具体的运算操作。Kernel为TensorFlow中算法操作的具体实现,如卷积操作,激活操作等。Distributed Master用于构建子图;切割子图为多个分片,不同的子图分片运行在不同的设备上;Master还负责分发子图分片到Executor/Work端。Executor/Work在设备(CPUs,GPUs,etc.)上,调度执行子图操作;并负责向其它Worker发送和接收图操作的运行结果。C API把TensorFlow分割为前端和后端,前端(Python/C++/Java Client)基于C API触发TensorFlow后端程序运行。Training libraries和Inference libs是模型训练和推导的库函数,为用户开发应用模型使用。

\\

f49c7051582c1182dd8232f4bf0d915c.jpg

\\

下图为Client、Master及Worker的内部工作原理。\"/job:worker/task:0\" 和 \"/job:ps/task:0\" 表示worker中的执行服务。\"job:ps\"表示参数服务器,用于存储及更新模型参数。\"job:worker\"用于优化模型参数,并发参数发送到参数服务器上。Distributed Master和Worker Service只存在于分布式TensorFlow中。单机版本的TensorFlow实现了Local的Session,通过本地进程的内部通讯实现上述功能。

\\

18e722ffc29df6f174de873ddc77ff88.jpg

\\

用户编写TensorFlow应用程序生成计算图,Client组件会创建Session,并通过序列化技术,发送图定义到Distributed Master组件。下图中,Client创建了一个 s+=w*x+b的图计算模型。

\\

fcb71a7105f746bb55185de8947833ff.jpg

\\

当Client触发Session运算的时候,Maser构建将要运行的子图。并根据设备情况,切割子图为多个分片。下面为Master构建的运行子图:

\\

682fa8d0d8def4813c044ac706e49913.jpg

\\

接着切割子图,把模型参数分组在参数服务器上,图计算操作分组在运算Worker上。下图为一种可行的图切割策略:

\\

fbfb98d77891c3dc80b74440998f6e98.jpg

\\

Distributed Master会根据模型参数的分区情况进行切割边,在Task间插入发送和接收Tensor信息的通信节点,如下图所示:

\\

102a8726cec11fb6d82d87e138fdfc0c.jpg

\\

接着Distributed Master通过RegisterGraph方法发送子图分片给Task,如下图所示:

\\

3acd89491819841cafa82d33270981e7.jpg

\\

Master通过RunGraph触发子图运算,Worker会使用GPU/CPU运算设备执行TensorFlow Kernel运算。在本节点的CPU和GPU之间,使用cudaMemcpyAsync传输数据;在本节点GPU和GPU之间,使用peer-to-peer DMA传输数据,避免通过CPU复制数据。TensorFlow使用gRPC(TCP)和RDMA (Converged Ethernet)技术,实现Worker间的数据通信及传输,如下图所示:

\\

ce964c563c035a2c7f31f8382dbdbd6d.jpg

\\

高性能程序设计

\\

TensorFlow内核采用C/C++开发,并提供了C++,Python,Java,Go语言的Client API。特别是Python API,是目前主流的TensorFlow模型开发接口。但为什么还需要采用C++ API去训练模型呢?本文基于如下两点考虑,首先当我们采用Python API去训练模型的时候,需要不断地用Python API调用C/C++底层接口,重复的接口调用一定程度上影响了程序的执行性能。更为重要的是,在GPU上训练模型的时候需要大量的内存交换;如果采用C++ API去训练模型,可提供更好的运算性能及更好地控制GPU内存的分配。

\\

下图为Python API的运算架构:在模型训练的每次迭代中,程序通过Python API读取Batch Data,然后通过TensorFlow Session Run接口,传递数据给C++,并触发神经网络训练。如下图所示:

\\

f3f075322532dc8dd0c653ddcebcbbf2.jpg

\\

下图为C++ API的运算架构:在模型训练的每次迭代中,通过C++ API读取Batch Data后,直接触发模型训练。减少了不同语言间API接口的循环调用及数据传输。如下图所示:

\\

d8a105a3c17575654104474dd6e839a6.jpg

\\

为了采用C++ API进行模型训练,我们首先需要编写训练模型,这个编写过程可以采用Python语言来完成。我们首先采用Python API编写训练模型,然后把图模型转换为Protobuf的序列化文件。接着通过C++ API加载该模型文件,创建TensorFlow Session,初始化模型变量,以及加载训练数据并执行神经网络训练。程序架构如下图所示:

\\

f85468a001bab49b17e9bb1eb8cdf463.jpg

\\

下面为使用Python API定义训练模型的示例:

\\

with tf.Session() as sess:

\\
\#定义Placeholder Tensor接入训练数据\    x = tf.placeholder(tf.float32, [None, 32], name=\"x\")\    y = tf.placeholder(tf.float32, [None, 8], name=\"y\")\\    #定义训练模型\    w1 = tf.Variable(tf.truncated_normal([32, 16], stddev=0.1))\    b1 = tf.Variable(tf.constant(0.0, shape=[16]))\    w2 = tf.Variable(tf.truncated_normal([16, 8], stddev=0.1))\    b2 = tf.Variable(tf.constant(0.0, shape=[8]))\    a = tf.nn.tanh(tf.nn.bias_add(tf.matmul(x, w1), b1))\    y_out = tf.nn.tanh(tf.nn.bias_add(tf.matmul(a, w2), b2), name=\"y_out\")\    cost = tf.reduce_sum(tf.square(y-y_out), name=\"cost\")\    optimizer = tf.train.AdamOptimizer().minimize(cost, name=\"train\")\\    #定义变量初始化操作\    init = tf.initialize_variables(tf.all_variables(), name='init_all_vars_op')\\    #把图模型转换为Protobuf文件\tf.train.write_graph(sess.graph_def, './', 'mlp.pb', as_text=False)
\\

下面为使用C++ API加载Protobuf图模型,并执行训练的示例:

\\
\#include \"tensorflow/core/public/session.h\"\#include \"tensorflow/core/graph/default_device.h\"\using namespace tensorflow;\\int main(int argc, char* argv[]) {\    //Protobuf模型文件名\    std::string graph_definition = \"mlp.pb\";\    //Tensorflow Sesssion\    Session* session;\\    //定义图模型对象\    GraphDef graph_def;\    SessionOptions opts;\\    //存储Session会话的运行结果\    std::vector\u0026lt;Tensor\u0026gt; outputs; \\    #加载Protobuf模型文件到图模型对象中\    TF_CHECK_OK(ReadBinaryProto(Env::Default(), graph_definition, \u0026amp;graph_def));\\    // 默认在gpu 0上执行模型的训练操作\    graph::SetDefaultDevice(\"/gpu:0\
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值