如果关注这个领域的同学可能知道,Ray其实在去年就已经在开源社区正式发布了,只不过后来就一直没有什么太大动静,前段时间也是因为机缘巧合,我又回头学习了解了一下,顺便总结如下:
Ray是什么?
Ray 是RISELab实验室(前身也就是开发Spark/Mesos等的AMPLab实验室)针对机器学习领域开发的一种新的分布式计算框架。按照官方的定义:“Ray is a flexible, high-performance distributed execution framework”。看起来很明确的定义对吧,不过所谓的:“灵活的高性能的分布式执行框架”,这句话无论是哪个分布式计算框架,大概都会往自己身上套。那么Ray的不同之处在哪里呢?当Spark/Flink/TensorFlow等一众计算框架在机器学习领域中不断开疆扩土,风头正劲的时候,为什么RISELab的同学们又要另起炉灶,再发明一个新的轮子呢?
这个问题的答案和其他发明轮子的同学的说法也很类似:因为既有的系统不满足某种需求。那么这种需求是真需求还是伪需求,如果是真需求,既有的系统不能满足的原因是暂时的,可以改进的,不关本质的具体实现问题,还是由于根源上的架构和方案的局限性所决定的呢?下面就让我来现学现卖,分析讨论一下。
目标问题
Ray的目标问题,主要是在类似增强学习这样的场景中所遇到的工程问题。那么增强学习的场景和普通的机器学习,深度学习的场景又有什么不同呢?简单来说,就是对整个处理链路流程的时效性和灵活性有更高的要求。
增强学习的场景,按照原理定义,因为没有预先可用的静态标签信息,所以通常需要引入实际的目标系统(为了加快训练,往往是目标系统的模拟环境)来获取反馈信息,用做损失/收益判断,进而完成整个训练过程的闭环反馈。典型的步骤是通过观察特定目标系统的状态,收集反馈信息,判断收益,用这些信息来调整参数,训练模型,并根据新的训练结果产出可用于调整目标系统的行为Action,输出到目标系统,进而影响目标系统状态变化,完成闭环,如此反复迭代,最终目标是追求某种收益的最大化(比如对AlphoGo来说,收益是赢得一盘围棋的比赛)。
在这个过程中,一方面,模拟目标系统,收集状态和反馈信息,判断收益,训练参数,生成Action等等行为可能涉及大量的任务和计算(为了选择最佳Action,可能要并发模拟众多可能的行为)。而这些行为本身可能也是千差万别的异构的任务,任务执行的时间也可能长短不一,执行过程有些可能要求同步,也有些可能更适合异步。
另一方面,整个任务流程的DAG图也可能是动态变化的,系统往往可能需要根据前一个环节的结果,调整下一个环节的行为参数或者流程。这种调整,可能是目标系统的需要(比如在自动驾驶过程中遇到行人了,那么我们可能需要模拟计算刹车的距离来判断该采取的行动是刹车还是拐弯,而平时可能不需要这个环节),也可能是增强学习特定训练算法的需要(比如根据多个并行训练的模型的当前收益,调整模型超参数,替换模型等等)。
此外,由于所涉及到的目标系统可能是具体的,现实物理世界中的系统,所以对时效性也可能是有强要求的。举个例子,比如你想要实现的系统是用来控制机器人行走,或者是用来打视频游戏的。那么整个闭环反馈流程就需要在特定的时间限制内完成(比如毫秒级别)。
总结来说,就是增强学习的场景,对分布式计算框架的任务调度延迟,吞吐量和动态修改DAG图的能力都可能有很高的要求。按照官方的设计目标,Ray需要支持异构计算任务,动态计算链路,毫秒级别延迟和每秒调度百万级别任务的能力。
那么现有的框架,真的不能满足这种场景的需求么?
从上面提到的目标问题来看,需求在对应的场景下是真需求应该问题不大。但现有的框架,通过适当的改进,真的满足不了这些需求么?以下我们主要结合Spark/Flink/TensorFlow等常见的当红分布式计算框架来讨论一下这些问题,也算是为Ray的方案选择再做一下理论和背景铺垫。
海量任务调度能力
首先来看每秒百万级别任务调度的能力,上述三种计算框架,基本采用的是中心集中式的任务调度机制,在作业任务调度的角色集中在单个中心节点的情况下,单个作业要实现每秒百万级别任务的调度能力,的确是不太现实的。
但问题未必只有一种解决方式,如果不能实现百万级别的