螞蟻端智能計(jì)算容器
編者按:本文是支付寶體驗(yàn)科技沙龍第 3 期-走進(jìn)螞蟻端智能技術(shù)的回顧系列文章,螞蟻集團(tuán)客戶端工程師朱木分享了螞蟻端側(cè)計(jì)算容器面臨的挑戰(zhàn)、思考和設(shè)計(jì)方案。
背景與挑戰(zhàn)

一個(gè)應(yīng)用場(chǎng)景要落地端智能方案,一般分為以下幾個(gè)階段:
決策鏈路研發(fā):決策的調(diào)用、決策邏輯的執(zhí)行和決策結(jié)果的響應(yīng)。
端特征的研發(fā):特征數(shù)據(jù)采集、計(jì)算,并以服務(wù)的形式提供給訓(xùn)練和決策環(huán)節(jié)。
端模型的研發(fā):樣本數(shù)據(jù)采集、端模型的研發(fā)、轉(zhuǎn)換。
決策邏輯研發(fā):業(yè)務(wù)前置處理、模型推理、業(yè)務(wù)后置處理。
端智能解決方案研發(fā)過程中,面臨的幾大問題與挑戰(zhàn):
基礎(chǔ)功能支持:具備豐富的數(shù)據(jù)供給、特征生產(chǎn)加工、端模型推理、業(yè)務(wù)邏輯編寫等基礎(chǔ)能力。
迭代部署效率:云端模型一天一迭代,而客戶端按月發(fā)版,無法滿足迭代效率的訴求,需要能快速搭建工程鏈路并具備動(dòng)態(tài)化執(zhí)行能力來承載各業(yè)務(wù)定制化的復(fù)雜邏輯。
端高性能計(jì)算:在云端,具備流批一體的計(jì)算能力、高性能存儲(chǔ)和查詢能力。在移動(dòng)端,一方面需要具備毫秒級(jí)別的計(jì)算能力,保障業(yè)務(wù)調(diào)用成功率,另一方面計(jì)算任務(wù)天然消耗資源,需要平衡用戶使用體驗(yàn)。
端側(cè)高穩(wěn)定性:移動(dòng)端碎片化驗(yàn)證,穩(wěn)定性可謂是重中之重。我們需要從研發(fā)、發(fā)布、運(yùn)行、監(jiān)控、熔斷等全鏈路進(jìn)行梳理和重點(diǎn)保障。
針對(duì)上面提到的幾大挑戰(zhàn),我們?cè)O(shè)計(jì)了端智能計(jì)算容器,來提供端側(cè)的數(shù)據(jù)特征服務(wù)和解決方案的運(yùn)行時(shí)支撐和保障,并能在穩(wěn)定性、研發(fā)效率、計(jì)算性能等方面滿足要求。
整體架構(gòu)

端計(jì)算容器的整體架構(gòu)如圖所示,端上運(yùn)行時(shí)環(huán)節(jié),分為三部分:
計(jì)算引擎:提供特征和決策邏輯的基礎(chǔ)計(jì)算環(huán)境,包括了實(shí)時(shí)計(jì)算、模型推理、PythonVm、任務(wù)管理等。
特征引擎:提供端云一體的統(tǒng)一端特征服務(wù)供各業(yè)務(wù)方使用。
決策引擎:封裝了基礎(chǔ)的服務(wù)框架,給算法和工程同學(xué)提供便捷的研發(fā)環(huán)境。
在平臺(tái)側(cè),通過端智能研發(fā)平臺(tái)Moobileaix和研發(fā)套件,給研發(fā)同學(xué)提供便捷的研發(fā)體驗(yàn)。在計(jì)算引擎部分,重點(diǎn)紹一下端側(cè)實(shí)時(shí)計(jì)算引擎。
實(shí)時(shí)計(jì)算引擎

