成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

DPP推薦引擎架構升級演進之路

開發
圖化DAG編排在我們落地的一些場景中顯著提升了性能,同時新的開發模式要求策略同學關注算子級別的實現,減少對調度邏輯的關注。在產品側DPP-后臺提供了產品化工具支持本地調試和可視化管理。

一、DPP整體架構

DPP依賴于算法平臺的引擎服務(FeatureServer,召回引擎, 精排打分),提供“開箱即用”的召回,粗排,精排服務。采用“熱加載技術”解決算法平臺的工程和算法同學策略迭代效率問題,支持策略隨時發布,讓他們可以專注于業務邏輯,即可擁有穩定的推薦在線服務。

圖片

圖1.0 DPP服務整體架構

平臺特性

  1. 快速迭代:通過系統解耦,實現算法、策略的快速迭代。
  2. 效果分析自動化:打通數據平臺,BI數據分析標準化。
  3. 靈活實驗:通過分層實驗平臺,支持多層多實驗的靈活配置。
  4. 診斷方便:落地各子流程中間結果,支持算法、策略的細化分析;提供方便的監控告警,運維,時光機等問題排查工具。

二、DPP引擎演進

DPP編排引擎的迭代分為了3個階段:固定編排,靈活編排,圖化DAG編排;均是在策略迭代過程中,圍繞著“迭代效率”提升的不斷進化。下面分別介紹下各階段引擎產生的背景及其方案。

固定編排 - DPP-Engine

推薦業務一般都可以抽象為“召回->融合->粗排->精排->干預”等固定的幾個階段,每個階段通常是有不同的算法或工程同學進行開發和維護,為了提升迭代效率,通過對推薦流程的抽象,將各階段的邏輯抽象為“組件"+"配置”,整體的流程同樣是一個配置,統一由“編排引擎”進行調度,同時提供統一的埋點/日志等。讓工程或算法同學可以關注在自己的業務模塊和對應的邏輯,而框架側也可以做統一的優化和升級。

DPP-Engine就是在此基礎上,將業務策略抽象為“初始層->召回層->融合層->粗排層->精排層->干預層”這6層, 有DPP負責串行調度這6層,每一層有若干個組件組成,各層將結果進行合并后傳遞到下一層(也就是List)。

圖片

圖1.2-1 DPP-Engine層編排

通過分層,DPP-Engine較好的支持了業務的快速迭代,業務“各層”的開發同學可以獨立迭代。但是隨著場景的增多,對“靈活”編排有了更多的需求,比如不固定6層,層內可有自己的"編排"等。

其次對于DPP平臺同學來說,DPP-Engine嵌入在DPP系統內, 不利于引擎的迭代和維護。

靈活編排 - BizEngine

BizEngine根據策略同學提供的組件及其編排流程,負責執行和調度,包括組件間的并發。它在推薦系統鏈路中的位置如下圖:

圖片

圖1.3-1 DPP系統(BizEngine)

目前在BizEngine看來,“組件”是策略開發的最小粒度,策略同學在DPP-后臺中可以在場景維度劃分桶(小流量桶, 分層桶),在桶可以配置不同的層編排,默認為6層:INIT層->召回層->融合層->粗排層->精排層->干預層。分別在層內可以配置不同的組件。一次請求中,BizEngine負責按層進行調度(層與層之間為串行調度),層內的組件根據組件間的依賴進行串行或者并發調度。

圖片

圖1.3-2 編排管理及其配置協議

用戶請求到DPP后, 會通過AB分流得到該請求(用戶)命中的所有實驗(包括桶,層,實驗),DPP解析命中配置后,可以構建出BizEngine需要的入參-編排配置(桶配置+實驗配置+組件配置),它會根據層及組件的配置構建出執行的層Stages,按組件維度提交到各線程池進行同步或異步的調度,流程可參考下圖:

圖片

圖1.3-3 BizEngine的組件調度和執行

