在推薦場景下,用戶經常需要調整召回策略、排序模型以及模型參數以測試新思路。為此,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)