為了在端智能場(chǎng)景中提供用秒級(jí)的用戶響應(yīng)和滿足決策引擎對(duì)特征生產(chǎn)高時(shí)效的要求,我們也探索出在端側(cè)的進(jìn)行實(shí)時(shí)計(jì)算的引擎,及對(duì)產(chǎn)生的數(shù)據(jù),直接在端側(cè)進(jìn)行復(fù)雜流式計(jì)算處理。大致的設(shè)計(jì)方案如圖所示:
接口層:提供強(qiáng)大的實(shí)時(shí)計(jì)算任務(wù)定義能力,并實(shí)現(xiàn)了端側(cè)計(jì)算任務(wù)動(dòng)態(tài)化更新部署。
服務(wù)層:提供端實(shí)時(shí)聚合、實(shí)時(shí)匹配、實(shí)時(shí)串聯(lián)的底層數(shù)據(jù)模型結(jié)構(gòu)以及DSL的運(yùn)行時(shí)環(huán)境。
數(shù)據(jù)層:提供多技術(shù)棧數(shù)據(jù)統(tǒng)一采集,實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)源統(tǒng)一化、標(biāo)準(zhǔn)化,為上層數(shù)據(jù)消費(fèi)服務(wù)提供訂閱管理服務(wù)。
事件標(biāo)準(zhǔn)化

實(shí)時(shí)計(jì)算數(shù)據(jù)層面臨的問題和挑戰(zhàn):
采集覆蓋:技術(shù)棧涉及到原生Native、H5/小程序、卡片等,覆蓋全場(chǎng)景的數(shù)據(jù)有較大的難度。
研發(fā)效率:很多業(yè)務(wù)場(chǎng)景數(shù)據(jù)依賴純手動(dòng)埋點(diǎn),任何埋點(diǎn)改動(dòng)都需要依賴客戶端發(fā)版或者業(yè)務(wù)發(fā)布,加之?dāng)?shù)據(jù)采集的需求復(fù)雜多變,日常投入了大量時(shí)間在數(shù)據(jù)埋點(diǎn)上,研發(fā)效率較低,
埋點(diǎn)時(shí)機(jī):手動(dòng)埋點(diǎn)的觸發(fā)時(shí)機(jī)完全是業(yè)務(wù)手動(dòng)控制的,一旦時(shí)機(jī)錯(cuò)亂會(huì)導(dǎo)致歸因不準(zhǔn);
數(shù)據(jù)口徑:各業(yè)務(wù)手動(dòng)埋點(diǎn)采集口徑不統(tǒng)一,比如曝光口徑,不同業(yè)務(wù)對(duì)于曝光比例多少算作有效曝光有不同的定義;
我們通過統(tǒng)一的采集框架,基于切面、注入等技術(shù),實(shí)現(xiàn)了不同技術(shù)棧、不同類型數(shù)據(jù)的統(tǒng)一采集,數(shù)據(jù)口徑統(tǒng)一,事件模型統(tǒng)一。采集框架標(biāo)準(zhǔn)化事件后,通過實(shí)時(shí)事件流pipeline,源事件快照源源不斷的,向各引擎上的任務(wù)實(shí)例進(jìn)行分發(fā)。
實(shí)時(shí)聚合

