Angel的设计理念,从一开始就围绕机器学习和模型
。整体上的接口崇尚简约,利用Parameter Server的本质来支持高维度的模型。Angel的主要核心抽象是PSModel
,它将对分布于多台PS Server上的远程模型
操作透明化。通过PSModel,用户可以方便的进行模型的更新,自定义函数计算,以及同步控制,从而实现各种高效的机器学习算法。
在Angel中,模型
是一等公民,在Angel中实现一个算法,可以很直白的,从Model Base的思路,来考虑要怎么样设计。
值得留意的是,PSModel是分布式可变的,这种可变性是线程安全,也是对用户透明的。这是Angel和Spark最大的区别,也是它的优势所在。
PSModel(远程模型)
PSModel是Angel的核心抽象。它是一个远程模型的概念,对于Client来说,它是一个类似模型代理
的类。通过它,你可以在每个Worker上,像操作本地对象一样的,去操作一个模型,而实际上,你在操作的是,一个均匀切分在远程多个PSServer上的分布式模型切片,而且所有的操作都是透明并发的。
所以,实现一个算法的最小集,需要定义一个PSModel,例如:
val loss = PSModel[DenseDoubleVector]("lr_loss_martrix", 1, epochNum)
MLModel(模型集)
很多复杂的算法,光一个模型是不够的,需要多个模型一起运作,这时我们需要一个类,来对这些模型进行统一操作。
例如在GBDT中,我们定义了多个PSModel,并添加到MLModel中
addPSModel(SKETCH_MAT, sketch)
addPSModel(FEAT_SAMPLE_MAT, featSample)
addPSModel(SPLIT_FEAT_MAT, splitFeat)
…………
整体性的操作,包括predict,setSavePath……都统一通过MLModel进行。但是算法对远程模型的具体操作,都是通过PSModel来进行
所有的算法都需要一个启动类,在Angel中,启动类需要继承MLRunner,并实现train和predict两个方法
最简单的Runner,使用标准流程的话,非常的简单:
- train方法
train(conf: Configuration)
- predict方法
predict(predict(conf: Configuration))
很遗憾,在最后,我们还需要编写两个任务类,有点类似Hadoop
的Mapper
和Reducer
,当然了,它们本质上是完全不同的,但是作用类似,都是将任务封装好,传给远程的Worker去分布式启动和执行。
Angel的这两个Task中,都是BaseTask的子类,Angel会负责透明的数据切分和读取,并Feed给这些Task类,用户需要定义的,其实主要是2个公共操作:
-
解析数据(parse)
- 将单行数据解析为算法所需的数据结构(例如用于LR/SVM等算法的LabeledData)
- 没有默认实现,必须实现
-
预处理(preProcess)
- 读取原始数据集,按行调用parse方法,将数据进行简单预处理,需要的话,切换训练集(Training Set)和 检验集(Validation Set)
- 有默认实现,可以不实现
当然了,TrainTask需要实现train方法,PredictTask需要实现predict方法,这些都有默认的实现,具体Task需要做的,其实只是把MLModel创建好,传递给父类方法就好。
Angel本身的算法编写,接口略微简朴。但是这种方式,可以让Angel更加Focus在并提升机器学习算法性能,而无需过多关注其它事情。
但是有些用户希望更加灵活的写法,或者他们希望Spark也能基于Angel获得高维度模型的训练能力。为此在Spark on Angel上,也可以有体现和支持。具体可以查看:《Spark on Angel 编程指南》