背景
在模型迭代和上线过程中,我们常常需要确认新添加或修改的特征是否按预期生效。有时,即使特征已在线上发生变化,模型的最终输出分数却没有变化,这使得判断特征的有效性变得困难。本文档旨在提供一套系统化的方法,通过深层分析来校验特征是否被模型正确接收和处理。
前置要求
已成功部署用于排序的模型服务(例如,在PAI-EAS上)。
已成功部署PAI-Rec引擎服务,并且在引擎或AB实验配置中,已配置调用上述模型服务并使用了目标特征。
校验特征是否生效
核心思路是:捕获一次真实的线上请求,将其特征数据本地化,然后通过修改特定特征值并重新请求,观察特征进入模型前的变化来判断特征是否被正确处理。
步骤一:捕获在线请求的特征数据
向推荐引擎服务发送Debug请求。登录PAI-Rec控制台,左侧菜单单击排查工具 > 推荐结果诊断,选择相应环境,打开调试模式,单击诊断发送请求。
请确保该请求能够路由到您要验证的模型服务(例如,通过用户白名单或设置为100%流量)。当模型服务接收到Debug请求时,它会自动将引擎传入的特征数据以Protobuf(PB)格式保存到服务的挂载目录中。

定位并下载特征文件。进入PAI-EAS 控制台,找到对应的模型服务实例。
在EAS控制台查看请求。打开使用的EAS模型服务,在日志页面根据requestid搜索Debug请求,并可看到对应的特征名称。


下载特征文件。如果根据requestid的查找不能满足分析需求,则可以查看模型挂载路径下载pb格式的特征文件。


步骤二:本地分析与对照实验
使用以下 Python 脚本来解析下载的 pd 文件、修改特征并重新请求模型,以观察内部数据变化。
执行如下分析脚本。
## pip install -U eas-prediction --user 安装eas_prediction的包 from eas_prediction import PredictClient from eas_prediction.torchrec_request import TorchRecRequest from eas_prediction.torchrec_predict_pb2 import PBRequest from google.protobuf import text_format def read_pb_and_request_and_save(path, str_path, client, req): with open(path, 'rb') as f: pb_data = f.read() pb_req = PBRequest() pb_req.ParseFromString(pb_data) req.request_data = pb_req resp = client.predict(req) print(resp) with open(str_path,'w',encoding='utf-8') as f: f.write(str(pb_req)) def predict_new_pb(str_path,debug_feature_path,client,req): with open(str_path, 'r', encoding='utf-8') as f: pb_data = f.read() pb_req = PBRequest() text_format.Merge(pb_data, pb_req) req.request_data = pb_req req.set_debug_level(2) resp = client.predict(req) with open(debug_feature_path, 'w', encoding='utf-8') as f: f.write(str(resp)) if __name__ == '__main__': path = 'torch_req/on_line.pb' # 下载的本地pb路径 str_path = 'torch_req/on_line.txt' # 本地解析pb为字符串要保存的路径 debug_feature_path = 'torch_req/on_score.txt' # 请求保存下来的raw feature(fg前的所有特征)和generate(fg后的所有特征) # 模型url配置 client = PredictClient('173xxxx.cn-beijing.pai-eas.aliyuncs.com', '{model_name}') # 模型token client.set_token('eas_token==') client.init() req = TorchRecRequest() # 1.先调用read_pb_and_request_and_save,发送一次请求并保存pb成字符串 # 2.修改要变化的特征 # 3.注释调read_pb_and_request_and_save,运行predict_new_pb read_pb_and_request_and_save(path,str_path,client,req) # predict_new_pb(str_path,debug_feature_path,client,req)生成可读的特征文件on_line.txt。配置
path,str_path调用read_pb_and_request_and_save。这会生成一个on_line.txt文件,其中包含了所有请求特征,格式清晰可读。修改特征并进行对照实验。打开
on_line.txt文件,找到您关心的特征,手动修改其值。例如,将一个数值特征从0.1改为0.9,或将一个 ID 特征替换为另一个值。召回的集合通常条目数量较多,您可以减少集合数量,只修改其中几条的特征。获取Debug输出。保存修改后的
on_line.txt,然后运行脚本中的predict_new_pb函数(注意注释掉read_pb_and_request_and_save)。该函数会用您修改后的特征重新请求模型,并将详细的调试信息(包含raw_features和generate_features)保存到on_score.txt
结果验证。打开
on_score.txt文件,可以看到两组关键信息:raw_features:模型服务收到的、经过特征预处理(如查表、拼接)但未经过 FG (Feature Generation) 算子编码的原始特征。generate_features:经过 FG 算子编码后,最终输入模型进行打分的特征。
通过以下检查来确认特征是否生效:
检查
raw_features:确认您修改的特征及其新值是否正确出现在raw_features中。这证明特征已成功传递到模型服务。检查
generate_features:观察该特征经过 FG 编码后,在generate_features中的表现。如果您的修改(例如,从0.1到0.9)导致了generate_features中对应 Embedding ID 或数值的变化,那么证明特征的在线处理逻辑是生效的。
问题排查:更换特征,模型分数未变化
如果您确认 generate_features 已经随您的修改而变化,但最终的模型分数(score)依然不变,这通常意味着该特征对于模型的权重几乎为零,属于模型效果问题,而非工程链路问题。
但如果您发现修改了 raw_features,generate_features 却保持不变,且多次尝试都是同样效果。则问题可能是在线 FG 算子的处理逻辑与预期不符,您可以尝试进行离线验证:
找到 FG 配置文件:在您的模型项目中,找到用于精排的fg encoder特征配置文件。
模拟离线执行:使用
pyfg等工具,将在raw_features中观察到的特征值作为输入,在本地离线执行 FG 转换。比对结果:将离线
pyfg的输出结果与在线generate_features的值进行比对。如果一致:说明在线 FG 逻辑正确执行了您的配置。
如果不一致:说明在线环境与离线环境可能存在差异,需要进一步排查环境问题。