全部產品
Search
文件中心

Artificial Intelligence Recommendation:A/B服務整合

更新時間:Nov 15, 2024

在推薦情境下,使用者經常需要調整召回策略、排序模型以及模型參數以測試新思路。為此,PAI-Rec開發了一款輕量級A/B測試服務,旨在最小化對現有系統的幹擾,並支援快速實驗。目前,該服務已提供伺服器端的實驗功能。

A/B服務介紹

A/B服務主要包括以下組件:

  • AB Web控制台:作為A/B服務後台管理系統,用於實驗配置。資料會持久化到MySQL裡。

  • AB Server:提供HTTP API服務,並部署在PAI-EAS中。該服務從MySQL中讀取資料,要求EAS能夠直接存取MySQL資料庫,確保網路連通性。詳情請參見配置網路連通

  • AB SDK:需整合到服務端程式中,支援實驗配置與流量分配策略。通過SDK可實現請求分流及實驗匹配,並依據返回結果採取進一步行動。目前的版本支援Go、Python和Java語言。

整合A/B服務實驗功能

操作原理

在召回運行時,首先檢查是否存在相關的實驗參數,如果存在,根據已有的召回執行個體反射調用 CloneWithConfig方法,並傳入實驗參數,產生新的召回執行個體。新產生的召回執行個體將被註冊到系統中。後續調用時,系統將直接返回登入的執行個體,避免重複建立。

操作步驟

  1. 設定環境

    環境值可設為dailyprepubproduct,設定方法有兩種:

    • config.json中配置RunMode

    • 設定環境變數PAIREC_ENVIRONMENT,其優先順序高於config.json中的設定。

  2. 配置實驗參數

    PAI-Rec預先定義了一些實驗參數,設定這些參數時必須嚴格遵守命名規則,否則即使匹配到實驗也無法找到相應參數。

    參數名稱

    類型

    說明

    樣本

    類目+".RecallNames"

    json array

    召回的列表,需要包含所有的召回。

    "default.RecallNames":[ "HomepageEtrecRecall"**, **"HomepageDssmRecall"]

    "recall."+具體的recall name

    json object

    根據recall config,建立新的recall。

    {"recall.MyRecall":{"version":"v2"}}

    filterNames

    json array

    過濾列表,包含所有的過濾流程。

    {"filterNames":["UniqueFilter", "UserExposureFilter"]}

    rankconf

    recconf.RankConfig

    排序演算法的配置。

    "rankconf":{"RankAlgoList":["pai_homepage_fm"],"RankScore":"${pai_homepage_fm}"}

    features.scene.name

    string

    Features load對應的情境名稱。

    "homepage"

    user_features.scene.name

    string

    User Features預期對應的情境名稱。詳情請參見User特徵預取

    "Home_feed"

    類目+".SortNames"

    json array

    排序模組的列表,需要包含所有排序的模組名稱。

    "default.SortNames": [

    "RetargetDistinctSort",

    "RetargetSort",

    "TagWeightSort",

    "PositionReviseSort",

    "DiversitySortHead" ]

    "sort."+具體的sort name

    json object

    根據sort config建立新的sort。

    {

    "sort.RetargetSortV": {

    "Debug": false,

    "BoostScoreConditions": [

    {

    "Conditions": [

    {

    "Name": "recall_name",

    "Domain": "item",

    "Type": "string",

    "Value": "retarget_u2i",

    "Operator": "equal"

    }

    ],

    "Expression": "score * 1.0"

    }

    ]

    }

    }

    generalRankConf

    recconf.GeneralRankConfig

    粗排的配置,包括user feature的擷取、演算法配置RankConf。具體操作,請參見粗排配置

    {"generalRankConf":{"FeatureLoadConfs":[{"FeatureDaoConf":{}}],"RankConf":{},"ActionConfs":[]}}

    coldStartGeneralRankConf

    recconf.ColdStartGeneralRankConfig

    冷啟動粗排配置。具體操作,請參見粗排配置

    {"coldStartGeneralRankConf":{"FeatureLoadConfs":[{"FeatureDaoConf":{}}],"RankConf":{},"ActionConfs":[]}}

    coldStartRankConf

    recconf.ColdStartRankConfig

    冷啟動召回,rank階段配置,指定rank演算法。

    {"coldStartRankConf":{"RecallName":"ColdStartRecall", "AlgoName":"linucb"}}

  3. 匹配實驗

    每次請求均需匹配實驗,並構建上下文。範例程式碼如下:

    	func (c *HomeFeedController) makeRecommendContext() {
    	c.context = context.NewRecommendContext()
    	c.context.Size = c.param.Limit
    	c.context.Param = &c.param
    	c.context.RecommendId = c.RequestId
    	c.context.Config = recconf.Config
    	c.context.Debug = c.param.Debug
    	abcontext := model.ExperimentContext{
    		Uid:         c.param.DistinctId,
    		RequestId:   c.RequestId,
    		FilterParams: map[string]interface{}{},
    	}
    
    	if abtest.GetExperimentClient() != nil {
    		c.context.ExperimentResult = abtest.GetExperimentClient().MatchExperiment(c.param.SceneId, &abcontext)
    		log.Info(c.context.ExperimentResult.Info())
    	}
    }
  4. 調整實驗參數

    RecommendContext對象可通過context.ExperimentResult擷取特定的實驗參數。使用GetLayerParams擷取某一層上的實驗參數,支援Get、GetInt、GetFloat、GetInt64方法。第一個參數是參數名,第二個參數是預設值,在找不到指定參數時返回預設值。

    	count := r.recallCount
    	if context.ExperimentResult != nil {
    		count = context.ExperimentResult.GetLayerParams("").GetInt("recall.base.count", count)
    	}
    	fmt.Println("test count", count)
  5. 對召回做實驗

    對於特定的召回做實驗時,可通過不同參數動態調整recall配置。需要遵循以下規則:

    • 參數名稱格式為:"recall."+已有的recall name

    • 參數配置應採用JSON映射形式。

    • 相關召回執行個體必須實現CloneWithConfig方法,用於基於給定參數產生新的召回執行個體。例如:

      type MyRecall struct {
      	version string
      }
      
      func NewMyRecall() *MyRecall {
      	r := MyRecall{version: "v1"}
      
      	return &r
      }
      func (m *MyRecall) CloneWithConfig(params map[string]interface{}) *MyRecall {
      
      	r := MyRecall{}
      	if _, ok := params["version"]; ok {
      		r.version = params["version"].(string)
      	}
      	return &r
      }

整合A/B服務參數功能

使用方式如下:

// 擷取到具體的情境名稱
scene := context.GetParameter("scene").(string)

// 根據情境擷取參數列表,然後用具體的 Get* function 擷取具體的參數值
count := abtest.GetParams(scene).GetInt("count", 100)
fmt.Println("recall count:", count)