從上圖可以看到我們是按層進行串行調度的,“分層”是按推薦的業務策略邏輯來分的,符合工程算法同學的分工和職責,特別是算法同學通常有各自負責的領域(召回模型,粗排模型,精排模型,干預),按層劃分和進行實驗可以有效提高迭代效率,做到相互之間不影響。“組件”則是BizEngine層內調度的單元,但是目前組件的粒度可大可小,比如社區的部分場景,他們在組件內拆分了更細粒度的Steps,并且獨立于組件進行調度(依賴DPP場景線程池或自定義線程池),因此策略代碼即負責了策略的邏輯, 還需要負責策略邏輯單元(Step)的調度。由此可以看出BizEngine未來的可進一步發展的方向:

  1. 按層進行串行調度,即便層與層組件之間為串行,也需要按層調度,存在一定開銷。
  2. BizEngine的線程調度和策略內自定義調度的沖突,線程池資源難于實現高效利用。
  3. “組件粒度”問題:目前看策略同學實現的組件對BizEngine來說是“邏輯黑盒”,里面可能是CPU,也可能是IO,也可能是一個發起并發任務的模塊,可能涉及自定義的線程池資源。
  4. 隨著業務不斷迭代, 策略組件的遷移和重構成本逐漸上升;缺少“組件”/“代碼”共享及發現的機制,不利于我們通過“組件復用”的方式去提升迭代效率。

圖化DAG - DagEngine

為什么需要做圖化?

那為什么要去做“圖化”/“DAG”呢?其實要真正要回答的是:  如何應對上面看到的挑戰?如何解決BizEngine目前發展碰到的問題?

從業界搜推領域可以看到不約而同地在推進“圖化”/“DAG”。 從TensorFlow廣泛采用之后,我們已經習慣把計算和數據通過采用算子(Operation)和數據(Tensor)的方式來表達,可以很好的表達搜索推薦的“召回/融合/粗排/精排/過濾”等邏輯,圖化使得大家可以使用一套“模型”語言去描述業務邏輯。DAG引擎也可以在不同的系統有具體不同的實現,處理業務定制支持或者性能優化等。

通過圖(DAG)來描述我們的業務邏輯,也帶來這些好處:為算法的開發提供統一的接口,采用算子級別的復用,減少相似算子的重復開發;通過圖化的架構,達到流程的靈活定制;算子執行的并行化和異步化可降低RT,提升性能。

圖片

圖化架構

圖化是要將業務邏輯抽象為一個DAG圖,圖的節點是算子,邊是數據流。不同的算子構成子圖,用于邏輯高一層的封裝,子圖的輸出可以被其他子圖或者算子引用。圖化后,策略同學的開發任務變成了開發算子,抽象業務領的數據模型。不用再關心“并行化異步化”邏輯,交由DAG引擎進行調度。“算子”要求我們以較小粒度支持,通過數據實現節點的依賴。

圖化定義了新的業務編排框架,對策略同學來說是“新的開發模式”,可分為3個部分:一個是我們會定義算子/圖/子圖的標準接口和協議,策略同學實現這些接口,構建業務的邏輯圖;二是DAG引擎,負責邏輯圖的解析,算子的調度,保證性能和穩定性;三是產品化,DAG Debug助手支持算子/圖/子圖的開發調試,后臺側提供算子/子圖/圖的可視化管理。整體架構參考下圖:

圖片

圖4.0.0 - DPP圖化框架

圖片

圖4.0.1 - DagEngine

圖化核心設計和協議

1.算子

  • 算子接口定義Processor<O>
public interface Processor<O> {
    /**
     * 執行邏輯
     *
     * @param computeContext 執行上下文信息
     * @return 返回執行結果
     */
    DataFrame<O> run(ComputeContext computeContext, DataFrame... inputs);
}
  • 算子注解@DagProcessor

通過注解可對算子進行描述和提供運行時信息:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface DagProcessor {
    /**
     * 標記IO/CPU, 影響DagEngine的調度
     * @return
     */
    String type() default "IO";
    /**
     * 算子描述
     *
     * @return String
     */
    String desc() default "";
    /**
     * 用于標識該算子會輸出的一些中間值, 可用于做運行時的依賴校驗
     * 可理解為是算子OP的side effects
     */
    String sideValues() default "";
}
  • 依賴配置@ConfigAnno)

算子通過注解(@ConfigAnno) 一是聲明算子需要的配置(通過DPP-后臺實驗配置進行配置), 二是運行時DAG引擎會對注解的值進行注入。

  • 依賴數據@DependsDataAnno

算子節點上游的數據,通過接口參數也會透傳過來(DataFrame數組),算子內可以通過dataFame.getName()獲取數據的唯一標識(請求session內唯一)。

