lpr的摸鱼记录v1.0
月度总结1.0
摸鱼快乐!
近一个月参与了Wearfit Pro App (简称WP)中推荐系统排序链路的CTR预估模块研发与优化工作。本文将总结个人在模型设计、特征工程与线上效果验证过程中的一些思考与收获。
Wearfit Pro 的视频内容模块以类似小红书的“双列短视频”形式展现,为用户提供更轻量化的健康生活内容推荐体验。尽管 App 本身还具备运动手环连接、健康数据指导、商城等功能模块,但这些与推荐系统链路关联较弱,当前我们主要聚焦在视频推荐部分的 CTR 预估优化上。线下关注的指标包括AUC、用户AUC(uAUC)、加权用户AUC(wuAUC)、MAE、MSE等,线上指标包括点赞收藏率、CTR(点击率)、用户渗透率以及后一天的用户留存率。
由于视频推荐功能刚刚上线,各类机制仍处于初步构建阶段,数据端也呈现出一系列挑战性特征,包括:
- 用户行为稀疏:整体用户点击率偏低,绝大多数用户每天仅触发极少推荐行为,训练样本稀疏;除此之外,通过数据分析还能检测到大量爬虫行为的存在。
- 冷启动问题突出:无论是新用户还是新内容(如短视频),都存在较长的“空窗期”,难以快速融入排序模型;
- 数据波动大:推荐位存在样式变动、内容池更新频繁,且由于审核机制刚刚健全,推流了大量科技数码视频以冲洗违规内容,导致样本分布不稳定;
- 负样本数量庞大:多数曝光未转化为点击,样本极度不平衡,训练易偏向负类。
基于以上问题,在特征工程、模型架构设计、Embedding表达优化、损失函数&负采样策略等角度进行了多轮线上/线下实验。
特征工程
由于视频推荐模块刚刚上线,行为数据尚不完备,我们在构建 CTR 预估模型时,特征工程成为提升模型效果的关键环节。我们从以下几个维度出发,设计并优化了多类特征:
基础侧特征
主要包括数值特征、离散特征以及列表类特征(基本处理逻辑还是常用的归一化、补空、分桶、log映射、截断等等),下面仅仅介绍一下我们能获取的特征不做详细数据展示,对统计和交叉特征仅作大概描述。
- 用户侧特征:包括如用户ID、设备型号、系统版本、性别、位置等常见特征,以及用户偏好等
- 物品侧特征:如视频ID、视频时长、作者、内容类型、发布时间等;
- 上下文特征:如曝光时间段、曝光次数、曝光场景等;
统计特征:
为了刻画用户的偏好强度,我们构建了若干基于滑窗的行为统计特征,例如用户窗口内活跃度、用户偏好和类别匹配结果的语义化、内容曝光情况、基于地理位置/IP分块的统计数据。这些特征一定程度上缓解了线下训练冷启动时用户画像难以描述的问题,以及线上实验用户渗透、留存过低的问题。(虽然大部分尝试没有收益)
交叉特征:
为了增强模型的表达能力,我们引入部分组合特征。显示交叉特征的构建往往收益较大,但需要注意,不同模型对相同显式交叉特征利用效果不同(通过TayFCS: Training-free Align Your Frames with Concepts and Semantics验证成功)。目前的结论是场景是一个很有趣的特征。
模型架构设计
目前已经探索的模型/方法:
- ESMM:这篇在之前的blog中提及过,是用于解决Selective Bias的架构,其本质是两个MoE模型分别作ctr和cvr的结果,该模型效果不好并且训练时间大大增加。查阅文章后,认为问题出在shared bottom,如果任务相关性不强,它优化的时候会出现梯度冲突、任务优化优先级有先后(跷跷板现象)
- MMoE:同上,多专家之间出现严重的极化现象,有的专家根本无法发挥作用,训练时间过长。
- GNOLR:这篇仅仅实现了GNOLR的Neural版本,这一基础版本用户偏好子任务相互独立,无法捕捉到每种反馈所特有的特征依赖关系,导致训练出来的累计概率不单调递增。为解决这种独立问题,提出的Nested版本使用用户偏好序列长度个双塔结构,最后逐用户偏好程度嵌套,训练成本过高,不适合用于当前场景。
- Wide&Deep、DCN、DCNv2等传统网络:效果与MLP接近(初步怀疑是交叉特征不足限制模型发挥,但是构造交叉特征会消耗大量推理耗时),于是后面的工作基本上在MLP上完成
- DCN^2:提出了一种新的仅密集层(onlydense layer),作为交叉层的替代方案。仅密集层在原始的密集空间中执行显式的特征交叉操作,而不是先将输入投影到低维空间。在资源不受限的情况下更优,但当前场景必须用cpu进行训练及推理。
除此之外,还尝试了其他包括知识蒸馏的优化方法,均会导致超时or某一线上指标崩盘。
Embedding表达优化
在本项目中,Embedding 表达能力对 CTR 模型性能有着直接影响。由于推荐链路中的用户ID、物品ID、tag类别 等字段均为稀疏离散特征,其分布高度不均,Embedding 学习面临以下主要挑战:
- 长尾现象严重:呈现典型的 Zipf 分布,少数高频 ID 占据大部分曝光,绝大多数 ID 为低频甚至一次都未出现的冷门值。
- 活跃用户训练不足:区别于其他常见App,WP场景下活跃用户极少,导致缺乏有效Embedding。
- Embedding过拟合与稳定性问题:在短期上线数据中,由于样本量有限,Embedding层易出现过拟合波动。
进行了如下的探索:
- 基于Group Embedding的冷启动优化。选择若干个分组字段,对用户进行分组(在我们的数据中,性别是一个比较良好的分组字段)。之后在预测阶段,如果遇到了冷启动用户,则使用该用户所在组别的平均user_id的嵌入值来表示当前用户的嵌入值,而非随机嵌入或生成全0向量,可以一定程度上缓解用户冷启动带来的模型表现下降。
- 复现了Sparse Optimizer和Frequency-Adaptive Learning Rate(FAL),这两个组件的作用分别是加速embedding层收敛和根据ID频率动态调整学习率缓解多轮过拟合。在本地和榜单测试中,引入这两个策略会显著加快模型收敛,并提升模型表现。但是引入Sparse Optimizer会导致模型出现更严重的过拟合(One-Epoch)现象,判断是原文的使用场景与我们的并不相同,因此原文需要调高嵌入层的学习率以缓解欠拟合现象,但由于我们的场景下,嵌入层本身就有一定的过拟合,因此实际上并不能照搬论文的内容。
- 使用Sbert对tag进行语义化处理,即使用Sbert替代nn.Embedding处理单独的tag
- Helen优化器:发现特征频率与特征emb的最高特征值之间存在正相关性,这种相关性凸显了参数空间中损失的不平衡分布,使得传统的优化器很难发现有效泛化的平坦的最小值,而导致将模型优化到次优状态,因而选择利用频率Hessian特征值正则化优化CTR模型。效果一般
- NEFTune:这篇文章本来是LLM方向,主要思想是加入噪声的嵌入提升指令微调效果,用在推荐系统这边存在一点缓解过拟合提高AUC的效果。
- 对过高频tag进行降采样后,再决定是否保留。(这一出发点是之前运维推流大量视频去除违规视频产生的)
损失函数&负采样
虽然这一内容是召回层应该做的,但是我们排序阶段获得的数据仍出现正负样本急剧不平衡的问题。具体情况是当前场景正负样本比例近1:500,导致click发生的类别在训练时反向传播梯度更新的几率更小,对loss的贡献也比较低,不利于其收敛,最终导致click不发生的类别主导了模型,使得模型整体偏向它们。针对此类问题,主要探索了Focal Loss一系列方法和负样本降采样。
Loss方法
针对正负样本急剧不平衡的问题,在CV目标识别领域有专门的解决方法:OHEM方法——Focal Loss及其变体。这个链接给出了经典的Focal loss,GHM loss的实现。他们的数学本质都是重加权,通过修改模型的 loss,在 loss 计算上,加大对少样本的 loss 奖励。
Focal Loss 是一种解决不平衡问题的经典 loss,基本思想就是把注意力集中于那些预测不准的样本上。GHM (gradient harmonizing mechanism) 是一种梯度调和机制(怎么又是gradient norm),GHM Loss 的改进思想有两点:
- 在使模型继续保持对 hard example 关注的基础上,使模型不去关注这些离群样本;
- 另外 Focal Loss 中, 的值分别由实验经验得出,而一般情况下超参 是互相影响的,应当共同进行实验得到。
这两种方法均在线下进行测试,效果不如传统的pointwise的BSE loss和pairwise的Ranking loss。感觉问题出在hard样本在推荐领域纯为特征表示难以分辨,而非cv的类似离群点导致的难样本,本质上来讲还是特征稀疏导致的。
负样本降采样
这个有点像data pruning(什么逆天联动),本质上都是抛弃一部分样本,但dp的时候往往导致性能的下降,而在极度不平衡的时候,负采样会提高一些性能。在实践中,更多的是做的uv向的负采样,对无点击行为的用户进行采样(这样的用户巨多)。尝试的策略如下:
- 全抛弃:这个虽然夸张,但是在线上获得了较好的用户渗透、点赞收藏等收益。从业务角度分析来说,就是这一行为导致线上为用户推流的都是常客看的视频,属于在讨好老用户(不管新用户死活)。当然,这一策略也导致了线上留存的暴跌。
- 随机采样、均匀采样方法
- 设计曝光置信度进行筛选:曝光置信度与Exposure BIas相关,其本质思想是“曝光而未点击的样本不一定是用户不喜欢的,直接作为负样本其置信度存疑”。因此,基于这篇文章的想法,进行对曝光置信度的模拟。
- 基于综述文章,尝试多种静态采样方法:包括基于用户相似度的USD方法、基于模拟社交网络图的SamWalker++方法。
这些还在探索中,目前看到线下效果随机的采样效果确实不如各种启发式/非启发式算法。
反思
也算是入门了搜推领域,做了一些实际的尝试并取得了一定的效果,写完技术性的总结,也应该写一些业务上的总结:
- 数据的重要性:模型训练的基础是特征,特征的基础是数据,在实际场景中,数据不能简单看作一组数字or字符串,它们具有实际的意义。因此,在进行特征工程的时候,不仅需要考虑数据分布等基本模型训练能用到的信息,还需要考虑其是否能为实际指标作出什么贡献。
- 线上指标和线下指标的gap:做的不管是ctr预估还是对用户完播的预估,其本质上还是对线上实际业务指标的映射,哪怕线下效果再好,也很难说线上能在诸多指标上取得进步。
- Traceback的重要性:当一个策略不太好使的时候,需要反思其是否具有业务意义,需要追溯其数据输出等自顶而下地查问题。