實(shí)時(shí)聚合的三個(gè)演進(jìn)階段:
1.0階段:功能快速落地。我們稱之為刀耕火種階段,native側(cè)硬編碼業(yè)務(wù)邏輯,支撐了poc場(chǎng)景的快速落地和驗(yàn)證,但需求改動(dòng)都需要跟隨客戶端發(fā)版,無法滿足業(yè)務(wù)對(duì)于迭代效率的要求。
2.0階段:解決研發(fā)效率問題。數(shù)據(jù)存儲(chǔ)在關(guān)系型數(shù)據(jù)庫或者時(shí)序數(shù)據(jù)庫,上層通過編寫sql查詢加工數(shù)據(jù)。但隨著業(yè)務(wù)數(shù)據(jù)的增多,性能問題急劇突增,一次查詢多則需要幾百毫秒甚至秒級(jí),影響業(yè)務(wù)調(diào)用成功率和用戶的使用體驗(yàn)。而為了支撐不同業(yè)務(wù)的不同訴求,大量的數(shù)據(jù)寫入也會(huì)造成高頻IO和存儲(chǔ)浪費(fèi)。
3.0階段:解決性能存儲(chǔ)問題。為了解決特征計(jì)算在性能、存儲(chǔ)、動(dòng)態(tài)性方面的問題,我們?cè)O(shè)計(jì)了端側(cè)實(shí)時(shí)聚合引擎,可以針對(duì)端數(shù)據(jù)進(jìn)行切分、拼接、取參的操作,以及計(jì)次、求和、平均值、序列等多種聚合計(jì)算,同時(shí)對(duì)結(jié)果快照進(jìn)行分級(jí)緩存,在使用時(shí)提供毫秒級(jí)的獲取能力。隨著接入業(yè)務(wù)的增多,不同業(yè)務(wù)之間的計(jì)算任務(wù)不免有重復(fù),為了進(jìn)一步降低計(jì)算資源消耗,我們還設(shè)計(jì)了任務(wù)的相似度檢測(cè)和自動(dòng)合并的方案,實(shí)現(xiàn)了跨任務(wù)的計(jì)算復(fù)用,并通過分級(jí)的任務(wù)調(diào)度,實(shí)現(xiàn)了任務(wù)的按需計(jì)算。
實(shí)時(shí)匹配

端智能業(yè)務(wù)對(duì)于復(fù)雜事件匹配的主要核心訴求如下:
支持多事件匹配:一開始端智能任務(wù)的觸發(fā)模式是按鈕點(diǎn)擊、頁面打開等單一事件,隨著應(yīng)用場(chǎng)景越來越廣泛,業(yè)務(wù)對(duì)于復(fù)雜事件觸發(fā)的訴求越來越多,比如從A頁面進(jìn)入B頁面,停留10s又退回A頁面
能夠動(dòng)態(tài)部署:初期我們可以通過硬編碼的方式去支持場(chǎng)景的觸發(fā);可當(dāng)類似的場(chǎng)景訴求越來越多時(shí),算法對(duì)效率、實(shí)時(shí)性要求越來越高時(shí),受限端發(fā)布、開發(fā)成本等問題,原方法慢慢變的不再可行。
能夠?qū)崟r(shí)相應(yīng):云端實(shí)時(shí)計(jì)算,需要把先原數(shù)據(jù)明細(xì)即時(shí)上報(bào),云端流處理服務(wù)處理完成后再下發(fā)結(jié)果,網(wǎng)絡(luò)延遲加上處理耗時(shí),只能做到準(zhǔn)實(shí)時(shí),而無法實(shí)時(shí)響應(yīng)當(dāng)前交互操作
基于上述考慮,我們?cè)诙松显O(shè)計(jì)一套支持動(dòng)態(tài)下發(fā)自定義規(guī)則的規(guī)則引擎來完成事件序列的匹配與觸發(fā)工作。
首先,我們通過定義一套基于json格式描述的DSL描述語言來定義規(guī)則;
之后,我們將自定義DSL內(nèi)容動(dòng)態(tài)下發(fā)到端上,并在端上實(shí)現(xiàn)相應(yīng)的自定義語言解析器,解析器解析出同樣表達(dá)能力的一個(gè)Pattern鏈表(RE);
再之,基于已解析出的Pattern鏈表,通過實(shí)現(xiàn)的NFA編譯器,把目標(biāo)編譯成NFA實(shí)例;
最后, NFA實(shí)例初始化完成即可以開始對(duì)輸入信息進(jìn)行處理。
實(shí)時(shí)匹配引擎的核心運(yùn)行處理是NFA非確定性狀態(tài)機(jī),其運(yùn)行時(shí)首先會(huì)把DSL任務(wù)編譯成一個(gè)有向無環(huán)圖,再基于有向無環(huán)圖,實(shí)時(shí)處理輸入的數(shù)據(jù)流,當(dāng)NFA成功到達(dá)終點(diǎn)的節(jié)點(diǎn)時(shí),即匹配結(jié)果成功,成功識(shí)別一個(gè)目標(biāo)狀態(tài)實(shí)例。
實(shí)時(shí)串聯(lián)

