回调接口¶
回调接口也是 PAI-REC 内置的 api 接口。 回调接口主要用来落实时特征日志。单独拿出来介绍。
背景¶
实时特征是推荐中很重要的一环,尤其是其中的实时序列特征,一般来说能拿到较明显的推荐效果提升。然而实时特征对准确性的要求很高,如通过离线卡时间窗口关联的方式,由于很难估计系统各链路间的延时,很容易就出现特征不准确、特征穿越的问题,加上这些不准确的特征拿到适得其反的效果。
如何定义准确性?一个训练样本S_i(对应推荐请求R_i)中的实时特征,需要是推荐请求R_i时刻的user和item特征,因此最佳保证实时特征是在推荐请求打到推荐服务的时候,在算法计算推荐结果的同时,把recomid+user的实时特征+item的实时特征落入日志中(如Kafka等),然后再同步到 MaxCompute(ODPS) 中。
然而往往因为AB实验的原因,一个推荐服务不是接受所有的实验流量的,没有办法给所有的实验流量来落实时特征,训练的时候又往往需要全量的训练样本进行训练,这些样本都需要有实时特征才能发挥实时特征的效果。因此,最佳近似实时的方式是通过callback接口,简单来说,A服务如果想落实时特征(f1,f2,f3…),B服务在下发之前,会异步调用A服务的callback接口,告诉A服务下发列表,让A服务把这些特征给落下来。该方案灵活性也较高,A服务想落的实时特征不会跟B服务想落的产生冲突,且实时性有保障,下发时刻和算法获取特征的时刻是近似同时的,不会出现特征穿越的问题。
接口定义¶
接口名称¶
/api/callback
请求参数¶
参数名称 |
参数类型 |
是否必须 |
参数说明 |
用例 |
---|---|---|---|---|
scene_id |
string |
是 |
首页推荐 |
homepage |
uid |
string |
是 |
用户注册ID |
85578510 |
request_id |
string |
是 |
请求的唯一标识 |
d9cb1c8d-4d3f-491b-9ea3-380481dabde3 |
features |
json string |
否 |
用户特征 |
{“age”:25, “city”:”beijing”} |
item_list |
json list |
是 |
推荐的uid列表 |
[{“item_id”:”99886867”}, {“item_id”:”99888623”}] |
request_info |
json string |
否 |
请求信息 |
{“recom_id”:”12334234”} |
请求样例¶
curl 'http://host/api/callback' -d '{"uid":"84603208","request_id":"d9cb1c8d-4d3f-491b-9ea3-380481dabde3","scene_id":"homepage","features":{"age":25, "city":"beijing"}, "item_list":[{"item_id":"113939841"},{"item_id":"113764910"}],"request_info":{"recom_id":"1111111"}}'
返回数据¶
{
"code":200,
"msg":"success",
}
字段 |
类型 |
描述 |
示例 |
---|---|---|---|
code |
integer |
返回码标识 |
接口状态码,200成功 |
msg |
string |
提示信息 |
成功为success |
回调配置¶
Callback 流程主要分两部分,
加载 user/item 特征,
很多情况下如果使用 EasyRec 模型, item 特征是与模型绑定到一起的。 需要请求 easyrec 模型,拿到模型生成的 FG 特征
把上面的特征数据写入到消息队列(datahub) 中。
"CallBackConfs": {
"home_feed": {
"DataSource": {
"Name": "pairec_callback_dh",
"Type": "datahub"
},
"RankConf": {
"RankAlgoList": [
"ali_rnk_v2_woid_callback_public_v2"
],
"ContextFeatures": [
"none"
],
"Processor": "EasyRec"
}
}
}
home_feed 是场景名称,针对哪个场景落日志
DataSource
Type 消息队列类型,目前支持 datahub
pairec_callback_dh datahub 的数据源名称, 在 DatahubConfs 能找到
RankConf 配置的模型信息,和正常的引擎服务的模型配置一样,如果没有模型产生的特征信息,可以不配置
数据源配置¶
"DatahubConfs": {
"pairec_callback_dh": {
"Endpoint": "http://dh-cn-hangzhou-int-vpc.aliyuncs.com",
"AccessId": "<AccessId>",
"AccessKey": "<AccessKey>",
"ProjectName": "<ProjectName>",
"TopicName": "pairec_callback_log",
"Schemas": [
{
"Field": "request_id",
"Type": "string"
},
{
"Field": "module",
"Type": "string"
},
{
"Field": "scene",
"Type": "string"
},
{
"Field": "request_time",
"Type": "integer"
},
{
"Field": "user_features",
"Type": "string"
},
{
"Field": "item_features",
"Type": "string"
},
{
"Field": "request_info",
"Type": "string"
},
{
"Field": "user_id",
"Type": "string"
},
{
"Field": "item_id",
"Type": "string"
},
{
"Field": "raw_features",
"Type": "string"
},
{
"Field": "generate_features",
"Type": "string"
},
{
"Field": "context_features",
"Type": "string"
}
]
}
}
在上面的配置中, topic name 可以不用手动创建, PAI-REC 可以根据 topic name 及 schema 自动创建。
特征加载配置¶
特征加载配置 参考。这里不同一点就是 场景名称 + _callback 作为特征加载的场景别名。
home_feed_callback 的场景名称是 home_feed + _callback 来的。
"FeatureConfs": {
"home_feed_callback": {
"AsynLoadFeature": true,
"FeatureLoadConfs": [
{
"FeatureDaoConf": {
"AdapterType": "hologres",
"HologresName": "pairec-holo",
"FeatureKey": "user:uid",
"UserFeatureKeyName": "client_str",
"HologresTableName": "dwd_ali_user_all_feature_v2_holo",
"UserSelectFields": "*",
"FeatureStore": "user"
},
"Features": [
{
"FeatureType": "new_feature",
"FeatureName": "day_h",
"Normalizer": "hour_in_day",
"FeatureStore": "user"
},
{
"FeatureType": "new_feature",
"FeatureName": "week_day",
"Normalizer": "weekday",
"FeatureStore": "user"
},
{
"FeatureType": "new_feature",
"FeatureName": "rand_int_v",
"Normalizer": "random",
"FeatureStore": "user"
}
]
},
{
"FeatureDaoConf": {
"AdapterType": "hologres",
"HologresName": "pairec-holo",
"FeatureKey": "user:uid",
"UserFeatureKeyName": "client_str",
"HologresTableName": "dwd_ali_user_table_v3_expo_static_feature_v2_holo",
"UserSelectFields": "*",
"FeatureStore": "user"
}
}
]
}
}
日志格式¶
callback 请求数据包含一个 uid + item 列表。 很多请求下, user 的特征比较大,为了省空间,我们会把 user 特征 和 item 特征分开落下来。
user 特征日志,包含下面数据
request_id 请求ID, callback 请求里获得
scene 场景名称,callback 请求里获得
request_time 请求时间
user_features user 特征, json string
user_id 用户ID标识
request_info 额外的请求信息, callback 请求里获得
module 固定值 user , 表明是 user 特征
item 特征日志,包含下面数据
request_id 请求ID, callback 请求里获得
scene 场景名称,callback 请求里获得
request_time 请求时间
module 固定值 item , 表明是 item 特征
item_id item ID 标识
user_id 用户ID标识
raw_features easyrec 模型返回raw features
generate_features easyrec 模型返回的 FG 之后的特征信息
context_features easyrec 模型返回的上下文特征
item_features item 特征, json string