前一篇文章我们分析了xdl的稀疏API embedding的实现。同时也发现了一些的新的问题,首先来回顾一下。

embedding接口在模型中创建几类Op:Variable Op, 参数拉取op, Combiner Op; embedding接口相关的几个Op都继承于XDL自己定义的OpKernel,包括PsRegisterVariableOp, PsSparsePullOp, PsPullOp。我们知道,tensorflow的模型graph,只能包含继承于tensorflow Op的Op。那么embedding接口引入的这几个Op是如何与tensorflow的Op一起组成模型的呢?

并且,同时通过阅读源码(代码位置:xdl/xdl/core/)发现,xdl自己实现了一套新的runtime framework,包括graph, device, op, executor,tensor等等核心类的定义。对tensorflow的核心概念都有自己的一套实现。那么这套新的runtime framework与tensorflow如何一起工作的呢?

首先先看一下完整的XDL例子

样例

例子来自于xdl自带的example(代码位置:xdl/examples/deepctr/deepctr.py)

def train():...## 省略掉了数据加载部分. 注意emb1和emb2为xdl op,具体为PsSparsePullOpemb1 = xdl.embedding('emb1', batch['sparse0'], xdl.TruncatedNormal(stddev=0.001), 8, 1024, vtype='hash')emb2 = xdl.embedding('emb2', batch['sparse1'], xdl.TruncatedNormal(stddev=0.001), 8, 1024, vtype='hash')## loss, train_op 均为xdl oploss = model(batch['deep0'], [emb1, emb2], batch['label'])train_op = xdl.SGD(0.5).optimize()log_hook = xdl.LoggerHook(loss, "loss:{0}", 10)sess = xdl.TrainSession(hooks=[log_hook])while not sess.should_stop():sess.run(train_op)@xdl.tf_wrapper()
def model(deep, embeddings, labels):## input 为tensorflow concat op, 这里有个问题,model函数的输入## deep, embedding, labels均为xdl op, 为什么可以直接作为tensorflow## concat op的输入呢 ? input = tf.concat([deep] + embeddings, 1)## fc1, fc2, fc3, y 均为tensorflow op, 并且这些全连接网络层## 会引入模型参数,这些参数是如果交由xdl的参数服务器管理的呢?并## 没有看到显示的调用xdl api分配这些dense的参数。fc1 = tf.layers.dense(input, 128, kernel_initializer=tf.truncated_normal_initializer(stddev=0.001, dtype=tf.float32))fc2 = tf.layers.dense(fc1, 64, kernel_initializer=tf.truncated_normal_initializer(stddev=0.001, dtype=tf.float32))fc3 = tf.layers.dense(fc2, 32, kernel_initializer=tf.truncated_normal_initializer(stddev=0.001, dtype=tf.float32))y = tf.layers.dense(fc3, 1, kernel_initializer=tf.truncated_normal_initializer(stddev=0.001, dtype=tf.float32))## loss也是tensorflow的op, 为什么上面说model返回的是xdl op呢?## 上面函数train_op是xdl op,它是如果做参数训练的呢 ?loss = tf.losses.sigmoid_cross_entropy(labels, y)return loss

将上面的问题罗列一下:

  • xdl op为什么可以直接作为tensorflow concat op的输入
  • tf.layers.dense全连接网络的参数,如果分配到xdl的参数服务器的
  • loss是tensorflow op, 为什么说model返回的是xdl op

回答这些问题的关键点在于:

  • 装饰器xdl.tf_wrapper(代码位置:xdl/xdl/python/backend/tf/tf_backend.py)
  • hook函数get_variable(代码位置:xdl/xdl/python/backend/tf/tf_hook.py)
  • xdl backend op: TFBackendOp(代码位置:xdl/xdl/core/backend/tf/backend_op.cc)

装饰器xdl.tf_wrapper

python装饰器语法不是本文的重点,不熟悉的读者可以找相关文档了解一下。直接介绍xdl.tf_wrapper的作用

  • 为被装饰的函数(比如example中的model函数)的输入(一般为xdl op),生成对应的tensorflow placeholder op
  • 调用被装饰的函数,并传入原始输入对应的placeholder op,被装饰函数一般用来构建tensorflow graph,但此时被装饰函数的输入已经有从xdl op 换成了相对应的tensorflow placeholder了
  • 被装饰函数创建的tensorflow graph,以及原始输入,都会成为xdl TFBackendOp的输入, xdl TFBackendOp会加入到xdl graph
  • 目前为止,xdl graph中有了embedding相关的op, 以及TFBackendOp,接下来xdl session会驱动xdl graph的运行

hook函数get_variable

被装饰函数(比如example中的model函数)在构建tensorflow网络的时候,一般是模型的dense部分,同样也会申请tensorflow variable,这些variable同样需要放到xdl的参数服务器上管理,但是被装饰函数里并没有显示的调用xdl的参数分配函数,这是怎么做到的呢?

答案是xdl hook了tensorflow的api tf.get_variable,替换为xdl自己实现的get_variable函数。

xdl在的自己实现的get_variable函数内

  • 首先调用原始的tensorflow get_variable函数,添加tensorflow variable op到tensorflow graph
  • 然后为刚添加的tensorflow variable op, 在xdl graph里添加一个对应的xdl variable op并作为TFBackendOp的输入

