在线学习因其能捕捉用户的动态行为,实现模型快速适应,已成为提升推荐系统性能的重要工具。然而,它对链路和模型的稳定性以及训练系统的性能提出了很高的要求。在基于原生TensorFlow设计在线推荐算法的过程中,我们发现了三个主要问题:
为了应对这些问题,我们对TensorFlow进行了弹性改造,实现了弹性特征伸缩体系,提高了模型稀疏性,并显著提升了线上效果。此外,我们还实现了模型体积压缩90%,完善了特征管理和模型稳定性监控。
在原生TensorFlow中,我们通过Variable声明变量,若变量超出单机承载能力,可使用partitionedvariables将其分配到不同的机器上。但这种方式需要预先指定维度,且声明后不可更改。由于推荐系统中大量使用稀疏特征,通常采用embeddinglookup_sparse一类的方法在一个庞大的Dense Variable中查找向量并求和,而不是进行矩阵乘法。开源TensorFlow限制了Variable在使用前必须声明维度大小,这带来了两个问题:
为了解决这些限制,我们对TensorFlow进行了优化,在服务器端新增了基于HashMap的HashVariable,其内存结构如下:
plaintext
在声明该变量时,只需添加一句,其他训练代码皆不需改动:
每个特征都通过哈希函数映射到一个2的64次方大小的空间内。当需要计算该特征时,参数服务器会按需惰性创建并返回。通过这种方式,我们打破了固定维度的限制,实现了特征的动态添加和删除。在此基础上,我们完成了Group Lasso FTRL、频次过滤和模型压缩等一系列算法。
经过这样的改造,在离线批量学习上,带来了以下变化:
plaintext
在线学习上,能带来如下变化:
plaintext
除了性能有明显的提升外,其最大的优势是不需要提前请求空间,训练可以无缝波动运行。
弹性架构的主要目的是特征优选,使模型自适应地选择最优特征,进而实现稀疏化,降低过拟合。本节介绍特征优选的两个核心技术:
稀疏化是算法追求的重要模型特性。从简单的L1正则化和Truncated Gradient,再到讨论累积梯度平均值的RDA,再到目前常见的FTRL,这些都是针对广义线性模型优化问题提出的稀疏性优化算法。然而,它们都没有针对稀疏DNN中的特征embedding层做特殊处理。将embedding参数向量当作普通参数进行稀疏化,并不能达到在线性模型中能达到的特征选择效果,从而无法有效地进行模型压缩。
例如,当包含新特征的样本进入时,一个特征对应的一组参数(如embedding size为7,则参数数量为7)被激活,FTRL判断特征中的部分参数有效时,也不能安全地将该特征删除。因此,在L1和L2正则的基础上,引入了L21正则(group lasso)和L2正则(exclusive sparsity)。L21正则(group lasso)可以在嵌入层中删除或保留整组参数,从而提升模型泛化性。
在L21中,由于内层L2正则将一个特征的所有参数施加相同的约束,可以将整组参数清除或保留,由此决定嵌入层中某些特征对应的嵌入向量是否完全删除,提升模型泛化性。因此称为group lasso。
Group lasso是弹性计算改造后,模型性能提升和压缩的关键。在我们实现的优化器中,Variable以及accum和linear两个slot也是KV存储。
讨论完特征动态删除的方法后,我们再分析特征的准入策略。
在Google讨论FTRL的文章中提到,在高维数据中大部分特征都是非常稀疏的,在亿级别的样本中只出现几次。那么一个有趣的问题是,FTRL或Group FTRL优化器能否删除(lasso)极低频特征?
在RDA的优化公式中,满足以下条件的特征会被置0:
plaintext
若在t步之前,该特征只出现过几次,未出现的step的梯度为0,随着步数增大,满足上述条件变得越来越容易。由此RDA是可以直观处理极稀疏特征的。但对于FTRL,要满足:
plaintext
其中,
plaintext
不仅与历史梯度有关,还与历史学习率和权重w有关。因此FTRL虽然也能处理极稀疏特征,但并没有RDA那么激进(此处还待详细地分析其下界,Group FTRL与此相似)。
由于FTRL在设计和推导时并未明确考虑极低频特征,虽然通过增大λ,的确能去除大量极低频特征,但由于约束太强,导致部分有效特征也被lasso,在离线实验中被证明严重影响性能。其次,对这些海量极低频特征,保存历史信息的工程代价是很高昂的(添加几倍的参数空间和存储需求)。
因此,我们提出能否在实时数据流上模拟离线频次过滤,为特征提供准入门槛,在不降低模型性能的基础上,尽量去除极低频特征,进一步实现稀疏化?
由于默认的embeddinglookupsparse对特征执行了unique操作(特征归一化以简化计算),因此在参数服务器端是不能获取真实特征和标签频次的。需要Python端对占位符统计后,上传给服务器端指定的变量,优化器通过插槽获得该变量后作出结合决策。
最朴素的想法是模拟离线频次过滤,对特征进行计数,只有达到一定阈值后才进入训练,但这会破坏数据完整性。为此,我们提出了两种优化方案:
基于泊松分布的特征频次估计
在离线shuffle后的特征满足平均分布,但对在线数据流,特征进入训练系统可视为泊松过程,符合泊松分布:
plaintext
其中n为当前出现的次数,t为当前的步数,λ为单位时间发生率,是泊松分布的主要参数,T为训练总步数。
plaintext
为特征最低门限(即最少在T时间内出现的次数)。
因此,我们可以通过前t步的特征出现的次数n,将t时刻视为单位时间,则
plaintext
。根据泊松分布,我们可以计算出剩余时间内事件发生的概率
plaintext
每次该特征出现时,都可按该概率
plaintext
做伯努利采样,特征在t步进入系统的概率用下式计算:
plaintext
经过真实线上数据仿真,它能接近离线频次过滤的效果,其λ是随每次特征进入时动态计算的。它的缺陷是:
动态调整L1正则方案
在经典的FTRL实现中,L1正则对每个特征都是相同的。这导致了在2.2.1中提到的问题:过大的L1虽然过滤了极低频特征,但也影响了模型的性能。参考各类优化器(如Adam)对learning_rate的改进,我们提出:通过调整L1正则系数,使得不同频次的特征有不同的lasso效果。
特征频次与基于最大似然估计(MLE)的参数估计的置信度相关,出现次数越低置信度越低。如果在纯频率统计基础上加入一个先验分布(正则项),当频率统计置信度越低的时候,越倾向于先验分布,相应的正则系数要更大。我们通过多个实验,给出了以下的经验公式:
plaintext
其中c是惩罚倍数,
plaintext
为特征最低门限,这两者皆为超参,
plaintext
是当前特征出现的频次。
我们在实际环境中使用了动态调整L1正则的方案。在UV-CTR不降甚至有些微提升的基础上,模型特征数比不使用频次过滤减少了75%,从而从实验证明了频次过滤对稀疏化的正面作用。它的缺陷也很明显:特征频次和正则系数之间的映射关系缺乏严谨证明。
在工程上,由于做了优化,如特征被优化器lasso后,只将其置0,并不会真正删除;在足够多步数后才删除。同时引入内存池,避免特征的反复创建和删除带来的不必要的性能损失。这就导致在训练结束后,模型依然存在大量0向量。导出时要进一步做模型压缩。
由于引入了HashPull和HashPush等非TF原生算子,需要将其裁剪后转换为原生TF的op。我们将这些步骤统称为图裁剪(GraphCut),它使得线上推理引擎不需要做任何改动即可兼容弹性改造。由于有效特征大大减少,打分速度相比原引擎提升50%以上。
我们将图裁剪看作TF-graph的静态优化问题,分为3个步骤:
我们完成了残缺简约的图裁剪工具,在模型热导出时调用,将模型从原先的8GB左右压缩到几百兆大小,同时保证模型打分一致。
在线学习的波动性非常重要。我们将线上真实效果与实时模型生成的效果进行了严密的监控,一旦样本偏离过多,就会触发报警。
由于需捕捉时变的数据变化,因此不能用固定的离线数据集评价模型结果。我们使用阿里流式日志系统SLA最新流入的数据作为评价样本,以滑动窗口先打分后训练,既维持了不间断的训练,不浪费数据,同时尽可能高频地得到最新模型效果。
我们对如下核心指标进行了监控:
线上与训练目的之间的对应关系如下表:
plaintext
通过HTTP接口,每隔一段时间发送监控数据,出现异常会及时产生钉钉和邮件报警。下图是对9月20日至27号的监控,从第二张图表来看,模型能较好地顺应当前数据流的打分分布。
User-AUC:传统的AUC并不能完全描述UV-CTR,因为模型很可能学到了不同用户间的偏序关系,而非单个用户在不同offer下的点击偏序关系。为此,我们使用了User-AUC,它尽可能地模拟了线上UV-CTR的计算过程,在真实实验中,监控系统的UV-CTR小时报表与实时模型输入的User-AUC高度一致。
目前算法已经在支付宝首页的多个推荐位上线。推荐系统根据用户的历史点击,融合用户画像和兴趣,结合实时特征,预测用户CTR,进而提升系统整体点击率。
我们以推荐位业务为例说明,其采用了经典的wide&deep网络结构,其稀疏部分包含数百级别的group(见下段备注1)。一天流入约百亿样本,标签的join窗口为固定时长。由于负样本占大多数,下游链路对正负样本做了1:8的降采样(见下文备注2)。
训练任务采用蚂蚁统一训练平台构建,并使用工作流进行定时调度,离线和在线任务的其他参数全部相同。Batchsize为512,每200步(即20万样本)评估一次结果,定时将模型通过图裁剪导出到线上系统。当任务失败时,调度系统会自动拉起,从检查点恢复。
该推荐业务的在线学习桶最近一周相比线上多模型融合最优桶提升4.23%,相比随机对照提升达34.67%。另一资讯推荐业务其最近一周,相比DNN基准UV-CTR提升+0.77%,PV-CTR提升+4.78%。实验效果相比有较大的提升。
备注1:group embedding是将相似的embedding特征分组,各自lookup求和后再concat,使得特征交叉在更高层进行。其设计是考虑到不同group的特征差异很大(如user和item),不应直接对位求和。
备注2:推理打分仅做点式排序,采样虽改变了数据分布但不改变偏序关系,因此并未在训练上做补偿。
弹性特征已经成为蚂蚁实时强化深度学习的核心要素。这只是第一步,在处理特征空间按需创建问题后,它会带来一个充满想象力的底层架构,许多技术都可以在此基础上深入挖掘:在工程上,可以继续从分钟级向秒级优化,进一步提升链路实时性并实现模型增量更新;在算法上,我们正在探索如样本重要性采样,自动特征学习,在线线性规划与DNN的结合,优化器结合决策等技术。
由于在线学习是一个复杂的系统工程,我们在开发和调优过程中遇到了大量的困难,涉及样本回流,训练平台,模型打分,线上评价等一系列问题,尤其是波动性,但基本都逐一克服。为了保证线上结果稳定可信,我们在观察和优化两三个月后才发布这篇文章,希望和业界同仁一起交流讨论。