轉(zhuǎn) 機器學(xué)習(xí) 算法生產(chǎn)環(huán)境部署

本文由攜程技術(shù)中心投遞,ID:ctriptech桐玻。作者:潘鵬舉荆萤,攜程酒店研發(fā)BI經(jīng)理,負責(zé)酒店服務(wù)相關(guān)的業(yè)務(wù)建模工作偏竟,主要研究方向是用機器學(xué)習(xí)實現(xiàn)業(yè)務(wù)流程自動化敞峭、系統(tǒng)智能化、效率最優(yōu)化褪子,專注于算法實踐和應(yīng)用。

我們經(jīng)常會碰到一個問題:用了復(fù)雜的GBDT或者xgboost大大提升了模型效果呀枢,可是在上線的時候又犯難了裙秋,工程師說這個模型太復(fù)雜了缨伊,我沒法上線,滿足不了工程的要求枷恕,你幫我轉(zhuǎn)換成LR吧谭胚,直接套用一個公式就好了,速度飛速胡控,肯定滿足工程要求旁趟。這個時候你又屁顛屁顛用回了LR锡搜,重新訓(xùn)練了一下模型,心里默罵千百遍:工程能力真弱纷宇。
這些疑問蛾方,我們以前碰到過,通過不斷的摸索拓春,試驗出了不同的復(fù)雜機器學(xué)習(xí)的上線方法亚隅,來滿足不同場景的需求。在這里把實踐經(jīng)驗整理分享懂鸵,希望對大家有所幫助匆光。(我們的實踐經(jīng)驗更多是傾向于業(yè)務(wù)模型的上線流程,廣告和推薦級別的部署請自行繞道)夺巩。
首先在訓(xùn)練模型的工具上周崭,一般三個模型訓(xùn)練工具,Spark美澳、R摸航、Python忙厌。這三種工具各有千秋江咳,以后有時間,我寫一下三種工具的使用心得爹土。針對不同的模型使用場景踩身,為了滿足不同的線上應(yīng)用的要求挟阻,會用不同的上線方法。

一脱拼、總結(jié)來說坷备,大體會區(qū)分這三種場景,請大家對號入座赌蔑,酌情使用
如果是實時的、小數(shù)據(jù)量的預(yù)測應(yīng)用跷乐,則采用的SOA調(diào)用Rserve或者python-httpserve來進行應(yīng)用劈猿;這種應(yīng)用方式有個缺點是需要啟用服務(wù)來進行預(yù)測潮孽,也就是需要跨環(huán)境,從Java跨到R或者Python環(huán)境仗颈。對于性能挨决,基本上我們用Rserver方式订歪,針對一次1000條或者更少請求的預(yù)測,可以控制95%的結(jié)果在100ms內(nèi)返回結(jié)果盖高,100ms可以滿足工程上的實踐要求眼虱。更大的數(shù)據(jù)量捏悬,比如10000/次,100000/次的預(yù)測甥厦,我們目前評估下來滿足不了100ms的要求寇钉,建議分批進行調(diào)用或者采用多線程請求的方式來實現(xiàn)摧莽。

如果是實時、大數(shù)據(jù)量的預(yù)測應(yīng)用油够,則會采用SOA,訓(xùn)練好的模型轉(zhuǎn)換成PMML(關(guān)于如何轉(zhuǎn)換揩悄,我在下面會詳細描述)鬼悠,然后把模型封裝成一個類焕窝,用Java調(diào)用這個類來預(yù)測。用這種方式的好處是SOA不依賴于任何環(huán)境巴帮,任何計算和開銷都是在Java內(nèi)部里面消耗掉了榕茧,所以這種工程級別應(yīng)用速度很快客给、很穩(wěn)定。用此種方法也是要提供兩個東西蜻拨,模型文件和預(yù)測主類纵菌;

如果是Offline(離線)預(yù)測的,D+1天的預(yù)測笛辟,則可以不用考慮第1手幢、2中方式忱详,可以簡單的使用Rscript x.R或者python x.py的方式來進行預(yù)測。使用這種方式需要一個調(diào)度工具监透,如果公司沒有統(tǒng)一的調(diào)度工具,你用shell的crontab做定時調(diào)用就可以了胀蛮。

以上三種做法院刁,都會用SOA里面進行數(shù)據(jù)處理和變換,只有部分變換會在提供的Function或者類進行處理粪狼,一般性都建議在SOA里面處理好退腥,否則性能會變慢。
大概場景羅列完畢再榄,簡要介紹一下各不同工具的線上應(yīng)用的實現(xiàn)方式狡刘。