在云端螞蟻域內(nèi)各業(yè)務(wù)間相互調(diào)用、依賴關(guān)系等都是通過一系列的ID體系進(jìn)行規(guī)范約束,方便鏈路串聯(lián)分析。但在端側(cè),傳統(tǒng)串聯(lián)體系面臨的幾大問題:
串聯(lián)相互割裂:由于端側(cè)環(huán)境的復(fù)雜性,加上多方業(yè)務(wù)的接入、接口調(diào)用、服務(wù)端網(wǎng)絡(luò)請(qǐng)求等的介入,很多域有自己的ID體系,這些id體系之間相互獨(dú)立,只能部分還原用戶動(dòng)線,無法還原一個(gè)用戶動(dòng)線的全貌,而其中一些資源的串聯(lián)現(xiàn)在還沒有一套可跟蹤的體系。
計(jì)算資源消耗大:以上數(shù)據(jù)絕大部分通過埋點(diǎn)回流到云端進(jìn)行計(jì)算,而為了準(zhǔn)確的還原用戶動(dòng)線,需要經(jīng)過云端海量數(shù)據(jù)的計(jì)算聚合,這個(gè)對(duì)計(jì)算資源、存儲(chǔ)占用、實(shí)時(shí)性都是一個(gè)巨大的挑戰(zhàn)。
因此,我們?cè)O(shè)計(jì)了一套完整實(shí)時(shí)串聯(lián)的能力,解決上訴的問題。
我們使用表示行為的節(jié)點(diǎn)來構(gòu)建分層樹模型表示各模型的生命周期,比如Session代表行為會(huì)話、app代碼應(yīng)用啟動(dòng)、Scene代碼頁面實(shí)例、Page代表頁面訪問等。其中Session/App/Scene/Page節(jié)點(diǎn)構(gòu)成了樹的骨架結(jié)構(gòu),而Behavior行為做為葉子節(jié)點(diǎn)表示用戶在當(dāng)次頁面訪問中的具體操作行為。骨架節(jié)點(diǎn)之間保持層級(jí)強(qiáng)約束關(guān)系,即Session->App->Scene->Page之間為父子關(guān)系,節(jié)點(diǎn)不可越層級(jí)添加子節(jié)點(diǎn);
同時(shí)通過來去源引用關(guān)系,表示出用戶行為中的跳轉(zhuǎn)關(guān)系。僅有Page節(jié)點(diǎn)才有邏輯去源子節(jié)點(diǎn),表示由當(dāng)前Page節(jié)點(diǎn)去到其它目標(biāo)節(jié)點(diǎn)的邏輯跳轉(zhuǎn)行為,觸發(fā)的原因?yàn)閜age下的某一具體葉子節(jié)點(diǎn)行為。
特征引擎
問題與挑戰(zhàn)
在刀耕火種的年代是將特征代碼邏輯放在業(yè)務(wù)邏輯代碼中的,特征研發(fā)面臨的困難和挑戰(zhàn):
特征難以復(fù)用:每個(gè)算法同學(xué)都需要從0開始研發(fā)特征,一些公用特征無法沉淀,也會(huì)造成數(shù)據(jù)的重復(fù)計(jì)算。
研發(fā)環(huán)境不友好:算法同學(xué)熟悉的是云端的研發(fā)環(huán)節(jié),但到了端上,涉及到數(shù)據(jù)口徑溝通、運(yùn)行環(huán)境部署、任務(wù)配置、代碼研發(fā)、業(yè)務(wù)觸發(fā)、代碼驗(yàn)證等環(huán)節(jié),流程長(zhǎng),研發(fā)難。
穩(wěn)定性保障難道大:手機(jī)端的計(jì)算資源有限、碎片化嚴(yán)重,一個(gè)簡(jiǎn)單的計(jì)算查詢語句可能會(huì)對(duì)性能和穩(wěn)定性造成影響較大的代碼,如何保障端側(cè)運(yùn)行的穩(wěn)定性,是我們面臨的一大挑戰(zhàn)。
要解決上訴問題,需要從特征的研發(fā)和使用兩個(gè)方面進(jìn)行優(yōu)化,提升研發(fā)體驗(yàn)。
低代碼特征研發(fā)

