标签:开始 进一步 red 很多 async 绑定 建立 star shared
ps-lite框架是DMLC组自行实现的parameter server通信框架,是DMLC其他项目的核心,例如其深度学习框架MXNET的分布式训练就依赖ps-lite的实现。
在机器学习和深度学习领域,分布式的优化已经成了一种先决条件,因为单机已经解决不了目前快速增长的数据与参数带来的问题。现实中,训练数据的数量可能达到1TB到1PB之间,而训练过程中的参数可能会达到\(10^9\)到\(10^{12}\)。而往往这些模型的参数需要被所有的worker节点频繁的访问,这就会带来很多问题和挑战:
在parameter server中,每个 server 实际上都只负责分到的部分参数(servers共同维持一个全局的共享参数),而每个 work 也只分到部分数据和处理任务。
PS架构包括计算资源与机器学习算法两个部分。其中计算资源分为两个部分,参数服务器节点和工作节点:
机器学习算法也分成两个部分,即参数和训练:
这种设计有两种好处:
从而,PS架构有五个特点:
在parameter server中,参数都是可以被表示成(key, value)的集合,比如一个最小化损失函数的问题,key就是feature ID,而value就是它的权值。对于稀疏参数,不存在的key,就可以认为是0。
把参数表示成k-v, 形式更自然, 易于理,更易于编程解。workers跟servers之间通过push与pull来通信的。worker通过push将计算好的梯度发送到server,然后通过pull从server更新参数。为了提高计算性能和带宽效率,parameter server允许用户使用Range Push跟Range Pull 操作。
Task也分为同步和异步,区别如下图所示:
所以,系统性能跟算法收敛速率之间是存在一个平衡,你需要同时考虑:
考虑到用户使用的时候会有不同的情况,parameter server 为用户提供了多种任务依赖方式:
算法1是没有经过优化的直接算法和它的流程图如下:
算法3中的KKT Filter可以是用户自定义过滤:
对于机器学习优化问题比如梯度下降来说,并不是每次计算的梯度对于最终优化都是有价值的,用户可以通过自定义的规则过滤一些不必要的传送,再进一步压缩带宽消耗:
上面说了parameter server的原理,现在来看下这个是怎么实现的。ps-lite是DMLC实现parameter server的一个程序,也是MXNet的核心组件之一。
ps-lite包含三种角色:Worker、Server、Scheduler。具体关系如下图:
图9 三种角色的关系图
Worker节点负责计算参数,并发参数push到Server,同时从Serverpull参数回来。
Server节点负责管理Worker节点发送来的参数,并“合并”,之后供各个Worker使用。
Scheduler节点负责管理Worker节点和Server节点的状态,worker与server之间的连接是通过Scheduler的。
Postoffice是全局管理类,单例模式创建。主要用来配置当前node的一些信息,例如当前node是哪种类型(server,worker,scheduler),nodeid是啥,以及worker/server 的rank 到 node id的转换。
Van是负责通信的类,是Postoffice的成员。Van中std::unordered_map
Customer用来通信,跟踪request和response。每一个连接对应一个Customer实例,连接对方的id和Customer实例的id相同。
SimpleApp是一个基类;提供了发送接收int型的head和string型的body消息,以及注册消息处理函数。它有2个派生类。
KVServer是SimpleApp的派生类,用来保存key-values数据。里面的Process()被注册到Customer对象中,当Customer对象的receiving thread接受到消息时,就调用Process()对数据进行处理。
KVWorker是SimpleApp的派生类,主要有Push()和Pull(),它们最后都会调用Send()函数,Send()对KVPairs进行切分,因为每个Server只保留一部分参数,因此切分后的SlicedKVpairs就会被发送给不同的Server。切分函数可以由用户自行重写,默认为DefaultSlicer,每个SlicedKVPairs被包装成Message对象,然后用van::send()发送。
KVPairs封装了Key-Value结构,还包含了一个长度选项。
SArray是Shared array,像智能指针一样共享数据,接口类似vector。
Node封装了节点的信息,例如角色、ip、端口、是否是恢复节点。
Control封装了控制信息,例如命令类型、目的节点、barrier_group的id、签名。
Meta封装了元数据,发送者、接受者、时间戳、请求还是相应等。
Message是要发送的信息,除了元数据外,还包括发送的数据。
为了更好地看到ps-lite的运行原理,我们先来看下它在本地运行的脚本:
#!/bin/bash
# set -x
if [ $# -lt 3 ]; then
echo "usage: $0 num_servers num_workers bin [args..]"
exit -1;
fi
export DMLC_NUM_SERVER=$1
shift
export DMLC_NUM_WORKER=$1
shift
bin=$1
shift
arg="$@"
# start the scheduler
export DMLC_PS_ROOT_URI='127.0.0.1'
export DMLC_PS_ROOT_PORT=8000
export DMLC_ROLE='scheduler'
${bin} ${arg} &
# start servers
export DMLC_ROLE='server'
for ((i=0; i<${DMLC_NUM_SERVER}; ++i)); do
export HEAPPROFILE=./S${i}
${bin} ${arg} &
done
# start workers
export DMLC_ROLE='worker'
for ((i=0; i<${DMLC_NUM_WORKER}; ++i)); do
export HEAPPROFILE=./W${i}
${bin} ${arg} &
done
wait
这个脚本主要做了两件事,第一件是为不同的角色设置环境变量,第二件是在本地运行多个不同的角色。所以说ps-lite是要多个不同的进程(程序)共同合作完成工作的,ps-lite采取的是用环境变量来设置角色的配置。
test_simple_app.cc是一人很简单的app,其它复杂的流程原理这个程序差不多,所以我们就说说这个程序是怎么运行的。先来看下刚开始运行程序时,worker(W)\Server(S)\Scheduler(H)之间是怎么连接的,这里没有写Customer处理普通信息的流程。W\S\H代表上面脚本运行各个角色后在不同角色程序内的处理流程。
Customer处理普通信息流程如下:
参考引用:
[1] http://blog.csdn.net/stdcoutzyx/article/details/51241868
[2] http://blog.csdn.net/cyh_24/article/details/50545780
[3] https://www.zybuluo.com/Dounm/note/529299
[4] http://blog.csdn.net/KangRoger/article/details/73307685
【防止爬虫转载而导致的格式问题——链接】:
http://www.cnblogs.com/heguanyou/p/7868596.html
MXNet之ps-lite及parameter server原理
标签:开始 进一步 red 很多 async 绑定 建立 star shared
原文地址:http://www.cnblogs.com/heguanyou/p/7868596.html