二、如何轉(zhuǎn)換PMML不跟,并封裝PMML
大部分模型都可以用PMML的方式實現(xiàn)颓帝,PMML的使用方法調(diào)用范例見:
jpmml的說明文檔:GitHub - jpmml/jpmml-evaluator: Java Evaluator API for PMML窝革;
Java調(diào)用PMML的范例(PPJUtils/java/pmml at master · pjpan/PPJUtils · GitHub)购城,此案例是我們的工程師寫的范例,大家可以根據(jù)此案例進行修改即可虐译;
Jpmml支持的轉(zhuǎn)換語言瘪板,主流的機器學(xué)習(xí)語言都支持了,深度學(xué)習(xí)類除外漆诽;
從下圖可以看到侮攀,它支持R、python和spark厢拭、xgboost等模型的轉(zhuǎn)換兰英,用起來非常方便。

三供鸠、接下來說一下各個算法工具的工程實踐
1.python模型上線:我們目前使用了模型轉(zhuǎn)換成PMML上線方法畦贸。
python-sklearn里面的模型都支持,也支持xgboost楞捂,并且PCA薄坏,歸一化可以封裝成preprocess轉(zhuǎn)換成PMML,所以調(diào)用起來很方便寨闹;
特別需要注意的是:缺失值的處理會影響到預(yù)測結(jié)果胶坠,大家可以可以看一下;
用PMML方式預(yù)測繁堡,模型預(yù)測一條記錄速度是1ms沈善,可以用這個預(yù)測來預(yù)估一下根據(jù)你的數(shù)據(jù)量乡数,整體的速度有多少。

2.R模型上線-這塊我們用的多闻牡,可以用R model轉(zhuǎn)換PMML的方式來實現(xiàn)瞳脓。
這里我介紹另一種的上線方式:Rserve。具體實現(xiàn)方式是:用SOA調(diào)用Rserve的方式去實現(xiàn)澈侠,我們會在服務(wù)器上部署好R環(huán)境和安裝好Rserve劫侧,然后用JAVA寫好SOA接口,調(diào)用Rserve來進行預(yù)測哨啃;
java調(diào)用Rserve方式見網(wǎng)頁鏈接:Rserve - Binary R server烧栋;
centos的Rserve搭建方法見:centos -Rserve的搭建,這里詳細描述了Rserve的搭建方式拳球。

Rserve方式可以批量預(yù)測审姓,跟PMML的單個預(yù)測方式相比,在少數(shù)據(jù)量的時候祝峻,PMML速度更快魔吐,但是如果是1000一次一批的效率上看,Rserve的方式會更快莱找;用Rserve上線的文件只需要提供兩個:
模型結(jié)果文件(XX.Rdata)酬姆;
預(yù)測函數(shù)(Pred.R)。

Rserve_1啟動把模型結(jié)果(XX.Rdata)常駐內(nèi)存奥溺。預(yù)測需要的輸入Feature都在Java里定義好不同的變量辞色,然后你用Java訪問Rserve_1,調(diào)用Pred.R進行預(yù)測浮定,獲取返回的List應(yīng)用在線上相满。最后把相關(guān)的輸入輸出存成log進行數(shù)據(jù)核對。

Pred.R <- function(x1,x2,x3){
data <- cbind(x1,x2,x3)
# feature engineering
score <- predict(modelname, data, type = 'prob')
return(list(score))
}