算子的返回作為該算子的輸出數據,通過name可以獲取, 比如 @DependsDataAnno(name = "某一路的輸出",desc = "recall1")。

寫策略邏輯過程中的中間變量是我們必不可少的,算子可以通過注解@DagProcessor#sideValues聲明會輸出那些數據(names),通過name 可以獲取。

比如依賴了同一個算子(多個實例),它的輸出name是一樣的,下游獲取需要通過這個優先級決定。

Note:@DagProcessor#sideValues 可能作為必須的,只有sideValues聲明了的數據,才可以被依賴算子引用,這有助于我們管理和防止依賴不存在的數據。

Note:算子獲取sideValue時有多相同name的數據時,通過配置指定算子優先級。

2.圖/子圖

  • 圖/子圖/配置文件

圖分為圖和子圖,一個場景可以有多個圖,可按垂直桶制定不同的圖;子圖定位為業務邏輯模版,可以將若干個獨立算子組裝為具有特定業務含義的“子圖”,子圖和算子一樣可在場景大“圖”中進行配置,即運行時可有多個“實例”,實現邏輯的復用和配置化。

圖或子圖通過“配置文件”文件來描述,考慮到可讀性和是否支持注釋等特性,確定選用yaml來定義。

  • 協議

子圖

## 子圖(定位為邏輯模版, 包含: 若干個算子及其依賴關系, 子圖的配置及其默認值
## Note: 子圖的配置實際為算子的配置, 在算子中引用
name: 'Recall子圖1' ## 場景全局唯一
type: 'subgraph' ## 標記圖為"子圖"
configs: ## 子圖包含配置項( 指定默認值 )
  - name: 'configKey1' ## 
    value: '默認值Value, 可為string, json等, xx'
  # - 其他配置及其默認值
  # ...
nodes: ## 子圖包含的所有算子, 通過dpends指定依賴.
  ## 比如一路召回
  - name: 'fistRecallOp1'
    op: 'com.dag.demo.recrecall.FirstRecallOP'
    depends: []
    # 指定子圖中該算子的默認值
    configs:
    - name: 'configKey1'
      value: 'fistRecallOp1s value'
  - name: 'otherRecall1'
    op: 'com.dag.demo.recrecall.OtherRecallOP'
    depends: ['fistRecallOp1']

## 圖(場景邏輯描述, 包含若干個算子或子圖, 及其他們的依賴關系, 圖的配置及其默認值(Note: 圖的配置實際為算子的配置, 在算子中引用)
name: '場景圖Name' ## 場景全局唯一
type: 'graph'
configs: ## 圖包含配置項( 指定默認值 )
  - name: 'configKey1'
    value: '默認值Value, 可為string, json等'
  # - 其他配置及其默認值
  # ...
nodes: ## 圖包含的所有算子或子圖, 通過dpends指定依賴.
  ## 比如一路召回
  - name: 'fistRecallOp1'
    op: 'com.dag.demo.recrecall.FirstRecallOP'
    depends: []
  - name: 'otherRecall1'
    op: 'com.dag.demo.recrecall.OtherRecallOP'
    depends: ['fistRecallOp1']
  ## 子圖1( 為`Recall子圖1`的實例 )
  - name: 'someRecallComplex1'
    op: '$Recall子圖1' ## 依賴該子圖
    configs: ## 子圖包含配置項( 指定默認值 )
      - name: 'configKey1' 
        value: 'fistRecallOp1s value'
        ## 覆蓋這兩個算子的默認值
        targets: ['recallGroup1', 'dssmRandomBatchRecall']
      ## todo 修改op的配置
      ## 
    depends: ['fistRecallOp1']
  ## 子圖2( 為`Recall子圖1`的實例 )
  - name: 'someRecallComplex1'
    op: '$Recall子圖1' ## 依賴該子圖
    depends: ['fistRecallOp1']

3.算子配置如何獲取? 如何配置?

圖通過算子(子圖)+數據依賴的DAG描述了業務的邏輯關系,配置的作用就是影響邏輯如何生效。這些配置通過“實驗/AB”來決定,不同的實驗就是對圖或算子的不同配置。

  • 默認值

配置的默認值通過兩種方式指定:1/ 算子變量的默認值(代碼方式);2/ 圖或者子圖的Confgis#key#defaultValue

  • 運行時的值

算子某個配置在運行時的值,是通過該次請求命中的所有實驗進行配置融合和覆蓋后得到的。

  • 如何配置?