TFBackendOp

TFBackendOp负责驱动tensorflow graph的执行,也就是说整个tensorflow graph都将以TFBaclendOp的形式,参与xdl graph的执行。

TFBackendOp是连接xdl graph与tensorflow graph的关键,从tensor流动角度分析:

  • 从xdl graph到tensorflow graph的tensor,都将作为TFBackendOp的input;比如前面添加的tensorflow placeholder, tensorflow variable的填充值,都将通过TFBackendOp的input传入
  • 从tensorflow graph到xdl graph的tensor,都将作为TFBackendOp的output

总结

至此,我们大致理解了XDL的运行机制

  • XDL有自己的独立的framework,XDL API创建的是XDL Graph,添加的是XDL Op,并由XDL Session驱动运行
  • Tensorflow API创建的是tensorflow graph, 添加的的是tensorflow op, 由XDL TFBackendOp调用tensorflow session驱动执行
  • TFBackendOp是连接两个Graph的桥梁,Tensor正式通过这个桥梁在Graph间流动的

深入浅出XDL(三):framework相关推荐

  1. (转)[Cocoa]深入浅出 Cocoa 之 Framework

    [Cocoa]深入浅出 Cocoa 之 Framework 罗朝辉(http://blog.csdn.net/kesalin/) CC许可,转载请注明出处 Framework 简介 Mac OS X ...

  2. 深入浅出XDL(四):模型训练

    上一篇我们分析了XDL的framework的架构设计,了解了XDL的模型构建和运行机制,以及XDL如何将tensorflow作为自己的backend. 本篇继续分析XDL的架构设计,重点关注XDL的参 ...

  3. 深入浅出XDL(二):embedding

    XDL(X-DeepLearning)是阿里巴巴开源的一款深度学习框架.官方介绍,此框架针对广告.推荐.搜索的场景做了很多优化. 广告.推荐和搜索的模型,一个重要的特点是存在大量的稀疏特征,为此xdl ...

  4. python数列求和-加强版_ES6深入浅出-3 三个点运算 新版字符串-1.函数与对象的语法糖...

    主要讲的内容 时间充裕的话就讲,模板字面量 默认参数值 首先讲es6之前,我们是怎么做的.例如我们要写一个求和的函数, 请两个参数的和,但是如果有的人就是穿一个参数呢? 那么b没有传值,b的值是多少呢 ...

  5. CSS深入浅出(三)

    一.表单美化 百度搜索框 上传图片 美化按钮 二.Bootstrap Bootstrap引入 https://getbootstrap.com/ http://www.bootcss.com 生产环境 ...

  6. 深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例

    第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入 ...

  7. 深入浅出XDL(一):Blaze推理引擎

    Blaze是阿里巴巴开源的一款深度学习推理引擎,官方介绍,它是一款面向广告/搜索/推荐场景的高性能深度学习推理引擎.本文对blaze的源码进行简单的分析. 内核源码目录结构 Blaze的内核采用c++ ...

  8. 深入浅出TCP三次握手四次挥手

    每每想起TCP三次握手这个问题,就会陷入如下的困惑: var forget = ? while(forget) {百度/Google } 而重点在于forget永远等于true,无情的消耗着我这颗只有 ...

  9. 深入浅出JMS(三)–ActiveMQ简单的HelloWorld实例(转载)

    第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入 ...

最新文章

  1. 关于OSD::mkfs: ObjectStore::mkfs failed with error (5) Input/output error问题的解决
  2. 习题4-11 兔子繁衍问题 (15 分)
  3. hdu 2612(bfs)Find a way
  4. Fibonacci Knapsack
  5. VS2010如何在编辑器自动换行
  6. 1英寸大底手机来了 是索尼的营销噱头吗?
  7. C++STL笔记(X):栏位宽度、填充字符、位置调整
  8. Thinkphp if标签不支持3层以上嵌套
  9. 七月算法机器学习3 矩阵分析与应用
  10. 计算机组成原理期末复习【超实用】
  11. 二、云计算-私有云-国产-华为-FusionCloud+HCIE Cloud相关知识点+笔试题库
  12. 因为制作爬虫程序,我收到了警告
  13. CCF计算机职业资格认证考试201403-2“窗口”试题及答案
  14. gerrit常见问题及解决方法
  15. go import 导入包名前加下划线 _
  16. 云计算概念简述(讲解)
  17. 2142. The Number of Passengers in Each Bus I
  18. 超级详细的vue2学习笔记
  19. openstack上传镜像
  20. 【Linux】基本指令(下)

热门文章

  1. python保存plot图片_Matplotlib savefig只保存图像,不保存行
  2. 如何安装Jenkins
  3. 美国Disqus、国内JiaThis、友言、评论啦、搜狐畅言 评论系统(第三方评论系统)
  4. GB2312汉字区位码、交换码和机内码
  5. 一位非IT人士的见血封喉 SCM与ERP的异同和尴尬(1)
  6. 流体力学基本流动复势推导
  7. stm32f407探索者开发板资料
  8. session实现用户登陆功能
  9. html前端小知识:制作简单的纯文字图标按钮
  10. 软件体系结构设计模式