3.Spark模型上線-好處是脫離了環(huán)境桦卒,速度快立美。
Spark模型的上線就相對簡單一些,我們用Scala訓(xùn)練好模型(一般性我們都用xgboost訓(xùn)練模型)然后寫一個Java Class方灾,直接在JAVA中先獲取數(shù)據(jù)建蹄,數(shù)據(jù)處理,把處理好的數(shù)據(jù)存成一個數(shù)組迎吵,然后調(diào)用模型Class進行預(yù)測躲撰。模型文件也會提前l(fā)oad在內(nèi)存里面针贬,存在一個進程里面击费,然后我們?nèi)フ{(diào)用這個進程來進行預(yù)測。所以速度蠻快的桦他。
Spark模型上線蔫巩,放在spark集群谆棱,不脫離spark環(huán)境,方便圆仔,需要自己打jar包垃瞧;
我們這里目前還沒有嘗試過,有一篇博客寫到了如果把spark模型導(dǎo)出PMML,然后提交到spark集群上來調(diào)用坪郭,大家可以參考一下:Spark加載PMML進行預(yù)測个从。

四、只用Linux的Shell來調(diào)度模型的實現(xiàn)方法-簡單粗暴
因為有些算法工程師想快速迭代歪沃,把模型模擬線上線看一下效果嗦锐,所以針對離線預(yù)測的模型形式,還有一種最簡單粗暴的方法沪曙,這種方法開發(fā)快速方便奕污,具體做法如下:
寫一下R的預(yù)測腳本,比如predict.R液走,是你的主預(yù)測的模型碳默;
然后用shell封裝成xx.sh,比如predict.sh缘眶,shell里面調(diào)用模型嘱根,存儲數(shù)據(jù);

predict.sh的寫法如下:

# 數(shù)據(jù)導(dǎo)出
data_filename = xxx
file_date = xxx
result = xxx
updatedt = xxx
cd path
hive -e "USE tmp_xxxdb;SELECT * FROM db.table1;" > ${data_filname};
# R腳本預(yù)測
Rscript path/predict.R  $file_date
if [ $? -ne 0 ]
then 
echo "Running RScript Failure"
fi
# R預(yù)測的結(jié)果導(dǎo)入Hive表
list1="use tmp_htlbidb;
load data local inpath 'path/$result'
overwrite into table table2 partition(dt='${updatedt}');"
hive -e "$list1"

最后用Crontab來進行調(diào)度巷懈,很簡單儿子,如何設(shè)置crontab,度娘一下就好了砸喻。

>crontab -e
-------------------------
### 每天5點進行預(yù)測模型柔逼;
0 5 * * * sh predict.sh

五、說完了部署上線割岛,說一下模型數(shù)據(jù)流轉(zhuǎn)的注意事項
區(qū)分offline和realtime數(shù)據(jù)愉适,不管哪種數(shù)據(jù),我們根據(jù)key和不同的更新頻次癣漆,把數(shù)據(jù)放在redis里面去维咸,設(shè)置不同的key和不同的過期時間;
大部分redis數(shù)據(jù)都會存放兩個批次的數(shù)據(jù)惠爽,用來預(yù)防無法取到最新的數(shù)據(jù)癌蓖,則用上一批次的數(shù)據(jù)來進行填充;
針對offline數(shù)據(jù)婚肆,用調(diào)度工具做好依賴租副,每天跑數(shù)據(jù),并生成信號文件讓redis來進行讀冉闲浴用僧;
針對realtime數(shù)據(jù)结胀,我們區(qū)分兩種類型,一種是歷史+實時责循,比如最近30天的累計訂單量糟港,則我們會做兩步,第一部分是D+1之前的數(shù)據(jù)院仿,存成A表秸抚,今天產(chǎn)生的實時數(shù)據(jù),存儲B表歹垫,A和B表表結(jié)構(gòu)相同耸别,時效性不同;我們分別把A表和B表的數(shù)據(jù)放在Redis上去县钥,然后在SOA里面對這兩部分?jǐn)?shù)據(jù)實時進行計算秀姐;
模型的輸入輸出數(shù)據(jù)進行埋點,進行數(shù)據(jù)跟蹤若贮,一是用來校驗數(shù)據(jù)省有,二來是用來監(jiān)控API接口的穩(wěn)定性,一般性我們會用ES來進行l(wèi)og的查看和性能方面的監(jiān)控谴麦;
任何接口都需要有容災(zāi)機制蠢沿,如果接口超時,前端需要進行容災(zāi)匾效,立即放棄接口調(diào)用數(shù)據(jù)舷蟀,返回一個默認(rèn)安全的數(shù)值,這點對于工程上非常重要面哼。

以上就是我們在模型部署的經(jīng)驗分享野宜,歡迎大家來找我一起探討相關(guān)工程上的最佳實踐。
攜程技術(shù)中心現(xiàn)開放大數(shù)據(jù)相關(guān)崗位魔策,包括資深NLP科學(xué)家/算法工程師/大數(shù)據(jù)底層架構(gòu)工程師/大數(shù)據(jù)平臺開發(fā)工程師/機器學(xué)習(xí)工程師/自然語言處理工程師/圖像識別工程師等匈子,有意者可砸簡歷至tech@ctrip.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闯袒,一起剝皮案震驚了整個濱河市虎敦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌政敢,老刑警劉巖其徙,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異喷户,居然都是意外死亡唾那,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門摩骨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來通贞,“玉大人,你說我怎么就攤上這事恼五〔郑” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵灾馒,是天一觀的道長茎用。 經(jīng)常有香客問我秒梅,道長英染,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任炊苫,我火速辦了婚禮容达,結(jié)果婚禮上古涧,老公的妹妹穿的比我還像新娘。我一直安慰自己花盐,他們只是感情好羡滑,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著算芯,像睡著了一般柒昏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上熙揍,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天职祷,我揣著相機與錄音,去河邊找鬼届囚。 笑死有梆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的意系。 我是一名探鬼主播淳梦,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昔字!你這毒婦竟也來了爆袍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤作郭,失蹤者是張志新(化名)和其女友劉穎陨囊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夹攒,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蜘醋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咏尝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片压语。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡啸罢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胎食,到底是詐尸還是另有隱情扰才,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布厕怜,位于F島的核電站衩匣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏粥航。R本人自食惡果不足惜琅捏,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望递雀。 院中可真熱鬧柄延,春花似錦、人聲如沸缀程。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杠输。三九已至赎败,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蠢甲,已是汗流浹背僵刮。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹦牛,地道東北人搞糕。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像曼追,于是被迫代替她去往敵國和親窍仰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容