實驗配置中:

需要考慮配置key在子圖和算子中的name作為前綴,規則為<subGraph'sName>.<op'sName>.<key'sName>,若算子不在子圖中(即, 直接配置在主圖中),那么配置為_.<op'sName>.<key'sName>。

算子代碼中:

通過注解 @ConfigAnno(key = "key'sName")來獲取對的key'sName的值. 運行時DAG引擎負責識別<subGraph'sName> 和<op'sName>。

配置支持json和dto對象綁定,DAG運行時實現緩存和校驗指定Json配置和類的映射,@ConfigAnno(key = "somepojo.value",isJson = true,clazz = SomePojo.class),DAG引擎負責反序列化。

圖化相關特性/結果

  • DPP圖化落地廣告/社區等場景。

圖片


  • 圖桶推全SOP流程: 通過引入"分支"概念,圖桶推全變為合入Master,待推全各桶由各Owner自行合并Master。支持一分支綁定多桶。簡化了場景編排迭代流程。
  • 圖編輯可視化: 支持算子及其依賴的表單化修改,提升修改效率和易用性。

三、總結

DPP編排引擎經歷了固定編排,靈活編排到圖化DAG編排三個階段,持續提升策略迭代效率。

圖片

圖化DAG編排在我們落地的一些場景中顯著提升了性能,同時新的開發模式要求策略同學關注算子級別的實現,減少對調度邏輯的關注。在產品側DPP-后臺提供了產品化工具支持本地調試和可視化管理。

未來我們可以進一步探索圖化DAG編排在更多業務場景中的應用,尤其是需要高性能和靈活定制的場景。其次加強算子復用機制和標準化建設,降低組件遷移與重構成本, 持續優化DagEngine的高性能特性,如DataFrame數據結構的使用,以進一步提升系統性能。 并且隨著引擎及機器學習平臺圖化的推進,我們有可能也去端到端鏈路上實現“全圖化”。用一張圖描述一個業務的策略邏輯。

責任編輯:龐桂玉 來源: 得物技術
相關推薦

2023-08-21 19:37:21

得物DGraph引擎

2011-08-16 16:24:28

全文檢索數據挖掘

2019-01-28 08:31:47

360架構系統

2024-08-22 12:35:37

2025-04-17 04:00:00

2012-12-28 13:16:35

大數據架構

2012-12-31 12:02:56

百度推薦引擎數據架構

2016-03-15 16:24:47

集群調度框架演進

2023-11-01 18:06:46

彩虹橋架構性能

2024-06-03 10:19:05

2023-07-02 11:14:21

工具TypeScript框架

2024-11-13 18:57:49

2023-09-15 09:34:54

2022-03-25 08:40:32

分布式架構

2021-08-03 07:21:14

架構微服務開發

2021-08-18 17:16:10

Git分片讀寫分離

2019-07-23 18:15:26

技術大數據數據庫

2024-03-07 10:46:13

人工智能?

2015-07-24 12:21:14

wot 2015移動開發者大會

2020-02-10 19:16:52

服務端高并發架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩一区二区三区精品 | av免费在线播放 | 色www精品视频在线观看 | 日韩中文一区二区三区 | 亚洲精品18 | 91网视频 | 久久久久久久久国产 | 日韩中文字幕免费在线 | 天天摸天天干 | 久久se精品一区精品二区 | 亚洲精品专区 | 九九国产在线观看 | 精品亚洲永久免费精品 | 精品一区二区三区在线观看国产 | 国产中文原创 | 久久久亚洲 | 日韩中文字幕第一页 | 国产精品亚洲一区二区三区在线 | 欧美精品电影一区 | 亚洲精品一区二区在线观看 | 中文字幕乱码视频32 | 免费在线观看一区二区三区 | 免费在线观看av的网站 | 韩日一区二区三区 | 91麻豆蜜桃一区二区三区 | 国产成人精品a视频一区www | 天天人人精品 | 久久人爽| www.亚洲一区| 欧美成年黄网站色视频 | av电影一区二区 | 精品久久久久久久久久久久久久 | 老外黄色一级片 | 久久国内 | 7777久久 | 夜夜爽99久久国产综合精品女不卡 | 久久久女 | 欧美日韩国产在线观看 | 午夜视频网站 | 久久里面有精品 | 国产福利在线视频 |