去年春節期間支付寶推出的集五福的活動可謂風靡一時,每張福卡背面都有刮刮卡,裡面有來自螞蟻金服、阿裡巴巴以及合作夥伴的上百種權益。集五福的活動集中在春節前的幾天,具有很強的時效性。是以如何實作權益和投放人群的自動比對,解決系統的冷啟動問題,優化轉化率和提升使用者體驗,就成了一個線上學習的優化問題。
之前我們搭建一個這樣的系統需要的子產品非常繁雜。我們需要日志收集、資料聚合、樣本的拼接和采樣等流處理任務,需要對接模型訓練、模型驗證等機器學習子產品,需要有把模型實時加載的模型服務,還需要其他的配套設施等等。衆多子產品的銜接極大地增加了系統的複雜性。

由于涉及的系統比較多,我們之前的系統遇到了比較多的問題。比如大促時為了保證高優鍊路的穩定性,上遊某些資料處理的鍊路就會被降級了,但下遊同學并不知情。另外一個很常見問題的是流批邏輯不一緻,需要離線特征來訓練基準模型,同時線上計算的特征來對模型進行實時更新。這兩個子產品一個在離線一個線上,曾經出現過處理邏輯的細微差别對業務效果造成了很大的影響。
總結下來,我們曾經遇到的坑可以歸結為三類:
- SLA:整個鍊路的SLA會受到每個子產品的SLA的影響,并随着子產品的增多而放大,穩定性成為制約業務發展的重要因素。
- 系統效率:子產品之間的銜接多數是通過資料的落盤來進行,子產品間的排程通過系統排程來實作,造成不必要的I/O、計算和網絡開銷。
- 開發和運維的成本:各個子產品風格迥異,開發模式、計算架構、甚至代碼風格都不一緻,開發和運維對接時需要花很多時間去熟悉系統,降低業務開放的效率。
一個理想的系統應該提供什麼樣的能力呢?可以從“穩快簡”三個方面來講:首先從資料來講它需要保證資料和計算一緻性,實作整個鍊路端到端的SLA,資料一緻性和鍊路的穩定是保障業務穩定的基礎。第二是我們需要去優化系統效率,我們希望把這十幾個系統的銜接轉換成系統内部的銜接,希望把這些作業排程轉換成任務的排程,通過這樣轉化我們希望把計算與計算之間協同排程,進而提高系統效率和降低網絡帶寬使用的目的。一個融合的系統也可以對開發和運維提供非常大的便利,以前需要對接十幾個系統,現在隻要對接一個系統就可以了。以前我們在應急的時候需要回溯好幾個業務來發現問題,現在融合在一起的系統調試也會更加容易。
線上機器學習最外層需要透出資料處理、模型訓練、模型服務三個能力。這三個能力反映到對計算引擎架構上的需求是靈活的調用機制、比較靈活的資源管控,以及比較完善的容錯機制。上層的系統往往是通過不同程式設計語言來實作的,是以還需要有多語言接口。通過對底層需求的考量以及現在各架構的特點,最後我們選擇了Ray為融合計算的底座。
Ray是由伯克利大學RiseLab實驗室發起,螞蟻金服共同參與的一個開源分布式計算架構,它提出的初衷在于讓分布式系統的開發和應用能夠更加簡單。Ray作為計算架構可以幫我們實作上面“穩快簡”三個目标。Ray作為計算架構具有靈活的排程機制,用它可以一秒鐘進行上百萬次任務排程,它也可以根據計算對資源使用的需求實作異構排程。
在目前比較流行的分布式架構,都有三個比較基礎的分布式原語,分布式任務、對象和服務。而我們常用的面向過程的程式設計語言中,也剛好有三個基本概念,函數、變量和類。這三個程式設計語基本概念剛好可以和分布式架構的原語對應起來。在Ray系統中,可以通過簡單的改動,實作他們之間的轉換。
左邊是一個簡單的例子,在這個函數前面需要加入一個“@remote”修飾符,就可以把一個函數轉換成為分布式任務。任務通過“.remote”調用執行,傳回值是一個變量,又可以參與到其他計算中。
右邊是另一個例子,通過加“@remote”修飾符的方式可以把一個類轉變成服務。類中的方法可以通過“.remote”調用變成一個分布式任務,和函數的使用非常相似。通過這種方式可以實作從單機程式到分布式任務的轉變,把本地的任務排程到遠端的機器上進行執行。
Ray上應該做怎麼樣的排程,衡量名額就是系統的效率問題,系統的效率很多時候取決于計算和資料的組織方式,比如說我們要計算Add(a,b),首先這個函數在本地會被自動注冊并且提供給本地排程器。之後通過全劇排程器和第二個節點的本地排程器一起協同工作,把A備份到第二個節點執行Add這個操作。它還可以根據A和B的資料大小來進行進一步的排程和控制優化,A和B可以是簡單資料類型,也可以是比較複雜的變量或者矩陣。
Ray上面提供多語言API接口。由于曆史原因,在螞蟻金服内部流式計算使用最多的語言是Java,而機器學習模組化比較普遍使用的語言是Python。我先希望重用Java語言實作的流處理算子,同時保留Python進行機器學習模組化的便捷性。Ray上面提供這樣的多元化支援就非常友善我們做這個事情,使用者在上層開發的時候可以可以友善地使用Java和Python分别進行流處理和機器學習模型的開發。
對于線上機器學習來說,它最核心需要解決的問題是要打通流計算和模型訓練,那我們需要使用一個媒體,這個媒體能夠比較友善的将兩者銜接在一起。之前我們介紹Ray的幾個特點,如提供多語言的接口、靈活的調動機制,這是因為這兩個特點在Ray上可以比較友善做這個事情,Ray可以起到銜接的作用。資料處理的最後一個節點是流計算的輸出,worker節點消費資料,是模型訓練的輸入。Ray就可以通過排程機制把這兩個計算排程在一個節點上,實作資料共享進而實作兩個模式的打通。通過這種方式不僅可以相容流計算和機器學習,也可以将其他模式進行銜接。
計算中DAG概念最開始是為了解決多階段分布式計算的效率而提出的,主要思想是通過排程減少計算時的IO。但是以前的計算DAG,在任務執行的時候它就已經确定了,但我們在機器學習的任務裡面,很多時候我們會需要設計新的模型,或者對模型的超參進行調試,我們希望看到這些模型能被加載到鍊路上,看到業務效果的同時又不想線上已經有的模型的訓練和服務被中斷。在Ray系統内部,計算的過程中可以動态的生成另外一個節點,我們可以利用這個特性來增點和變,進而動态的對DAG進行局部修正。
線上系統和離線系統之間比較大的差別,在于如果一個離線系統裡的任務挂了,一般來說可以通過重新開機機器的方式來解決,但對線上系統來說,出于時效性的考慮,我們不能簡單的通過重新開機機群回溯資料的方式來解決。是以就需要有比較完善的容錯機制。我們在模型訓練的時候可以利用Ray的Actor來拉起模型訓練的worker和server節點。如果worker或者server節點處于不健康狀态,我們就可以利用Actor的容錯特性通過血緣關系來對資料和計算進行恢複,進而實作容錯的訓練。
我們比較追求鍊路的時效性,模型能夠盡快的拟合實時資料裡。但是追求時效性的同時也要保證整個鍊路的穩定性,在靈活和敏感之間達到平衡。我們從三個方面,系統穩定性、模型穩定性、機制穩定性來保障整個鍊路的穩定性。
- 系統穩定性,裡面包括資料實時性和強一緻性保障。
- 模型穩定性,我們希望設計的模型能夠拟合實時資料流,但同時要防止線上學習鍊路在各種不确定性因素下,如資料噪音,造成的效果退化。是以我們需要考慮線上特征和離線特征的組合,在模型設計上需要考慮到深層模型和淺層模型對資料的敏感性和噪音的容忍度。
- 機制穩定性,賽馬機制、快速復原政策。
除了之前用Ray來實作融合以及它帶來的好處,我們也做了非常多的子產品建設,TF融合、穩定性保障、樣本回流、延遲樣本修正、資料共享、流批一體、端到端強一緻、模型增量導出。我們把這個平台上線了支付寶的幾個場景,從下面的幾個數字可以一探效果:
- 99.9%的全鍊路SLA
- 業務名額有2%到40%的提升
- 幾十分鐘模型延遲到4、5分鐘,并且可以根據業務的需求進一步降低
- 機器使用降低了60%
我們從去年8月份開始建設,今年2月份開始上線第一個場景,在支付線财富線也都取得了不錯的效果,接下來我們會推廣到螞蟻金服的其他業務線上。
基于融合計算機器學習,它是融合計算和機器學習這兩種模式的有機組合,實作優化資源共享。我們通過這兩方面的探索初步驗證了融合計算的架構,融合計算是旨在資料共享來進行計算模式的相容,融合的本質是開放,開放的基礎是實作資料的互通,隻要我們能夠友善的實作各模式之間的資料互通,并且能夠保障它們數字的實時性和端到端的一緻性,就可以實作複雜場景裡面需要多種模式進行組合的計算。子產品的銜接就像搭樂高積木一樣,基本的子產品可能隻有幾種,但是搭建出複雜且多變的系統。