在推薦情境下,使用者經常需要調整召回策略、排序模型以及模型參數以測試新思路。為此,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方法,並傳入實驗參數,產生新的召回執行個體。新產生的召回執行個體將被註冊到系統中。後續調用時,系統將直接返回登入的執行個體,避免重複建立。
操作步驟
設定環境
環境值可設為daily、prepub或product,設定方法有兩種:
在config.json中配置RunMode。
設定環境變數PAIREC_ENVIRONMENT,其優先順序高於config.json中的設定。
配置實驗參數
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"}}
匹配實驗
每次請求均需匹配實驗,並構建上下文。範例程式碼如下:
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()) } }調整實驗參數
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)對召回做實驗
對於特定的召回做實驗時,可通過不同參數動態調整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)