ps-lite框架是DMLC組自行實現的parameter server通訊框架,是DMLC其餘項目的核心,例如其深度學習框架MXNET的分佈式訓練就依賴ps-lite的實現。html
在機器學習和深度學習領域,分佈式的優化已經成了一種先決條件,由於單機已經解決不了目前快速增加的數據與參數帶來的問題。現實中,訓練數據的數量可能達到1TB到1PB之間,而訓練過程當中的參數可能會達到\(10^9\)到\(10^{12}\)。而每每這些模型的參數須要被全部的worker節點頻繁的訪問,這就會帶來不少問題和挑戰:node
在parameter server中,每一個 server 實際上都只負責分到的部分參數(servers共同維持一個全局的共享參數),而每一個 work 也只分到部分數據和處理任務。算法
PS架構包括計算資源與機器學習算法兩個部分。其中計算資源分爲兩個部分,參數服務器節點和工做節點:編程
機器學習算法也分紅兩個部分,即參數和訓練:bash
這種設計有兩種好處:服務器
從而,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<int, void*> senders_保存了node_id到鏈接的映射。Van只是定義了接口,具體實現是依賴ZMQ實現的ZMQVan,Van類負責創建起節點之間的互相鏈接(例如Worker與Scheduler之間的鏈接),而且開啓本地的receiving thread用來監聽收到的message。。
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