机器学习系统


机器学习系统的演进 神经网络模型构建细节 神经网络基类抽象方法

计算图

  • 为了兼顾编程的灵活性和计算的高效性,设计了基于计算图的深度学习框架。
  • 计算图的基本数据结构是张量,基本运算单元是算子。
  • 计算图可以表示机器学习模型的计算逻辑和状态,利用计算图分析图结构并进行优化。
  • 计算图是一个有向无环图,图中算子间可以存在直接依赖和间接依赖关系,或者相互关系独立,但不可以出现循环依赖关系。
  • 可以利用控制流来改变数据在计算图中的流向,常用的控制流包括条件控制和循环控制。
  • 计算图的生成可以分为静态生成和动态生成两种方式。
  • 静态图计算效率高,内存使用效率高,但调试性能较差,可以直接用于模型部署。
  • 动态图提供灵活的可编程性和可调试性,可实时得到计算结果,在模型调优与算法改进迭代方面具有优势。
  • 利用计算图和算子间依赖关系可以解决模型中的算子执行调度问题。
  • 根据计算图可以找到相互独立的算子进行并发调度,提高计算的并行性。而存在依赖关系的算子则必须依次调度执行。
  • 计算图的训练任务可以使用同步或者异步机制,异步能够有效提高硬件使用率,缩短训练时间。

动态图与静态图的转换和融合

基于追踪转换

  • 优势:原理相对简单,当使用动态图模式构建好网络后,使用追踪(Tracing)进行转换将分为两个阶段。第一个阶段计算框架会创建一个新的计算图,此时以动态图模式执行代码,计算框架会自动追踪数据流的流动以及算子的调度,将所有的操作捕获并根据调度顺序构建静态图模型。第二个阶段,当执行完一次动态图后,计算框架已生成静态图,当再次调用相同的模型时,计算框架会自动指向静态图模型,以高效的性能执行计算。
  • 问题:追踪技术只是记录第一次执行动态图时调度的算子,但若是模型中存在依赖于中间结果的条件分支控制流,只能追踪到根据第一次执行时触发的分支。此时构建的静态图模型并不是完整的,缺失了数据未流向的其他分支。在后续的调用中,因为静态模型已无法再改变,若计算过程中数据流向缺失分支会导致模型运行错误。同样的,依赖于中间数据结果的循环控制也无法追踪到全部的迭代状态。

基于源码转换

  • 动静代码差异:动态图基于前端语言自身的解释器进行模型代码的解析执行。比如当Python作为前端语言,采取原生Python边运行边解释的特性,配合框架提供的数据处理/算子分发的功能计算,即可实现动态图的即时执行特性。而且静态图则采用计算框架自带的图编译器,对神经网络模型进行建图后,再调用图结构进行计算。动态图代码与静态图代码之间存在差异,不能直接使用静态图编译器,因此基于源码转换的方法需要将动态图代码转换为静态图代码描述。
    基于源码转换的方式则能够改善基于追踪转换的缺陷。
  • 第一个阶段,对动态图模式下的代码扫描进行词法分析,通过词法分析器分析源代码中的所有字符,对代码进行分割并移除空白符、注释等,将所有的单词或字符都转化成符合规范的语法单元列表。接着进行语法分析即解析器,将得到的语法单元列表转换成树形式,并对语法进行检查避免错误。
  • 第二阶段,动态图转静态图的核心部分就是对抽象语法树进行转写,计算框架中对每一个需要转换的语法都预设有转换器,每一个转换器对语法树进行扫描改写,将动态图代码语法映射为静态图代码语法。其中最为重要的前端语言控制流,会在这一阶段分析转换为静态图接口进行实现。转写完毕之后,将新的语法树再还原回静态图代码,就可以使用静态生成执行。使用该方式可以避免基于追踪转换中控制流表达缺失的情况。

计算图调度

  • 通过拓扑排序的方式得到算子的执行顺序
  • 对于没有依赖关系的算子,可以并行执行

文章作者: 万川
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 万川 !
  目录