【分散式計算】MapReduce的替代者-Parameter Server

李博Garvin發表於2015-07-13

首先還是要宣告一下,這個文章是我在入職阿里雲1個月以來,對於分散式計算的一點膚淺的認識,可能有些地方不夠妥善,還請看官可以指出不足的地方,共同進步。

一.背景

隨著網際網路的發展,資料量的增大,很多對於資料的處理工作(例如一些推薦系統、廣告推送等)都遷移到了雲端,也就是分散式計算系統上。衍生了很多牛逼的分散式計算的計算模型,比較著名的就是MapReduce、MPI、BSP等。後來也產生了一些分散式計算系統,大家耳熟能詳的Hadoop就是基於MapReduce實現的。

本文的主人公是Parameter Server,其實也不算是新寵了,這個模型已經被提出好幾年了,只不過在國內還不是特別熱。不過最近一些雲服務巨頭們開始了對於PS的深入開發和研究。

引用一位演算法大神的話簡單描述下什麼事Parameter Server:總結是一種計算模型SSP+一種分散式設計看板模式Client+Server(partitioned table)+基於演算法的排程策略(Scheduler)。可能有些同學還不太理解這句話,沒關係,下面通過一個例項來介紹一下PS。

二.場景

因為我在學習PS的過程中是對照Map Reduce來學習的。所以也通過一個機器學習演算法的平行計算的例項,來比較Map Reduce和PS。為了更好地突出PS的優勢,這裡用到的演算法是一個梯度逼近最佳結果的一種演算法-邏輯迴歸(Logical Regression)。

為了更好地幫大家理解這些內容,我也羅列了一些必須的知識儲備:
1.邏輯迴歸演算法-最好fork裡面的程式碼看一下
2.隨機梯度下降SGD
3.李沐大神實現的一個PS開源庫,上面有一個論文,一定要讀
4.並行邏輯迴歸-等會會借用裡面的內容來講
5.ps開原始碼網站

三.Work Flow

首先還是要補充幾句,Map-Reduce在實現並行演算法的過程中有它的優勢,但是也有很大的弊端,它在處理梯度問題上沒有很好的效率。這一點PS通過client+server的模式很好的解決了這個問題。


1.Map-Reduce處理LR

首先來看下Map-Reduce是如何解決邏輯迴歸(下文統一稱為LR)的。首先是map的過程,將很大的資料切割成key-value的形式,我們在這裡假設所有的資料都是稠密的。比如說你有100行資料,切割成5份,那麼每一個worker就處理其中的20行資料。Reduce主要是負責統一worker的計算結果。下面具體到LR的演算法實現來講解下Map-Reduce的過程。

先來看看整體的流程圖:
這裡寫圖片描述

第一步:首先是進行map階段對於長尾資料的分割,我們假設資料是稠密非稀疏的。邏輯迴歸的平行計算的資料分割,可以按行分、按列分或者行列一起分。分好的資料通過key-value的形式傳到每一個worker中,對應上圖的map phase階段的worker。當然,map裡也包含LR的計算邏輯,邏輯請大家看上面的資料自己學習下。分割圖如下:這裡寫圖片描述

第二步:利用隨機梯度(SGD)方法逼近最優解,在凸函式中LR是可以無限接近最優模型的,可以通過限定迴圈次數和收斂條件來實現。這其中就有一個問題,認真研究LR的同學可能會發現,如果我們使用SGD的話,因為worker之間雖然有一定的通訊機制,但是並不是實時同步的,所以每一個worker並不知道對方的梯度是多少,形象的描述一下就是我們可以把SGD看成一個下坡問題。
這裡寫圖片描述
每個worker都在往終點方向下山(收斂模型),但是它們彼此間並不能實時協作,也就是說A不知道B爬到哪裡,C不知道A爬到哪裡。傳入一個路徑,我就接著向下爬一點,可能會走重複的路徑。所以說Map-Reduce的SGD是一種範圍的梯度。每個worker不一定一直往下走,可能走走停停甚至往後走一點,但是因為資料量巨大總是可以走到終點的。 但是這樣就會浪費了很多效率,這也就是Parameter Server重點解決的問題。

第三步:負責reduce的伺服器統一出一個模型輸出。


2.Parameter Server的一些機制

下面我們看下Parameter Server是怎麼解決這個問題。首先看下PS的總體架構,PS是由client和server組成的,client對應於上文的worker,負責計算。server是負責統一所有的client它們的引數,server間是聯通的。
如下圖:
這裡寫圖片描述
總體來看,PS的優勢是通過server來協同client的輸出,如上一節的下山問題,PS可以協同每一個client按照一個方向直線下山,從而提高了效率。而這其中也有很多的技術細節需要考慮。

1).並行化設計
PS可以運用很多並行化的思想從而提高效率。
(1)首先在client端,計算和上傳資料是採用的多執行緒機制,計算和資料傳輸在不同的執行緒中進行從而增加了效率。同時server並不是等待所有引數都上傳完成,才向下分發的。如果一個client_a計算比較慢,server可以暫時不採用client_a的資料,而採用歷史資料。
(2)資料上傳也可以用樹狀結構代替直接上傳,在client和server之間增加一層樹狀結構可以提高資料傳輸效率,節約server的處理資源。可以從下圖的左邊,變為右邊。
這裡寫圖片描述

2).pull和push機制
首先,是在client端應該上傳怎樣的資料,因為每個client節點都會不停的接受和反饋資料給server,那麼到底應該push怎樣的資料上去呢?這個一般來講是選擇步長最長的引數,也就是最大的梯度值的引數push上去。

3).server端的異構形式
因為每個client只處理一部分引數,server端需要將這些引數拼接起來,所以server端是一個異構的組成形式。
這裡寫圖片描述


3.Parameter Server處理LR

上面講了很多PS的機制,這裡具體說一下PS怎麼實現LR。因為LR的輸出是一個線性的迴歸模型。輸出的結果是下面的這種式子:
z=w1*x1+w2*x2…..+w10*x2+….
我們要求的是裡面的w1,w2,w3….這些引數,在PS中每個client計算的是其中的某些△w。通過server將這些△w同步上去,然後再push下去繼續迭代計算。這樣的好處是對於梯度問題,每個client可以沿著一個方向走。
這裡寫圖片描述


後話:我的理解還很淺,具體實現還有非常多的技術細節要敲定,部署在叢集上也會出現各種問題,如:log怎麼輸出,有的client掛了怎麼辦等等。建議有空可以看下李沐的開源專案的程式碼,還有上面提到的一些文件。

作者微信公眾號:凡人機器學習

長期分享機器學習實戰相關資訊,感謝關注!

這裡寫圖片描述

本文來自部落格 “李博Garvin“
轉載請標明出處:http://blog.csdn.net/buptgshengod]

相關文章