我們?cè)O(shè)計(jì)了低代碼特征研發(fā)平臺(tái)來提升研發(fā)效率、保障用戶體驗(yàn)。特征研發(fā)分為了四個(gè)環(huán)節(jié):特征研發(fā)、特征調(diào)試、特征集成、特征發(fā)布。
特征研發(fā):特征研發(fā)有三種模式:配置/配置+腳本/腳本。經(jīng)過前面的介紹,多數(shù)行為特征可以通過實(shí)時(shí)聚合的能力進(jìn)行計(jì)算,但是dsl語言理解成本較高,為此我們提供了可視化的配置頁面,業(yè)務(wù)同學(xué)填寫簡(jiǎn)單的參數(shù)即可完成研發(fā),實(shí)現(xiàn)0代碼研發(fā)。而對(duì)于有復(fù)雜計(jì)算訴求的,例如矩陣變化、甚至模型計(jì)算,可以在腳本層進(jìn)行處理,并通過提供的研發(fā)腳手架來提升研發(fā)效率。
特征調(diào)試:在調(diào)試驗(yàn)證環(huán)節(jié),提供了研發(fā)IDE,支持真機(jī)部署、日志查看、斷點(diǎn)調(diào)試、全鏈路mock等能力,修改完配置或代碼后,可以實(shí)時(shí)部署查看特征數(shù)據(jù)。
特征集成:研發(fā)完成之后,基于端上穩(wěn)定性和權(quán)限等因素,我們會(huì)對(duì)特征進(jìn)行穩(wěn)定性、性能等測(cè)試和集中的審批。
特征發(fā)布:發(fā)布能力極其靈活,支持機(jī)型、版本、人群的灰度、ab控制,并且還可以同云端系統(tǒng)一起進(jìn)行聯(lián)合實(shí)驗(yàn)。
通過上面的設(shè)計(jì),特征從研發(fā)到上線,最快半天即可完成。
端特征服務(wù)

我們通過端特征服務(wù)對(duì)外提供特征數(shù)據(jù)。使用時(shí),傳入特征名稱即可查詢到對(duì)應(yīng)的特征值,特征服務(wù)內(nèi)部進(jìn)行統(tǒng)一路由,屏蔽特征實(shí)現(xiàn),降低了調(diào)用成本,并通過統(tǒng)一的管控,對(duì)調(diào)用方進(jìn)行權(quán)限的校驗(yàn)。平臺(tái)側(cè)我們也提供了端特征中心,對(duì)特征進(jìn)行元數(shù)據(jù)的管理,可以便捷的查詢到目前已沉淀的特征和特征的預(yù)覽值,方便研發(fā)同學(xué) 在使用過程中發(fā)現(xiàn)的幾個(gè)問題:
特征無效計(jì)算:業(yè)務(wù)下線掉特征調(diào)用后,特征還在繼續(xù)生產(chǎn),對(duì)于資源有限的手機(jī)端存在非常大的浪費(fèi)。
特征數(shù)據(jù)異動(dòng):諸多特征依賴上游業(yè)務(wù)數(shù)據(jù),業(yè)務(wù)某些小的改動(dòng)可能造成數(shù)據(jù)缺失,影響模型的準(zhǔn)確率。
因此我們還建設(shè)了特征實(shí)時(shí)監(jiān)控能力,例如特征血緣、特征質(zhì)量、特征耗時(shí),當(dāng)發(fā)生無效計(jì)算或者特征異動(dòng)之后,可以及時(shí)發(fā)出告警進(jìn)行診斷和優(yōu)化。傳統(tǒng)云端特征生成消費(fèi)鏈路的幾個(gè)痛點(diǎn):
特征時(shí)效性低:云端傳統(tǒng)的行為數(shù)據(jù)獲取使用埋點(diǎn),埋點(diǎn)上報(bào)到云端,通常有分鐘級(jí)別延遲,服務(wù)端通過實(shí)時(shí)計(jì)算引擎解析,存在任務(wù)延遲,導(dǎo)致實(shí)時(shí)特征進(jìn)一步延遲。
計(jì)算資源消耗高:全量用戶行為關(guān)聯(lián)時(shí),需要對(duì)多個(gè)數(shù)據(jù)進(jìn)行聚合,這在云端是非常消費(fèi)資源的,尤其是實(shí)時(shí)數(shù)據(jù)流的聚合。
我們封裝了產(chǎn)品化的方案,用戶可以在平臺(tái)側(cè)便捷的配置觸發(fā)時(shí)機(jī)、勾選特征列表和選擇分級(jí)的實(shí)時(shí)通道,便可在云端通過實(shí)時(shí)特征服務(wù)獲取的對(duì)應(yīng)的特征。
決策引擎

