查看特征是否生效

背景

在模型迭代和上线过程中,我们常常需要确认新添加或修改的特征是否按预期生效。有时,即使特征已在线上发生变化,模型的最终输出分数却没有变化,这使得判断特征的有效性变得困难。本文档旨在提供一套系统化的方法,通过深层分析来校验特征是否被模型正确接收和处理。

前置要求

  • 已成功部署用于排序的模型服务(例如,在PAI-EAS上)。

  • 已成功部署PAI-Rec引擎服务,并且在引擎或AB实验配置中,已配置调用上述模型服务并使用了目标特征。

校验特征是否生效

核心思路是:捕获一次真实的线上请求,将其特征数据本地化,然后通过修改特定特征值并重新请求,观察特征进入模型前的变化来判断特征是否被正确处理。

步骤一:捕获在线请求的特征数据

  1. 向推荐引擎服务发送Debug请求。登录PAI-Rec控制台,左侧菜单单击排查工具 > 推荐结果诊断,选择相应环境,打开调试模式,单击诊断发送请求。

    请确保该请求能够路由到您要验证的模型服务(例如,通过用户白名单或设置为100%流量)。当模型服务接收到Debug请求时,它会自动将引擎传入的特征数据以Protobuf(PB)格式保存到服务的挂载目录中。

    image.png

  2. 定位并下载特征文件。进入PAI-EAS 控制台,找到对应的模型服务实例。

    1. EAS控制台查看请求。打开使用的EAS模型服务,在日志页面根据requestid搜索Debug请求,并可看到对应的特征名称。

      image.png

      image.png

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

      image.png

      image.png

步骤二:本地分析与对照实验

使用以下 Python 脚本来解析下载的 pd 文件、修改特征并重新请求模型,以观察内部数据变化。

  1. 执行如下分析脚本。

    ## 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)
    
    1. 生成可读的特征文件on_line.txt。配置pathstr_path调用read_pb_and_request_and_save。这会生成一个 on_line.txt 文件,其中包含了所有请求特征,格式清晰可读。

    2. 修改特征并进行对照实验。打开 on_line.txt 文件,找到您关心的特征,手动修改其值。例如,将一个数值特征从 0.1 改为 0.9,或将一个 ID 特征替换为另一个值。召回的集合通常条目数量较多,您可以减少集合数量,只修改其中几条的特征。

    3. 获取Debug输出。保存修改后的 on_line.txt,然后运行脚本中的 predict_new_pb 函数(注意注释掉read_pb_and_request_and_save)。该函数会用您修改后的特征重新请求模型,并将详细的调试信息(包含 raw_features 和 generate_features)保存到 on_score.txt

  2. 结果验证。打开 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_featuresgenerate_features 却保持不变,且多次尝试都是同样效果。则问题可能是在线 FG 算子的处理逻辑与预期不符,您可以尝试进行离线验证:

  1. 找到 FG 配置文件:在您的模型项目中,找到用于精排的fg encoder特征配置文件。

  2. 模拟离线执行:使用 pyfg 等工具,将在 raw_features 中观察到的特征值作为输入,在本地离线执行 FG 转换。

  3. 比对结果:将离线 pyfg 的输出结果与在线 generate_features 的值进行比对。

    • 如果一致:说明在线 FG 逻辑正确执行了您的配置。

    • 如果不一致:说明在线环境与离线环境可能存在差异,需要进一步排查环境问题。