共计 2375 个字符,预计需要花费 6 分钟才能阅读完成。
问题
在做推荐系统做分布式训练,面临的经典问题应该就是以下两个问题:
- 高维稀疏数据存储问题
- 在做推荐相关的工作,尤其是模型这块,ps应该是最常被提起的一个东西。推荐系统一个典型的现象就是高维稀疏数据,产生这些的稀疏数据的原因就在于庞大的用户体量、物料体量。对于一个日活上亿的应用,你要去跑模型,对用户id建模,从常规的构建embedding 矩阵,如果只是单机服务,肯定是装不下这么大的数据量。为了解决这个问题,ps就应运而生。
- 分布式训练参数更新问题
- 按照常规的分布式训练,从master将所有的网络参数同步到slave节点网络带宽消耗太大,这块是直接影响到性能。
当然这两个问题可能在现有的大环境下已经被解决掉了,因为这是基础架构的一部分,大部分公司在做基建的时候就已经搞定了这些问题,所以说只从使用的角度来看,那其实不是个问题。
那么现在为什么还要提出这个问题?核心的点就是知其所以然,但是并不是完全的。如果涉及到ps调参其实是有必要了解ps的内部原理机制。
如何解决?
既然这篇文章是讲ps的,那么解决方案肯定是ps方案了。
概念
ps全称是 parameter service(参数服务器),也可以理解为一个“数据库”(kv数据库),你给一个id,我给你返回 embedding ,那么可以理解key 就是id,value 就是embedding。当然不单单是存储数据,尤其是反向传播参数更新之类的都有。具体是怎么运作的可以继续往下看。
ps是如何运作?
再稍微具体一点,基于Parameter Server的训练流程如下图所示:
- 系统中主要有两大类节点
-
- Work节点,负责读取本地的局部训练数据,计算梯度
- Server节点,负责存储局部的参数空间,响应worker请求,对自己负责的局部参数进行读写。
-
[Worker] 训练时,每个worker先归纳一下当前batch需要涉及到哪些feature_id。
-
- 观察图中的x,其所在行代表样本,其所在列代表feature_id,可以发现训练数据的确是非常稀疏的。
- 因此一个batch所涵盖的特征相对于整个特征空间,仍然是十分渺小的。
-
[Worker] 每个worker向整个ps server集群请求“当前batch涵盖的feature”的最新参数(e.g., 一阶权重或embedding)。即图中的Pull。
-
[Server] 因为每台ps server只拥有一部分feature的参数,所以尽管图中没有表现,但是中间会有一个路由机制,将worker的请求拆分、路由到合适的ps server上。
-
[Server] 收到“拉数据”请求的ps server,从本地存储中找到这些feature_id的最新参数,回复。
-
[Worker] 收到ps server发送回来的各feature的最新参数,worker就可以在当前batch的数据上进行前代+回代,得到这些feature上的梯度。
-
[Worker] Worker将计算好的梯度发往Server,即图中的Push。
-
[Server] 接到worker发来的梯度后,Server汇总聚合梯度,再用各种SGD的变体(e.g., FTRL、Adam、Adagrad等)更新本地参数。
问题解答
- 如何处理高维稀疏数据?—-因为是分布式ps,可以将数据按块划分,后续会讲这些数据怎么存储,简单的方式就是有多少个节点,总的数据量处以节点数,就是每个机器上的存储的数据量
- 数据同步的问题?—-这里的数据同步主要就是worker 向sever传递梯度以及拉取embedding和权重参数
解决方案实现:ps-lite
这个标题其实算是标题党,现在成熟的ps架构肯定比这个更完善。ps-lite,故名思义是一个轻量版本,它会给出核心的骨架,有一点麻雀虽小五脏俱全的感觉,当然对我来说是有一个学习ps内部原理的机会。
三种节点类型
在使用SGD进行训练的场景下:
- worker:从server pull最新的待优化参数,读本地数据,计算出梯度,向server push梯度
-
server: 其实就是一个key/value数据库,
-
- 应对pull请求,将worker请求的参数的最新值发送回去
- 应对push请求,聚合各worker发送过来的gradient,再利用各种SGD的变体(e.g., Adam,Adagrad)更新weight
-
scheduler: 一个系统中只有一个scheduler节点,主要负责
-
- 其他server/worker节点的管理:有节点加入或退出时,都需要将本集群内最新的节点名单广播给群内的所有节点
- 多节点之间的数据同步:统计有多少节点已经运行了到“同步”点;如果所有节点都“到齐”了,向所有参与节点的节点发“解除阻塞”的信息
五个重要数据类型
-
PostOffice: 每个进程(无论scheduler/worker/server),有且只有一个“邮局”,是该进程的消息集散中心。它掌管着在它那里等消息的“顾客”的名单。 |
-
Van:每个邮局只有一辆“邮车”,负责收发信件的具体工作。派发信件时,Van通过PostOffice的名单,找到某个“顾客”,将信件交到他手上。 |
-
Customer:邮局的顾客,其实就是个中介。worker和server为了更好地专心业务工作,将“在邮局排队等消息”的工作外包给了“顾客”。Customer从Van手中接过信件后,转手就交给它的顾主,worker或server。
-
Worker:Customer的顾主,训练时主要负责处理样本、计算梯度等工作。
-
Server:Customer的顾主,训练时主要负责接收梯度,汇总梯度(同步模式下),更新权重等工作。
将上述的点用一张图来表示,大概如下图所示
总结
- 了解ps解决了什么问题
- 了解ps运作的方式
- ps-lite的重要组成
附录:
- https://zhuanlan.zhihu.com/p/467650462