隨著端智能的基礎(chǔ)設(shè)施逐漸完善,參與的算法同學(xué)越來越多,端決策面臨的挑戰(zhàn):
更快的進(jìn)行開發(fā)和上線解決方案和進(jìn)行AB實(shí)驗(yàn)
在端用戶體驗(yàn)不變的情況下,支撐更多的端智能方案部署
為此,我們定義了基于決策框架的業(yè)務(wù)接入引擎,包括三部分:
觸發(fā)時(shí)機(jī)(Trigger)?+?決策邏輯+?決策響應(yīng)(Action)
三段式的設(shè)計(jì)很好的區(qū)分了工程和算法的邊界,工程專注于工程鏈路的建設(shè),算法專注于決策邏輯的開發(fā)和部署
觸發(fā)時(shí)機(jī)提供了基于自動(dòng)化埋點(diǎn)和行為規(guī)則引擎的事件,可以滿足90%的使用場(chǎng)景,避免重復(fù)開發(fā)
決策響應(yīng)提供了端上常用的用戶觸達(dá)通道,簡(jiǎn)化了工程側(cè)鏈路
觸發(fā)時(shí)機(jī)和決策響應(yīng)可以隨意組合來實(shí)現(xiàn)不同的工程鏈路,已有工程鏈路也可以被多個(gè)決策邏輯使用,可以進(jìn)行方案間的AB,這樣來提升工程鏈路的復(fù)用度。
決策邏輯就是端智能腳本,是運(yùn)行在經(jīng)過我們裁剪、優(yōu)化、擴(kuò)展的python虛擬機(jī)運(yùn)行環(huán)境中的。在研發(fā)階段,建設(shè)開箱即用的框架和算法模版方案,例如predict和rerank模板方案,來降低研發(fā)難度。代碼寫完之后,需要提供一套能與端上運(yùn)行時(shí)環(huán)境相匹配的調(diào)試工具,也是我們面臨的較大難題,舉幾個(gè)例子,比如編寫完代碼后如何查看運(yùn)行結(jié)果,如果需要走一次發(fā)布流程肯定是不行的,耗時(shí)費(fèi)力;實(shí)現(xiàn)快速調(diào)試,腳本是運(yùn)行在手機(jī)端還是pc端,是我們面臨的選型問題;端決策腳本通常需要業(yè)務(wù)數(shù)據(jù)的輸入和特征數(shù)據(jù),受限于工程鏈路研發(fā)的進(jìn)度、環(huán)境等因素,在沒有這些數(shù)據(jù)的情況下,如何快速的進(jìn)行決策邏輯的研發(fā)。我們基于VSCode的插件體系提供了端智能腳本的掃碼部署能力,具體包括了一鍵打包、真機(jī)部署、斷點(diǎn)調(diào)試、日志查看、全鏈路的數(shù)據(jù)mock等功能。
在發(fā)布階段,提供了灰度管控、多模型AB和端云聯(lián)合AB能力,聯(lián)合AB支持端云系統(tǒng)的不同實(shí)驗(yàn)室實(shí)驗(yàn)之間的流量穿透。
另外,提供了統(tǒng)一的調(diào)度和管控能力,主要包括基于觸發(fā)時(shí)機(jī)的審核、調(diào)度和算力配額。