抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

美团技术年货:1200+页电子书,覆盖前后端、算法、数据、安全、测试、顶会论文

新年将至,年味渐浓。虽然疫情的阴霾还没彻底消散,但是相信很多人都对2022年的春天充满了期待。期待春暖花开,期待国泰民安,期待早一天在阳光下自由地呼吸。

老规矩,一年一度的美团技术年货如期而至。

在2022年春节到来之际,我们精选过去一年公众号50多篇技术文章以及20多篇国际顶会论文,整理制作成一本厚达1200多页的电子书,作为新年礼物赠送给大家。

这本电子书内容覆盖前端、后端、算法、数据、安全、测试等多个领域, 希望能对同学们的工作和学习有所帮助。

大家如果觉得有价值,也欢迎转给更多有相同兴趣、积极上进的同事和朋友们,一起切磋,共同成长。

最后,祝大家阖家欢乐,健康平安。新的一年,「虎」力全开,走出个「龙行虎步」,闯出个「虎虎生威」!

如何获取?

关注「美团技术团队」微信公众号,回复 【2021年货】,即可获取电子书的下载链接,大家可免费在线阅读、下载。

温馨提示:今年,我们不仅为大家准备了2021年的年度合集,同时我们将2019年到2021年美团技术团队前端、后端、算法的文章进行了分类整理,同时将安全、运维、测试相关的文章做了综合,大家可以选择性下载或者阅读。

  • 2021美团技术年货合辑:共1250页,约108M;
  • 2019年-2021年前端篇:共735页,约52M;
  • 2019年-2021年后端篇:共950页,约65M;
  • 2019年-2021年算法篇:共920页,约75M;
  • 2019年-2021年综合篇:共475页,约37M。

因文件较大,可能需要一点耐心。因部分文章中的动态图片无法在电子书中进行完全的展示,大家可以移步美团技术团队官方博客 tech.meituan.com 或在美团技术团队公众号历史文章中进行查阅,感谢您的理解。

往期技术年货

微信扫一扫,识别文末的二维码,关注「美团技术团队」微信公众号,回复【2020年货】、【2019年货】、 【2018年货】、【2017年货】,即可获取往期年货下载链接。

DSTC10开放领域对话评估比赛冠军方法总结

1. 背景

对话系统技术挑战赛DSTC(The Dialog System Technology Challenge)由微软、卡内基梅隆大学的科学家于2013年发起,旨在带动学术与工业界在对话技术上的提升,在对话领域具有极高的权威性和知名度。对话系统挑战赛今年已举办至第十届(DSTC10),吸引了微软、亚马逊、卡内基梅隆大学、Facebook、三菱电子研究实验室、美团、百度等全球知名企业、顶尖大学和机构同台竞技。

DSTC10共包含5个Track,每个Track包含某一对话领域的数个子任务。其中Track5 Task1 Automatic Open-domain Dialogue Evaluation较为系统全面地将开放领域对话的自动评估任务引入DSTC10比赛中。开放领域对话自动评估是对话系统的重要组成部分,致力于自动化地给出符合人类直觉的对话质量评估结果。相比于速度慢、成本高的人工标注,自动化评估方法可以高效率、低成本地对不同对话系统进行打分,有力促进了对话系统的发展。

不同于任务型对话有一个固定的优化目标,开放领域对话更接近人类真实的对话,评估难度更大,因而吸引了广泛的关注。DSTC10 Track5 Task1比赛共包含14个验证数据集(共包含37种不同的对话评估维度)和5个测试数据集(共包含11个评估维度)。美团语音团队最终以平均0.3104的相关性取得了该比赛的第一名,该部分工作已完成一篇论文MME-CRS: Multi-Metric Evaluation based on Correlation Re-Scaling for Evaluating Open-Domain Dialogue,并收录在AAAI2022 Workshop。

图1 DSTC10对话系统挑战赛

2. 赛题简介

开放领域对话评估比赛收集了对话领域论文中的经典数据集,包括14个验证数据集(12个Turn-Level级别数据集和2个Dialog-Level级别数据集)和5个测试数据集。

数据集中的每个对话主要包含以下信息:

  • Context:对话中的提问,或者说对话的上下文。
  • Response:针对Context的回复,也即评估的具体对象;对话数据集中的Response一般由不同对话生成模型产生,如GPT-2和T5。
  • Reference:人工给出的针对Context的参考回答,一般为5条左右。

每个对话包含多个评估维度,如Context和Response的相关性,Response本身的流畅度等。每个数据集的评估维度不同,14个验证集总共包含37种不同的评估维度,具体包含Overall、Grammar、Relevance、Appropriateness、Interesting等。每个评估维度都有人工标注的打分,打分从1到5,分数越高表示当前评估维度的质量越高。

验证集和测试集的统计信息如图2和图3所示:

图2 DSTC10 Track5 Task1验证集数据统计信息

图3 DSTC10 Track5 Task1测试集数据统计信息

其中Turns表示对应数据集中的对话轮数;Qualities表示数据集中每个对话的评估维度,每个评估维度都有对应的人工标注打分;Annos表示每个数据集的标注量。

在该比赛中,每个数据集每个对话每个评估维度都有人工标注的打分,打分范围一般为1到5,一般求均值用于相关性计算。参赛队伍需要设计评估指标用于预测每个对话不同评估维度的打分。每个数据集的每个评估维度的预测打分会和人工标注的打分计算Spearman相关性,最后的比赛结果基于全部测试数据集的评估维度求均值。

3. 现有方法和问题

3.1 现有方法

开放领域对话的自动评估方法主要分为三类。

Overlap-based方法

早期研究人员将对话系统中Reference和Response类比于机器翻译中的原句和翻译句,借鉴机器翻译的评价指标来评估对话质量。Overlap-based方法计算对话中Response和Reference之间的词重叠情况,词重叠越高打分越高。经典方法包括BLEU[1]和ROUGE[2]等,其中BLEU根据精确率衡量评估质量,而ROUGE根据召回率衡量质量。Response的评估依赖于给定的Reference,而开放领域下合适的Response是无限的,因此,Overlap-based方法并不适用于开放领域对话评估。

Embedding-based方法

随着词向量和预训练语言模型的快速发展,Embedding-based评估方法取得了不错的性能。基于深度模型分别编码Response和Reference,并基于二者的编码计算相关性打分。主要方法包括Greedy Matching[3]、Embedding Averaging[4]和BERTScore[5-6]等。Embedding-based方法相比Overlap-based方法有较大的提升,但是同样依赖于Reference,仍然存在较大的优化空间。

Learning-based方法

基于Reference的开放领域对话评估存在一个One-To-Many[7]困境:即开放领域对话合适的Response是无限的,但人为设计的Reference是有限的(一般为5条左右)。因此,基于对比Reference和Response的相似性(字面重叠或者语义相似)设计开放领域评估方法存在较大局限性。相比已有的Overlap-based方法和Embedding-based方法,ADEM方法[8]首次使用层次化的编码器来编码Context和Reference,并对输入的Response进行打分。ADEM方法基于模型打分和人工打分的均方误差来优化模型参数,期望逼近人类的打分。ADEM模型相比Overlap-based方法和Embedding-based方法取得了很大的成功,Learning-based方法也逐渐成为了开放领域自动化评估的主流方法。

为了不断提高对话评估的准确和全面性,各种不同的评估维度层出不穷。为了应对越来越多评估维度带来的挑战,USL-H[9]将评估维度分为Understandability、Sensibleness和Likeability三类,如图4所示。USL-H针对性提出了VUP(Valid Utterance Prediction)、NUP(Next Utterance Prediction)和MLM(Mask Language Model)3种指标,分别衡量对话中:

  1. Response是否通顺流畅。
  2. Context和Respose的相关程度。
  3. Response本身是否详细,更像人类等。

图4 USL-H评估算法的分层次模型

3.2 问题

现有的评估方法主要有以下问题:

设计的对话指标不够全面,难以综合衡量对话的质量

现有的自动评估方法主要聚焦在个别数据集的部分评估维度上。以当前较为全面的USL-H为例,该方法考虑了Response的流畅度、丰富度以及Context-Response句子对的相关性,但是USL-H忽略了:

  1. 更细粒度的Context-Response句子对的主题一致性。
  2. 回复者对当前对话的参与度。

实验证明,这些指标的遗漏严重影响了评估方法的性能。为了更全面稳定地评估多个对话数据集,设计考虑更多评估维度的指标势在必行。

缺乏有效的指标集成方法

现有方法大多倾向于为每种评估维度设计一种评估指标,这种思路面对越来越多的评估维度显得力不从心(考虑下比赛测试集共包含37种不同的评估维度)。每种对话维度的评估可能依赖数种评估指标,如Logical评估维度需要对话:1)Response流畅;2)Response和Context是相关的。设计基本的评估子指标,再通过合适的集成方法集成多个子指标打分,可以更全面有效表示不同的对话评估维度。

4. 我们的方法

针对评估指标不够全面,本文设计了5类共7种评估指标(Multi-Metric Evaluation,MME)用于全面衡量对话的质量。基于设计的5类7种基础指标,我们进一步提出了相关性重归一化方法(Correlation Re-Scaling Method,CRS)来集成不同评估指标的打分。我们将提出的模型称为MME-CRS,模型整体架构图5所示:

图5 模型总体架构设计图

4.1 基础指标

为了解决现有方法的第一个问题,即设计的对话指标不够全面,我们在比赛中设计了5类共7种评估子指标。

4.1.1 Fluency Metric (FM)

目的:分析Response本身是否足够流畅可理解。

内容:首先基于Dailydialog数据集[10]构建response流畅度数据集,流程如下:

  1. 在Dailydialog数据集中随机选择一个Response,并以0.5概率决定r是正样本还是负样本。
  2. 如果样本r是正样本,随机选择一种调整:a.不调整;b.对每一个停用词,以0.5的概率删除。
  3. 如果样本r是负样本,随机选择一种调整:a.随机打乱词序;b.随机删除一定比例的词语;c.随机选择部分词语并重复。

基于上述规则构建流畅度数据集后,在预训练模型SimCSE模型[11]上微调。微调后的模型可以计算任一对话的Response流畅度打分,记为FM打分。

4.1.2 Relevance Metric (RM)

目的:分析Context和Response的相关程度。

内容:基于Dailydialog数据集构建Context-Response句子对形式的相关性数据集,其中句子对相关为正样本,不相关则为负样本。负样本的通常构建思路是将Response随机替换成其他对话的Response。PONE方法[12]指出随机挑选的Respose和Context基本不相关,模型训练收益很小。因此,这里的做法是随机选择10条Response,并计算和真实Response的语义相关度,并选择排名居中的句子作为伪样本。构造数据集后再在SimCSE模型上微调,微调后的模型可用于计算对话中Context和Response的相关度打分,记为RM打分。

4.1.3 Topic Coherence Metric (TCM)

目的:分析Context和Response的主题一致性。

内容:GRADE方法[13]构建了Context和Response的主题词级别的图表示,并计算了Context和Response的主题词级别的相关度。相比粗粒度的相关性指标,GRADE更加关注细粒度级别的主题相关程度,是相关性指标的有效补充。TCM指标借鉴GRADE方法。

具体流程如下:首先提取Context和Response中的关键词构建图,其中每个关键词都是一个节点,只有Context和Response的关键词之间存在边。基于ConceptNet获取每个节点的表示,再使用图注意力网络(GATs)聚集关键词邻居节点的信息并迭代每个节点的表示,最后综合全部节点的表示得到对话的图表示。在主题词级别的图表示上连接全连接层用于分类,微调后的模型即可用于计算对话的TCM打分。

4.1.4 Engagement Metric (EM)

目的:分析生成Response的人或对话模型有多大的意愿参与当前对话。

内容:前面提到的指标都是从Context和Response视角评估对话质量,而用户参与度则是基于用户的视角来评估。用户参与度打分一般是0~5,分数越大,表示用户参与当前对话的兴趣越大。我们将ConvAI数据集[10]的参与度打分从1~5缩放到0~1,作为参与度打分数据集。预训练模型仍然使用SimCSE,用于预测对话的参与度打分。预训练后的模型可用于预测对话的用户参与度打分,记为EM。

4.1.5 Specificity Metric (SM)

目的:分析Response本身是否足够细节。

内容:SM指标用于避免Response模棱两可,缺乏信息量。

具体做法如下:序列Mask掉Response中的每一个Token,并基于SimCSE模型的MLM任务计算Negative Log-Likelihood损失,得到的打分称为SM-NLL。替换损失函数为Negative Cross-Entropy和Perplexity可以分别得到SM-NCE和SM-PPL打分,共3个SM指标打分。3个SM指标打分都需要分别归一化到0和1之间。

4.2 集成方法CRS

集成不同评估指标的打分是提高自动化对话评估效果的有效手段。

对每一个待评估的对话,基于上述5类7种基础指标可以得到7种不同的打分。对于待评估数据集的某个评估维度,需要综合7种指标打分得到一个综合打分,用于和人类打分计算相关性。我们的集成方法分为以下两步。

4.2.1 不同评估维度权重分布的计算

首先,计算验证集上每个数据集每个评估维度7种评估指标的相关性打分,相关性打分越大,认为该指标对该评估维度越重要。对越重要的评估指标赋予一个更大的权重,并将得到的权重在指标维度重新归一化,这样则得到了每个数据集每个评估维度上不同评估指标的权重分布:

其中$S{ijk}$是第$i$个数据集第$j$个评估维度上第$k$个评估指标的相关性打分,$d{ij}$是相关性打分的幂数,$d{ij}$越大则相关性打分越高的指标的权重就越大。一般当max($S{ijk}^{d{ij} }$)在1/3到1/2之间时集成效果最好,这是计算$d{ij}$的一种简单有效手段。实验中,将$d{ij}$设置为常数可以获得更好的泛化效果,我们将$d{ij}$设置为2,并在验证集上计算权重分布,再迁移到测试集上,取得了比赛最优性能。

在数据集维度,将不同数据集中相同评估维度的权重求均值,得到每个评估维度在不同评估指标上的权重分布:

注意这里得到的权重分布已经和具体数据集无关,可以将权重分布迁移到测试集上。

4.2.2 计算指标打分的加权和

对每个测试集的每个评估维度,计算7种指标打分并基于第一步的权重求加权和,得到综合打分:

加权得到的综合打分和人工打分计算相关性,得到每种评估维度上的模型打分和人工打分的相关性打分。

我们的集成方法基于指标的相关性打分赋予权重并重新归一化,所以将该集成方法称为相关性重归一化方法。在得到的MME指标上使用CRS集成方法,可得MME-CRS评估算法。

5. 实验分析

5.1 实验结果

我们的方法主要基于Dailydialog数据集预训练(除了EM子指标是使用ConvAI2数据集),在比赛验证集上计算集成方法的权重分布,最终在测试集上取得了0.3104的Spearman相关性打分。

图6展示了比赛基准模型Deep AM-FM[14]以及比赛Top5队伍在测试集上不同数据集评估维度的性能。本文的方法以0.3104的平均Spearman相关性系数取得了第一,且在5个数据集全部11个评估维度中的6个取得了第一,证明了本文方法的优越性能。

图6 测试集上Top 5队伍的Spearman相关性打分对比(%)

为了方便展示,图中方法采用了数据集-评估维度的展示方式。其中J、E、N、DT、DP分别表示JSALT、ESL、NCM、DST10-Topical、DSTC10-Persona数据集,而A、C、G、R分别表示Appropriateness、Content、Grammar、Relevance评估维度。我们对每个评估维度上最好的性能进行了加粗。

5.2 消融实验

在消融实验部分,我们以本文方法MME-CRS评估为基准,在集成阶段分别去除FM、RM、TCM、EM、SM、RM+TCM指标,对比不同指标在集成过程中的重要性。实验性能如图7所示:

图7 测试集上不同评估指标的消融实验(%)

相关性指标RM和主题一致性指标TCM都使用了对话中的Context和Response信息,因此在实验中同时去除这两个指标,观察对性能的影响。从图7中的实验结果可以看出:

  • TCM、RM和EM对于模型性能的贡献最大,打分集成阶段删除这三个评估指标后,测试集上的平均Spearman相关性打分分别降低了3.26%、1.56%和1.01%。
  • 粗粒度的RM指标和细粒度的TCM指标是有益的互相补充。如果分别去除RM或TCM指标,性能会有稍微下降;如果同时去除RM和TCM指标,评估方法缺乏了Context相关的信息,性能会大幅降低到11.07%。
  • SM指标在测试集上的提升基本可以忽略。我们分析原因是:测试集中用于生成Response的各个生成模型在测试集语料上过拟合较为严重,因此生成了很多非常详细,但和Context不相关的Response。因此SM指标的优劣对于测试集质量的评估基本没有作用。

5.3 CRS效果

为了分析集成算法CRS的作用,本文对比了MME-CRS和MME-Avg(将MME多个指标打分简单平均)两个评估方法的性能,如图8所示:

图8 MME-CRS和MME-Avg在测试集上的性能对比(%)

从图中可以看出,MME-CRS方法相比于MME-Avg高了3.49%,证明了CRS算法在集成子指标打分方面的优越性能。

6. 总结

在本次比赛中,我们总结了开放领域对话自动评估存在的两个主要问题,即评估指标不够全面和缺乏有效的指标集成方法。针对评估指标不够全面的问题,本文设计了5类7种评估指标用于全面衡量对话的质量;基于7种基础指标,提出了相关性重归一化方法来计算每种对话评估维度的集成打分。

虽然本文方法在DSTC10比赛中取得了较好的成绩,但后续我们将继续探索其他更有效的评估指标和指标集成方法。我们正在尝试将比赛中的技术应用到美团具体业务中,如语音交互中心的智能外呼机器人、智能营销和智能客服中,在多个不同维度评估机器、人工客服与用户的对话质量,不断优化对话效果,提升用户的满意度。

7. 参考文献

  • [1] Papineni, K.; Roukos, S.; Ward, T.; and Zhu, W.-J. 2002. Bleu: A method for automatic evaluation of machine translation. In Proceedings of the 40th annual meeting of the Association for Computational Linguistics, 311–318.
  • [2] Lin C Y. Rouge: A package for automatic evaluation of summaries[C]//Text summarization branches out. 2004: 74-81.
  • [3] Rus, V.; and Lintean, M. 2012. An optimal assessment of natural language student input using word-to-word similarity metrics. In International Conference on Intelligent Tutoring Systems, 675–676. Springer.
  • [4] Wieting, J.; Bansal, M.; Gimpel, K.; and Livescu, K. 2016. Towards universal paraphrastic sentence embeddings. In 4th International Conference on Learning Representations.
  • [5] Zhang, T.; Kishore, V.; Wu, F.; Weinberger, K. Q.; and Artzi, Y. 2019. BERTScore: Evaluating text generation with BERT. In International Conference on Learning Representations.
  • [6] Liu C W, Lowe R, Serban I V, et al. How NOT To Evaluate Your Dialogue System: An Empirical Study of Unsupervised Evaluation Metrics for Dialogue Response Generation[C]//Proceedings of the 2016 Conference on Empirical Methods in Natural Language Processing. 2016: 2122-2132.
  • [7] Zhao, T.; Zhao, R.; and Eskenazi, M. 2017. Learning discourse-level diversity for neural dialog models using conditional variational autoencoders. In Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers), 654–664.
  • [8] Lowe R, Noseworthy M, Serban I V, et al. Towards an Automatic Turing Test: Learning to Evaluate Dialogue Responses[C]//Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers). 2017: 1116-1126.
  • [9] Phy, V.; Zhao, Y.; and Aizawa, A. 2020. Deconstruct to reconstruct a configurable evaluation metric for open-domain dialogue systems. In Proceedings of the 28th International Conference on Computational Linguistics, 4164–4178.
  • [10] Zhao, T.; Lala, D.; and Kawahara, T. 2020. Designing precise and robust dialogue response evaluators. In Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, 26–33.
  • [11] Gao T, Yao X, Chen D. SimCSE: Simple Contrastive Learning of Sentence Embeddings[J]. arXiv preprint arXiv:2104.08821, 2021.
  • [12] Lan, T.; Mao, X.-L.; Wei, W.; Gao, X.; and Huang, H. 2020. Pone: A novel automatic evaluation metric for open-domain generative dialogue systems. ACM Transactions on Information Systems (TOIS), 39(1): 1–37.
  • [13] Huang, L.; Ye, Z.; Qin, J.; Lin, L.; and Liang, X. 2020. Grade: Automatic graph-enhanced coherence metric for evaluating open-domain dialogue systems. In Proceedings of the 2020 Conference on Empirical Methods in Natural Language Processing (EMNLP), 9230–9240.
  • [14] Zhang, C.; D’Haro, L. F.; Banchs, R. E.; Friedrichs, T.; and Li, H. 2021. Deep AM-FM: Toolkit for automatic dialogue evaluation. In Conversational Dialogue Systems for the Next Decade, 53–69. Springer.

作者简介

鹏飞,晓慧,凯东,汪建,春阳等,均为美团平台/语音交互部工程师。

招聘信息

美团语音交互部负责美团语音和智能交互技术及产品研发,面向美团业务和生态伙伴,提供语音和口语数据的大规模处理及智能响应能力。团队在语音识别、合成、口语理解、智能问答和多轮交互等技术上已建成大规模的技术平台服务,研发包括外呼机器人、智能客服、语音交互平台等解决方案和产品并广泛落地。我们长期招聘志同道合的伙伴,感兴趣的同学可以将简历发送至:yuanchunyang@meituan.com(邮件主题:美团平台语音交互部)

从0到1:美团端侧CDN容灾解决方案

1. 前言

作为业务研发,你是否遇到过因为 CDN 问题导致的业务图片加载失败,页面打开缓慢,页面布局错乱或者页面白屏?你是否又遇到过某些区域 CDN 域名异常导致业务停摆,客诉不断,此时的你一脸茫然,不知所措?作为 CDN 运维,你是否常常被业务方反馈的各种 CDN 问题搞得焦头烂额,一边顶着各种催促和压力寻求解决方案,一边抱怨着服务商的不靠谱?今天,我们主要介绍一下美团外卖技术团队端侧 CDN 的容灾方案,经过实践,我们发现该产品能有效减少运维及业务开发同学的焦虑,希望我们的这些经验也能够帮助到更多的技术团队。

2. 背景

CDN 因能够有效解决因分布、带宽、服务器性能带来的网络访问延迟等问题,已经成为互联网不可或缺的一部分,也是前端业务严重依赖的服务之一。在实际业务生产中,我们通常会将大量的静态资源如 JS 脚本、CSS 资源、图片、视频、音频等托管至 CDN 服务,以享受其边缘节点缓存对静态资源的加速。但是在享用 CDN 服务带来更好体验的同时,也经常会被 CDN 故障所影响。比如因 CDN 边缘节点异常,CDN 域名封禁等导致页面白屏、排版错乱、图片加载失败。

每一次的 CDN 故障,业务方往往束手无策,只能寄希望于 CDN 团队。而 CDN 的监控与问题排查,对 SRE 也是巨大的难题和挑战。一方面,由于 CDN 节点的分布广泛,边缘节点的监控就异常困难。另一方面,各业务汇聚得到的 CDN 监控大盘,极大程度上隐匿了细节。小流量业务、定点区域的 CDN 异常往往会被淹没。SRE 团队也做了很多努力,设计了多种方案来降低 CDN 异常对业务的影响,也取得了一定的效果,但始终有几个问题无法很好解决:

  • 时效性:当 CDN 出现问题时,SRE 会手动进行 CDN 切换,因为需要人为操作,响应时长就很难保证。另外,切换后故障恢复时间也无法准确保障。
  • 有效性:切换至备份 CDN 后,备份 CDN 的可用性无法验证,另外因为 Local DNS 缓存,无法解决域名劫持和跨网访问等问题。
  • 精准性:CDN 的切换都是大范围的变更,无法针对某一区域或者某一项目单独进行。
  • 风险性:切换至备份 CDN 之后可能会导致回源,流量剧增拖垮源站,从而引发更大的风险。

当前,美团外卖业务每天服务上亿人次,即使再小的问题在巨大的流量面前,也会被放大成大问题。外卖的动态化架构,70%的业务资源都依赖于 CDN,所以 CDN 的可用性严重影响着外卖业务。如何更有效的进行 CDN 容灾,降低 CDN 异常对业务的影响,是我们不断思考的问题。

既然以上问题 SRE 侧无法完美地解决,端侧是不是可以进行一些尝试呢?比如将 CDN 容灾前置到终端侧。不死鸟(Phoenix) 就是在这样的设想下,通过前端能力建设,不断实践和完善的一套端侧 CDN 容灾方案。该方案不仅能够有效降低 CDN 异常对业务的影响,还能提高 CDN 资源加载成功率,现已服务整个美团多个业务和 App。

3. 目标与场景

3.1 核心目标

为降低 CDN 异常对业务的影响,提高业务可用性,同时降低 SRE 同学在 CDN 运维方面的压力,在方案设计之初,我们确定了以下目标:

  • 端侧 CDN 域名自动切换:在 CDN 异常时,端侧第一时间感知并自动切换 CDN 域名进行加载重试,减少对人为操作的依赖。
  • CDN 域名隔离:CDN 域名与服务厂商在区域维度实现服务隔离且服务等效,保证 CDN 切换重试的有效性。
  • 更精准有效的 CDN 监控:建设更细粒度的 CDN 监控,能够按照项目维度实时监控 CDN 可用性,解决 SRE CDN 监控粒度不足,告警滞后等问题。并根据容灾监控对 CDN 容灾策略实施动态调整,减少 SRE 切换 CDN 的频率。
  • 域名持续热备:保证每个 CDN 域名的持续预热,避免流量切换时导致回源。

3.2 适用场景

适用所有依赖 CDN ,希望降低 CDN 异常对业务影响的端侧场景,包括 Web、SSR Web、Native 等技术场景。

4. Phoenix 方案

一直以来,CDN 的稳定性是由 SRE 来保障,容灾措施也一直在 SRE 侧进行,但仅仅依靠链路层面上的保障,很难处理局部问题和实现快速止损。用户终端作为业务的最终投放载体,对资源加载有着天然的独立性和敏感性。如果将 CDN 容灾前置到终端侧,无论从时效性,精准性,都是 SRE 侧无法比拟的。在端侧进行容灾,就需要感知 CDN 的可用性,然后实现端侧自动切换的能力。我们调研整个前端领域,并未发现业内在端侧 CDN 容灾方面有所实践和输出,所以整个方案的实现是从无到有的一个过程。

4.1 总体设计

图 1

Phoenix 端侧 CDN 容灾方案主要由五部分组成:

  • 端侧容灾 SDK:负责端侧资源加载感知,CDN 切换重试,监控上报。
  • 动态计算服务:根据端侧 SDK 上报数据,对多组等效域名按照城市、项目、时段等维度定时轮询计算域名可用性,动态调整流量至最优 CDN。同时也是对 CDN 可用性的日常巡检。
  • 容灾监控平台:从项目维度和大盘维度提供 CDN 可用性监控和告警,为问题排查提供详细信息。
  • CDN 服务:提供完善的 CDN 链路服务,在架构上实现域名隔离,并为业务方提供等效域名服务,保证端侧容灾的有效性。等效域名,就是能够通过相同路径访问到同一资源的域名,比如:cdn1.meituan.net/src/js/test.js 和 cdn2.meituan.net/src/js/test.js 能够返回相同内容,则 cdn1.meituan.net 和 cdn2.meituan.net 互为等效域名。
  • 容灾配置平台:对项目容灾域名进行配置管理,监控上报策略管理,并提供 CDN 流量人工干预等措施。

4.2 容灾流程设计

为保证各个端侧容灾效果和监控指标的一致性,我们设计了统一的容灾流程,整体流程如下:

图 2

4.3 实现原理

4.3.1 端侧容灾 SDK

Web 端实现

Web 端的 CDN 资源主要是 JS、CSS 和图片,所以我们的容灾目标也聚焦于这些。在 Web 侧的容灾,我们主要实现了对静态资源,异步资源和图片资源的容灾。

实现思路

要实现资源的容灾,最主要的问题是感知资源加载结果。通常我们是在资源标签上面添加错误回调来捕获,图片容灾可以这样实现,但这并不适合 JS,因为它有严格的执行顺序。为了解决这一问题,我们将传统的标签加载资源的方式,换成XHR来实现。通过Webpack在工程构建阶段把同步资源进行抽离,然后通过PhoenixLoader来加载资源。这样就能通过网络请求返回的状态码,来感知资源加载结果。

在方案的实现上,我们将 SDK 设计成了 Webpack Plugin,主要基于以下四点考虑:

  1. 通用性:美团前端技术栈相对较多,要保证容灾 SDK 能够覆盖大部分的技术框架。
  2. 易用性:过高的接入成本会增加开发人员的工作量,不能做到对业务的有效覆盖,方案价值也就无从谈起。
  3. 稳定性:方案要保持稳定可靠,不受 CDN 可用性干扰。
  4. 侵入性:不能侵入到正常业务,要做到即插即用,保证业务的稳定性。

通过调研发现,前端有 70%的工程构建都离不开 Webpack,而 Webpack Plugin 独立配置,即插即用的特性,是实现方案的最好选择。整体方案设计如下:

图 3

当然,很多团队在做性能优化时,会采取代码分割,按需引入的方式。这部分资源在同步资源生成的过程中无法感知,但这部分资源的加载结果,也关系到业务的可用性。在对异步资源的容灾方面,我们主要是通过对 Webpack 的异步资源处理方式进行重写,使用Phoenix Loader接管资源加载,从而实现异步资源的容灾。整体分析过程如下图所示:

图 4

CSS 资源的处理与 JS 有所差别,但原理相似,只需要重写 mini-css-extract-plugin 的异步加载实现即可。

Web 端方案资源加载示意:

图 5

容灾效果

图6 容灾大盘

图7 容灾案例

Native 端容灾

客户端的 CDN 资源主要是图片,音视频以及各种动态化方案的 bundle 资源。Native 端的容灾建设也主要围绕上述资源展开。

实现思路

重新请求是 Native 端 CDN 容灾方案的基本原理,根据互备 CDN 域名,由 Native 容灾基建容灾域名重新进行请求资源,整个过程发生在原始请求失败后。Native 容灾基建不会在原始请求过程中进行任何操作,避免对原始请求产生影响。原始请求失败后,Native 容灾基建代理处理失败返回,业务方仍处于等待结果状态,重请新求结束后向业务方返回最终结果。整个过程中从业务方角度来看仍只发出一次请求,收到一次结果,从而达到业务方不感知的目的。为将重新请求效率提升至最佳,必须尽可能的保证重新请求次数趋向于最小。

调研业务的关注点和技术层面使用的网络框架,结合 Phoenix 容灾方案的基本流程,在方案设计方面,我们主要考虑以下几点:

  • 便捷性:接入的便捷性是 SDK 设计时首先考虑的内容,即业务方可以用最简单的方式接入,实现资源容灾,同时也可以简单无残留拆除 SDK。
  • 兼容性:Android 侧的特殊性在于多样的网络框架,集团内包括 Retrofit 框架,okHttp 框架,okHttp3 框架及已经很少使用的 URLConnection 框架。提供的 SDK 应当与各种网络框架兼容,同时业务方在即使变更网络框架也能够以最小的成本实现容灾功能。而 iOS 侧则考虑复用一个 NSURLProtocol 去实现对请求的拦截,降低代码的冗余度,同时实现对初始化项进行统一适配。
  • 扩展性:需要在基础功能之上提供可选的高级配置来满足特殊需求,包括监控方面也要提供特殊的监控数据上报能力。

基于以上设计要点,我们将 Phoenix 划分为以下结构图,图中将整体的容灾 SDK 拆分为两部分 Phoenix-Adaptor 部分与 Phoenix-Base 部分。

图 8

Phoenix-Base

Phoenix-Base 是整个 Phoenix 容灾的核心部分,其包括容灾数据缓存,域名更换组件,容灾请求执行器(区别于原始请求执行器),监控器四个对外不可见的内部功能模块,并包含外部接入模块,提供外部接入功能。

  1. 容灾数据缓存:定期获取及更新容灾数据,其产生的数据只会被域名更换组件使用。
  2. 域名更换组件:连接容灾数据缓存,容灾请求执行器,监控器的中心节点,负责匹配原始失败 Host,过滤错误码,并向容灾请求执行器提供容灾域名,向监控器提供整个容灾过程的详细数据副本。
  3. 容灾执行器:容灾请求的真正请求者,目前采用内部 OkHttp3Client,业务方也可以自主切换至自身的执行器。
  4. 监控器:分发容灾过程的详细数据,内置数据大盘的上报,若有外部自定义的监控器,也会向自定义监控器分发数据。

Phoenix-Adaptor

Phoenix-Adaptor 是 Phoenix 容灾的扩展适配部分,用于兼容各种网络框架。

  • 绑定器:生成适合各个网络框架的拦截器并绑定至原始请求执行者。
  • 解析器:将网络框架的 Request 转换为 Phoenix 内部执行器的 Request,并将 Phoenix 内部执行器的 Response 解析为外部网络框架 Response,以此达到适配目的。

容灾效果

业务成功率

以外卖图片业务为例,Android 业务成功率对比(同版本 7512,2021.01.17 未开启 Phoenix 容灾,2021.01.19 晚开启 Phoenix 容灾)。

图 9

iOS 业务成功率对比(同版本 7511,2021.01.17 未开启 Phoenix 容灾,2021.01.19 晚开启 Phoenix 容灾)。

图 10

风险应对

以外卖与美团图片做为对比 ,在 CDN 服务出现异常时,接入 Phoenix 的外卖 App 和未接入的美团 App 在图片成功率方面的对比。

图 11

4.3.2 动态计算服务

端侧的域名重试,会在某一域名加载资源失败后,根据容灾列表依次进行重试,直至成功或者失败。如下图所示:

图 12

如果域名 A 大范围异常,端侧依然会首先进行域名 A 的重试加载,这样就导致不必要的重试成本。如何让资源的首次加载更加稳定有效,如何为不同业务和地区动态提供最优的 CDN 域名列表,这就是动态计算服务的要解决的问题。

计算原理

动态计算服务通过域名池和项目的 Appkey 进行关联,按照不同省份、不同地级市、不同项目、不同资源等维度进行策略管理。通过获取 5 分钟内对应项目上报的资源加载结果进行定时轮询计算,对域名池中的域名按照地区(城市&&省份)的可用性监控。计算服务会根据域名可用性动态调整域名顺序并对结果进行输出。下图是一次完整的计算过程:

图 13

假设有 A、B、C 三个域名,成功率分别是 99%、98%、97.8%,流量占比分别是 90%、6%、4%。基于转移基准,进行流量转移,比如,A 和 B 成功率差值是 1,B 需要把自己 12 的流量转移给 A,同时 A 和 C 的成功率差值大于 1,C 也需要把自己 12 的流量转移给 A,同时 B 和 C 的差值是 0.2,所以 C 还需要把自己 14 的流量转移给 B。最终,经过计算,A 的流量占比是 95%,B 是 3.5%,C 是 1.5%。最后,经过排序和随机计算后将最终结果输出。

因为 A 的占比最大,所以 A 优先被选择;通过随机,B 和 C 也会有一定的流量;基于转移基准,可以实现流量的平稳切换。

异常唤起

当某个 CDN 无法正常访问的时候,该 CDN 访问流量会由计算过程切换至等效的 CDN B。如果 SRE 发现切换过慢可以进行手动干预分配流量。当少量的 A 域名成功率上升后,会重复计算过程将 A 的流量加大。直至恢复初始态。

图 14

服务效果

动态计算服务使得资源的首次加载成功率由原来的99.7%提升至99.9%。下图为接入动态计算后资源加载成功率与未接入加载成功率对比。

图 15

4.3.3 容灾监控

在监控层面,SRE 团队往往只关注域名、大区域、运营商等复合维度的监控指标,监控流量巨大,对于小流量业务或者小范围区域的 CDN 波动,可能就无法被监控分析识别,进而也就无法感知 CDN 边缘节点异常。容灾监控建设,主要是为了解决 SRE 团队的 CDN 监控告警滞后和监控粒度问题。监控整体设计如下:

图 16

流程设计

端侧容灾数据的上报,分别按照项目、App、资源、域名等维度建立监控指标,将 CDN 可用性变成项目可用性的一部分。通过计算平台对数据进行分析聚合,形成 CDN 可用性大盘,按照域名、区域、项目、时间等维度进行输出,与天网监控互通,建立分钟级别的监控告警机制,大大提升了 CDN 异常感知的灵敏性。同时,SRE 侧的天网监控,也会对动态计算服务结果产生干预。监控整体流程如下:

图 17

监控效果

CDN 监控不仅从项目维度更加细粒度的监测 CDN 可用性,还为 CDN 异常排查提供了区域、运营商、网络状况、返回码等更丰富的信息。在监控告警方面,实现了分钟级异常告警,灵敏度也高于美团内部的监控系统。

图 18

4.3.4 CDN 服务

端侧域名切换的有效性,离不开 CDN 服务的支持。在 CDN 服务方面,在原有 SRE 侧容灾的基础上,对 CDN 服务整体做了升级,实现域名隔离,解决了单域名对应多 CDN 和多域名对应单 CDN 重试无效的弊端。

图 19

5. 总结与展望

经过一年的建设与发展,Phoenix CDN 容灾方案日趋成熟,现已成为美团在 CDN 容灾方面唯一的公共服务,在多次 CDN 异常中发挥了巨大的作用。在端侧,当前该方案日均容灾资源3000万+,挽回用户35万+,覆盖外卖,酒旅,餐饮,优选,买菜等业务部门,服务200+个工程,外卖 App美团 App大众点评 App均已接入。

在 SRE 侧,实现了项目维度的分钟级精准告警,同时丰富了异常信息,大大提高了 SRE 问题排查效率。自从方案大规模落地以来,CDN 异常时鲜有手动切换操作,极大减轻了 SRE 同学的运维压力。

由于前端技术的多样性和复杂性,我们的 SDK 无法覆盖所有的技术方案,所以在接下来的建设中,我们会积极推广我们的容灾原理,公开动态计算服务,希望更多的框架和服务在我们的容灾思想上,贴合自身业务实现端侧的 CDN 容灾。另外,针对方案本身,我们会不断优化资源加载性能,完善资源验签,智能切换等能力,也欢迎对 Phoenix CDN 容灾方案有兴趣的同学,跟我们一起探讨交流。同时更欢迎加入我们,文末附招聘信息,期待你的邮件。

6. 作者简介

魏磊、陈彤、张群、粤俊等,均来自美团外卖平台-大前端团队,丁磊、心澎,来自美团餐饮 SaaS 团队。

7. 招聘信息

美团外卖平台-大前端团队是一个开放、创新、无边界的团队,鼓励每一位同学追求自己的技术梦想。团队长期招聘Android、iOS、FE 高级/资深工程师和技术专家。欢迎感兴趣的同学投递简历至:wangxiaofei03@meituan.com(邮件标题请注明:美团外卖大前端)。

7次KDD_Cup&Kaggle冠军的经验分享:从多领域优化到AutoML框架

1 背景与简介

反馈快速、竞争激烈的算法比赛是算法从业者提升技术水平的重要方式。从若干行业核心问题中抽象出的算法比赛题目具有很强的实际意义,而比赛的实时积分榜促使参加者不断改进,以试图超越当前的最佳实践,而且获胜方案对于工业界与学术界也有很强的推动作用,例如KDD Cup比赛产出的Field-Aware Factorization Machine(FFM)算法[1]、ImageNet比赛产出的ResNet模型[2]在业界都有着广泛的应用。

美团到店广告质量预估团队在美团内部算法大赛MDD Cup中获得了第一名,受大赛组委会的邀请,希望分享一些比较通用的比赛经验。本文是笔者7次Kaggle/KDD Cup冠军经验(如下图1所示)的分享,希望能帮助到更多的同学。

图1 国际顶级比赛冠军经历

大家都知道,Kaggle/KDD Cup的比赛均为国际顶级赛事,在比赛圈与工业界有着很大的影响力。具体而言,Kaggle是国际上最大的顶级数据挖掘平台,拥有全球几十万用户,通过高额奖金与分享氛围产出了大量优秀算法方案,例如Heritage Health奖金高达三百万美元。目前,Kaggle比赛在艾滋病研究、棋牌评级和交通预测等方面均取得了突出成果,得益于此,Kaggle平台后来被Google公司收购。

ACM SIGKDD (国际数据挖掘与知识发现大会,简称 KDD)是数据挖掘领域的国际顶级会议。KDD Cup比赛是由SIGKDD主办的数据挖掘研究领域的国际顶级赛事。从1997年开始,每年举办一次,是目前数据挖掘领域最具影响力的赛事。该比赛同时面向企业界和学术界,云集了世界数据挖掘界的顶尖专家、学者、工程师、学生等参加,为数据挖掘从业者们提供了一个学术交流和研究成果展示的平台。

通过分析不难发现,KDD Cup举办20年来,一直紧密结合工业界前沿与热点问题,演进主要分为三个阶段。第一阶段从2002年左右开始,专注于互联网的热点推荐系统方面问题,包括推荐、广告,行为预测等;第二阶段聚焦在传统行业问题,比较关注教育、环境、医疗等领域;而在第三阶段,自2019年以来,重点关注非监督问题,例如AutoML、Debiasing、强化学习等问题,这类比赛的共同特点是通过以前方法难以解决现有的新问题。这三个阶段趋势也一定程度反应着当前工业界与学术界的难点与重点,无论从方式、方法,还是从问题维度,都呈现出从窄到宽,从标准向非标准演进的趋势。

图2 KDD Cup近20年问题趋势

本文会先介绍笔者的7次KDD Cup/Kaggle比赛冠军的方案与理解,问题涉及推荐、广告、交通、环境、人工智能公平性等多个领域问题。接着会介绍在以上比赛中发挥关键作用的AutoML技术框架,包括自动化特征工程,自动化模型优化,自动化模型融合等,以及如何通过该技术框架系统性建模不同的问题。最后再介绍以上比赛形成的通用方法,即面对一个新问题,如何进行分析、理解、建模、与挑战解决、从而实现问题的深度优化。

本文主要面向以下两类读者,其他感兴趣的同学也欢迎了解。

  • 算法比赛爱好者,希望理解国际数据挖掘顶级比赛冠军方案的方法与逻辑,取得更好的名次。
  • 工业界工程师与研究员,借鉴比赛方法,应用于实际工作,取得更优的结果。

2 多领域建模优化

本部分将我们将以上比赛分为三个部分进行方案介绍,第一部分为推荐系统问题;第二部分为时间序列问题,跟第一部分的重要差别在于预测的是未来的多点序列,而非推荐系统的单点预估;第三部分为自动化机器学习问题,该问题比赛输入不为单一数据集,而是多问题的多数据集,并且在最终评估的b榜数据集问题也是未知的。因此,对于方案的鲁棒性要求非常高。如表1所示,后续将具体介绍七个比赛赛道的获胜方案,但会合并为五个核心解决方案进行具体的介绍。

表1 竞赛及解决方案

2.1 推荐系统问题

本节主要介绍Kaggle Outbrain Ads Click Prediction和KDD Cup 2020 Debiasing比赛。二者任务都是面向用户下一次点击预估问题,但因为应用场景与背景的不同,存在着不同的挑战:前者的数据规模庞大,涉及到数亿个用户在千级别数量异构站点上的数十亿条浏览记录,对模型优化、融合有着严格的要求;后者则尤为关注推荐系统中的偏差问题,要求参赛选手提出有效的解决方案,来缓解选择性偏差以及流行度偏差,从而提高推荐系统的公平性。本节将分别介绍这两场比赛。

Kaggle Outbrain Ads Click Prediction:基于多层级多因子的模型融合方案

竞赛问题与挑战:竞赛要求在Outbrain网页内容发现平台上,预估用户下一次点击网页广告,具体参考:Kaggle Outbrain比赛介绍详情[26]。参赛选手会面对以下两个重要挑战:

  • 异构性:平台提供需求方平台(DSP)广告投放服务,涉及到用户在数千个异质站点上的行为刻画。
  • 超高维稀疏性:特征高维稀疏,数据规模庞大,包含了7亿个用户、20亿次浏览记录。

基于多层级多因子的模型融合方案:针对本次赛题的挑战,我们队采用了基于多层级多因子的模型融合方案来进行建模。一方面对于异构站点行为,单一模型不易于全面刻画,另一方面,亿级别的数据规模给多模型的分别优化带来了较大的空间。由于FFM具有强大的特征交叉能力以及较强的泛化能力,能更好地处理高维稀疏特征。因此,我们选择该模型作为融合基模型的主模型。模型融合通过不同模型学习到有差异性的内容,从而有效挖掘用户在不同站点上的异质行为。模型融合的关键是产生并结合“好而不同”的模型[3][4]。基于多层级多因子的模型融合方案首先通过模型差异性、特征差异性多个角度来构造模型之间的差异性,然后通过多层级以及使用基学习器的多特征因子(模型pCTR预估值、隐层表征)进行融合:

图3 多层级多因子模型融合

具体地,如上图3所示。第一层级的目的是构建出有差异性的单个模型,主要通过不同类型的模型在用户最近行为、全部行为数据以及不同特征集合上分别进行训练,来产生差异性。第二层级则通过不同单个模型的组合进一步产生差异性,差异性的提升来源于两个方面,分别是模型组合方式的不同(用不同模型,根据单模型特征进行打分)以及用于模型组合的特征因子的不同,这里特征因子包括模型的打分以及模型中的隐层参数。第三层级则是考虑如何将不同融合结果组合在一起。由于划分出来的验证数据集较小,如果使用复杂非线性模型往往容易过拟合。所以这里使用了一个基于约束的线性模型来获得第二层级模型的融合权重。

上述方案同我们业务中模型相比,采用更多的模型融合,在取得高精度的同时产生了更高的开销,而在实际业务中要更加注重效果与效率的平衡。

KDD Cup 2020 Debasing:基于i2i多跳游走的Debiasing方案

竞赛问题与挑战:竞赛是以电子商务平台为背景,预估用户下一次点击的商品。并围绕着如何缓解推荐系统中的选择性偏差以及流行度偏差进行展开,具体参考:KDD Cup 2020 Debiasing比赛介绍详情[27]。推荐系统中的偏差问题有很多,除了上述两种偏差,还有曝光偏差、位次偏差等等[5][6]。我们团队之前也对位次偏差进行了相关研究[7]。而本次竞赛为了更好地衡量推荐系统对历史低热度商品的推荐效果,选手的成绩主要采用NDCG@50_half指标进行排名。该指标是从整个评测数据集中取出一半历史曝光少的点击商品,由于是低热度且有被点击的商品,可以跟更好的评估偏差问题。本次比赛包含了以下挑战:

  • 赛题只提供点击数据,构造候选集时需要考虑选择性偏差问题。
  • 不同商品热度差异大,商品历史点击次数呈现一个长尾分布,数据存在严重的流行度偏差问题,并且评估指标 NDCG@50_half 用于考察低热度商品的排序质量。

基于i2i游走的Debiasing排序方案:我们的方案为基于i2i建模的排序框架。如图所示,整体流程包含四个阶段:i2i构图与多跳游走、i2i样本构建、i2i建模以及u2i排序。前两个阶段解决了选择性偏差问题,后两个阶段则侧重于解决流行度偏差问题。

图4 基于i2i的建模框架

第一个阶段是基于用户行为数据和商品多模态数据构建i2i图,并在该图上多跳游走生成候选样本。这种方式扩大了商品候选集,更好地近似系统真实候选集,缓解了选择性偏差。

第二个阶段是根据不同i2i关系计算i2i候选样本的相似度,从而决定每种i2i关系下候选样本的数量,最终形成候选集。通过不同候选的构造方法,探索出更多有差异的候选商品,可以进一步缓解选择性偏差问题。

第三个阶段包括基于i2i样本集的自动化特征工程,以及使用流行度加权的损失函数进行消除流行度偏差的建模。自动化特征工程中包含了商品多模态信息的刻画,这类信息能够反应商品在热度信息以外的竞争关系,能够一定程度上缓解流行度偏差问题。而流行度加权的损失函数定义如下:

其中,参数α与流行度成反比,来削弱流行商品的权重,从而消除流行度偏差。参数β是正样本权重,用于解决样本不平衡问题。

第四个阶段首先将i2i打分通过Max操作进行聚合,突出打分集合中低热度商品的高分信号,从而缓解流行度偏差问题。然后对商品列表的打分结合商品热度进行调整处理,进而缓解流行度偏差问题。

关于该比赛的更多细节,大家可以参考《KDD Cup 2020 Debiasing比赛冠军技术方案及在美团的实践》一文。

2.2 时间序列问题

时序系列问题:时间序列问题相比于推荐系统问题的有较大差异。在任务上,推荐系统预测的是未来单个点,而时间序列预测未来多个点;在数据上,推荐系统通常包含用户、商品、上下文等多维信息,时间序列通常包含时间空间上变化的数值序列信息。

时间序列竞赛:在本文中,时间序列竞赛主要介绍KDD Cup 2018 Fresh Air和KDD Cup 2017 HighWay Tollgates Traffic Flow Prediction。它们都是时间序列问题,前者是预测未来两天的污染物浓度以及变化,后者是预测未来几个小时高速交通情况和变化。它们的共同点一是传统行业问题,实际意义强;二是存在各种突变性、稳定性低;三是都涉及到多地域、多空间问题,需结合时空进行建模。它们的异同点是污染物浓度突变需要一个短期时间才能发生,数据在突变时存在一定规律性,但交通突变具有强偶发性,交通道路容易受到偶发性车祸、偶发性地质灾害等影响,数据不会呈现出明显的规律性。

KDD Cup 2018 Fresh Air:基于时空门控DNN和Seq2Seq的空气质量预测方案

竞赛问题及挑战:竞赛目标是预测北京和伦敦48个站点在未来48小时里PM2.5/PM10/O3的浓度变化,具体参考: KDD Cup 2018比赛介绍详情[28]。参赛选手需要解决以下两个挑战:

  • 时序性:预测未来48小时的污染浓度情况,实际污染物浓度存在突变的情况。如图5所示,站点2在05-05以及05-06、05-07之间存在大量的波动和突变。
  • 空间性:不同站点上污染物浓度有明显差异,并且和站点之间的拓扑结构相关联。如图所示,站点1、2的波形有较大差别,但是在05-07产生了相同的凸起。

图5 时空挑战图

基于Spatial-temporal Gated DNN与Seq2Seq的模型融合方案[9]:为了强化时间序列和空间拓扑的建模,我们引入了Spatial-temporal Gated DNN与Seq2Seq两个模型,并与LightGBM一起构建模型融合方案,具体如下。

(1)Spatial-temporal Gated DNN:对于时序问题而言,由于未来预测临近时间点的统计特征值差异较小,直接使用DNN模型会使得不同小时和站点的预测值差异性小,因此我们在DNN中引入Spatial-temporal Gate来突出时空信息。如下图6所示,Spatial-temporal Gated DNN采用了双塔结构,拆分了时空信息和其他信息,并且通过门函数来控制和强调时空信息,最终能够提高模型对时空的敏感度,实验中发现引入swish激活函数f(x) = x · sigmoid(x)能提升模型精度。

图6 Spatial-temporal Gated DNN

(2)Seq2Seq:尽管Spatial-temporal Gated DNN相比DNN对时空信息进行了强化,但是它们的数据建模方式都是将样本的历史数据复制48份,分别打上未来48小时的标签,相当于分别预测48小时的污染浓度值。这种方式其实和时间序列预测任务有所脱离,失去了时间连续性。而Seq2Seq建模方式可以很自然地解决这一问题,并且取得了不错的效果。下图7是本次比赛中,我们采用的Seq2Seq模型结构。针对时序性挑战,历史天气特征通过时间前后组织成序列输入到编码器当中,解码器依赖于编码结果以及未来天气预报特征进行解码,得到48小时的污染物浓度序列。未来天气预报信息对齐到解码器每个小时的解码过程中,解码器可以通过天气预报中的天气信息(比如风级、气压等)来有效预估出突变值。针对空间性挑战,方案在模型中加入站点嵌入以及空间拓扑结构特征来刻画空间信息,在模型中和天气信息进行拼接以及归一化,从而实现时空联合建模。

图7 Seq2Seq模型

(3)模型融合:我们队采用了Stacking融合的方式,单个学习器通过不同模型、数据、建模方式来构建差异性。LightGBM模型使用了天气质量、历史统计、空间拓扑等特征,Spatial-temporal Gate则是引入了门结构,强化了时空信息。Seq2Seq利用序列到序列的建模方式,刻画了序列的连续性、波动性。最后使用了基于约束的线性模型将不同的单个学习器进行融合。

更多详情,大家可参考SIGKDD会议论文:AccuAir: Winning Solution to Air Quality Prediction for KDD Cup 2018

KDD Cup 2017 Traffic Flow Prediction:基于交叉验证降噪与多损失融合的高稳定性交通预测方案

竞赛问题及挑战:竞赛目标是以20分钟为时间窗口,给定前2小时高速公路入口到关卡的行驶状况,预测未来2小时的行驶状况,具体可参考:KDD Cup 2017比赛介绍详情[29]。竞赛根据行驶状况的不同,分为了行驶时间预测和交通流量预测两个赛道。参赛选手需要解决以下两个挑战:

  • 数据小、噪声多。如下图8所示,框中时间段的数值分布和其他时间段的分布有明显的差异。

图8 交通流量数据中的噪音

  • 极值对结果影响大,评估指标使用了MAPE,如下式,其中 At 代表实际值,Ft 代表预测值,当实际值为较小值(特别为极小值)时,这一项对整个和式的贡献拥有很大的权重。

基于交叉验证降噪的极值点优化模型融合方案:

(1)基于交叉验证的降噪,由于在线仅能进行一天一次的提交,并且最终的评测会由A榜测试集切到B榜测试集,并且由于A榜数据集小在线评测指标存在不稳定性,故而离线迭代验证的方式就显得尤为重要。为了能使离线迭代置信,我们采用两种验证方式进行辅助,第一种是下一天同时间段验证,我们在训练集最后M天上对每一天都取在线同一时间段的数据集,得到M个验证集。第二种是N-fold天级采样验证,类似N-fold交叉验证,我们取最后N天的每一天数据作为验证集,得到N个验证集。这两种方法共同辅助模型离线效果的迭代,保证了我们在B榜上的鲁棒性。

(2)极值点问题优化和模型融合:由于MAPE对于极值较敏感,我们在标签、损失、样本权重等不同方面分别进行多种不同处理,例如标签上进行Log变换和Box-Cox变换,Log变换是对标签进行Log转换,模型拟合后对预估值进行还原,这样能帮助模型关注于小值同时更鲁棒,损失使用MAE、MSE等多种,样本权重上利用标签对样本进行加权等,我们在XGBoost、LightGBM、DNN上引入这些处理生成多个不同模型进行模型融合,优化极值点问题,达到鲁棒效果。

备注:特别感谢共同参加KDD Cup 2017的陈欢、燕鹏、黄攀等同学。

2.3 自动化机器学习问题

自动化机器学习问题[10]主要包括KDD Cup 2019 AutoML和KDD Cup 2020 AutoGraph比赛。该类问题,一般具有以下三个特性:

  • 数据多样性强:15+个数据集,来源于不同领域问题,且不会标识数据来源,要求选手设计的自动化机器学习框架能够兼容多领域的数据,并对不同领域数据做出一定的适配。
  • 自动化的鲁棒性:公共排行榜与私有榜评测数据不一样,最终评分按照多个数据集的平均排名/得分得到,要求能够在不曾见过的数据集上得到鲁棒的结果。
  • 性能限制:与现实问题搜索空间有较大对应,需要在有限时间和内存上求解。

KDD Cup 2020 AutoGraph:基于代理模型的自动多层次图学习优化方案

竞赛问题及挑战:自动化图表示学习挑战赛(AutoGraph)是第一个应用于图结构数据的AutoML挑战,详情请见KDD Cup 2020 AutoGraph 比赛介绍[30]。竞赛选择图结点多分类任务来评估表示学习的质量,参与者需设计自动化图表示学习[11-13]解决方案。该方案需要基于图的给定特征、邻域和结构信息,高效地学习每个结点的高质量表示。比赛数据从真实业务中收集,包含社交网络、论文网络、知识图谱等多种领域共15个,其中5个数据集可供下载,5个反馈数据集评估方案在公共排行榜的得分,剩余5个数据集在最后一次提交中评估最终排名。

图9 AutoGraph图数据集概览

每个数据集给予了图结点id和结点特征,图边和边权信息,以及该数据集的时间预算(100-200秒)和内存算力(30G)。每个训练集随机将划分40%结点为训练集,60%结点为测试集,参赛者设计自动化图学习解决方案,对测试集结点进行分类。 每个数据集会通过精度(Accuracy)来确定排名,最终排名将根据最后5个数据集的平均排名来评估。综上,本次比赛需要在未见过的5个数据集上直接执行自动化图学习方案,参赛者当时面临着以下挑战:

  • 图模型具有高方差、稳定性低等特点。
  • 每个数据集都有严格的时间预算和内存算力限制。

基于代理模型的自动化多层次模型优化[14]

图10 AutoHEnsGNN框架

多类别层次化图模型优化:

(1)候选图模型的生成:现实世界中的图通常是多种属性的组合,这些属性信息很难只用一种方法捕捉完全,因此,我们使用了基于谱域、空域、Attention机制等多种不同类型的模型来捕捉多种属性关系。不同模型在不同数据集上效果差异较大,为了防止后续模型融合时加入效果较差的模型,会对GCN、GAT、APPNP、TAGC、DNA、GraphSAGE、GraphMix、Grand、GCNII等候选模型进行快速筛选,得到模型池。

(2)层次模型集成:这部分共包含两个维度的集成。第一层为模型自集成,为了解决图模型对初始化特别敏感,同种模型精度波动可达±1%的问题,采用了同模型的自集成,同时生成多个同种模型,并取模型预测的平均值作为该种模型的输出结果,成功降低了同种模型方差,提高了模型在不同数据集上的稳定性。第二层为不同模型集成,为了有效地利用来自本地和全球邻域的信息,充分捕获图的不同性质,我们采用加权集成了不同种类的图模型,进一步提高性能。同时针对在参数搜索阶段,需要同时优化模型内参数α,以及多种模型加权集成参数β,使用模型集成参数和模型内参数通过互迭代的梯度下降进行求解,有效提升了速度。

图11 多类别层次化图模型优化

基于代理模型与最终模型的两阶段优化:数据集采样,对子图根据Label进行层次采样,减少模型验证时间;代理模型与Bagging,计算多个较小隐层模型的平均结果,快速对该类模型进行评估。使用Kendall Rank和SpeedUp平衡准确度与加速倍率,得到合适的代理模型。最终通过代理模型得到了最优的超参数,然后再对最终的大模型在搜索好的参数上进行模型训练。

具体详情,大家可参考团队ICDE 2022论文,AutoHEnsGNN: Winning Solution to AutoGraph Challenge for KDD Cup 2020

3 AutoML技术框架

3.1 自动化框架概述

图12 AutoML整体框架

经过上述的多场比赛,团队在多领域建模中不断总结与优化,抽象出其中较为通用的模块,总结得到针对数据挖掘类问题时的一套较为通用的解决方案——AutoML框架。该框架包含数据预处理,自动化特征工程[15]和自动化模型优化[16-20]三个部分。其中数据预处理部分主要负责特征分类、数据编码、缺失值处理等常见的基础操作,不过多展开。主要针对AutoML框架的自动化特征工程和自动化模型优化两个部分进行详细介绍。

3.2 自动化特征工程

图13 自动化特征工程

特征工程是机器学习中至关重要的工作,特征的好坏直接决定了模型精度的上限。目前常见的方式是人工手动对特征进行组合与变换,但人工特征挖掘存在速度较慢、无法挖掘全面等问题。因此,设计全面挖掘的自动化特征工程能够比较好地解决上述问题,自动化特征工程主要包含三个部分:

  • 一、二阶特征算子:对数据的基础操作,可以得到更为复杂的高阶特征。特征算子包含三个,频数编码是指对于类别型特征在样本中次数、nunique等值的统计。目标编码指对数值型特征进行均值、求和、最大最小、百分位等操作。时序差分是指对于对时间特征进行差分处理。一阶算子使用一个实体计算,二阶算子使用二个实体计算,如用户在某品类下的订单数量,使用了用户与品类两个实体。
  • 快速特征选择:因为自动化特征工程是针对全部实体依次按照不同特征算子进行的笛卡尔积组合,会产生大量的无效特征,故需要进行快速特征选择。使用LightGBM模型快速识别有效特征及无用特征,从指标提升及特征重要性角度考虑,裁剪掉没用的特征,同时标识重要特征与其他特征再次进行更为高阶的组合。
  • 高阶特征算子:基于一、二阶特征算子组合构建的新特征,进一步与其他特征进行高阶组合,基于K阶(K>=1)的K+1高阶组合循环迭代,能够产出大量人为考虑不足的高阶特征。

高阶特征算子按多实体结果是否完全匹配,分为Match方式——匹配全部实体,All方式——匹配部分实体,得到另一实体的全部值的计算结果,这样两种特征产出方式。下图中举例说明,Match方式匹配用户与时间段两个实体,得到用户在该时间段的平均订单价格;All方式则只匹配用户,得到用户在所有时间段的平均订单价格。

图14 高阶算子特征产出方式

相较于DeepFM、DeepFFM等算法,自动化特征工程具有三个方面的优势。首先在存在多表信息的情况下,容易利用非训练数据的信息,如在广告场景中,通过特征可以利用自然数据的信息,相比直接使用自然数据训练,不容易产生分布不一致等问题;其次,只通过模型自动交叉学习,对于某些强特征交叉没有手动构造学习得充分,许多显示交叉特征如用户商品点击率等往往有较强的业务意义,让模型直接感知组合好的特征往往比自动学习特征间的关系更为简单;第三方面对于许多高维度稀疏ID特征,如亿级别以上的推荐或广告场景中,DeepFM、DeepFFM对于这些特征的学习很难充分,自动化特征工程能给这些稀疏ID构造很强的特征表示。

3.3 自动化模型优化

图15 自动化模型优化

基于重要度的网格搜索:在我们框架中采用的是全局基于重要度按照贪心的方式进行搜索,加快速度;得到的最优结果再进行小领域更详细网格搜索,缓解贪心策略导致的局部最优。根据以往比赛经验,总结不同模型的超参重要性排序如下:

  • LightGBM:学习率>样本不平衡率>叶子数>行列采样等。
  • DNN:学习率>Embedding维度>全连接层数和大小。值得一提的是,超参搜索在整个迭代过程中会进行多次,同时迭代前期与迭代后期参数搜索策略也有所不同,迭代前期,一般会选择更大的学习率,更小Embedding维度和全连接层数等,降低模型参数量加快迭代速度,而在后期则选择更多参数,获得更好的效果。
  • 模型融合:模型融合的关键点在于构造模型间的差异性,LightGBM和DNN的模型本身差异性较大,同种模型中差异性主要体现在,数据差异、特征差异、超参差异三个方面。数据差异主要通过自动化行采样实现,自动生成不同数据采样的模型;特征差异通过自动化列采样,生成特征采样的模型;超参差异通过高优参数扰动生成,在最优局部进行参数组网格局部扰动。模型融合方法一般Blending、Stacking或简单Mean Pooling等,融合前进行需要进行模型粒度剪枝(去除效果较差的模型避免影响融合效果)与正则化。

3.4 AutoML框架近期实战:MDD Cup 2021美团外卖图谱推荐比赛冠军方案

在2021年8-9月美团举行的内部算法比赛MDD Cup 2021中,美团到店广告平台质量预估团队应用了AutoML框架并获得了冠军。下面结合这场比赛,介绍框架在具体问题中的应用。

MDD Cup 2021需要参赛者根据用户、商家在图谱中的属性、用户的历史点击、实时点击以及下单行为,预测下次购买的商家。包含四周的135万个订单行为,涉及20万个用户,2.9万个商家,17.9万个菜品,订单关联菜品数据共438万条,构成知识图谱。使用Hitrate@5作为评价指标。

数据预处理阶段:进行特征分类、异常值处理、统一编码等操作。主要涉及用户(用户画像特征等)、商家(品类、评分、品牌等)、菜品(口味、价格、食材等)三种实体数据及点击、购买(LBS、价格、时间等)两类交互数据,对原始数据进行特征分类、数据编码、缺失值处理等常见预处理操作。

自动化特征工程:一、二阶特征算子,首先对于类别、数据、时序、标签四类原始特征,按照可抽象的三种实体及两类交互数据进行一、二阶特征交叉,运用频数编码、目标编码与时序差分算子操作,在多时段上统计得到一、二阶统计特征。举例说明,如频数编码可计算用户点击某商家的次数、用户购买商家品类的nunique值,用户在某场景的下单数量等。目标编码可计算用户的平均订单价格,用户点击次数最多的商家品类等。时序差分可计算如用户购买某口味菜品的平均时间差等。多时段统计则意味着上述特征均可在不同时段上计算得到。

图16 多阶特征交叉

快速特征选择,上述自动产出的一、二阶统计特征数量共有1000+,其中存在大量无效特征,故使用LightGBM模型,从指标提升与重要性角度进行特征筛选与重要标识。如用户 x 菜品口味的特征没什么效果,进行筛除;用户最常购买的价格区间则很有效果,标识为重要特征进行高阶组合。

高阶特征算子,基于一、二阶特征算子组合构建的新特征,可以作为输入进行高阶特征组合。这里值得一提的是,高阶特征组合存在两种形式,第一种原始特征的更高阶组合,如用户在某个商家中最喜欢的菜品口味,结合三个实体,并不需要额外的运算,第二种需使用一、二阶新特征,其中频数编码的结果可以直接使用,目标编码与时序差分需要先进行数值分桶操作转换为离散值后才可使用,如用户订单价格区间的众数 x 商家订单价格平均值的分桶的联合count。循环进行特征组合与筛选后就得到了最终的特征集。

自动化模型优化:模型部分使用了LightGBM和DIN的融合方案,迭代过程中多次进行了自动超参搜索,通过自动化行、列采样及最优参数局部扰动构造了具有差异性的多个模型,融合得到最终的结果。

4 通用建模方法与理解

本节会就比赛的通用建模方法进行介绍,即面对一个新问题,如何进行快速高效的整体方案设计。

4.1 建模框架与方法

在面对新问题时,我们主要将技术框架分为以下三个阶段,即探索性建模、关键性建模、自动化建模。三个阶段具有逐渐深化,进一步补充的作用。

图17 三阶段算法建模

探索性建模:比赛前期,首先进行问题理解,包括评估指标与数据表理解,然后进行基础的模型搭建,并线上提交验证一致性。在一致性验证过程中往往需要多次提交,找到同线上指标一致的评估方式。探索性建模的核心目标是要找到迭代思路与方法,所以需要对问题做多方面探索,在探索中找到正确的方向。

一般在非时序问题,采用N-fold方法构造多个验证集,并可以灵活变换生成种子,得到不同的集合。而在时序问题,一般会采用滑窗方式,构造同线上提交时间一致的验证集,并可以向前滑动k天,来构造k个验证集。在多个验证集评估中,可以参考均值,方差,极值等参考指标综合评估,得到同线上一致的结果。

关键性建模:比赛中期,会就关键问题进行深挖,达成方案在榜单Top行列,在问题理解方面,会尽可能就评估方式进行损失函数自定义设计。

分类问题优化,可以结合Logloss、AUC Loss[21]、NDCG Loss等不同损失函数进行Mix Loss设计。而回归问题的损失函数设计要更复杂,一方面可以结合平方误差,绝对值误差等进行损失函数设计,另一方面可以结合Log变换,Box-cox变换等解决回归异常值等问题。

自动化建模:比赛后期,由于基于人的理解一方面在细节与角度有盲区,另一方面较难进行抽象关系的建模,所以我们会采用自动化建模进行补充。如下图18所示,先基于关系型多表输入,进行自动化关联,然后通过生成式自动化特征工程构建大量特征,再进行特征选择与迭代,然后基于模型输入进行自动化超参搜索与模型选择,最终基于多模型进行自动化融合构建,将生成的多元化模型关系进行选择与赋权。

图18 自动化建模框架

自动化建模一般采用如图18的框架,先进行多表关联,然后基于先扩展后过滤的逻辑进行特征选择,下一步基于精选特征与多个超参范围进行超参搜索,最后采用XGBoost[22]、LightGBM、DNN、RNN、FFM等不同模型进行自动化模型融合。

4.2 同工业界方法联系

算法比赛相对于工业界实际情况而言,一个重要区别是工业界涉及线上系统,在工程方面性能的挑战更大,在算法方面涉及更多的线上线下效果一致性问题。因此算法比赛会在模型复杂度、模型精度更进一步,在算法比赛中也产出了ResNet、Field-aware Factorization Machine(FFM)、XGBoost等算法模型,广泛应用于工业界实际系统。

在空气质量预测中,我们采用了时空结合的Spatial-temporal Gated DNN网络进行有效建模,同空气质量问题相接近,在美团的实际业务中也面临着时空相结合的建模问题,以用户行为序列建模为例。我们对用户的历史时空信息和当前时空信息进行了充分的建模和交互[24]。我们分辨出用户行为的三重时空信息,即:用户点击发生时的时间、用户请求发出的地理位置、用户所点击的商户的地理位置。

基于上述三重时空信息,我们提出Spatio-temporal Activator Layer(如图19):三边时空注意力机制神经网络来对用户历史行为进行建模,具体通过对请求经纬度信息、商户经纬度信息和请求时间的交互进行学习。针对空间信息交叉,我们进一步采用地理位置哈希编码和球面距离相结合的方式;针对时间信息交叉,我们也采用绝对与相对时间相结合的方式,有效实现用户行为序列在不同时空条件下的三边表达。最后,经上述网络编码后的时空信息经过注意力机制网络融合,得到LBS场景下用户超长行为序列对不同请求候选的个性化表达。

相比较而言,比赛中的Spatial-temporal Gated DNN更注重时空融合信息对于预测值的影响,由于需要预测的时间序列问题,更侧重于不同的时间、空间信息有能够将差异性建模充分。而在美团业务中的时空网络注重于细粒度刻画空间信息,源于不同的球面距离,不同的区块位置影响大,需要多重信息深度建模。更多详情,大家可参考团队的CIKM论文:Trilateral Spatiotemporal Attention Network for User Behavior Modeling in Location-based Search[23]

图19 基于三边时空注意力机制的用户行为序列网络

在实际建模中,相对于比赛涉及到更多线上部分,而比赛主要专注于离线数据集的精度极值。同Debiasing比赛相比,在实际线上系统中,涉及到Bias等更多的问题,以Position Bias为例,实际的展示数据高位点击率天然高于低位,然而一部分是源于用户高低位之间的浏览习惯差异,因此对于数据的直接建模不足以表征对于高低位广告点击率与质量的评估。我们在美团实际广告系统中,设计了位置组合预估框架进行建模,取得不错的效果,这里不再详述。具体详情,大家可参考团队SIGIR论文:Deep Position-wise Interaction Network for CTR Prediction[7]

4.3 建模关键理解

一致的评估方式是决定模型泛化能力的关键

在比赛的机制中,通常最终评测的Private Data和此前一直榜单的Public Data并不是一份数据,有时切换数据会有几十名的名次抖动,影响最终排名。因此避免过拟合到常规迭代的Public Data是最终取胜的关键。那么在此问题上,如何构造同线上分布一致的验证集呢?从一致性角度,一般会构造时间间隔一致的验证集。而部分问题数据噪音较重,可以用动态滑窗等方式构造多个验证集相结合。一致的验证集决定着后面的迭代方向。

大数据注重模型的深化,小数据注重模型的鲁棒

不同数据集注重的内容不一样,在数据充分的场景下,核心问题是模型深化,以解决特征之间交叉,组合等复杂问题。而在小数据下,因为噪音多,不稳定性强,核心问题是模型的鲁棒。高数据敏感性是方案设计的关键。

方差与偏差的平衡是后期指导优化的关键

从误差分解角度去理解,平方误差可以分解为偏差(Bias)与方差(Variance)[25],在中前期模型复杂度较低时,通过提升模型复杂度,能够有效减低偏差。而在偏差已经被高度优化的后期,方差的优化是关键,因此在后期会通过Emsemble等方式,在单模型复杂度不变的基础上,通过模型融合优化结果。

AutoML的关键是人为先验的不断减少

在运用AutoML框架的同时,会有一些超参数等隐蔽的人为先验,把AutoML技术也以模型视角来理解,同样存在模型复杂度越高越容易过拟合的问题,迭代中的一个关键问题不是评估效果的好坏,而是方案是否存在不必要的超参数等信息,能否不断地简化AutoML的建模,不断地自动化,自适应适配各类问题。

最后,也特别感谢Convolution Team、Nomo Team、Getmax Team、Aister Team等队伍的队友们。

总结

本文基于笔者7次算法比赛的冠军经历,分享推荐系统、时间序列及自动化机器学习等不同领域比赛中的算法经验,接着结合具体问题介绍AutoML技术框架,最后总结比赛中通用的建模方案,结合工业界方案介绍其与比赛的联系。希望文章中的一些算法比赛相关经验能够帮助算法爱好者更好地参与竞赛,能为大家提供一些思路,启迪更多的工程师与研究员在实际工作中取得更优结果。未来,我们团队将持续关注国际算法竞赛,积极进行比赛思路与工业方案结合的尝试,同时也欢迎大家加入我们团队,文末附有招聘信息,期待你的邮件。

作者简介

胡可、兴元、明健、坚强,均来自美团广告平台质量预估团队。

参考文献

  • [1] Juan Y , Zhuang Y , Chin W S , et al. Field-aware Factorization Machines for CTR Prediction[C]// the 10th ACM Conference. ACM, 2016.
  • [2] He K , Zhang X , Ren S , et al. Identity Mappings in Deep Residual Networks[J]. Springer, Cham, 2016.
  • [3] Ali, Jehad & Khan, Rehanullah & Ahmad, Nasir & Maqsood, Imran. (2012). Random Forests and Decision Trees. International Journal of Computer Science Issues(IJCSI). 9.
  • [4] Robi Polikar. 2006. Ensemble based systems in decision making. IEEE Circuits and systems magazine 6, 3 (2006), 21–45.
  • [5] Jiawei Chen, Hande Dong, Xiang Wang, Fuli Feng, Meng Wang, and Xiangnan He. 2020. Bias and Debias in Recommender System: A Survey and Future Directions. arXiv preprint arXiv:2010.03240 (2020).
  • [6] H. Abdollahpouri and M. Mansoury, “Multi-sided exposure bias in recommendation,” arXiv preprint arXiv:2006.15772, 2020.
  • [7] Huang J, Hu K, Tang Q, et al. Deep Position-wise Interaction Network for CTR Prediction[J]. arXiv preprint arXiv:2106.05482, 2021.
  • [8] KDD Cup 2020 Debiasing比赛冠军技术方案及在美团的实践.
  • [9] Luo Z, Huang J, Hu K, et al. AccuAir: Winning solution to air quality prediction for KDD Cup 2018[C]//Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. 2019: 1842-1850.
  • [10] He Y, Lin J, Liu Z, et al. Amc: Automl for model compression and acceleration on mobile devices[C]//Proceedings of the European conference on computer vision (ECCV). 2018: 784-800.
  • [11] Yang Gao, Hong Yang, Peng Zhang, Chuan Zhou, and Yue Hu. 2020. Graph neural architecture search. In IJCAI, Vol. 20. 1403–1409.
  • [12] Matheus Nunes and Gisele L Pappa. 2020. Neural Architecture Search in Graph Neural Networks. In Brazilian Conference on Intelligent Systems. Springer, 302– 317.
  • [13] Huan Zhao, Lanning Wei, and Quanming Yao. 2020. Simplifying Architecture Search for Graph Neural Network. arXiv preprint arXiv:2008.11652 (2020).
  • [14] Jin Xu, Mingjian Chen, Jianqiang Huang, Xingyuan Tang, Ke Hu, Jian Li, Jia Cheng, Jun Lei: “AutoHEnsGNN: Winning Solution to AutoGraph Challenge for KDD Cup 2020”, 2021; arXiv:2111.12952.
  • [15] Selsaas L R, Agrawal B, Rong C, et al. AFFM: auto feature engineering in field-aware factorization machines for predictive analytics[C]//2015 IEEE International Conference on Data Mining Workshop (ICDMW). IEEE, 2015: 1705-1709.
  • [16] Yao Shu, Wei Wang, and Shaofeng Cai. 2019. Understanding Architectures Learnt by Cell-based Neural Architecture Search. In International Conference on Learning Representations.
  • [17] Kaicheng Yu, Rene Ranftl, and Mathieu Salzmann. 2020. How to Train Your Super-Net: An Analysis of Training Heuristics in Weight-Sharing NAS. arXiv preprint arXiv:2003.04276 (2020).
  • [18] Haixun Wang, Wei Fan, Philip S Yu, and Jiawei Han. 2003. Mining concept-drifting data streams using ensemble classifiers. In Proceedings of the ninth ACM SIGKDD international conference on Knowledge discovery and data mining. 226–235.
  • [19] Robi Polikar. 2006. Ensemble based systems in decision making. IEEE Circuits and systems magazine 6, 3 (2006), 21–45.
  • [20] Chengshuai Zhao, Yang Qiu, Shuang Zhou, Shichao Liu, Wen Zhang, and Yanqing Niu. 2020. Graph embedding ensemble methods based on the heterogeneous network for lncRNA-miRNA interaction prediction. BMC genomics 21, 13 (2020), 1–12.
  • [21] Rosenfeld N , Meshi O , Tarlow D , et al. Learning Structured Models with the AUC Loss and Its Generalizations.
  • [22] Chen T , Tong H , Benesty M . xgboost: Extreme Gradient Boosting[J]. 2016.
  • [23] Qi, Yi, et al. “Trilateral Spatiotemporal Attention Network for User Behavior Modeling in Location-based Search”, CIKM 2021.
  • [24] 广告深度预估技术在美团到店场景下的突破与畅想.
  • [25] Geurts P . Bias vs Variance Decomposition for Regression and Classification[J]. Springer US, 2005
  • [26] Kaggle Outbrain比赛链接: https://www.kaggle.com/c/outbrain-click-prediction.
  • [27] KDD Cup 2020 Debiasing比赛链接 https://tianchi.aliyun.com/competition/entrance/231785/introduction.
  • [28] KDD Cup 2018比赛链接:https://www.biendata.xyz/competition/kdd_2018/.
  • [29] KDD Cup 2017比赛链接:https://tianchi.aliyun.com/competition/entrance/231597/introduction.
  • [30] KDD Cup 2020 AutoGraph比赛链接:https://www.automl.ai/competitions/3

招聘信息

美团到店广告平台算法团队立足广告场景,探索深度学习、强化学习、人工智能、大数据、知识图谱、NLP和计算机视觉前沿的技术发展,探索本地生活服务电商的价值。主要工作方向包括:

  • 触发策略:用户意图识别、广告商家数据理解,Query改写,深度匹配,相关性建模。
  • 质量预估:广告质量度建模。点击率、转化率、客单价、交易额预估。
  • 机制设计:广告排序机制、竞价机制、出价建议、流量预估、预算分配。
  • 创意优化:智能创意设计。广告图片、文字、团单、优惠信息等展示创意的优化。

岗位要求

  • 有三年以上相关工作经验,对CTR/CVR预估、NLP、图像理解、机制设计至少一方面有应用经验。
  • 熟悉常用的机器学习、深度学习、强化学习模型。
  • 具有优秀的逻辑思维能力,对解决挑战性问题充满热情,对数据敏感,善于分析/解决问题。
  • 计算机、数学相关专业硕士及以上学历。

具备以下条件优先

  • 有广告/搜索/推荐等相关业务经验。
  • 有大规模机器学习相关经验。

感兴趣的同学可投递简历至:chengxiuying@meituan.com(邮件标题请注明:广平算法团队)。

2021年美团技术团队最受欢迎的22篇技术文章

再见2021,你好2022!

「美团技术团队」微信公众号祝大家新年快乐!温故而知新,我们根据文章的「阅读量」和「在看」数,以及所覆盖的技术领域,精选了22篇技术文章作为新年礼物送给大家。希望在2022年,继续陪大家一起,静心苦练,砥砺向前。

为了做出更好的内容,从2022年开始,我们在选题层面想多听听大家的意见和建议。我们准备了一份调研问卷,欢迎大家帮忙填写。我们会评选出5位小伙伴,送上来自美团礼品店精美的键盘手托(本次活动的截止日期为2022年1月6日)。

2021年「阅读量」最高的11篇技术文章

如何优雅地记录操作日志 阅读量42391

操作日志几乎存在于每个系统中,而这些系统都有记录操作日志的一套API。操作日志和系统日志不一样,操作日志必须要做到简单易懂。所以如何让操作日志不跟业务逻辑耦合,如何让操作日志的内容易于理解,如何让操作日志的接入更加简单?上面这些都是本文要回答的问题。本文主要围绕着如何「优雅」地记录操作日志展开描述。

美团基于知识图谱的剧本杀标准化建设与应用 阅读量30035

剧本杀作为爆发式增长的新兴业务,在商家上单、用户选购、供需匹配等方面存在不足,供给标准化能为用户、商家、平台三方创造价值,助力业务增长。

本文介绍了美团到店综合业务数据团队从0到1快速建设剧本杀供给标准化的过程及算法方案。我们将美团到店综合知识图谱(GENE,GEneral NEeds net)覆盖至剧本杀行业,构建剧本杀知识图谱,实现供给标准化建设,包括剧本杀供给挖掘、标准剧本库构建、供给与标准剧本关联等环节,并在多个场景进行应用落地。

美团商品知识图谱的构建及应用 阅读量24601

商品知识图谱作为新零售行业数字化的基石,提供了围绕商品的精准结构化理解,对业务应用起到了至关重要的作用。相比于美团大脑中原有的围绕商户的图谱而言,商品图谱需应对更加分散、复杂、海量的数据和业务场景,且面临着信息来源质量低、数据维度多、依赖常识以及专业知识等挑战。本文将围绕零售商品知识图谱,介绍美团在商品层级建设、属性体系建设、图谱建设人效提升等方向的探索。

GraphQL及元数据驱动架构在后端BFF中的实践 阅读量22247

GraphQL是Facebook提出的一种数据查询语言,核心特性是数据聚合和按需索取,目前被广泛应用于前后端之间,解决客户端灵活使用数据问题。本文介绍的是GraphQL的另一种实践,我们将GraphQL下沉至后端BFF(Backend For Frontend)层之下,结合元数据技术,实现数据和加工逻辑的按需查询和执行。这样不仅解决了后端BFF层灵活使用数据的问题,这些字段加工逻辑还可以直接复用,大幅度提升了研发的效率。

美团外卖实时数仓建设实践 阅读量21767

本文主要介绍一种通用的实时数仓构建的方法与实践。实时数仓以端到端低延迟、SQL标准化、快速响应变化、数据统一为目标。美团外卖数据智能组总结的最佳实践是:一个通用的实时生产平台跟一个通用交互式实时分析引擎相互配合,同时满足实时和准实时业务场景。两者合理分工,互相补充,形成易开发、易维护且效率高的流水线,兼顾开发效率与生产成本,以较好的投入产出比满足业务的多样性需求。

美团酒旅数据治理实践 阅读量20692

数据已成为很多公司的核心资产,而在数据开发的过程中会引入各种质量、效率、安全等方面的问题,而数据治理就是要不断消除引入的这些问题,保障数据准确、全面和完整,为业务创造价值,同时严格管理数据的权限,避免数据泄露带来的业务风险。数据治理是数字时代很多公司一项非常重要的核心能力,本文介绍了美团酒旅平台在数据治理方面的实践。

FlutterWeb性能优化探索与实践 阅读量19642

美团外卖商家端基于 FlutterWeb 的技术探索已久,目前在多个业务中落地了App、PC、H5的多端复用,有效提升了产研的整体效率。在这过程中,性能问题是我们面临的最大挑战,本文结合实际业务场景进行思考,介绍美团外卖商家端在FlutterWeb性能优化上所进行的探索和实践。

百亿规模API网关服务Shepherd的设计与实现 阅读量19591

在微服务架构下,服务拆分会让API的规模成倍增长,使用API网关来管理API逐渐成为一种趋势。美团统一API网关服务Shepherd就是在这种背景下应运而生,适用于美团业务且完全自研,用于替换传统的Web层网关应用,业务研发人员通过配置的方式即可对外开放功能和数据。本文将介绍美团统一API网关诞生的背景、关键的技术设计和实现,以及API网关未来的规划。

情感分析技术在美团的探索与应用 阅读量18820

2021年5月,美团NLP中心开源了迄今规模最大的基于真实场景的中文属性级情感分析数据集ASAP,该数据集相关论文被自然语言处理顶会NAACL2021录用,同时该数据集加入中文开源数据计划千言,将与其他开源数据集一起推动中文信息处理技术的进步。

本文回顾了美团情感分析技术的演进和在典型业务场景中的应用,包括篇章/句子级情感分析、属性级情感分析和观点三元组分析。在业务应用上,依托情感分析技术能力构建了在线实时预测服务和离线批量预测服务。截至目前,情感分析服务已经为美团内部十多个业务场景提供了服务。

多业务建模在美团搜索排序中的实践 阅读量18124

本文分享了美团搜索中的多业务排序建模优化工作,我们主要聚焦在到店商家多业务场景,后续的内容会分为以下四个部分:第一部分是对美团搜索排序分层架构进行简单介绍;第二部分会介绍多路融合层上的多业务融合建模;第三部分会介绍精排模型的多业务排序建模;最后一部分是总结和展望。

Spock单元测试框架以及在美团优选的实践 阅读量15531

Spock是国外一款优秀的测试框架,基于BDD(行为驱动开发)思想实现,功能非常强大。Spock结合Groovy动态语言的特点,提供了各种标签,并采用简单、通用、结构化的描述语言,让编写测试代码更加简洁、高效。目前,美团优选物流绝大部分后端服务已经采用了Spock作为测试框架,在开发效率、可读性和维护性方面均取得了不错的收益。

2021年「在看」数最高的11篇技术文章

速度与压缩比如何兼得?压缩算法在构建部署中的优化 在看数3279

压缩在数据传输和存储过程中经常扮演着十分重要的角色,因此提高压缩的效率可以帮助我们节省时间和降低存储成本。本文介绍了压缩算法的优化在构建部署平台的应用,能够帮助研发团队提高研发和交付效率。

基于SSD的Kafka应用层缓存架构设计与实现 在看数3254

Kafka在美团数据平台承担着统一的数据缓存和分发的角色,针对因PageCache互相污染,进而引发PageCache竞争导致实时作业被延迟作业影响的痛点,美团基于SSD自研了Kafka的应用层缓存架构。本文主要介绍了该架构的设计与实现,主要包括方案选型,与其他备选方案的比较以及方案的核心思考点等,最后介绍该方案与其他备选方案的性能对比。

让Flutter在鸿蒙系统上跑起来 在看数3155

鸿蒙系统HarmonyOS是华为推出的一款分布式操作系统,那么如何在保证开发迭代效率的前提下,以相对低的成本将移动应用快速移植到鸿蒙平台上呢?美团外卖MTFlutter团队近期做了一次技术探索,成功地实现了Flutter对于鸿蒙系统的原生支持。

自动驾驶轨迹预测算法:NeurIPS挑战赛冠军方案 在看数2931

美团无人车配送中心团队获得NeurIPS 2020 INTERPRET轨迹预测挑战赛Generalizability赛道冠军、Regular赛道亚军,本文对算法层面进行了介绍。

一款可以让大型iOS工程编译速度提升50%的工具 在看数2163

本文介绍了美团平台自研的一款cocoapods插件,该插件可以大幅提升iOS工程代码的编译速度。文章前半部分主要介绍相关的原理,后面主要阐述在工程层面的实践。

美团外卖特征平台的建设与实践 在看数1974

随着美团外卖业务的发展,算法模型也在不断演进迭代中。本文从特征框架演进、特征生产、特征获取计算以及训练样本生成四个方面介绍了美团外卖特征平台在建设与实践中的思考和优化思路。

OCTO 2.0:美团基于Service Mesh的服务治理系统详解 在看数1616

OCTO 2.0是美团下一代分布式服务治理系统,它基于美团现有服务治理系统OCTO 1.0与Service Mesh通信基础设施层的结合,是命名服务、配置管理、性能监控、限流鉴权等服务治理功能的全新演进版本。本文主要讲述OCTO 2.0的重要功能及实现思路。

FlutterWeb在美团外卖的实践 在看数1369

在多形态业务场景下,如何保障多端体验的一致性,是前端技术领域一个比较受关注的方向。美团外卖前端技术团队基于FlutterWeb探索跨端(App\PC\H5)的解决方案,真正实现「Write Once & Run AnyWhere」,本文系该团队的实践经验总结。

设计稿(UI视图)自动生成代码方案的探索 在看数1037

设计稿(UI视图)转代码是前端工程师日常不断重复的工作,这部分工作复杂度较低但工作占比较高,所以提升设计稿转代码的效率一直是前端工程师追求的方向之一。

此前,前端工程师尝试过将业务组件模块化构建成通用视图库,并通过拖拽、拼接等形式搭建业务模块,从而实现视图复用,降低设计稿转代码的研发成本。但随着业务的发展和个性化的驱动,通用视图库无法覆盖所有应用场景,本文提出了一种设计稿自动生成代码的方案。

美团图数据库平台建设及业务实践 在看数807

图数据结构,能够更好地表征现实世界。美团业务相对较复杂,存在比较多的图数据存储及多跳查询需求,亟需一种组件来对千亿量级图数据进行管理,海量图数据的高效存储和查询是图数据库研究的核心课题。本文介绍了美团在图数据库选型及平台建设方面的一些工作。

实践之后,我们来谈谈如何做好威胁建模 在看数540

对美团安全团队来说,引入领先的安全技术设计能力,构建全方位、多维度智能防御体系,是我们不懈追求的目标。美团有众多基础设施,核心业务系统也需要以成熟的方法论进行威胁评审。本文将着重分享威胁建模是如何帮助美团安全团队评估、发现大量安全设计的风险,以及互联网企业应该如何大范围地实施威胁建模并完整地进行落地。

备注:数据统计于2021年12月30日16:00,同时入围两个榜单的文章已经做了去重处理。

写在后面

再次邀请大家帮忙填一下美团技术团队公众号的调研问卷,欢迎大家留下宝贵的意见或者建议,期待未来我们能共同成长。

2013年12月4日,美团技术团队博客诞生,发表了第1篇文章。8年多的时间,2948天,目前我们已经发布了483篇技术文章,美团技术团队博客/公众号,感谢大家的一路相伴!

最后,祝大家在2022年,健康平安,「虎」力冲天。

FlutterWeb性能优化探索与实践

一、背景

1.1 关于FlutterWeb

时间回拨到 2018 年,Google 首次公开 FlutterWeb Beta 版,表露出要实现一份代码、多端运行的愿景。经过无数工程师两年多的努力,在今年年初(2021 年 3 月份),Flutter 2.0 正式对外发布,它将 FlutterWeb 功能并入了 Stable Channel,意味着 Google 更加坚定了多端复用的决心。

图1 FlutterWeb历史

当然 Google 的“野心”不是没有底气的,主要体现在它强大的跨端能力上,我们看一下 Flutter 的跨端能力在 Web 侧是如何体现的:

图2 Flutter跨端能力

上图分别是 FlutterNative 和 FlutterWeb 的架构图。通过对比可以看出,应用层 Framework 是公用的,意味着在 FlutterWeb 中我们也可以直接使用 Widgets、Gestures 等组件来实现逻辑跨端。而关于渲染跨端,FlutterWeb 提供了两种模式来对齐 Engine 层的渲染能力:Canvaskit Render 和 HTML Render,下方表格对两者的区别进行了对比:

图3 模式对比

Canvaskit Render 模式:底层基于 Skia 的 WebAssembly 版本,而上层使用 WebGL 进行渲染,因此能较好地保证一致性和滚动性能,但糟糕的兼容性(WebAssembly 从 Chrome 57 版本才开始支持)是我们需要面对的问题。此外 Skia 的 WebAssembly 文件大小达到了 2.5M,且 Skia 自绘引擎需要字体库支持,这意味着需要依赖超大的中文字体文件,对页面加载性能影响较大,因此目前并不推荐在 Web 中直接使用 Canvaskit Render(官方也建议将 Canvaskit Render 模式用于桌面应用)。

HTML Render 模式:利用 HTML + Canvas 对齐了 Engine 层的渲染能力,因此兼容性表现优秀。另外,MTFlutterWeb 对滚动性能已有过探索和实践,目前能够应对大部分业务场景。而关于加载性能,此模式下的初始包为 1.2M,是 Canvaskit Render 模式产物体积的 1/2,且我们可对编译流程进行干预,控制输出产物,因此优化空间较大。

基于以上原因,美团外卖技术团队选择在 HTML Render 模式下对 FlutterWeb 页面的性能进行优化探索。

1.2 业务现状

美团外卖商家端以 App、PC 等多元化的形态为商家提供了订单管理、商品维护、顾客评价、外卖课堂等一系列服务,且 App、PC 双端业务功能基本对齐。此外,我们还在 PC 上特供了针对连锁商家的多店管理功能。同时,为满足平台运营诉求,部分业务具有外投 H5 场景,例如美团外卖商家课堂,它是一个以文章、视频等形式帮助商家学习外卖运营知识、了解行业发展和跟进经营策略的内容平台,具有较强的传播属性,因此我们提供了站外分享的能力。

图4 业务形态

为了实现多端(App、PC、H5)复用,提升研发效率,我们于 2021 年年初开始着手 MTFlutterWeb 研发体系的建设。目前,我们基于 MTFlutterWeb 完成提效的业务超过了 9 个,在 App 中,能够基于 FlutterNative 提供高性能的服务;在 PC 端和 Mobile 浏览器中,利用 FlutterWeb 做到了低成本适配,提升了产研的整体效率。

然而,加载性能问题是 MTFlutterWeb 应用推广的最大障碍。这里依然以美团外卖商家课堂业务为例,在项目之初页面完全加载时间 TP90 线达到了 6s 左右,距离我们的指标基线值(页面完全加载时间 TP90 线不高于 3s,基线值主要依据美团外卖商家端的业务场景、用户画像等来确定)有些差距,用户访问体验有很大的提升空间,因此 FlutterWeb 页面加载性能优化,是我们亟需解决的问题。

二、挑战

不过,想要突破 FlutterWeb 页面加载的性能瓶颈,我们面临的挑战也是巨大的。这主要体现在 FlutterWeb 缺失静态资源的优化策略,以及复杂的架构设计和编译流程。下图展示了 Flutter 业务代码被转换成 Web 平台产物的流程,我们来具体进行分析:

图5 FlutterWeb 编译流程

  1. Framework、Flutter_Web_SDK(Flutter_Web_SDK 基于 HTML、Canvas,承载 HTML Render 模式的具体实现)等底层 SDK 是可被业务代码直接引入的,帮助我们快速开发出跨端应用;
  2. flutter_tools 是各平台(Android、iOS、Web)的编译入口,它接收 flutter build web 命令和参数并开始编译流程,同时等待处理结果回调,在回调中我们可对编译产物进行二次加工;
  3. frontend_server 负责将 Dart 转换为 AST,生成 kernel 中间产物 app.dill 文件(实际上各平台的编译过程都会生成这样的中间产物),并交由各平台 Compiler 进行转译;
  4. Dart2JS Compiler 是 Dart-SDK 中具体负责转译 JS 的模块,它将上述中间产物 app.dill 进行读取和解析,并注入 Math、List、Map 等 JS 工具方法,最终生产出 Web 平台所能执行的 JS 文件。
  5. 编译产物主要为 main.dart.js、index.html、images 等静态资源,FlutterWeb 对这些静态资源缺少常规 Web 项目中的优化手段,例如:文件 Hash 化、文件分片、CDN 支持等。

可以看出,要完成对 FlutterWeb 编译产物的优化,就需要干预 FlutterWeb 的众多编译模块。而为了提升整体的编译效率,大部分模块都被提前编译成了 snapshot 文件( 一种 Dart 的编译产物,可被 Dart VM 所运行,用于提升执行效率),例如:flutter_tools.snapshot、frontend_server.snapshot、dart2js.snapshot 等,这又加大了对 FlutterWeb 编译流程进行干预的难度。

三、整体设计

如前文所述,为了实现逻辑、渲染跨平台,Flutter 的架构设计及编译流程都具有一定的复杂性。但由于各平台(Android、iOS、Web)的具体实现是解耦的,因此我们的思路是定位各模块(Dart-SDK、Framework、Flutter_Web_SDK、flutter_tools)的 Web 平台实现并寻求优化,整体设计图如下所示:

图6 整体设计

  • SDK 瘦身:我们分别对 FlutterWeb 所依赖的 Dart-SDK、Framework、Flutter_Web_SDK 进行了瘦身,并将这些精简版 SDK 集成合入 CI/CD(持续集成与部署)系统,为减小产物包体积奠定了基础;
  • 编译优化:此外,我们在 flutter_tools 中的编译流程做了干预,分别进行了 JS 文件分片、静态资源 Hash 化、资源文件上传 CDN 等优化,使得这些在常规 Web 应用中基础的性能优化手段得以在 FlutterWeb 中落地。同时加强了 FlutterWeb 特殊场景下的资源优化,如:字体图标精简、Runtime Manifest 隔离、Mobile/PC 分平台打包等;
  • 加载优化:在编译阶段进行静态资源优化后,我们在前端运行时,支持了资源预加载与按需加载,通过设定合理的加载时机,从而减小初始代码体积,提升页面首屏的渲染速度。

下面,我们分别对各项优化进行详细的说明。

四、设计与实践

4.1 精简 SDK

4.1.1 包体积分析

工欲善其事,必先利其器,在开始做体积裁剪之前,我们需要一套类似于 webpack-bundle-analyzer 的包体积分析工具,便于直观地比较各个模块的体积占比,为优化性能提供帮助。

Dart2JS 官方提供了 –dump-info 命令选项来分析 JS 产物,但其表现差强人意,它并不能很好地分析各个模块的体积占比。这里更推荐使用 source-map-explorer ,它的原理是通过 sourcemap 文件进行反解,能清晰地反映出每个模块的占用大小,为 SDK 的精简提供了指引。下图展示了 FlutterWeb JS 产物的反解信息(截图仅包含 Framework 和 Flutter_Web_SDK):

图7 反解信息

4.1.2 SDK 裁剪

FlutterWeb 依赖的 SDK 主要包括 Dart-SDK、Framework 和 Flutter_Web_SDK,这些 SDK 对包体积的影响是巨大的,几乎贡献了初始化包的所有大小。虽然在 Release 模式下的编译流程中,Dart Compiler 会利用 Tree-Shaking 来剔除那些引入但未使用的 packages、classes、functions 等,很大程度上减少了包体积。但这些 SDK 中仍然存在一些能被进一步优化的代码。

以 Flutter Framework 为例,由于它是全平台公用的模块,因此不可避免地存在各平台的兼容逻辑(通常以 if-else、switch 等条件判断形式出现),而这部分代码是不能被 Tree-Shaking 剔除的,我们观察如下的代码:

// FileName: flutter/lib/src/rendering/editable.dart
void _handleKeyEvent(RawKeyEvent keyEvent) {
  if (kIsWeb) {
    // On web platform, we should ignore the key.
    return;
  }
  // Other codes ...
}

上述代码选自 Framework 中的 RenderEditable 类,当 kIsWeb 变量为真,表示当前应用运行在 Web 平台。受限于 Tree-Shaking 的机制原理,上述代码中,其它平台的兼容逻辑即注释 Other codes 的部分是无法被剔除的,但这部分代码,对 Web 平台来说却是 Dead Code(永远不可能被执行到的代码),是可以被进一步优化的。

图8 部分功能构成

上图展示了 SDK 的一部分功能构成,从图中可以看出,FlutterWeb 依赖的这些 SDK 中包含了一些使用频率较低的功能,例如:蓝牙、USB、WebRTC、陀螺仪等功能的支持。为此,我们提供了对这些长尾功能的定制能力(这些功能默认不开启,但业务可配置),将未被启用长尾的功能进行裁剪。

通过上述分析可得,我们的思路就是对 Dead Code 进行二次剔除,以及对这些长尾功能做裁剪。基于这样的思路,我们深入 Dart-SDK、Framework 和 Flutter_Web_SDK 各个击破,最终将 JS Bundle 产物体积由 1.2M 精简至 0.7M,为 FlutterWeb 页面性能优化打下了坚实的基础。

图9 精简成果

4.1.3 SDK 集成 CI/CD

为了提升构建效率,我们将 FlutterWeb 依赖的环境定制为 Docker 镜像,集成入 CI/CD(持续集成与部署)系统。SDK 裁剪后,我们需要更新 Docker 镜像,整个过程耗时较长且不够灵活。因此,我们将 Dart-SDK、Framework、Flutter_Web_SDK 按版本打包传至云端,在编译开始前读取 CI/CD 环境变量:sdk_version(SDK 版本号),远程拉取相应版本的 SDK 包,并替换当前 Docker 环境中的对应模块,基于以此方案实现 SDK 的灵活发布,具体流程图如下图所示:

图10 集成CI/CD

4.2 JS 分片

FlutterWeb 编译之后默认会生成 main.dart.js 文件,它囊括了 SDK 代码以及业务逻辑,这样会引起以下问题:

  1. 功能无法及时更新:为了实现浏览器的缓存优化,我们的项目开启了对静态资源的强缓存,若 main.dart.js 产物不支持 Hash 命名,可能导致程序代码不能被及时更新;
  2. 无法使用 CDN:FlutterWeb 默认仅支持相对域名的资源加载方式,无法使用当前域名以外的 CDN 域名,导致无法享受 CDN 带来的优势;
  3. 首屏渲染性能不佳:虽然我们进行了 SDK 瘦身,但 main.dart.js 文件依然维持在 0.7M 以上,单一文件加载、解析时间过长,势必会影响首屏的渲染时间。

针对文件 Hash 化和 CDN 加载的支持,我们在 flutter_tools 编译流程中对静态资源进行二次处理:遍历静态资源产物,增加文件 Hash(文件内容 MD5 值),并更新资源的引用;同时通过定制 Dart-SDK,修改了 main.dart.js、字体等静态资源的加载逻辑,使其支持 CDN 资源加载。

更详细的方案设计请参考《Flutter Web在美团外卖的实践》一文。下面我们重点介绍 main.dart.js 分片相关的一些优化策略。

4.2.1 Lazy Loading

Flutter 官方提供 deferred as 关键字来实现 Widget 的懒加载,而 dart2js 在编译过程中可以将懒加载的 Widget 进行按需打包,这样的拆包机制叫做 Lazy Loading。借助 Lazy Loading,我们可以在路由表中使用 deferred 引入各个路由(页面),以此来达到业务代码拆离的目的,具体使用方法和效果如下所示:

// 使用方式
import 'pages/index/index.dart' deferred as IndexPageDefer;
{
  '/index': (context) => FutureBuilder(
    future: IndexPageDefer.loadLibrary(),
    builder: (context, snapshot) => IndexPageDefer.Demo(),
  )
  ... ...
}

图11 效果演示

使用 Lazy Loading 后,业务页面的代码会被拆分到了多个 PartJS(对应图中 xxx.part.js 文件) 中。这样看似解决了业务代码与 SDK 耦合的问题,但在实际操作过程中,我们发现每次业务代码的变动,仍然会导致编译后的 main.dart.js 随之发生变化(文件 Hash 值变化)。经过定位与跟踪,我们发现这个变化的部分是 PartJS 的加载逻辑和映射关系,我们称之为 Runtime Manifest。因此,需要设计一套方案对 Runtime Manifest 进行抽离,来保证业务代码的修改对 main.dart.js 的影响达到最低。

4.2.2 Runtime Manifest抽离

通过对业务代码的抽离,此时 main.dart.js 文件的构成主要包含 SDK 和 Runtime Manifest:

图12 main.dart.js构成

那如何能将 Runtime Manifest 进行抽离呢?对比常规 Web 项目,我们的处理方式是把 SDK、Utils、三方包等基础依赖,利用 Webpack、Rollup 等打包工具进行抽离并赋予一个稳定的 Hash 值。同时,将 Runtime Manifest (分片文件的加载逻辑和映射关系)注入到 HTML 文件中,这样保证了业务代码的变动不会影响到公共包。借助常规 Web 项目的编译思路,我们深入分析了 FlutterWeb 中 Runtime Manifest 的生成逻辑和 PartJS 的加载逻辑,定制出如下的解决方案:

图13 Runtime Manifest抽离

在上图中,Runtime Manifest 的生成逻辑位于 Dart2JS Compiler 模块,在该生成逻辑中,我们对 Runtime Manifest 代码块进行了标记,之后在 flutter_tools 中将标记的 Runtime Manifest 代码块抽离并写入 HTML 文件中(以 JS 常量形式存在)。而在 PartJS 的加载流程中,我们将 manifest 信息的读取方式改为了 JS 常量的获取。按照这样的拆分方式,业务代码的变更只会改变 Runtime Manifest 信息 ,而不会影响到 main.dart.js 公共包。

4.2.3 main.dart.js 切片

经过以上引入 Lazy Loading、Runtime Manifest 抽离,main.dart.js 文件的体积稳定在 0.7M 左右,浏览器对大体积单文件的加载,会有很沉重的网络负担,所以我们设计了切片方案,充分地利用浏览器对多文件并行加载的特性,提升文件的加载效率。

具体实现方案为:将 main.dart.js 在 flutter_tools 编译过程拆分成多份纯文本文件,前端通过 XHR 的方式并行加载并按顺序拼接成 JavaScript 代码置于 < script > 标签中,从而实现切片文件的并行加载。

图14 并行加载

4.3 预加载方案

如上一节所述,虽然我们做了很多工作来稳定 main.dart.js 的内容,但在 Flutter Tree-Shaking 的运行机制下,各个项目引用不同的 Framework Widget,就会导致每个项目生成的 main.dart.js 内容不一致。随着接入 FlutterWeb 的项目越来越多,每个业务的页面互访概率也越来越高,我们的期望是当访问 A 业务时,可以预先缓存 B 业务引用的 main.dart.js,这样当用户真正进入 B 业务时就可以节省加载资源的时间,下面为详细的技术方案。

4.3.1 技术方案

我们把整体的技术方案分为编译、监听、运行三个阶段。

  1. 编译阶段,在发布流水线上根据前期定制的匹配规则,筛选出符合条件的资源文件路径,生成云端 JSON 并上传;
  2. 监听阶段,在 DOMContentLoaded 之后,对网络资源、事件、DOM 变动进行监听,并对监听结果根据特定规则进行分析加权,得到一个首屏加载完成的状态标识;
  3. 运行阶段,在首屏加载完成之后对配置平台下发的云端 JSON 文件进行解析,对符合配置规则的资源进行 HTTP XHR 预加载,从而实现文件的预缓存功能。

下图为预缓存的整体方案设计:

图15 预缓存方案设计

编译阶段

编译阶段会扩展现有的发布流水线,在 flutter build 之后增加 prefetch build 作业,这样 build 之后就可以对产物目录进行遍历和筛选,得到我们所需资源进而生成云端 JSON,为运行阶段提供数据基础。下面的流程图为编译阶段的详细方案设计:

图16 预缓存编译阶段

编译阶段分为三部分:

  1. 第一部分:根据不同的发布环境,初始化线上/线下的配置平台,为配置文件的读写做好准备;
  2. 第二部分:下载并解析配置平台下发的资源组 JSON,筛选出符合配置规则的资源路径,更新 JSON 文件并发布到配置平台;
  3. 第三部分:通过发布流水线提供的 API,把 PROJECT_ID、发布环境注入HTML文件中,为运行阶段提供全局变量以便读取。

通过对流水线编译期的整合,我们可以生成新的云端 JSON 并上传到云端,为运行阶段的下发提供数据基础。

监听阶段

我们知道,浏览器对文件请求的并发数量是有限制的,为了保证浏览器对当前页面的渲染处于高优先级,同时还能完成预缓存的功能,我们设计了一套对缓存文件的加载策略,在不影响当前页面加载的情况下,实现对缓存文件的加载操作。以下为详细的技术方案:

图17 预缓存监听阶段

在页面 DOMContentLoaded 之后,我们会监听三部分的的变化。

  1. 第一部分是监听 DOM 的变化。这部分主要是在页面发生 Ajax 请求之后,随着MV模式的变动,DOM 也会随之发生变化。我们使用浏览器提供的 MutationObserver API 对 DOM 变化进行收集,并筛选有效节点进行深度优先遍历,计算每个 DOM 的递归权重值,低于阈值我们就认为首屏已加载完成。
  2. 第二部分是监听资源的变化。我们利用浏览提供的 PerformanceObserver API,筛选出 img/script 类型的资源,在 3 秒内收集的资源没有增加时,我们认为首屏已加载完成。
  3. 第三部分是监听 Event 事件。当用户发生 click、wheel、touchmove 等交互行为时,我们就认为当前页面处于一个可交互的状态,即首屏加载已完成,这样会在后续进行资源的预缓存。

通过上述步骤,我们就可以得到一个首屏渲染完成的时机,之后就可以实现预缓存功能了。以下为预缓存功能的实现。

运行阶段

预缓存的整体流程为:下载编译阶段生成的云端 JSON,解析出需要进行预缓存资源的 CDN 路径,最后通过 HTTP XHR 进行缓存资源进行请求,利用浏览器本身的缓存策略,把其他业务的资源文件写入。当用户访问已命中缓存的页面时,资源已被提前加载,这样可以有效地减少首屏的加载时间。下图为运行阶段的详细方案设计:

图18 预缓存运行阶段

在监听阶段,我们可以获取到页面的首屏渲染完成的时机,会获取到云端 JSON,首先判断该项目的缓存是否为启用状态。当该项目可用时,会根据全局变量 PROJECT_ID 进行资源数组的匹配,再以 HTTP XHR 方式进行预访问,把缓存文件写入浏览器缓存池中。至此,资源预缓存已执行完毕。

4.3.2 效果展示与数据对比

当有页面间互访问命中预缓存时,浏览器会以 200(Disk Cache)的方式返回数据,这样就节省了大量资源加载的时间,下图为命中缓存后资源加载情况:

图19 预缓存效果展示

目前,美团外卖商家端业务已有 10+ 个页面接入了预缓存功能,资源加载 90 线平均值由 400ms 下降到 350ms,降低了 12.5%;50 线平均值由 114ms 下降到 100ms,降低了 12%。随着项目接入接入越来越多,预缓存的效果也会越发的明显。

图20 预缓存数据展示

4.4 分平台打包

如前文所述,美团外卖商家业务大部分都是双端对齐的。为了实现提效的最大化,我们对 FlutterWeb 的多平台适配能力进行加强,实现了 FlutterWeb 在 PC 侧的复用。

在 PC 适配过程中,我们不可避免地需要书写双端的兼容代码,如:为了实现在列表页面中对卡片组件的复用。为此我们开发了一个适配工具 ResponsiveSystem,分别传入 PC 和 App 的各端实现,内部会区分平台完成适配:

// ResponsiveSystem 使用举例
Container(
  child: ResponsiveSystem(
    app: AppWidget(),
    pc: PCWidget(),
  ),
)

上述代码能较方便的实现 PC 和 App 适配,但 AppWidget 或 PCWidget 在编译过程中都将无法被 Tree-Shaking 去除,因此会影响包体积大小。对此,我们将编译流程进行优化,设计分平台打包方案:

图21 分平台打包

  1. 修改 flutter-cli,使其支持 –responsiveSystem 命令行参数;
  2. 我们在 flutter_tools 中的 AST 分析阶段增加了额外的处理:ResponsiveSystem 关键字的匹配,同时结合编译平台(PC 或 Mobile)来进行 AST 节点的改写;
  3. 去除无用 AST 节点后,生成各个平台的代码快照(每份快照仅包含单独平台代码);
  4. 根据代码快照编译生成 PC 和 App 两套 JS 产物,并进行资源隔离。而对于 images、fonts 等公用资源,我们将其打入 common 目录。

通过这样的方式,我们去除了各自平台的无用代码,避免了 PC 适配过程中引起的包体积问题。依然以美团外卖商家课堂业务(6 个页面)为例,接入分平台打包后,单平台代码体积减小 100KB 左右。

图22 效果展示

4.5 图标字体精简

当访问 FlutterWeb 页面时,即使在业务代码中并未使用 Icon 图标,也会加载一个 920KB 的图标字体文件:MaterialIcons-Regular.woff。通过探究,我们发现是 Flutter Framework 中一些系统 UI 组件(如:CalendarDatePicker、PaginatedDataTable、PopupMenuButton 等)使用到了 Icon 图标导致,且 Flutter 为了便于开发者使用,提供了全量的 Icon 图标字体文件。

Flutter 官方提供的 --tree-shake-icons 命令选项是将业务使用到的 Icon 与 Flutter 内部维护的一个缩小版字体文件(大约 690KB)进行合并,能一定程度上减小字体文件大小。而我们需要的是只打包业务使用的 Icon,所以我们对官方 tree-shake-icons 进行了优化,设计了 Icon 的按需打包方案:

图23 图标字体精简

  1. 扫描全部业务代码以及依赖的 Plugins、Packages、Flutter Framework,分析出所有用到的 Icon;
  2. 把扫描到的所有 Icon 与 material/icons.dart(该文件包含 Flutter Icon 的 unicode 编码集合)进行对比,得到精简后的图标编码列表:iconStrList;
  3. 使用 FontTools 工具把 iconStrList 生成字体文件 .woff,此时的字体文件仅包含真正使用到的 Icon。

通过以上的方案,我们解决了字体文件过大带来的包体积问题,以美团外卖课堂业务(业务代码中使用了 5 个 Icon)为例,字体文件从 920KB 精简为 11.6kB。

图24 效果展示

五、总结与展望

综上所述,我们基于 HTML Render 模式对 FlutterWeb 性能优化进行了探索和实践,主要包括 SDK(Dart-SDK、Framework、Flutter_Web_SDK)的精简,静态资源产物优化(例如:JS 分片、文件 Hash、字体图标文件精简、分平台打包等)和前端资源加载优化(预加载与按需请求)。最终使得 JS 产物由 1.2M 减少至 0.7M(非业务代码),页面完全加载时间 TP90 线由 6s 降到了 3s,这样的结果已能满足美团外卖商家端的大部分业务要求。而未来的规划将聚焦于以下3个方向:

  1. 降低 Web 端适配成本:目前已有 9+ 个业务借助 MTFlutterWeb 实现多端复用,但在 Web 侧(尤其是 PC 侧)的适配效率依然有优化空间,目标是将适配成本降低到 10% 以下(目前大约是 20% );
  2. 构建 FlutterWeb 容灾体系:Flutter 动态化包有一定的加载失败概率,而 FlutterWeb 作为兜底方案,能提升整体业务的加载成功率。此外 FlutterWeb 可以提供“免安装更新”的能力,降低 FlutterNative 老旧历史版本的维护成本;
  3. 性能优化的持续推进:性能优化的阶段性成果为 MTFlutterWeb 的应用推广巩固了基础,但依然是有进一步优化空间的,例如:目前我们仅将业务代码和 Runtime Manifest 进行了拆离,而 Framework 及 三方包在一定程度上也影响到了浏览器缓存的命中率,将这部分代码进行抽离,可进一步提升页面加载性能。

美团外卖技术团队正在基于 FlutterWeb 做更多的探索和尝试。如果你对这方面的技术也比较感兴趣,可以在文末留言,跟我们一起讨论。也欢迎大家给提出一些建议,非常感谢。

TensorFlow在推荐系统中的分布式训练优化实践

1 背景

TensorFlow(下文简称TF)是谷歌推出的一个开源深度学习框架,在美团推荐系统场景中得到了广泛的使用。但TensorFlow官方版本对工业级场景的支持,目前做得并不是特别的完善。美团在大规模生产落地的过程中,遇到了以下几方面的挑战:

  • 所有参数都是用Variable表达, 对于百亿以上的稀疏参数开辟了大量的内存,造成了资源的浪费;
  • 只支持百级别Worker的分布式扩展,对上千Worker的扩展性较差;
  • 由于不支持大规模稀疏参数动态添加、删除,增量导出,导致无法支持Online Learning;
  • 大规模集群运行时,会遇到慢机和宕机;由于框架层不能处理,导会致任务运行异常。

以上这些问题,并不是TensorFlow设计的问题,更多是底层实现的问题。考虑到美团大量业务的使用习惯以及社区的兼容性,我们基于原生TensorFlow 1.x架构与接口,从大规模稀疏参数的支持、训练模式、分布式通信优化、流水线优化、算子优化融合等多维度进行了深度定制,从而解决了该场景的核心痛点问题。

首先新系统在支持能力层面,目前可以做到千亿参数模型,上千Worker分布式训练的近线性加速,全年样本数据能够1天内完成训练,并支持Online Learning的能力。同时,新系统的各种架构和接口更加友好,美团内部包括美团外卖、美团优选、美团搜索、广告平台、大众点评Feeds等业务部门都在使用。本文将重点介绍大规模分布式训练优化的工作,希望对大家能够有所帮助或启发。

2 大规模训练优化挑战

2.1 业务迭代带来的挑战

随着美团业务的发展,推荐系统模型的规模和复杂度也在快速增长,具体表现如下:

  • 训练数据:训练样本从到百亿增长到千亿,增长了近10倍。
  • 稀疏参数:个数从几百到几千,也增长了近10倍;总参数量从几亿增长到百亿,增长了10~20倍。
  • 模型复杂度:越来越复杂,模型单步计算时间增长10倍以上。

对于大流量业务,一次训练实验,从几个小时增长到了几天,而此场景一次实验保持在1天之内是基本的需求。

2.2 系统负载分析

2.2.1 问题分析工具链

TensorFlow是一个非常庞大的开源项目,代码有几百万行之多,原生系统的监控指标太粗,且不支持全局的监控,如果要定位一些复杂的性能瓶颈点,就比较困难。我们基于美团已经开源的监控系统CAT[2],构建了TensorFlow的细粒度监控链路(如下图1所示),可以精准定位到性能的瓶颈问题。

图1 TensorFlow PS架构全链路监控

同时,在性能优化的过程中,会涉及到大量的性能测试和结果分析,这也是一个非常耗费人力的工作。我们抽象了一套自动化的实验框架(如下图2所示),可以自动化、多轮次地进行实验,并自动采集各类监控指标,然后生成报告。

图2 自动化实验框架

2.2.2 业务视角的负载分析

在推荐系统场景中,我们使用了TensorFlow Parameter Server[3](简称PS)异步训练模式来支持业务分布式训练需求。对于这套架构,上述的业务变化会带来什么样的负载变化?如下图3所示:

图3 TensorFlow PS架构大规模训练负载分析

总结来看,主要包括通信压力、PS并发压力、Worker计算压力。对于分布式系统来说,通常是通过横向扩展来解决负载问题。虽然看来起可以解决问题,但从实验结果来看,当PS扩展到一定数量后,单步训练时间反而会增加,如下图4所示:

图4 扩展PS提升训练性能实验

导致这种结果的核心原因是:Worker单步训练需要和所有的PS通信同步完成,每增加1个PS要增加N条通信链路,这大大增加了链路延迟(如下图5所示)。而一次训练要执行上百万、上千万步训练。最终导致链路延迟超过了加PS算力并发的收益

图5 增加PS带来的链路开销

而对于这个系统,优化的核心难点在于:如何在有限的PS实例下,进行分布式计算的优化

3 优化实践

3.1 大规模稀疏参数介绍

对于推荐系统模型,绝大多数参数都是稀疏参数,而对稀疏参数来说有一个非常重要的操作是Embedding,这个操作通常也是负载最重的,也是后续优化的重点。由于我们对稀疏参数进行了重新定义,后续的优化也基于此之上,所以我们先介绍一下这部分的工作。

在原生的TensorFlow中构建Embedding模块,用户需要首先创建一个足够装得下所有稀疏参数的Variable,然后在这个Variable上进行Embedding的学习。然而,使用Variable来进行Embedding训练存在很多弊端:

  • Variable的大小必须提前设定好,对于百亿千亿的场景,该设定会带来巨大的空间浪费;
  • 训练速度慢,无法针对稀疏模型进行定制优化。

我们首先解决了有无的问题,使用HashTable来替代Variable,将稀疏特征ID作为Key,Embedding向量作为Value。相比原生使用Variable进行Embedding的方式,具备以下的优势:

  1. HashTable的大小可以在训练过程中自动伸缩,避免了开辟冗余的存储空间,同时用户无需关注申请大小,从而降低了使用成本。
  2. 针对HashTable方案实施了一系列定制优化,训练速度相比Variable有了很大的提高,可以进行千亿规模模型的训练,扩展性较好。
  3. 得益于稀疏参数的动态伸缩,我们在此基础上支持了Online Learning。
  4. API设计上保持与社区版本兼容,在使用上几乎与原生Variable一致,对接成本极低。

简化版的基于PS架构的实现示意如下图6所示:

图6 支撑大规模稀疏参数的HashTable方案

核心流程大致可以分为以下几步:

  1. 稀疏特征ID(通常我们会提前完成统一编码的工作)进入Embedding模块,借助TensorFlow搭建的Send-Recv机制,这些稀疏特征ID被拉取到PS端,PS端上的Lookup等算子会实际从底层HashTable中查询并组装Embedding向量。
  2. 上述Embedding向量被Worker拉回进行后续训练,并通过反向传播计算出这部分参数的梯度,这些梯度进一步被位于PS端的优化器拉回。
  3. PS端的优化器首先调用Find算子,从HashTable获取到梯度对应的原始稀疏参数向量和相应的优化器参数,最终通过优化算法,完成对Embedding向量和优化器参数的更新计算,再通过Insert算子插入HashTable中。

3.2 分布式负载均衡优化

这部分优化,是分布式计算的经典优化方向。PS架构是一个典型的“水桶模型”,为了完成一步训练,Worker端需要和所有PS完成交互,因此PS之间的平衡就显得非常重要。但是在实践中,我们发现多个PS的耗时并不均衡,其中的原因,既包括TensorFlow PS架构简单的切图逻辑(Round-Robin)带来的负载不均衡,也有异构机器导致的不均衡。

对于推荐模型来说,我们的主要优化策略是,把所有稀疏参数和大的稠密参数自动、均匀的切分到每个PS上,可以解决大多数这类问题。而在实践过程中,我们也发现一个比较难排查的问题:原生Adam优化器,实现导致PS负载不均衡。下面会详细介绍一下。

在Adam优化器中,它的参数优化过程需要两个β参与计算,在原生TensorFlow的实现中,这两个β是所有需要此优化器进行优化的Variabl(或HashTable)所共享的,并且会与第一个Variable(名字字典序)落在同一个PS上面,这会带来一个问题:每个优化器只拥有一个β_1和一个β_2,且仅位于某个PS上。因此,在参数优化的过程中,该PS会承受远高于其他PS的请求,从而导致该PS成为性能瓶颈。

图7 Adam优化算法

但是通过观察Adam的优化算法,我们可以看到β_1和β_2都是常量,且蓝色高亮的部分都是相对独立的计算过程,各个PS之间可以独立完成。基于这样的发现,优化的方法也就非常直观了,我们为每一个PS上的Adam优化器冗余创建了β参数,并在本地计算t和alpha值,去除了因此负载不均导致的PS热点问题。

该优化所带来的提升具备普适性且效果明显,在美团内部某业务模型上,通过β热点去除可以带来9%左右的性能提升。此外,由于摆脱了对β的全局依赖,该优化还能提高PS架构的可扩展性,在扩增Worker数量的时候相比之前会带来更好的加速比。

3.3 通信优化

通过2.2章节的分析可知,系统的通信压力也非常大,我们主要基于RDMA做了通信优化的工作。首先简单介绍一下RDMA,相比较于传统基于套接字TCP/IP协议栈的通信过程,RDMA具有零拷贝、内核旁路的优势,不仅降低了网络的延迟,同时也降低了CPU的占用率,RDMA更适合深度学习模型的相关通信过程。

RDMA主要包括三种协议Infiniband、RoCE(V1, V2)、iWARP。在美团内部的深度学习场景中,RDMA通信协议使用的是RoCE V2协议。目前在深度学习训练领域,尤其是在稠密模型训练场景(NLP、CV等),RDMA已经是大规模分布式训练的标配。然而,在大规模稀疏模型的训练中,开源系统对于RDMA的支持非常有限,TensorFlow Verbs[4]通信模块已经很长时间没有更新了,通信效果也并不理想,我们基于此之上进行了很多的改进工作。

经过优化后的版本,在1TB Click Logs[5]公开数据集、DLRM[6]模型、100个Worker以上的训练,性能提升了20%~40%。在美团的多个业务模型上,对比TensorFlow Seastar[7]改造的通信层实现也有10%~60%的速度提升。同时也把我们的工作回馈给了社区

3.3.1 Memory Registration优化

RDMA有三种数据传输的方式SEND/RECV、WRITE、READ,其中WRITE、READ类似于数据发送方直接在远程Memory进行读写,Receiver无法感知,WRITE和READ适用于批量数据传输。在TensorFlow内部,基于RDMA的数据传输方式使用的是WRITE单边通信模式。

图8 RDMA传输方式

在RDMA传输数据时,需要提前开辟内存空间并将其注册到网卡设备上(Memory Registration过程,下称MR),使得这片空间可以被网卡直接操作。开辟新的内存并注册到设备上,整个过程是比较耗时的。下图9展示了不同大小的内存绑定到网卡设备上的耗时,可以看到随着注册内存的增大,绑定MR的耗时迅速增加。

图9 MR过程开销

社区版Tensorflow RDMA实现,Tensor创建依旧沿用了统一的BFC Allocator,并将所有创建的Tensor都注册到MR上。正如上面所提到的,MR的注册绑定具有性能开销,高频、大空间的MR注册会带来显著的性能下降。而训练过程中的Tensor,只有那些涉及到跨节点通信的Tensor有必要进行MR,其余Tensor并不需要注册到MR。因此,优化的方法也就比较直接了,我们识别并管理那些通信Tensor,仅对这些跨节点通信的Tensor进行MR注册就好了。

3.3.2 RDMA静态分配器

RDMA静态分配器是上一个MR注册优化的延伸。通过Memory Registration优化,去除非传输Tensor的MR注册,我们降低了MR注册数量。但是在稀疏场景大规模的训练下,并行训练的Worker常有几百上千个,这会带来新的问题:

  • PS架构中的PS和Worker互为Client-Server,这里以PS端为例,当Worker数目增加到上千个时,Worker数目的增多,造成PS端MR注册频次还是非常高,增加了内存分配注册的耗时。
  • 由于稀疏场景不同Step之间同一个算子输出Tensor的形状可能发生变化,导致了创建的MR可复用性较差,带来了较高的内存碎片和重复注册MR开销。

针对上面的问题,我们引入了MR静态分配器的策略。

图10 MR静态分配器

这里核心的设计思路为:

  1. 虽然稀疏场景同一个算子输出Tensor的Shape存在变化的可能,但是整体变化幅度可控,通过监控与分析,是可以找到一个较为稳定的内存大小,满足多Step间Tensor的存储需求。
  2. 基于上面的信息,我们修改了原有逐Tensor(Request)的MR申请策略,通过一次性预申请一块较大的空间并注册到网卡端,后续通过自己维护的分配策略进行空间的分配,大大降低了MR申请的频率,绝大多数情况下,训练全过程中只需要一次MR注册申请即可。
  3. 我们引入了一种简单的交换协议,将传输Tensor的Shape,Data打包到一起,写到Client端。Client端根据协议,解析出Tensor大小,并最终读取Data,避免了原生实现中因Tensor的Shape变化而产生的多次协商过程。

图11 MR静态分配器构造流程

具体到实现中,我们引入了Allocation Analysis模块,在训练开始的一段时间,我们会对分配的历史数据进行分析,以得到一个实际预开辟MR大小以及各个Tensor的预留空间大小。然后我们会暂停训练的进程,启动Allocator的构造过程,包括MR的创建以及通信双端的信息同步。利用相关信息构造MR Info Map,这个Map的Key是传输Tensor的唯一标记(ParsedKey,计算图切图时确定),Info结构体中包含了本地地址指针、offset大小、ibv_send_wr相关信息等。然后恢复训练,后续Tensor的传输就可以使用静态开辟好的MR进行收发,也免去了因Shape变化而产生的多次协商过程。

3.3.3 Multi RequestBuffer与CQ负载均衡

TensorFlow社区版的RDMA通信过程,不仅仅包含上面Tensor数据的发送和接收过程,还包括传输相关的控制消息的发送和接收过程,控制消息的发送和接收过程同样是使用了ibv_post_send和ibv_post_recv原语。原生的控制流实现存在一些瓶颈,在大规模训练时会限制控制流的吞吐,进而影响数据收发的效率。具体体现在:

  • 请求的发送通过同一片RequestBuffer内存进行写出,多个Client的请求均依赖这一片Buffer,也就导致到控制流信息实际是串行发送的,只有等到对端的Ack信息后,才可以下一个Request的写出,限制了请求的发送吞吐。
  • 在Client端需要轮询RDMA Completion Queue来获得请求的到达,以及相关状态的变更。原生实现仅有一个Completion Queue,单线程进行轮询处理,在大规模分布式训练中,限制了应答的效率。

针对上面的问题,我们采用了Multi RequestBuffer与CQ负载均衡优化,破除了在请求发送和请求应答环节可能存在的吞吐瓶颈。

3.3.4 Send-Driven & Rendezvous-Bypass

对于Tensorflow PS架构熟悉的同学会了解,一整张计算图被切割为Worker端和PS端后,为了使两张计算图能够彼此交换数据,建立了基于Rendezvous(汇合点)机制的异步数据交换模式。如下图12所示:

图12 TensoFlow切图之Send-Recv对添加

基于上图的切图逻辑,Recv算子代表着这一侧计算图有Tensor的需求,而Tensor的生产者则位于与之配对的另一设备上的Send算子背后。

在具体实现上,Tensorflow实现了Recv-Driven的数据交换模式,如上图所示,位于DeviceA和DeviceB的两张计算图会异步并发的执行,位于DeviceB的Recv执行时会发起一条RPC请求发往DeviceA,DeviceA收到请求后,会将请求路由到Rendezvous中,如果在当中发现所需要的数据已经生产好,并被Send算子注册了进来,那么就地获取数据,返回给DeviceB;如果此时数据还没有生产好,则将来自于DeviceB的Recv请求注册在Rendezvous中,等待后续DeviceA生产好后,由Send算子发送过来,找到注册的Recv,触发回调,返回数据给DeviceB。

我们看到,汇合点机制优雅地解决了生产者消费者节奏不同情况下数据交换的问题。不过Recv-Driven的模式也引入了两个潜在的问题:

  • 据我们的观察,在实际业务模型中,在Rendezvous中Recv算子等待Send算子的比例和Send算子等待Recv算子的比例相当,也就是说对于Send等到Recv的数据,在Send准备好的那一刹那就可以发给对端,但是由于机制实现问题,还是等待Recv算子过来,才将数据拉取回去,通信过程耗时较长。
  • Rendezvous作为一个数据交换的热点,它内部的逻辑开销并不低。

针对上面提到的问题,我们在RDMA上实现了另外一种数据交换的模式,叫做Send-Driven模式。与Recv-Driven模式相对,顾名思义就是有Send算子直接将数据写到Recv端,Recv端接收数据并注册到本地Rendezvous中,Recv算子直接从本地的Rendezvous中获取数据。具体流程如下图13所示:

图13 原生的Recv-Driven与补充的Send-Driven机制

从图中可以看到,相较于Recv-Driven模式,Send-Driven模式的通信流程得到了比较大的简化,另外在数据ready后立即发送的特性,跳过了一侧的Rendezvous,并且对于生产者先于消费者的情况,可以加快消费端数据获取的速度。

3.4 延迟优化

这部分优化,也是分布式计算的经典优化方向。整个流程链路上那些可以精简、合并、重叠需要不断去挖掘。对于机器学习系统来说,相比其它的系统,还可以用一些近似的算法来做这部分工作,从而获得较大的性能提升。下面介绍我们在两个这方面做的一些优化实践。

3.4.1 稀疏域参数聚合

在启用HashTable存储稀疏参数后,对应的,一些配套参数也需要替换为HashTable实现,这样整个计算图中会出现多张HashTable以及大量的相关算子。在实践中,我们发现需要尽量降低Lookup/Insert等算子的个数,一方面降低PS的负载,一方面降低RPC QPS。因此,针对稀疏模型的常见用法,我们进行了相关的聚合工作。

以Adam优化器为例,需要创建m、v两个slot,以保存优化中的动量信息,它的Shape与Embedding相同。在原生优化器中,这两个Variable是单独创建的,并在反向梯度更新的时候会去读写。同理,使用HashTable方案时,我们需要同时创建两张单独的HashTable用来训练m、v参数。那么在前向,反向中需要分别对Embedding、m、v进行一次Lookup和一次Insert,总共需要三次Lookup和三次Insert。

这里一个优化点就是将Embedding、 m、v,以及低频过滤的计数器(见下图14的Counting HashTable)聚合到一起,作为HashTable的Value,这样对稀疏参数的相关操作就可以聚合执行,大大减少了稀疏参数操作频次,降低了PS的压力。

图14 基于HashTable的参数融合策略

该特性属于一个普适型优化,开启聚合功能后,训练速度有了显著的提高,性能提升幅度随着模型和Worker规模的变化,效果总是正向的。在美团内部真实业务模型上,聚合之后性能相比非聚合方式能提升了45%左右。

3.4.2 Embedding流水线优化

流水线,在工业生产中,指每一个生产单位只专注处理某个片段的工作,以提高工作效率及产量的一种生产方式。在计算机领域内,更为大家熟知的是,流水线代表一种多任务之间Overlap执行的并行化技术。例如在典型的RISC处理器中,用户的程序由大量指令构成,而一条指令的执行又可以大致分为:取指、译码、执行、访存、写回等环节。这些环节会利用到指令Cache、数据Cache、寄存器、ALU等多种不同的硬件单元,在每一个指令周期内,这5个环节的硬件单元会并行执行,得以更加充分的利用硬件能力,以此提高整个处理器的指令吞吐性能。处理器的指令流水线是一套复杂而系统的底层技术,但其中的思想在分布式深度学习框架中也被大量的使用,例如:

  • 如果将分布式训练简单的抽象为计算和通信两个过程,绝大多数主流的深度学习框架都支持在执行计算图DAG时,通信和计算的Overlap。
  • 如果将深度模型训练简单的分为前向和反向,在单步内,由于两者的强依赖性,无法做到有效并行,字节BytePS[8]中引入的通信调度打破了step iteration间的屏障,上一轮的部分参数更新完毕后,即可提前开始下轮的前向计算,增强了整体视角下前反向的Overlap。
  • 百度AIBox[9]为了解决CTR场景GPU训练时,参数位于主存,但计算位于GPU的问题,巧妙调度不同硬件设备,搭建起了主要利用CPU/主存/网卡的参数预准备阶段和主要利用GPU/NVLink的网络计算阶段,通过两个阶段的Overlap达到更高的训练吞吐。

我们看到,在深度学习框架设计上,通过分析场景,可以从不同的视角发掘可并行的阶段,来提高整体的训练吞吐。

对于大规模稀疏模型训练时,核心模型流程是:先执行稀疏参数的Embedding,然后执行稠密部分子网络。其中稀疏参数Embedding在远端PS上执行,主要耗费网络资源,而稠密部分子网络在本地Worker执行,主要耗费计算资源。这两部分占了整个流程的大部分时间,在美团某实际业务模型上分别耗时占比:40+%、50+%。

那我们是否可以提前执行稀疏参数的Embedding,来做到通信和计算的Overlap,隐藏掉这部分时间呢?从系统实现上肯定是可行的,但从算法上讲,这样做会引入参数Staleness的问题,可能会导致模型精度受到影响。但在实际的生产场景中,大规模异步训练时本身就会带来几十到几百个步的滞后性问题。经过我们测试,提前获取一两步的稀疏参数,模型精度并未受到影响。

在具体实现上,我们把整个计算图拆分为Embedding Graph(EG)和Main Graph(MG)两张子图,两者异步独立执行,做到拆分流程的Overlap(整个拆分过程,可以做到对用户透明)。EG主要覆盖从样本中抽取Embedding Key,查询组装Embedding向量,Embedding向量更新等环节。MG主要包含稠密部分子网络计算、梯度计算、稠密参数部分更新等环节。

图15 Embedding流水线模块交互关系

两张子图的交互关系为:EG向MG传递Embeding向量(从MG的视角看,是从一个稠密Variable读取数值);MG向EG传递Embedding参数对应的梯度。上述两个过程的表达都是TensorFlow的计算图,我们利用两个线程,两个Session并发的执行两张计算图,使得两个阶段Overlap起来,以此到达了更大的训练吞吐。

图16 Embedding流水线架构流程图

上图是Embedding流水线的架构流程图。直观来看分为左侧的样本分发模块,顶部的跨Session数据交换模块,以及自动图切分得到的Embedding Graph和Main Graph,蓝色的圆圈代表新增算子,橙色箭头代表EG重点流程,蓝色箭头代表MG重点流程,红色箭头代表样本数据重点流程。

  1. 以对用户透明的形式引入了一层名为Pipeline Dataset的抽象层,这一层的产生是为了满足EG/MG两张计算图以不同节奏运行的需求,支持自定义配置。另外,为了使得整个流水线中的数据做到彼此的配套,这里还会负责进行一个全局Batch ID的生成及注册工作。Pipeline Dataset对外暴露两种Iterator,一个供EG使用,一个供MG使用。Pipeline Dataset底部共享TensorFlow原生的各层Dataset。
  2. 顶部的ExchangeManager是一个静态的,跨Session的数据交换媒介,对外暴露数据注册和数据拉取的能力。抽象这个模块的原因是,EG和MG原本归属于一张计算图,因为流水线的原因拆解为拆为两张图,这样我们需要建立一种跨Session的数据交换机制,并准确进行配套。它内部以全局Batch ID做Key,后面管理了样本数据、Embeding向量、Embedding梯度、Unique后的Index等数据,并负责这些数据的生命周期管理。
  3. 中间的Embedding Graph由独立的TF Session运行于一个独立的线程中,通过a算子获得样本数据后,进行特征ID的抽取等动作,并进行基于HashTable方法的稀疏参数查询,查询结果通过c算子放置到ExchangeManager中。EG中还包含用于反向更新的f算子,它会从ExchangeManager中获取Embedding梯度和与其配套的前向参数,然后执行梯度更新参数逻辑。
  4. 下面的Main Graph负责实际稠密子网络的计算,我们继承并实现一种可训练的EmbeddingVariable,它的构建过程(d算子)会从ExchangeManager查找与自己配套的Embedding向量封装成EmbeddingVariable,给稠密子网络。此外,在EmbeddingVariable注册的反向方法中,我们添加了e算子使得Embedding梯度得以添加到ExchangeManager中,供EG中的f算子消费。

通过上面的设计,我们就搭建起了一套可控的EG/MG并发流水线训练模式。总体来看,Embedding流水线训练模式的收益来源有:

  • 经过我们对多个业务模型的Profiling分析发现,EG和MG在时间的比例上在3:7或4:6的左右,通过将这两个阶段并行起来,可以有效的隐藏Embedding阶段,使得MG网络计算部分几乎总是可以立即开始,大大加速了整体模型的训练吞吐。
  • TensorFlow引擎中当使用多个优化器(稀疏与非稀疏)的时候,会出现重复构建反向计算图的问题,一定程度增加了额外计算,通过两张子图的拆分,恰好避免了这个问题。
  • 在实施过程中的ExchangeManager不仅负责了Embedding参数和梯度的交换,还承担了元数据复用管理的职责。例如Unique等算子的结果保存,进一步降低了重复计算。

另外,在API设计上,我们做到了对用户透明,仅需一行代码即可开启Embedding流水线功能,对用户隐藏了EG/MG的切割过程。目前,在美团某业务训练中,Embedding流水线功能在CPU PS架构下可以带来20%~60%的性能提升(而且Worker并发规模越大,性能越好)。

3.5 单实例PS并发优化

经过2.2章节的分析可知,我们不能通过持续扩PS来提升分布式任务的吞吐,单实例PS的并发优化,也是非常重要的优化方向。我们主要的优化工作如下。

3.5.1 高性能的HashTable

PS架构下,大规模稀疏模型训练对于HashTable的并发读写要求很高,因为每个PS都要承担成百乃至上千个Worker的Embedding压力,这里我们综合速度和稳定性考虑,选用了tbb::concurrent_hash_map[10]作为底层HashTable表实现,并将其包装成一个新的TBBConcurrentHashTable算子。经过测试,在千亿规模下TBBConcurrentHashTable比原生MutableDenseHashTable训练速度上快了3倍。

3.5.2 HashTable BucketPool

对于大规模稀疏模型训练来说,Embedding HashTable会面对大量的并发操作,通过Profiling我们发现,频繁动态的内存申请会带来了较大性能开销(即使TensorFlow的Tensor有专门的内存分配器)。我们基于内存池化的思路优化了HashTable的内存管理。

我们在HashTable初始化时,会先为Key和Value分别创造两个BucketPool,每个池子都会先Malloc较大一块内存备用,考虑到可能会有对HashTable进行中的Key和Value进行Remove的场景(如Online Learning训练时),需要对从HashTable中删除的Key和Value所使用的内存进行回收,因此每个BucketPool还有一个ReuseQueue来负责维护回收的内存。每次向内部的哈希表数据结构中Insert Key和Value的时候,Key和Value内存和释放分配都进行池化管理。用这种方式降低了大规模稀疏训练中遇到稀疏内存分配开销,整体端到端训练性能提升了5%左右。

图17 HashTable内存优化

3.6 单位算力吞吐优化

经过2.2章节的分析,Worker的计算压力也非常大,如果不优化Worker,同时要保持吞吐,需要横向扩展更多的Worker,给PS带来更大的压力。而对于用户来说,如果能在有限的计算资源下带来性能提升,对业务价值更高。我们通过CAT统计出了一些高频算子,并进行了专项优化。这里选取Unique&DynamicPartition算子融合案例进行分享。

在TensorFlow PS架构中,包括Embedding向量在内的共享参数都存储在PS上,并通过网络与Worker交互,在进行Embedding查询过程中,往往会涉及如下两个环节:

  • 由于稀疏参数的性质,从样本中抽取得到的待查询Embedding ID,它的重复率往往高达70%~90%,如果不进行去重查询,不论是对HashTable的查询还是网络的传输,都会带来不小的压力。因此,通常会在查询前进行Unique操作。
  • 在大规模稀疏场景中,为了存储千亿规模的参数,会有多个PS机器共同承载。而Worker端会负责对查询请求按照设定的路由规则进行切分,这里通常会在查询前进行DynamicPartition动作。

通常这两个过程会利用TensorFlow既有的算子进行搭建,但在实际使用中,我们发现它并不是很高效,主要问题在于:

  • Unique算子原生实现,它内部使用的内存分配策略较为低效。使用了两倍输入参数(Embedding ID)的大小进行内存分配,但由于输入参数较大,而且重复率高,导致HashTable创建过大且非常稀疏。几乎每次插入都会产生一次minor_page_fault,导致HashTable性能下降。我们使用Intel Vtune验证了这一点(参见图18)。
  • Unique和Dynamic Partition算子存在冗余数据遍历,这些操作其实可以在一次数据遍历中全部做完,节省掉算子切换、冗余数据遍历的耗时。

图18 Unique算子内部出现DRAM Bound问题

总结来说,HashTable开辟过大会导致大量的minor_page_fault,导致访存的时间增加,HashTable过小又可能会导致扩容。我们采用了基于启发式算法的内存自适应Unique算子实现,通过对训练历史重复率的统计,我们可以得到一个相对合理的HashTable大小,来提高访存的性能;另外Unique算子内HashTable的具体选择上,经过我们的多种测试,选择了Robin HashTable替换了原生TF中的实现。

进一步,我们对围绕Embedding ID的Unique和Partition环节进行了算子合并,简化了逻辑实现。经过上述的优化,Unique单算子可以取得51%的加速,在真实模型端到端上可以获得10%左右的性能提升,算子总数量降低了4%。

在整个关键算子优化的过程中,Intel公司的林立凡、张向泽、高明进行大量的技术支持,我们也复用了他们的部分优化工作,在此深表感谢!

4 大规模稀疏算法建模

大规模稀疏能力在业务落地的过程中,算法层面还需要从特征和模型结构上进行对应升级,才能拿到非常好的效果。其中外卖广告从业务特点出发,引入大规模稀疏特征完成外卖场景下特征体系的升级,提供了更高维的特征空间和参数空间,增强了模型的拟合能力。重新设计了面向高维稀疏场景的特征编码方案,解决了特征编码过程中的特征冲突问题,同时编码过程去掉了部分冗余的特征哈希操作,一定程度上简化了特征处理逻辑,并降低了特征计算的耗时。

在系统层面,面对百亿参数、百亿样本以上量级的大规模稀疏模型的训练,会带来训练迭代效率的大大降低,单次实验从一天以内,增长到一周左右。美团机器学习平台训练引擎团队,除了上述TensorFlow框架层面的优化、还针对业务模型进行了专项优化,整体吞吐优化了8到10倍(如果投入更多计算资源,可以进一步加速),大大提升业务的迭代效率,助力外卖广告业务取得了较为明显的提升。

5 总结与展望

TensorFlow在大规模推荐系统中被广泛使用,但由于缺乏大规模稀疏的大规模分布式训练能力,阻碍了业务的发展。美团基于TensorFlow原生架构,支持了大规模稀疏能力,并从多个角度进行了深度优化,做到千亿参数、千亿样本高效的分布式训练,并在美团内部进行了大规模的使用。对于这类关键能力的缺失,TensorFlow社区也引起了共鸣,社区官方在2020年创建了SIG Recommenders[11],通过社区共建的方式来解决此类问题,美团后续也会积极的参与到社区的贡献当中去。

美团推荐系统场景的模型训练,目前主要运行在CPU上,但随着业务的发展,有些模型变得越来越复杂,CPU上已经很难有优化空间(优化后的Worker CPU使用率在90%以上)。而近几年,GPU的计算能力突飞猛进,新一代的NVIDIA A100 GPU,算力达到了156TFLOPS(TF32 Tensor Cores)、80G显存、卡间带宽600GB/s。对于这类复杂模型的Workload,我们基于A100 GPU架构,设计了下一代的分布式训练架构,经过初步优化,在美团某大流量业务推荐模型上也拿到了较好的效果,目前还在进一步优化当中,后续我们会进行分享,敬请期待。

6 作者简介

  • 逸帆、家恒、峥少、鹏鹏、永宇、正阳、黄军等,来自美团基础研发平台,机器学习平台训练引擎组,主要负责美团分布式机器学习训练系统的性能优化与能力建设。
  • 海涛,来自美团外卖广告策略团队,主要负责美团外卖广告业务的算法探索和策略落地工作。

7 招聘信息

美团机器学习平台大量岗位持续招聘中,社招/校招均可(欢迎投递我们的校招北斗岗位:美团机器学习平台基础架构),坐标北京/上海,构建多领域的公司级机器学习平台,帮大家吃得更好,生活更好。简历可投递至:huangjun03@meituan.com

8 参考信息

细粒度情感分析在到餐场景中的应用

一、背景

作为一家生活服务在线电子商务平台,美团致力于通过科技链接消费者和商户,努力为消费者提供品质生活。到店餐饮(简称到餐)作为美团的核心业务之一,是满足用户堂食消费需求、赋能餐饮商户在线运营的重要平台,在服务百万级别的餐饮商户和亿级别C端用户的过程中,积累了海量的用户评论信息(User Generated Content, UGC),包含了用户到店消费体验之后的真情实感,如果能够有效提取其中的关键的情感极性、观点表达,不仅可以辅助更多用户做出消费决策,同时也可以帮助商户收集经营状况的用户反馈信息。

近年来,大规模预训练模型(BERT)、提示学习(Prompt)等NLP技术飞速发展。文本分类、序列标注、文本生成各类自然语言处理任务的应用效果得到显著提升,情感分析便是其中最常见的应用形式之一。它的任务目标在于通过NLP技术手段对输入文本进行分析、处理、归纳、推理,给出文本情感极性判定的结果。

按照情感极性判定粒度,可以细分为篇章/整句粒度情感分析、细粒度情感分析(ABSA, Aspect-based Sentiment Analysis)[1]。一般而言,细粒度情感分析的任务目标主要围绕属性(Aspect Term)、观点(Opinion Term)、情感(Sentiment Polarity)三要素展开,可以拆分为属性抽取、观点抽取以及属性-观点对的情感倾向判定三个级联任务[2-5]。例如,对于给定的用户评论“这家店环境不错,但服务很糟糕”,预期的输出结果为(环境,不错,正向)、(服务,糟糕,负向)。

图1 ABSA子任务<sup>[5]</sup>

到餐算法团队结合到餐业务供给侧、平台侧、需求侧的业务场景,为核心业务链路的智能化提供高效、优质的算法解决方案,通过算法能力辅助业务降本提效。本文结合到餐B/C端业务场景,探索细粒度情感分析技术在用户评价挖掘方向的应用实践。

二、目标回顾

2.1 业务问题

秉承“帮大家吃得更好,生活更好”的使命,到餐面向消费者提供包括套餐、代金券、买单、预订等在内的丰富产品和服务,并通过黑珍珠餐厅指南、大众点评必吃榜等榜单,以及搜索、查询、评价等,帮助消费者更好地作出消费决策。同时,为商家提供一站式的营销服务,帮助餐饮商户沉淀口碑、获取用户、增加复购等,进而轻松管理餐厅。

随着餐饮连锁化加速、行业竞争格局激烈,商户管理宽幅和难度逐步加大,商户的经营要求更加精细,数据管理意识更加迫切。用户历史评论中蕴含着大量用户消费后的反馈,是情感分析的重要组成部分,不仅能够描述消费感受,同时也能反映出就餐环境的好坏。因此,做好情感分析有利于帮助餐饮门店提升服务质量,也能够更好地促进消费体验。

图2 评论示例:(a) 菜品评价,(b) 服务评价,(c) 食安评价

UGC评价分析,主要是从评论文本中挖掘出菜品、服务、食品安全(简称食安)等方面相关信息,获取用户在各个维度的细粒度情感,细致刻画商家的服务现状,如上图2所示。对于餐饮商户,菜品、服务、食安评价分析问题可以拆解如下:

  1. 菜品评价,主要包括用户评论中的菜品识别、评价属性提取、菜品观点提取、观点情感分类;
  2. 服务评价,主要包括用户评论中评价属性提取、服务方面观点提取、观点情感分类;
  3. 食安评价,主要包括用户评论中评价属性提取、食安方面观点提取、观点情感分类。

其中问题2和3是典型的三元组抽取任务,即识别服务或食安方面的(属性,观点,情感)。对于问题1,在服务、食安评价问题的基础上,菜品评价需要识别评论中提及的菜品,相比业界四元组(属性,观点,属性类别,情感)[6]抽取任务,到餐场景下主要为 (菜品,属性,观点,情感)四元组的识别。

2.2 技术调研

在美团内部,我们针对UGC评价分析问题,调研了相关工作成果,主要为基于MT-BERT预训练模型开发了多任务模型,试图解决情感分析中的ACSA (Aspect-Category Setiment Analysis) 问题以及(属性,观点,情感)三元组抽取问题,并实现了句子粒度的情感分类工具开发,同时开源了基于真实场景的中文属性级情感分析数据集ASAP[7-9]。但对于美团到餐业务来说,我们需要基于具体场景提出针对性的解决方案,如四元组抽取任务,不能直接复用其他团队的相关技术和工具,因此有必要建设服务于到餐业务场景的细粒度情感分析技术。

在业界,我们也调研了行业其他团队如腾讯、阿里在细粒度情感分析方面的相关研究。2019年腾讯AI Lab和阿里达摩院合作[3],提出了基于两个堆叠的LSTM和三个组件(边界引导、情感一致性和意见增强)的模型,将“BIOES”标注体系与情感正向(Positive)、中性(Neutral)、负向(Negative)结合形成统一标签,可以同时识别属性和情感。同年,阿里达摩院提出了BERT+E2E-ABSA模型结构,进一步解决属性和情感的联合抽取问题[10],同时提出(属性,观点,情感)[2]三元组抽取任务,并给出了两阶段解决框架,首先分别识别出属性(情感融合为统一标签)和观点,然后判断属性-观点是否配对。

自此,业界后续研究开始向三元组联合抽取展开[11-14]。2021年2月,华为云[6]提出(属性,观点,属性类别,情感)四元组抽取多任务模型,其中一个任务识别属性和观点,另一个任务识别属性类别和情感。2021年4月,腾讯[15]引入Aspect-Sentiment-Opinion Triplet Extraction (ASOTE)任务,提出了一个位置感知的BERT三阶段模型,解决了(属性,观点,情感)三元组抽取问题。

调研机构行业预训练模型细粒度情感分析问题阅读理解问题三元组问题四元组问题联合抽取问题
阿里达摩院[2,10]电子商务
华为云[6]云服务
腾讯[15]社交
美团到餐本地生活

从学术界来看,更关注于如何更好地进行实体抽取、情感分类以及多任务的联合抽取,可能会忽略工业界落地更关注的计算时效性(如多维度标注与情感维度整合,增加计算、存储资源消耗,在有限资源下时长延迟)、效果准确性(如任务模块端到端开发,忽略业务的个性化,直接复用导致准确性降低)等方面要求,导致相关技术方法并不能直接应用于业务场景,需要进一步开发完善才能实现业务的落地。

如上表所示,针对以上调研,我们借鉴了美团搜索与NLP部在三元组细粒度情感分析方面的经验,拆解到餐四元组抽取问题,并结合学界最先进的阅读理解、注意力机制等方面的实体抽取、情感分类经验,设计开发了应用于到餐业务的细粒度情感分析解决方案。

2.3 技术目标

如上文所述,菜品评价主要关注菜品、评价属性、菜品观点和观点情感,而服务、食安评价问题,主要关注服务或食安方面的评价属性、观点和情感。就细粒度情感分析任务而言,可以看出,前一个问题涉及四元组信息,而后两个问题仅涉及三元组信息。

2.4 主要挑战

由于三元组问题可以看作是四元组问题的子问题,不失一般性,下文将重点阐述四元组相关技术挑战。

图3 到餐细粒度情感分析中的UGC示例

问题3:如何同时对四元组抽取、识别,减少pipeline方法的错误累计影响?

减少pipeline方法的错误累计影响,典型的解决方案是提出同时处理信息抽取和分类任务,即多任务学习。传统的方法是直接尝试多任务学习的思路,但过程中忽略了实体间依赖的关系,甚至远程关联关系[2]。当前也在尝试直接将四元组转化成多任务学习过程,将来期望通过建立实体间pair或triplet关系,进行联合抽取、识别。

综上,对于问题1问题2,我们会按照pipeline识别的结果,再利用策略进行抽取结果的优化;对于问题3,整合实体、关系及分类任务,进行联合学习,将有助于减少pipeline方法的错误累计影响。

三、细粒度情感分析实践

3.1 Pipeline方法

如上文2.3的问题2所述,我们采用pipeline的方法,将四元组抽取问题拆解为三个任务,分为实体识别、观点抽取、观点类别和情感分类,如下图4所示:

图4 三阶段模型

3.1.1 实体识别

自2018年BERT[16]出现以后,NER模型由传统的LSTM+CRF替换为BERT+CRF(或者BERT+LSTM+CRF),一度是业界NER任务的SOTA模型,近两年来NER任务主要从以下两个方面进行改进:

  1. 加入额外的特征[17-19]:如字特征、词特征、词性特征、句法特征、知识图谱表征;
  2. 转换任务形式[20-21]:将NER任务转化为问答(QA, Question Answering)任务或者机器翻译任务。

考虑到引入额外特征需要构建人工词典,以及转化问答任务形式依赖于人工模板,成本较高,因此采用BERT+CRF模型。

学习率调整,模型策略调优。在实验过程中,我们发现BERT+CRF相比简单的BERT+Softmax效果提升甚微,究其原因,由于预训练模型经过微调之后可以学习到具有明显区分度的特征,导致增加CRF层对实体识别结果几乎没有影响。然而,一个好的CRF转移矩阵显然对预测是有帮助的,可以为最后预测的标签添加约束来保证预测结果的合理性。进一步实验后发现,通过调整BERT和CRF层的学习率,如BERT使用较小的学习率而CRF层使用100倍于BERT的学习率 (即$e2/e1>100$,如图5所示),最终BERT+CRF的效果相比BERT+Softmax有了较明显的提升。此外,在传统NER模型LSTM+CRF基础上,我们也实验了BERT+LSTM+CRF,但效果居然有些许下降,而且预测时间也增加了,因此最终没有引入LSTM层。

图5 BERT+CRF(BIO标记)

3.1.2 观点抽取

观点抽取任务在业界也称为Target-oriented Opinion Words Extraction(TOWE),旨在从评论句子中抽取出给定目标对应的观点词。观点抽取也可以看作是一种NER任务,但若评论涉及多个实体和观点,如何准确抽取所有“实体-观点”关系是一个技术挑战。借鉴MRC(Machine Reading Comprehension)任务的思想,通过构建合理的Query引入先验知识,辅助观点抽取。

QA任务形式,观点抽取建模。如图6所示,模型整体由预训练层和输出层两部分组成。输出层我们使用了常规QA任务输出,包括开始标签(Start Label)和结束标签(End Label),但需要人工设计Quey。参考论文[20]经验,以图3为例,实验发现Query设计为“找出鲜虾馅饺子口味、口感、分量、食材、卖相、价格、卫生以及整体评价”效果最好,可能融入了观点描述信息,更加有助于观点抽取。考虑到QA任务天然有类别不平衡的问题,因此损失函数引入针对类别不平衡的Focal Loss,用于提升观点抽取模型的效果。由于观点抽取也可以看作是NER任务,故我们尝试将输出层设计为CRF层,但实验效果并不理想,可能由于观点语句长度不一且比较个性化,影响模型识别。另一方面,考虑到Google中文预训练模型BERT是以字粒度为切分,没有考虑到传统NLP中的中文分词,在预训练层我们将BERT模型替换为哈工大开源的中文预训练模型,如BERT-wwm-ext、RoBERTa-wwm等,最终模型效果取得进一步提升。

图6 BERT+MRC(通过开始标签和结束标签,抽取出观点词:特别好、有点贵)

3.1.3 观点类别和情感分类

观点类别和情感分类可以看作两个分类任务,其中菜品评价四元组任务的观点类别包含口感、口味、分量、食材、卖相、价格、卫生、菜品整体等8个标签,而情感包含正向、中性、负向、未提及等4个标签,都是业务预定义好的。考虑到用户评论提及某个菜品的观点可能涉及多个维度,若每个维度单独建模,需要构建多个模型,较复杂且维护困难。结合ATAE-LSTM[22]和NLP中心[7-9]情感分析的经验和到餐业务特点,模型整体结构设计为多任务多分类学习框架。

多任务多分类模型,联合建模观点类别和情感。如图7所示,模型整体分为两个部分,分别为BERT共享层和Attention独享层,其中BERT共享层学习观点Embedding表示,Attention独享层学习观点在各个观点类别的情感倾向。考虑到评论中各部分会聚焦不同的观点维度,通过引入Attention结构,使得模型更加关注特定维度相关的文本信息,进而提升整体效果。

图7 BERT+Attention

3.2 联合学习

pipeline方法的优点是将目标问题拆分为多个子模块问题,对子模块分别优化,通过后处理能在一定程度上解决实体间多对多关系的问题。然而,pipeline方法也会存在一些致命缺陷,主要包括:

  1. 误差传播,实体识别模块的错误会影响到观点抽取模型的性能;
  2. 忽略了任务之间的关联性,如实体和观点往往一起出现,如果可以知道观点,那么也能判断出所描述的实体,而pipeline方法显然不能利用这些信息;
  3. 信息冗余,由于需要对识别出来的实体都要进行观点抽取,以及提取出的观点都要进行分类,产生一些无效的匹配对,提升错误率。

参考业界情感分析联合学习现状,主要为(属性,观点,情感)三元组联合抽取。结合到餐业务场景特点(如挑战2.3的问题2所述),整体设计为两阶段模型,第一阶段为对菜品实体、观点和情感联合训练,第二阶段为对观点进行分类,进而得到四元组识别的结果。

3.2.1 三元组联合抽取

目前在学术界,三元组(属性,观点,情感)联合抽取的方法主要包括序列标注方法[11]、QA方法[5,12]、生成式方法[13,14]等。结合菜品分析场景和pipeline方法中观点抽取模块的经验,我们采取了QA式的联合抽取方法,主要参考模型Dual-MRC[5]

Dual-MRC模型的改进,三元组联合抽取建模。在模型设计过程中,由于Dual-MRC模型分类情感倾向是对某个属性的整体评价,即一个属性只对应一个情感。然而,在到餐业务场景中,新增了菜品实体的识别,同时UGC评论中存在对同一个菜品实体包含不同观点及情感倾向。如图3所示,“味道特别好”表达了对“鲜虾饺子”正向情感,而“有点贵”显然表达了负面情感。因此,我们对Dual-MRC模型进行了改造,将观点和情感标签整合成统一标签。如图8所示,到餐Dual-MRC整体结构基于双塔BERT模型,通过引入两个Query,左边负责抽取菜品实体,右边负责抽取观点和观点情感,从而实现三元组联合抽取。

图8 结合到餐业务特点改进的Dual-MRC模型

模型结构说明:

  1. 整体是由两个部分组成,左边BERT抽取菜品实体,右边BERT抽取观点和观点情感,将观点和情感构成统一标签B-{POS,NEU,NEG},I-{POS,NEU,NEG}以及O,其中未提及情感被整合到O标签中;
  2. 参考pipeline方法经验,构建两个Quey,左边Quey1构建为“找出评论中的菜品”,右边Quey2构建为“找出鲜虾馅饺子口味、口感、分量、食材、卖相、价格、卫生以及整体评价”;
  3. 训练阶段,对于左边标注的每个菜品实体,都需要重复右边流程,两边模型共享参数进行训练;预测阶段,由于实体不可知,采用pipeline方式,首先左边部分抽取出所有的菜品实体,然后对于每个实体输入到右边部分,抽取出观点和观点情感。

在此基础上,我们也探索了四元组联合抽取的可能,具体操作为对右边Query2进行改造,如“找出鲜虾馅饺子口味评价”,对于每个观点类别都需要构建Query进行预测,从而实现四元组联合抽取。但考虑计算量级较大且耗时较长,最终将观点类别另做预测。

3.2.2 观点类别分类

图9 BERT+P-tuning

观点类别分类,显然是一个文本分类问题,通常做法是基于BERT分类,取[CLS]位置的Embedding,接一个全连接层和Softmax层即可。在到餐业务场景中,主要面临少样本问题,参考业界NLP少样本解决方法,以基于对比学习的R-drop[23]方法和基于Prompt[24]的第四范式为代表。我们在BERT模型结构基础上,分别实验了Prompt模板方法(如图9所示)和R-drop数据增强(如图10所示)。其中,Prompt模板主要借鉴P-tuning[25]的思想,采取自动化构建模板的方式,基于MLM任务解决问题。

图10 BERT+R-drop

图9中[u1]~[u6]代表BERT词表里边的[unused1]~[unused6],即使用未出现的Token构建模板,Token数目为超参数。实验结果发现,基于BERT的预训练模型,结合P-tuning或R-drop结构,分类效果都能得到一定的提升,且P-tuning的效果略优于R-drop,后续还会持续探索少样本解决方法。

四、在到餐业务中的应用

4.1 模型效果对比

利用到餐的UGC标注数据,对于四元组识别进行了整体效果测评,最终以整体四元组的精确率和召回率计算F1值作为性能评估指标。如图11所示,采用经典的BERT+CRF模型进行实体抽取,在到餐评论标注数据仅达到0.61的F1,经过学习率等调参(Baseline Tuning)优化之后,F1值提升2.61%。如上文所述,在观点抽取模块中,将序列标注问题转化成问答(QA)问题后,采用BERT+MRC模型,F1显著提升至0.64,提升了5.9%,表明问题转化获得较大收益。此外,采用哈工大中文预训练BERT仍取得一定幅度的提升,F1提升至0.65。注意,图11中的模型迭代表示四元组问题中重点优化模块的模型,最终评测四元组整体效果来进行对比分析。

图11 在到餐场景细粒度情感分析效果演进

4.2 业务应用场景

图12 到餐场景细粒度情感分析的应用:(a) 品牌仪表盘,(b) 到餐商户菜品信息优化,(c) 开店宝评价管理

品牌仪表盘

品牌仪表盘作为旗舰店能力的重要环节,提供品牌层面的数据服务,助力生意增长。产品定位为头部餐饮品牌的数据中心,具备基础的数据披露能力,通过量化业务效果,指导商户经营决策。由于大客在平台沉淀了丰富的线上信息(大量的交易/流量/评论数据),可挖掘分析空间较大。应用细粒度情感分析技术从评论数据中挖掘菜品维度、服务维度、食品安全维度相关信息,量化商户经营表现,指导经营动作。关于菜品的用户反馈监控,品牌商户更关注菜品、口味、口感等维度的用户反馈。如上文所述模型迭代后,菜品情感、口味情感、口感情感识别准确率都得到一定的提升。

到餐商户菜品信息优化

随着到餐加强了菜品信息建设,主要包括在生产层面上,整合了商户各来源菜品数据,建设了商户菜品中心,并优化了C端菜品UGC上传功能,有效补充UGC菜品生产;在消费层面上,整合了商户通菜品和网友推荐菜菜品,并基于菜品信息的完善,优化了C端菜品信息的内容聚合及展示消费。同时配合到餐业务,持续通过评价信息生产建设赋能,更多的引导用户从评价生产层面进行商户菜品的描述介绍。主要针对到餐商户菜品关联的评价信息,进行信息联动与展示层面的优化,相比迭代前,有评价菜品覆盖率得到较大的提升。

开店宝评价管理

商家通过提供餐饮服务来获取用户,用户消费后通过评价给商家以反馈,促使商家去不断优化,提供更好的服务,从而获取更多的用户,达到正向循环。评价分析的意义在于建立起评价和餐饮服务之间的通道,实现评价对服务的正向促进循环。通过分析评价内容,帮助商家发现餐厅在菜品、服务、环境等方面,做得好和做得不好的地方,进而针对性的改善。相比迭代前,菜品、服务、环境维度关联评论数得到很大的提升。

五、未来展望

经过近一年的建设,情感分析相关能力不但成功应用到到餐商户经营、供应链等业务,而且优化了多源菜品信息,辅助品牌商户进行用户反馈监控,提升商户服务能力。在联合学习探索上,目前主要将四元组问题转化为两阶段模型,如图11所示,F1值有所下降,仅达到0.63。究其原因,可能是在三元组联合抽取模型中,忽略了实体间的关系,尤其长程关系 (如上文2.4的问题3所述),导致性能不足预期。接下来,将进一步提升情感分析四元组抽取能力,挖掘UGC中用户的核心需求以及重要反馈。在技术方面,将持续进行模型迭代演进,主要涉及:

  1. 持续优化现有模型,保证质量的同时也要提升效率

实验结果还有很大的改进空间,需要进一步探索模型优化方法,如优化预训练模型,使用MT-BERT等,以及在联合抽取中进一步引入实体间关系,来提升四元组抽取的性能。

  1. 深度探索情感分析领域,建设四元组联合抽取模型

主要通过改造Query实现四元组抽取,但是计算量级较大,需要探索模型结构优化,减少冗余的计算量,使其满足四元组联合抽取。

  1. 建设细粒度情感分析通用框架

到餐场景涉及多个情感分析场景,需要建设灵活方便的通用框架,有助于快速支持业务,以及减少资源消耗。

未来,团队将持续优化应用技术,解决到餐业务场景中的情感分析需求。细粒度情感分析是具有挑战和前景的任务,到店餐饮算法团队将和各位读者共同持续探索和研究。

六、参考文献

  • [1] Liu, B. 2012. Sentiment analysis and opinion mining. Synthesis lectures on human language technologies 5(1):1–167.
  • [2] Peng, H. Xu, L. Bing, L. Huang, F. Lu, W. and Si, L.2020. Knowing What, How and Why: A Near Complete Solution for Aspect-Based Sentiment Analysis. In AAAI, 8600–8607.
  • [3] Li, X. Bing, L. Li, P. and Lam, W. 2019a. A unified model for opinion target extraction and target sentiment prediction. In AAAI, 6714–6721.
  • [4] Zhao, H. Huang, L. Zhang, R. Lu, Q. and Xue, H. 2020. SpanMlt: A Span-based Multi-Task Learning Framework for Pair-wise Aspect and Opinion Terms Extraction. In ACL, 3239–3248.
  • [5] Y. Mao, Y. Shen, C. Yu, and L. Cai. 2021. A joint training dual-mrc framework for aspect based sentiment analysis. arXiv preprint arXiv:2101.00816.
  • [6] 华为云细粒度文本情感分析及应用
  • [7] 杨扬、佳昊等. 美团BERT的探索和实践.
  • [8] 任磊,步佳昊等. 情感分析技术在美团的探索与应用.
  • [9] Bu J, Ren L, Zheng S, et al. ASAP: A Chinese Review Dataset Towards Aspect Category Sentiment Analysis and Rating Prediction. In Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies. 2021.
  • [10] Xin Li, Lidong Bing, Wenxuan Zhang, and Wai Lam. Exploiting BERT for end-to-end aspect-based sentiment analysis. In W-NUT@EMNLP, 2019.
  • [11] Xu, L. Li, H. Lu, W. and Bing, L. 2020. Position-Aware Tagging for Aspect Sentiment Triplet Extraction. In EMNLP, 2339–2349.
  • [12] Chen, S. Wang, Y. Liu, J. and Wang, Y. 2021a. Bidirectional Machine Reading Comprehension for Aspect Sentiment Triplet Extraction. In AAAI.
  • [13] Yan, H. Dai, J. Qiu, X. Zhang, Z. et al. 2021. A Unified Generative Framework for Aspect-Based Sentiment Analysis. arXiv preprint arXiv:2106.04300.
  • [14] Wenxuan Zhang, Xin Li, Yang Deng, Lidong Bing, and Wai Lam. 2021. Towards Generative Aspect-Based Sentiment Analysis. In ACL/IJCNLP 2021, 504–510.
  • [15] Li Yuncong, Fang Wang, Zhang Wenjun, Sheng-hua Zhong, Cunxiang Yin, & Yancheng He. 2021. A More Fine-Grained Aspect-Sentiment-Opinion Triplet Extraction Task. arXiv: Computation and Language.
  • [16] Devlin, J. Chang, M.-W. Lee, K. and Toutanova, K. 2019. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. In NAACL-HLT, 4171–4186.
  • [17] Yue Zhang and Jie Yang. 2018. Chinese ner using lattice lstm. arXiv preprint arXiv:1805.02023.
  • [18] Li, X. Yan, H. Qiu, X. and Huang, X. 2020. FLAT: Chinese NER Using Flat-Lattice Transformer. arXiv preprint arXiv:2004.11795 .
  • [19] Tareq Al-Moslmi, Marc Gallofré Ocaña, Andreas L. Opdahl, and Csaba Veres. 2020. Named entity extraction for knowledge graphs: A literature overview. IEEE Access 8 (2020), 32862– 32881.
  • [20] X. Li, J. Feng, Y. Meng, Q. Han, F. Wu, and J. Li. 2020. A unified MRC framework for named entity recognition. In ACL, 5849–5859.
  • [21] Jana Strakova, Milan Straka, and Jan Hajic. 2019. Neural architectures for nested ner through linearization. In Proceedings of the 57th Annual Meeting of the Association for Computational Linguistics, 5326–5331.
  • [22] Yequan Wang, Minlie Huang, Li Zhao, and Xiaoyan Zhu. 2016. Attention-based lstm for aspect-level sentiment classification. In Proceedings of the conference on empirical methods in natural language processing, 606–615.
  • [23] Liang X, Wu L, Li J, et al. R-Drop: Regularized Dropout for Neural Networks[J]. arXiv preprint arXiv:2106.14448, 2021.
  • [24] P. Liu, W. Yuan, J. Fu, Z. Jiang, H. Hayashi, and G. Neubig. 2021. Pre-train, prompt, and predict: A systematic survey of prompting methods in natural language processing. arXiv preprint arXiv:2107.13586.
  • [25] X. Liu, Y. Zheng, Z. Du, M. Ding, Y. Qian, Z. Yang, and J. Tang. 2021. Gpt understands, too. arXiv preprint arXiv:2103.10385.

七、术语解释

术语解释
ABSA细粒度情感分析,Aspect-based Sentiment Analysis
NER命名实体识别,Named Entity Recognition
TOWE面向目标的观点词抽取,Target-oriented Opinion Words Extraction
MRC阅读理解,Machine Reading Comprehension
MLM语言掩码模型,Masked Language Model
BERT基于变换器的双向编码器表示,Bidirectional Encoder Representations from Transformers
CRF条件随机场,Conditional Random Fields
LSTM长短期记忆,Long Short-Term Memory
R-drop基于dropout的正则策略,regularization strategy upon dropout

八、作者介绍

储哲、王璐、润宇、马宁、建林、张琨、刘强,均来自美团到店事业群/平台技术部。

九、招聘信息

美团到店平台技术部的到餐业务数据策略组菜品知识图谱方向主要负责将菜品知识应用到到餐相关业务,使命是为到餐业务提供高效、优质、智能的应用算法解决方案。基于海量的到餐业务数据,应用前沿的实体抽取、关系挖掘、实体表征学习、细粒度情感分析、小样本学习、半监督学习等算法技术,为到餐业务提供算法能力支持。

业务数据策略组菜品知识图谱方向长期招聘自然语言处理算法专家/机器学习算法专家,感兴趣的同学可以将简历发送至hejianlin@meituan.com。

美团外卖终端容器无关化研发框架

终端容器无关化(Containerless):与服务无关化(Serverless)的概念类似,即在保持顶层业务研发语言不变更的情况下,在下层可以兼容性地升级、替换终端容器的能力,让用户无需关心终端容器的运维,只要将精力聚焦到业务逻辑上的技术。

一、前言

React2X是一款面向多终端、跨平台、容器无关化研发框架。在整个美团前端技术栈日益规范的趋势下,React技术栈在我们技术体系环节中的地位变得越来越重要。在广告、营销这些推广属性的业务上,在各个终端(包括美团App、美团外卖App、大众点评App,以及站外的微信小程序、百度小程序、头条&抖音小程序等其他终端)实现“一次开发,同步需求上线”的业务诉求也变得越来越多。在这样的背景下,我们定义了React2X应用的核心场景:

  • 面对美团内部丰富多样的技术容器体系(Mach、MRN、Titans、MTFlutter、MMP等),如何保证跨容器开发体验的一致性,以及建设跨容器应用开发的生态能力,是我们需要解决的问题。
  • 公司内丰富的终端容器化技术蓬勃发展,而因业务升级带来的改造成本也比较大,亟待一款高扩展性设计的顶层框架作为技术抓手。
  • 跨容器动态化能力覆盖,逐步成为各个业务方越来越重视的基础能力,可以大幅缩短需求交付的周期,提高上线发版的效率,并能有效地解决包体积大小的问题,提升业务的敏捷性
  • 多场景下的同构诉求,例如在各种推广页、模块化、游戏、轻量布局差异的PC/App同构场景下,可以节省多端研发的人力。

最终我们的核心痛点围绕在了美团系·小程序美团系·App矩阵上的同一个需求的多次开发运维上,为了解决研发人力瓶颈问题,我们需要一款“一次研发,多终端容器复用”的研发框架来提升研发效率

调研整个前端领域,我们找到了一些业界的解决方案,像是美团最早的mpvue、腾讯的Wepy、滴滴的Chameleon、京东的Taro等等。在经过比较与试用之后,我们最终基于投入产出比的价值判断,选择站在巨人的肩膀上研发定制一款满足美团技术、业务场景的研发框架——React2X(后面简称R2X)。从R2X第一个版本发布到现在,已经接受了来自于公司各个业务两年多的考验。所以我们希望通过本文帮助大家对R2X有一个大致的了解。

二、目标与场景

2.1 核心目标

为了解决业务需求在多端容器需要重复开发的难题,通过代码复用实现开发提效,我们确定了以下的目标:

  • 解决公司内部多终端容器开发痛点:实现Webview容器、小程序容器、MRN容器、Mach容器、游戏容器、部分运营推广场景PC容器的代码同构复用,统一开发规范,抹平开发差异,并提供对其他容器的扩展能力。
  • 建设跨容器动态化能力:跨容器动态化能力的缺失,导致产品不能够通过快速迭代来验证需求的效果,这个问题严重限制了业务的发展。跨容器动态化能力可以解决美团外卖业务端上发版和包体的问题,帮助业务实现快速发版上线、线上问题热修复、以及容灾的能力。
  • 建设容器无关的开发生态体系:R2X最终要解决的是容器差异性,进行统一的技术生态能力建设,为多终端容器开发场景提升生产和运维效率。

2.2 应用场景

R2X开发框架主要期望能最终面向多终端应用的终端容器,用于场景化研发:

图1

即:

  • 业务项目基于React语法为技术框架基础。
  • 业务方有在多终端/多容器(包括MRN容器、Webview容器、MP容器、Flutter容器、Mach容器、PC浏览器容器)运行的需求。
  • 业务方有特定的场景化诉求,包括推广页、模块化、小游戏、PC/App同构等等。

三、挑战与优势

3.1 业界调研

针对上述核心目标和应用场景,我们对市面上的跨容器框架进行了调研。由于美团外卖的技术栈统一是React为主,所以我们的必备要求是:一款以React为DSL语言的复用框架,能快速融入美团的技术生态。

根据下表的对比,如果以React为DSL语言出发,当时就只有Taro一家能满足我们的业务诉求,但它的生态环境并不适合在美团体系内使用。基于多方面因素的考虑,我们决定结合各大主流框架之所长,然后开发出一款属于美团外卖的跨容器复用框架。

对比项mpvueTaro 1.3ChameleonWePYUniApp
DSLVue类React(Nerv)类VueVueVue
是否支持 React Native是,但支持效果不佳Weex
兼容 API有(API支持程度不一)自研多态协议
跨端组件库
美团生态
语法校验ESLint自研
TypeScript
定制化扩展可自研Plugin
编译扩展
调研结论不匹配部分满足部分满足不匹配不匹配

注:前期调研时间截止到2019年05月,可能与当前数据存在一定的出入。

3.2 技术挑战

当我们决定要打造一款属于美团外卖的跨容器复用框架之后,在实现的过程中主要遇到了以下挑战:

① 各个容器之间差异性适配成本 - 语法语义:MRN/小程序/Webview在DSL上就有着完全不同的语法语义。 - 端能力:同一容器在不同端上表现也存在不少差异,比如外卖App中MRN容器和美团App中MRN容器分别有定制的Native模块以及各类桥协议等。

② 业务接入的使用成本 - 首次成本:作为一个新定义的框架如何让新业务方快速上手,如何从存量业务线进行迁移。 - 边际成本:如何融合美团的基建生态,让业务方快速复用平台能力。

③ 顶层架构的合理设计 - 高可维护性、高度扩展性:如何快速升级、替换、新增一款底层容器。

注:以上问题我们会在下文“技术全景”章节中给予解答。

3.3 项目优势

3.3.1 功能特点对比

目前,业界以小程序作为跨端目标平台的框架较多,但大多都是使用Web前端技术栈作为基础,但同时兼顾React Native的技术栈就比较少。下表中列出的是支持以React、类React作为DSL的相关框架进行对比。

R2XTaro 1.3Taro 3.0RaxRemax
原理R2X 1.0重编译时,R2X 2.0重运行时重编译时重运行时重运行时重运行时
容器重点以MRN,小程序,WebView为主,同时支持MTFlutter、Mach、游戏、PC浏览器以小程序、Web为主,React Native支持不多以小程序、Web为主,React Native交给58团队支持小程序、Web、Flutter小程序、Web
API支持KNB桥&对多平台API进行了统一对多平台API进行了统一对多平台API进行了统一多平台不统一多平台不统一
跨端组件库有TaroUI,但不支持React Native有TaroUI,但不支持React Native
业务组件扩展提供扩展方案参考TaroUI参考TaroUI提供扩展方案提供扩展方案
美团内部生态支持已支持埋点监控等
模块化能力支持不支持不支持不支持不支持
编译插件扩展支持不支持支持支持支持Webpack配置

综上所述,从目前的业务形态来看,R2X在容器的匹配程度以及美团生态支持程度上看,是现阶段的最佳方案。R2X相较于业界其他框架来说,拥有更加完善的适用于美团外卖团队的本地化实现。

3.3.2 性能数据对比

基于业界跨平台框架和美团内部的跨平台框架,我们针对性能也进行了Benchmark测试,最终对比结果如下。

小程序性能对比

框架创建更新添加交换删除
R2X-MP947.6586.81467.21355.282.2
Remax2798.21872.65162.24818.286.4
Taro-MP1653.4976.42483.22256.665.2

结论:可以看到,在小程序Benchmark测试结果中,R2X-MP是领先于Remax和Taro-MP。

与React Native性能对比

框架创建更新添加交换删除
R2X-MRN309.87583.75384191.87582.125
MRN297.625105.25400.125231.62565.875
Taro-RN209.577.5246.2585.12517.125

结论:在React Native的Benchmark测试结果中,R2X-MRN和MRN基本持平,但都低于纯React Native的性能表现。

3.3.3 同构场景对比

除了支持了基本的React Native、小程序和Webview容器同构场景之外,R2X还实现了在MTFlutter、Mach、小游戏(Webview游戏、微信小游戏&小程序、美团小游戏)、PC浏览器等容器上的同构能力扩展,相比于业内的其他跨容器开发框架的生态也更加丰富和健全。

React Native小程序WebviewFlutter模块级容器小游戏容器PC浏览器(PC/App同构)
R2X支持支持支持支持支持支持支持
Taro支持支持支持不支持不支持不支持不支持
Rax支持支持支持不支持不支持不支持不支持
Remax支持支持支持不支持不支持不支持不支持

四、技术全景

图2

上图为R2X的架构全景图,整体架构可以按照从下到上,从左到右的视角进行解读:

  • 最下层是R2X的生态环境建设,在R2X内部去实现公司生态的常用SDK以及业务中的各项专题能力;并通过搭建物料市场/插件市场,以业务共建的形式丰富R2X生态。
  • 再上层是R2XCore的根基,通过解析Command命令来执行唤起构建器,并实现了类似Webpack的插件系统,以插件化的形式组织驱动整个核心构建流程,便于维护以及扩展。
  • 再往上是跨端容器层,它是整个跨端能力的核心,通过实现了不同的容器插件来将R2X代码编译成各端可执行代码,并通过运行时能力对组件/API进行对齐。
  • 最上层是承载的App端,目前有美团外卖、大众点评、美团等多款移动App终端。
  • 最右边是R2X在研发、发布、运维以及用户文档上做的一些建设。

因为R2X覆盖了美团内部大部分的主流容器场景,所以技术体系较为复杂和庞大,大家可以根据自身的业务形态,选择性地去了解对应场景的同构方案。

4.1 底层基础框架

4.1.1 R2X-CLI的设计

CLI作为R2X项目驱动器,它不仅包含了命令行的启动,更重要的,它是各个编译构建的核心。

在早期,CLI执行build命令时,我们通过–type来区分不同的构建容器,从而加载不同的编译逻辑。通过指定构建容器的形式来实现同一套代码能够构建出不同的容器产物。但经过长时间的业务迭代,我们发现了这种结构存在的问题:

  • 整体流程冗长且复杂,长时间迭代会变得越来越难以维护。
  • 每个容器的构建流程相互独立,且构建逻辑各不一致,有多处重复的逻辑处理。
  • 编译流程缺少统一的关键节点,编译时无法进行业务方的定制扩展。

针对以上问题,我们考虑对CLI进行了一次全新的重构,引入插件化能力(关于插件化能力的具体实现会在下文详细描述)。CLI整体结构变成如下图所示:

图3

整个CLI模块只需要关心参数的解析以及插件的加载执行,不需要再实现各个容器的具体编译逻辑。通过Hooks的形式,将编译的各个时机暴露给插件,插件基于这些Hook进行编译能力的实现,最终输出产物给CLI模块。这种形式带来了以下几个好处:

  • CLI结构变得清晰,只需要维护配置解析、插件解析等功能。
  • 扩展性增强,可通过插件化的形式新增或删减容器/编译能力,保证代码独立维护功能的单一性。
  • 编译流程可梳理,无论什么容器的编译流程都基于编译器暴露的时机执行并串联,整体流程清晰明了。

4.1.2 组件及API的设计

R2X的目的是希望通过一套代码能够在多端上运行,但是由于多端差异的存在,我们需要设计一套统一的标准规范来进行对齐。在运行时部分,主要分为组件/接口的对齐。

多端差异

在开始讲述实现之前,我们先来看看各端之间的差异到底在哪些地方。

组件(标签)差异

API差异

样式差异

小程序的WXSS和Webview的CSS在参数属性上其实是几乎一致的,但是在层级关系上有着很大的差别,小程序分为全局样式与局部样式,各个组件之间的样式也是不会相互影响(默认配置下)。而对比React Native采用的StyleSheet,是用Inline Style的方式,不支持全局样式,不支持标签样式,并且属性有诸多限制,如只能使用Flex布局等等。

如何适配

从以上章节我们已经了解到了各个端之间有着非常大的差异点,那我们应该如何克服这些困难呢?

图4

由于各端对组件和API的支持程度不同,我们选定了一端为基础标准,定义好各个组件的属性以及接口参数,通过TypeScript的Interface进行实现。然后在各个端分别基于以上的接口进行功能对齐实现,对于端能力限制的功能进行了一定取舍,对高优功能进行了SDK底层实现适配。最终,我们基于已有的功能封装实现了一套完整的基础组件@r2x/components和基础API@r2x/r2x

4.1.3 开放式插件能力

随着R2X的在美团内部的应用越来越多,大家对于R2X模式的认可度也在不断提高,我们从业务方中经常听到以下这些问题:“是否可以增加支持某某功能/容器”,“我们业务架构比较特殊,能否做出一些调整”。业务方对R2X会有更多功能/容器的诉求,也会有更多定制化的需求出现。

所以,我们决定实现一套完整的开放式插件能力,提供一种相对比较简单的方式,让大家能够自己来定制这些特殊需求。在最新的版本中,我们将R2X的编译时进行了重构,在新的编译时架构中引入了基于Tapable的插件系统。开发者可以通过编写插件的方式为R2X拓展更多功能,或者为自身业务线定制更多的个性化功能。

在插件类型分为两类:

  • 容器插件,用于封装R2X所支持的容器的核心编译能力。
  • 功能插件,基于已有的容器插件,在此基础上进行某种特定功能的自定义实现。

插件能力的整体架构如下:

图5

借助开发式插件能力,我们将之前编写了若干个平台容器插件,开发者安装后即可使用:

  • 小程序容器插件:@r2x/plugin-container-wxapp。
  • MRN容器插件:@r2x/plugin-container-mrn。
  • Titans容器插件:@r2x/plugin-container-h5。

除了扩展新的容器平台,我们还可以通过继承现有的容器插件,来编写一些特殊的定制化功能插件。

1. 对代码进行预处理

基于开放式插件能力,我们可以像Babel插件一样,通过对AST语法的修改对代码源文件进行编译前后的修改。比如:修改文件引用路径、插入代码片段、处理本地图片等等。

2. 对文件产物进行修改

在编译产出生成时,我们可以对编译文件的内容、文件路径、文件结构进行修改。结合自身业务的定制化,CLI可以将R2X项目和现有的原生项目进行结合改造。

除了以上功能,插件化能力为用户在编译时提供了极大的自由度。如果你想体验的话,欢迎加入美团外卖技术团队。

4.1.4 特性能力-多态能力

为什么需要多态能力?

多态能力是用于提供跨端时各端组件及API的统一解决方案。基于多态能力,开发者可以定制自己的跨端组件。而R2X具备了完善的跨端能力,能够覆盖多终端和容器,为什么还需要多态?

业务研发为了满足各自场景的要求需要一定的灵活性。同时,Webview/小程序/React Native容器存在端上的差异,需要开发者人为进行环境判断。逻辑一复杂、跨端数量一多,代码可读性变低、维护成本起飞,这不是我们的本意。

基于这样的背景,R2X提供了扩展性良好的多态能力。

R2X多态能力介绍

对于多态能力的支持,我们分为两类:

  • 多态组件/API,R2X根据文件后缀区分编译目标端。

图6

  • 差异化代码,R2X提供getEnv环境方法用于判断当前语句编译目标端类型。

通过差异化代码可轻松满足端差异诉求。

4.2 应用场景同构

4.2.1 页面级容器场景同构

页面级容器场景同构我们借鉴了业内Taro1.x、Rax等优秀跨端框架的做法,结合美团内部容器、基建特点做了很多本地化实现和定制,在Webview、MRN、小程序三种容器上通过不同的编译时方案进行预处理,并且引入了React运行时,保证了对React DSL支持的完整程度和代码同构率,编译时转化流程方案和运行时结构如下图所示:

图7

R2X2.0相比于R2X1.0,运行时方案能够解决编译时方案带来的语法限制问题:

  1. 不能在包含JSX元素的map循环中使用if表达式 ✅
  2. 不能使用Array#map之外的方法操作JSX数组 ✅
  3. 不能在JSX参数中使用匿名函数 ✅
  4. 暂不支持在render()之外的方法定义JSX ✅
  5. 不允许在JSX 参数(props)中传入JSX元素 ✅
  6. 不能在JSX参数中使用对象展开符 ✅

同时也支持大部分React第三方生态库,目前已支持使用原生react-redux。彻底抹平各端的差异,无论是MRN、Flutter、小程序、Webview的自定义组件都可以直接当成React组件引入,小程序原生自定义组件也无需配置usingComponents。

4.2.2 模块级容器场景同构

在模块级同构方案上,我们在App上依赖Mach容器;在小程序容器中,我们克服了Mach容器渲染机制的约束(运行时与虚拟DOM的使用限制),单独在小程序上设计了Mach容器渲染方案,实现了R2X-模块化(R2X-Module)在客户端和小程序上99%以上的代码同构率。

整体方案

图8

  1. 核心驱动包,容器驱动的核心,针对渲染能力、解析能力、缓存能力、性能监控四个方面进行了实现,达到动态化驱动效果。
  2. 业务容器自定义,基于SDK提供的驱动能力,针对不同展位特性进行了容器自定义功能扩展配置,让业务方可根据实际业务场景自行扩展。
  3. 分环境构建,主要实现了将类React语法进行AST编译解析,根据构建平台分别编译成对应的Bundle产物。
  4. 自动化构建部署,将构建能力接入Talos(美团内部自研的构建部署工具),再结合低代码业务工具实现一键部署,将编译产物根据配置项上传至DD(美团内部自研移动端动态下发平台)。

模板驱动方案

目前,R2X-Module在客户端和小程序容器的同构率在99.3%以上,在性能方面首次渲染时长和模板渲染时长的TP50时间分别是185ms144ms,比较优秀但还存在优化空间。同时提供R2X-Module SDK供业务方选择。R2X-Module SDK初始化以及模板加载渲染流程如下图所示:

图9

4.2.3 PC/App适配同构

在移动互联网发展已经高度成熟的今天,移动端的PV流量占比绝大数,以外卖广告商家端为例,PC端仅仅占有很少比例,其中PC流量占比在我们部分业务上已经不及5%。因此在某些场景下实现PC/App的同构方案能够解放一部分人力,对提高开发效率来说是十分必要的。目前,外卖广告商家端的一些轻量布局差异的页面,已经完成了PC/App同构的方案设计和落地。

样式同构适配

图10

图11

端能力扩展

R2X的基础能力支持Webview/MRN/小程序三端,缺少对PC微前端子项目的支持。要实现PC/APP多端同构需要对R2X的端能力进行扩展。PC端本质上也属于Web端,因此PC微前端的端能力扩展可以复用大部分的Webview的端能力。整体架构图、技术设计要点、扩展流程图如下所示:

图12

平台代码处理

在项目同构开发中,不可避免地会出现跟平台强相关的代码或者业务逻辑,比如某些API调用的是App的底层能力,只能在React Native中使用,在Web端肯定是不支持的。或者由于产品需求的原因,某些交互或者展示差异较大等等。而项目针对某一端进行编译、打包时,其他不相关的端代码是无用、多余的,如果保留的话,不仅会增加代码体积,甚至会出现编译报错,因此我们需要借助平台代码处理的能力来进行优化。平台代码的处理主要包含三部分:模块导入、组件展示、业务逻辑。

主要思路是使用注释和指定平台的方式,让特定的平台代码只在特定平台生效,注释关键字%%platform%%,比如%%RN%%表示React Native端独有,%%MICRO%%表示PC微前端独有,%%MICROWebview%%表示PC微前端、Webview 两端生效。示例代码如下:

import A from '@r2x/r2x-a'; // %%RN%%只在React Native端保留。
import B from '@r2x/r2x-b'; // %%MICRO%% 只在MICRO端保留。
import C from  '@/utils/c'; // 这是所有端生效的公共模块。
import D from '@r2x/r2x-d'; // %%MICROWebview%%在MICRO、Webview多端生效的模块。

4.2.4 小游戏容器场景同构

实现react2x-game同构方案主要做的两点:渲染层的兼容、业务层的兼容。

  1. 渲染层的兼容:实现游戏引擎在多端环境下渲染能力的兼容(Canvas、WebGL)。
  2. 业务层的兼容:实现基础API、项目流程、公共模块的兼容,制定游戏差异的个性化定制规范。

渲染层兼容

在上文,我们提到过“无论是Webview游戏、小程序、小游戏、美团小游戏都为我们提供了Canvas、WebGL控件”,很大程度地降低了我们兼容渲染层的复杂度。下面表单,是各端对于语法以及Canvas、WebGL、Document、Window等基础功能的支持情况:

对象Webview微信小游戏微信小程序美团小游戏
语法JavaScriptJavaScriptJavaScriptJavaScript
Canvas支持支持支持支持
Canvas(离屏)支持支持不支持支持
WebGL支持支持>2.11.0支持
Ducument支持不支持不支持不支持
Window支持不支持不支持不支持

可以看出,在语法层面各端都支持了JavaScript语法,但是在执行环境以及基础功能上的差异比较大,总结来说:

执行环境:小游戏、小程序不具备DOM、BOM的能力(渲染引擎中会大量使用)。 基础功能:小程序不支持离屏Canvas,在2.11.0版本以后才开始支持WebGL。

为了解决这些问题,我们设计开发了adaptor层,用来模拟document、window的能力。使游戏引擎可以在非Webview的环境下正常的执行和调用BOM、DOM的基础功能。同时,制定离屏canvas的适配方案,用来解决小程序无法支持离屏canvas的问题。为了获取到有效离屏canvas,我们制作了 “r2x-add-wxml-loader” ,在.wxml文件的loader阶段自动注入额外的< canvas/>控件,并隐藏于手机屏幕之外,用于模拟游戏引擎中的离屏canvas。

图13

多端兼容构建

在构建层面,我们通过集成的多种个性化插件工具,对多端代码进行差异处理。如:环境变量注入、各端适配代码的混入、规范检测、代码解析和转化等。针对小游戏、小程序代码和执行环境的特殊性,制作wx-build-plugin、lwxapp-build-plugin等用于处理小游戏和小程序的打包工作。结合上文中提到的各类差异的处理方案,制作add-wxml-loader、transfrom-loader、wxss-loader等工具协助完成项目构建。如下图14所示,构建之初会注入本次构建的环境变量,读取和分析配置文件,集成和初始化构建工具集合,为项目构建做准备。然后在构建环节,针对各端的差异进行差别处理,分析层针对不同文件进行解析,并在转换层进行转换和构建,最终生成各端需要的最终产物。

图14

4.3 落地场景与效果

R2X-推广页容器场景同构 R2X-模块化容器场景同构 R2X-小游戏容器场景同构

效果收益

R2X在美团外卖业务中得到了广泛的应用。截止2021年10月,R2X累计在美团内部已有二十多个部门在使用或者在调研中,总计落地了上百个工程、页面,框架下载量达百万次,页面平均代码同构率达90%以上。R2X生态体系在容器代码复用与运维层面,累计为美团节省成本上千人/日,并提升动态化页面转化5%-8%的成功率。

五、展望与总结

综上所述,在美团外卖多元化业务形态和容器多样性的情况下,跨容器复用成为了发展的必经之路。而R2X在经历了两年的迭代下也取得了阶段性的成果,在美团各个业务场景都完成了业务的落地覆盖,针对公司的生态环境接入也做出了不少的基础建设。我们相信跨容器多端代码复用依旧是当前缩减项目交付周期,减少研发成本,提升研发效率的重要一环。但目前我们在很多复杂的业务场景下做的不够完美,因此还有许多工作待完善,例如:

  • 开发体验优化,目前想接入或正在接入的兄弟部门已经越来越多,如何减少接入成本,丰富基础建设,优化开发体验,帮助大家快速迁移接入,将是下一阶段的重要课题。
  • 渲染性能优化,在美团外卖场景下性能优化一直是我们在兼顾高效生产的另一个重要指标。特别在小程序场景下,低端机型的性能体验一直是业界瓶颈,如何突破这一难关将会是同构方案全面推广的“敲门砖”。

最后,感谢各个相关研发团队对R2X建设过程中的鼎力支持,R2X的发展离不开所有参与者日以继夜的投入和贡献,我们会持续基于R2X在终端容器领域进行更多探索。如果大家觉得R2X还不错,或者对美团的R2X框架比较感兴趣,欢迎跟我们一起交流探讨。

作者简介

正浩、宝石、彭震,均为美团外卖终端团队研发工程师。

招聘信息

美团外卖长期招聘Android、iOS、FE、Java高级/资深工程师和技术专家,欢迎有兴趣的同学投递简历到lizhenghao@meituan.com。

预训练技术在美团到店搜索广告中的应用

引言

美团到店搜索广告负责美团、大众点评双平台站内搜索流量的商业变现,服务于到店餐饮、休娱亲子、丽人医美、酒店旅游等众多本地生活服务商家。在美团搜索场景中广告的展示样式非常原生,用户使用美团服务不会明显区分广告和自然结果,而广告用户体验损失则会显著影响搜索流量。因此,搜索广告除了优化流量变现效率等商业指标外,也需要重点优化用户体验,不断降低不相关广告对用户体验的损害,这样才能保证整个平台生态长期健康地发展。

在优化用户体验的目标下,如何正确的衡量用户体验,定义不相关广告是首要解决的问题。在搜索广告中,受结果列表页广告位置偏差、素材创意等因素影响,我们无法单一使用点击率(CTR)等客观性指标来衡量用户体验,尤其首位、首屏等排序靠前广告的相关性问题被认为是影响用户体验的主要因素。因此,我们首先建立了美团场景下的搜索广告相关性标准和评估体系,主要通过例行采样和人工评估的方式对搜索广告结果进行相关、一般和不相关的分档标注,进而驱动我们的广告相关性模型和策略迭代。然后,使用广告排序前五位的Badcase率(即Badcase@5)作为搜索广告的相关性评估指标。

问题与挑战

在定义出广告相关性问题和评估指标后,使用相关性模型进行搜索关键词(Query)和候选广告(Doc)的相关性打分,类似于NLP文本匹配任务,但实际建模中也发现若干困难。美团搜索结果以商户门店(POI)粒度展示,即Doc除了POI文本外,还包含一系列的团单或商品描述,内容非常丰富但也带来较多冗余或歧义,且不同业务的文本表达差异较大,比如结婚类商品“朱颜【出门出阁红色秀禾】,南国【中式婚礼嫁衣红色秀禾】”,给广告内容编码带来挑战。

其次,美团广告商户大多没有选择竞价关键词,且POI和团单标题并未面向搜索优化,Doc内容与Query可能存在文本表达偏差。比如“满月酒”和“嗨派星球宝宝宴·游轮派对,生日宴个性气球拱门”,需要处理这类信息缺失的问题。我们最初采用ESIM[1]交互式模型,但实践中发现该模型对我们复杂广告内容的表征能力有限,正负样本区分能力不足,在过滤不相关广告的同时对相关广告的误伤率较高。自2018年底以来,以BERT[2]为代表的预训练模型在多项NLP任务上都取得了突破,我们也开始探索预训练技术在搜索广告相关性上的应用。

业界及美团的解决方案

针对搜索语义匹配任务,Google[3]和Bing[4]的搜索团队已经基于BERT来编码Query和候选Doc,进而改善相关性的效果。预训练模型在美团内部的NLP场景中也有不少落地实践,美团搜索已经验证了预训练模型在文本相关性任务上的有效性[5]。

而针对预训练在语义匹配任务中的应用,业界也提出不少的解决方案。中科院计算所郭嘉丰等人提出PROP[6]和B-PROP[7]等针对搜索任务的预训练方法,主要思想是引入文档中代表词预测ROP(Representative wOrds Prediction)任务。纽约大学石溪分校曹庆庆等人提出DeFormer[8]分解预训练语言模型来做问答等语义匹配任务,在BERT的低层分别对问题和文档各自编码,再在高层部分拼接问题和文档的表征进行交互编码,让文档和问题在编码阶段尽可能地独立,从而提升模型的整体效率。百度刘璟等人提出RocketQA[9]和RocketQAv2[10]等面向端到端问答的检索模型训练方法,通过跨批次负采样、去噪的强负例采样以及数据增强技术大幅提升了双塔模型的效果。陈丹琦等人提出SimCSE[11],采用自监督来提升模型的句子表示能力,从而提升语义匹配的效果。

另一方面,2020年至今,预训练从“大炼模型”迈向了“炼大模型”的阶段,通过设计先进的算法,整合尽可能多的数据,汇聚大量算力,集约化地训练超大模型,持续提升模型效果。不论是公开论文结果还是美团内部实践,均已证明:更大规模的预训练模型能带来更好的下游任务效果。因此,美团广告平台与美团搜索与NLP部进行了合作,尝试利用预训练模型来优化搜索关键词和广告结果的相关性,进一步降低首屏广告Badcase,提升用户体验。

本文分为算法探索、应用实践和总结规划三个部分,对预训练技术在搜索广告相关性的落地方案进行介绍。在算法探索部分介绍了我们在训练样本上的数据增强、预训练(Pre-training)和微调(Fine-tuning)阶段的模型结构优化;在应用实践部分,本文介绍了以知识蒸馏为主的模型压缩方法、相关性服务链路优化方案,以及所取得的业务效果;最后,我们总结了相关性方面的优化方法,并对未来技术探索进行了展望。希望这些经验和思考能够给从事相关研究的同学带来一些帮助或启发。

算法探索

在美团搜索广告场景中,相关性计算可以看做用户搜索意图(Query)和广告商户(POI/Doc)之间的匹配问题,实践中我们采用了能够从多角度衡量匹配程度的集成方法,具体方案为分别基于Query和POI的结构化信息匹配、文本匹配和语义匹配等方法进行打分并且进行分数融合。其中,结构化信息匹配主要是对Query分析结果与POI进行类目、属性等信息的匹配;文本匹配方面借鉴了搜索引擎中的传统相关性方法,包括Query和POI的term共现数、Query term覆盖率、TF-IDF、BM25打分等;语义匹配包括传统的隐语义匹配(如基于LDA或者Word2Vec计算相似度)和深度语义匹配方法。在广告相关性服务中,我们采用学习能力更强的深度语义匹配模型。

深度语义匹配通常分为表示型和交互型两类:表示型模型一般基于双塔结构分别得到两段输入文本的向量表示,最后计算两段文本表示的相似度;该方法的优点是Doc向量可提前离线计算缓存,且匹配阶段计算速度很快,适合线上应用;缺点是只在模型最后阶段进行交互,对文本之间匹配关系学习不足。而交互型模型在初期即对两段输入文本进行交互,匹配阶段可以采用更复杂的网络结构,以学习文本间细粒度匹配关系;这种方法往往可以达到更高的精度,主要挑战在于线上应用的性能瓶颈。

美团搜索广告相关性服务的基线模型采用Transformer+ESIM的交互式模型结构,在满足性能的前提下有效解决了部分相关性问题,但是实际应用中仍然存在一些不足,主要包括: 1. 训练数据中存在标签错误、正负样本分布不一致等问题; 2. Doc除了基础门店信息外还关联了大量商品和团单内容,如果直接将这些信息拼接成长文本作为Doc输入,由于模型结构限制往往需要对Doc文本进行截断,因而导致信息丢失; 3. 基线模型对于长文本的表征能力有限,相关性判别能力不足,很难在控制变现效率影响的同时解决更多的Badcase。

为了解决这些问题,我们基于BERT在训练数据、特征构造和模型方面进行若干探索和实践。下文将逐一展开介绍。

数据增强

由于BERT模型微调阶段所需数据量相比ESIM模型更少,并且对数据覆盖全面度、标签准确度、数据分布合理性等因素更为敏感,在进行模型结构探索前,我们先按照如下思路产出一份可用性较高的数据。搜索广告涉及的业务众多且差异性大,包含的团单和商品种类多元,我们希望BERT的微调数据尽可能覆盖各个场景和主要服务。如果全部人工标注人力和时间成本较高,而用户点击转化行为能一定程度反映出广告是否相关,所以训练数据主要基于曝光点击日志构造,对于部分困难样本加以规则及人工校验。我们根据业务特性对训练数据的主要优化包括以下几点。

正样本置信加权

正样本主要通过点击数据得到,我们对4个月内的Query-POI点击数据进行统计,并且基于曝光频次和CTR进行数据清洗以减少噪声。实际采样流程中,假设对于某个Query需要取N个POI构造N条正样本,采样过程中令POI被采样的概率与其点击数成正比,这样做主要是基于点击越多相关性越高的认知,既可以进一步保证标签置信,又有利于模型学习到POI之间不同的相关程度。

在实验中我们也尝试了另外两个正样本采样方法:1) 对某个Query随机取N个POI,2) 对某个Query取点击最多的N个POI。实践发现方法1会采样到较多的弱相关样本,而方法2得到的大多为强相关样本,这两种方式均不利于模型拟合真实场景的数据分布。

负采样分层

我们按照模型学习的困难程度,从低到高设计了三种负样本采样方式:

  • 全局随机负样本:大多为跨业务的负样本(比如烧烤和密室逃脱),模型学习最容易,可以有效识别跨类目的恶劣Badcase;
  • 一级类目内负样本:Query和POI属于相同一级类目(比如美食、丽人等),但是属于不同细化类目(比如祛痘和医学美容),这部分样本可以为模型学习增加一定难度,提高模型判别能力;
  • 三级类目内负样本:Query和POI属于相同的细化类目,但是POI并不提供Query相关的服务(比如光子嫩肤和水光针商户),这部分属于困难负样本,可以提升模型对语义相近但服务不相关的Badcase的判别能力,更大程度保障用户体验;但是在三级类目下采样可能取到较多相关样本,所以这部分样本还需要经过基于服务核心词的规则过滤以及人工校验。

采样平滑及分布一致性

  • 采样平滑:在正样本构建过程中对Query采样频次做了平滑,避免高频Query采样过多,导致模型忽略对中长尾Query样本的学习。
  • 样本分布一致性:在负样本构建中,对于每种负样本均需要保证各Query出现概率与其在正样本中概率相等,避免样本分布不一致性导致模型学习有偏。

文本关键词提取

美团搜索广告场景下,Query中可能包含地址词、品牌词、服务核心词等多种成分,Query文本一般较短,90%以上的Query长度小于10;POI的主要文本特征包括门店名称和商品信息,而广告主的商品数量普遍较多,直接拼接商品标题会导致POI文本过长,有26%的POI文本长度超过240。

由于相关性模型的主要目标是学习Query和POI之间的服务相关性,大量冗余文本信息会影响模型性能和学习效果,我们对Query和POI文本进行如下处理以提取关键文本信息:

  • 对于Query文本:基于命名实体识别(NER)和词权重结果过滤掉地址词、分店名等成分,保留服务核心词;
  • 对于POI文本:对所有商品标题进行关键词抽取,得到一组能反映商户核心服务的关键词,将其拼接作为POI文本。相比直接拼接原始商品文本,长度大幅下降,仅有5%的POI长度超过240,并且POI文本质量更高,模型学习效果更好。

最终,我们的微调样本包括约50万条数据,涵盖餐饮、休娱、亲子和丽人等20个主要类目,其中正负样本比例为1:5,三种负样本比例为2:2:1。

模型优化

基于多任务学习的多业务模型

由于美团搜索广告涉及餐饮、休娱亲子、丽人医美等大量业务场景,并且不同场景之间差异较大。从过去的实践经验可知,对于某个业务场景下的相关性优化,利用该业务数据训练的子模型相比利用全业务数据训练的通用模型往往效果更佳,但这种方法存在几个问题:1) 多个子模型的维护和迭代成本更高;2) 某些小场景由于训练数据稀疏难以正确学习到文本表示。

受到多业务子模型优缺点的启发,我们尝试了区分业务场景的多任务学习,利用BERT作为共享层学习各个业务的通用特征表达,采用对应不同业务的多个分类器处理BERT输出的中间结果,实际应用中根据多个小场景的业务相似程度划分成N类,亦对应N个分类器,每个样本只经过其对应的分类器。多业务模型的主要优势在于,能够利用所有数据进行全场景联合训练,同时一定程度上保留每个场景的特性,从而解决多业务场景下的相关性问题,模型结构如下图1所示:

图1 多业务模型结构

引入品类信息的预训练

由于美团商户POI和商品标题可能缺乏有效信息表达,有时仅根据Query和POI商品文本很难准确判断两者之间的语义相关性。例如【租车公司,<上水超跑俱乐部;宝马,奥迪>】,Query和POI文本的相关性不高,而该商户的三级品类是“养车-用车租车-租车”,我们认为引入品类信息有助于提高模型效果。

为了更合理的引入品类信息,我们对BERT模型的输入编码部分进行改造,除了与原始BERT一致的Query、Doc两个片段外,还引入了品类文本作为第三个片段,将品类文本作为额外片段的作用是防止品类信息对Query、Doc产生交叉干扰,使模型对于POI文本和品类文本区别学习。

下图2为模型输入示意图,其中红色框内为品类片段的编码情况,Ec为品类片段的片段编码(Segment Embedding)。由于我们改变了BERT输入部分的结构,无法直接基于标准BERT进行相关性微调任务。我们对BERT重新进行预训练,并对预训练方式做了改进,将BERT预训练中用到的NSP(Next Sentence Prediction)任务替换为更适合搜索广告场景的点击预测任务,具体为“给定用户的搜索关键词、商户文本和商户品类信息,判断用户是否点击”。预训练数据采用自然及广告搜索曝光点击数据,大约6千万样本。

图2 BERT输入部分引入POI品类信息

模型优化离线效果

为了清晰准确地反映模型迭代的离线效果,我们通过人工标注的方法构建了一份广告相关性任务Benchmark。基线ESIM模型、BERT模型以及本文提到的优化后BERT模型在Benchmark上的评估指标如下表1所示:

ModelAccuracyAUCF1-Score
ESIM(基线,旧训练数据)67.73%76.94%72.62%
MT-BERT-Base74.88%82.65%75.85%
MT-BERT-Base-多业务75.41%83.03%76.49%
MT-BERT-Base-引入品类信息77.33%83.85%77.93%
MT-BERT-Large-引入品类信息77.87%85.06%79.14%

表1 广告相关性任务模型优化迭代指标

我们首先利用上文介绍的数据增强后的训练样本训练了MT-BERT-Base模型(12层768维),与ESIM模型相比,各项指标均显著提升,其中AUC提升6.6PP。在BERT模型优化方面,多任务学习和引入品类信息这两种方式均能进一步提升模型效果,其中引入品类信息的MT-BERT-Base模型效果更佳,相比标准的MT-BERT-Base模型AUC提升1.2PP。

在BERT模型规模方面,实验发现随着其规模增长,模型效果持续提升,但是预训练和部署成本也相应增长,最终我们选取了大约3亿参数量的MT-BERT-Large模型(24层1024维),在同样引入品类信息的条件下,相比MT-BERT-Base模型AUC增长1.21PP,相比ESIM模型AUC增长8.12PP。

应用实践

在模型的实践落地过程中,我们也遇到若干挑战,并且针对性的设计了优化方案。第一个挑战是BERT模型的前向耗时无法满足线上性能要求,我们通过知识蒸馏和低精度量化方法对模型进行压缩,并且采用离线缓存与实时预测结合的方式进一步提升了服务性能。

另一个挑战是,在广告业务场景下,需要综合考虑平台变现效率、用户体验、商户供给及转化等因素,如何使相关性分数在广告整体链路中发挥出更好的作用。我们目前采用了低质量广告过滤、重排阶段考虑相关性因子以及TOP位次广告门槛控制等策略。下文对应用实践方面的具体方案进行介绍。

模型压缩

由于BERT模型的庞大参数量和前向预测耗时,直接部署上线会面临很大的性能挑战,通常需要将训练好的模型压缩为符合一定要求的小模型,业内常用模型压缩方案包括模型裁剪、低精度量化和知识蒸馏等。知识蒸馏[12]旨在有效地从大模型(教师模型)中迁移知识到小模型(学生模型)中,在业内得到了广泛的研究和应用,如HuggingFace提出的DistillBERT[13]和华为提出的TinyBERT[14]等蒸馏方法,均在保证效果的前提下大幅提升了模型性能。

经过在搜索等业务上的探索和迭代,美团NLP团队沉淀了一套基于两阶段知识蒸馏的模型压缩方案,包括通用型知识蒸馏和任务型知识蒸馏,具体过程如下图3所示。在通用型知识蒸馏阶段,使用规模更大的预训练BERT模型作为教师模型,对学生模型在无监督预训练语料上进行通用知识蒸馏,得到通用轻量模型,该模型可用于初始化任务型知识蒸馏里的学生模型或直接对下游任务进行微调。在任务型知识蒸馏阶段,使用在有监督业务语料上微调的BERT模型作为教师模型,对学生模型在业务语料上进行领域知识蒸馏,得到最终的任务轻量模型,用于下游任务。实验证明,这两个阶段对于模型最终效果的提升都至关重要。

图3 两阶段知识蒸馏

在美团搜索广告场景下,首先我们基于MT-BERT-Large(24层1024维)在大规模无监督广告语料上进行第一阶段通用型知识蒸馏,得到MT-BERT-Medium(6层384维)通用轻量模型,在下游的广告相关性任务上进行微调。MT-BERT-Medium属于单塔交互结构,如图4(a)所示。

目前,每个Query请求会召回上百个POI候选,交互模型需要分别对上百个Query-POI对进行实时推理,复杂度较高,很难满足上线条件。常见解决方案是将交互模型改造成如图4(b)所示的双塔结构,即分别对Query和POI编码后计算相似度。由于大量候选POI编码可以离线完成,线上只需对Query短文本实时编码,使用双塔结构后模型效率大幅提升。我们使用通用型蒸馏得到的MT-BERT-Medium模型对双塔模型中Query和POI的编码网络进行初始化,并且在双塔在微调阶段始终共享参数,因此本文将双塔模型记为Siamese-MT-BERT-Medium(每个塔为6层384维)。双塔结构虽然带来效率的提升,但由于Query和POI的编码完全独立,缺少上下文交互,模型效果会有很大损失,如表2所示,Siamese-MT-BERT-Medium双塔模型相比MT-BERT-Medium交互模型在相关性Benchmark上各项指标都明显下降。

图4 相关性模型结构对比

为了充分结合交互结构效果好和双塔结构效率高的优势,Facebook Poly-encoder[15]、斯坦福大学ColBERT[16]等工作在双塔结构的基础上引入不同复杂程度的后交互层(Late Interaction Layer)以提升模型效果,如图4©所示。后交互网络能提升双塔模型效果,但也引入了更多的计算量,在高QPS场景仍然很难满足上线要求。针对上述问题,在第二阶段任务型知识蒸馏过程中,我们提出了虚拟交互机制(Virtual InteRacTion mechanism, VIRT),如图4(d)所示,通过在双塔结构中引入虚拟交互信息,将交互模型中的知识迁移到双塔模型中,从而在保持双塔模型性能的同时提升模型效果。

图5 任务型知识蒸馏&虚拟交互

任务型知识蒸馏及虚拟交互的具体过程如上图5所示。在任务型知识蒸馏阶段,我们首先基于MT-BERT-Large交互模型在业务语料上进行微调得到教师模型。由于学生模型Siamese-MT-BERT-Medium缺乏上下文交互,如图5(b)所示,注意力矩阵中的灰色部分代表了2块缺失的交互信息,我们通过虚拟交互机制对缺失部分进行模拟,计算公式如下为:

我们对蒸馏阶段各个模型进行了Benchmark上的效果评估以及线上QPS=50时的性能测试,结果如表2所示。通过虚拟交互进行任务型知识蒸馏得到的任务轻量模型Siamese-MT-BERT-Medium相较于直接对通用轻量模型进行微调得到的同结构的Siamese-MT-BERT-Medium(W/O任务型知识蒸馏)模型,各项效果指标明显提升,其中Accuracy提升1.18PP,AUC提升1.66PP,F1-Score提升1.54PP。最终我们对任务轻量模型Siamese-MT-BERT-Medium进行上线,相较于最初的MT-BERT-Large模型,线上推理速度提升56倍,完全满足线上服务的性能要求。

Model模型规模 / 模型结构AccuracyAUCF1-Score参数量耗时
MT-BERT-Large24层1024维 / 交互77.87%85.06%79.14%340M227.5ms
通用轻量模型:MT-BERT-Medium6层384维 / 交互77.62%84.79%78.63%21M16.8ms
Siamese-MT-BERT-Medium(w/o 任务型知识蒸馏)6层384维 / 双塔74.23%81.65%75.37%21M4.0ms
任务轻量模型: Siamese-MT-BERT-Medium6层384维 / 双塔75.41%83.31%76.91%21M4.0ms

表2 模型效果对比

相关性服务链路优化

相关性计算

为了更好地衡量广告召回结果的相关程度,除了基于模型得出的语义相关性之外,我们还计算了文本相关性、类目相关性等分数,并对所有分数进行融合得到最终的相关性分数。其中,文本相关性的计算借鉴了搜索引擎场景的检索相关性方法,例如Query和POI的字符串包含关系、短语匹配数和匹配率、以及BM25分等。

另外,文本匹配同时考虑了原串匹配、核心词匹配及同义词匹配等多维度指标;类目相关性主要基于Query意图分类和商户类目信息进行匹配。分数融合模型可以选择LR或者GBDT等复杂度比较低的模型,并基于高质量标注数据集训练得到。

相关性应用

通过模型结构和分数融合策略的迭代优化可以得到更加准确合理的相关性分数,但是在实际的相关性应用中,还需要紧密结合广告业务场景,综合考虑平台变现效率、用户体验、广告主供给及转化等多方面因素。基于“减少低质量的不相关广告”和“相关广告排序应该尽量靠前”两个基本要求,我们设计了几种相关性分数的具体应用方式:

  • 过滤低质量广告:完全不相关的广告无疑会严重影响用户体验,需要进行过滤。考虑到不同召回策略和不同业务流量在变现效率及Badcase严重程度等方面存在差异,过滤阈值被设计成召回策略×类目的二维超参矩阵;
  • 重排序参考相关性:在广告系统的竞价排序模块,在考虑点击率、转化率、交易额和出价等因素的同时,也需要考虑相关性分数;
  • TOP位次相关性门槛:首位、首屏等排序靠前的广告结果对于用户体验影响更大,因此针对TOP位次设置了相关性门槛,进一步改善用户体验。

图6 相关性服务链路示意图

模型部署

为了进一步提升服务性能并且能有效利用计算资源,模型部署阶段我们采用高频流量缓存、长尾流量实时计算的方案。对高频Query-POI对进行离线相关性计算并写入缓存,每日对新增或商品信息变化的Query-POI对进行增量计算并更新缓存,线上相关性服务优先取缓存数据,如果失效则基于蒸馏后的任务轻量模型进行实时计算。对于输入相关性服务的Query-POI对,缓存数据的覆盖率达到90%以上,有效缓解了在线计算的性能压力。

图7 相关性分数离线/在线计算流程图

线上实时计算的任务轻量模型使用TF-Serving进行部署,TF-Serving预测引擎支持使用美团机器学习平台的模型优化工具—ART框架(基于Faster-Transformer改进)进行加速,在将模型转为FP16精度后,最终加速比可达到5.5,数值平均误差仅为5e-4,在保证精度的同时极大地提高了模型预测的效率。

线上效果

为了更加直接客观地反映线上广告相关性情况,我们建立了美团场景下的搜索广告相关性标准和评估体系,对搜索关键词和广告结果进行相关、一般和不相关的分档标注,采用排序前五位广告的Badcase率(即Badcase@5)作为搜索广告的相关性评估核心指标。

除此之外,由于CTR能够通过用户行为间接反映广告的相关程度,并且便于在线上进行AB实验评估,而NDCG可以反映相关性分数用于广告列表排序的准确性,所以我们选取CTR和NDCG作为间接指标来辅助验证相关性模型迭代的有效性。我们对本文的优化进行了线上小流量实验,结果显示,实验组CTR提升1.0%,覆盖率降低1.0%,变现效率基本没有损失。并且经过人工评测,Badcase@5降低2.2PP,NDCG提升2.0PP,说明优化后的相关性模型能够对召回广告列表进行更加准确的校验,有效提升了广告相关性,从而给用户带来更好的搜索体验。

下面列举了两个Badcase解决示例,图8(a)和8(b)分别包含了搜索“登记照”和“头皮SPA”时的基线返回结果(左侧截图)和实验组返回结果(右侧截图),截图第一位是广告结果。在这两个示例中,实验组相关性模型将不相关结果“麻朵新生儿摄影”和“莲琪科技美肤抗衰中心”检测出来并过滤掉,让相关广告得以首位展示曝光。

图8 Badcase解决示例

总结与展望

本文介绍了预训练技术在美团到店搜索广告相关性上的应用,主要包括样本数据增强、模型结构优化、模型轻量化及线上部署等优化方案。在数据增强方面,为了基于曝光点击数据构造出适合美团广告场景下相关性任务的训练数据,我们构造了多种类型负样本,在采样时考虑正样本置信度、关键词频率平滑、正负样本均衡等因素,另外也对POI和团单商品文本进行关键词抽取得到更加简短有效的文本特征。

在模型结构优化方面,我们尝试了对不同业务场景做多任务学习,以及在BERT输入中引入品类文本片段这两种方案使模型更好地拟合美团搜索广告业务数据,并利用规模更大的预训练模型进一步提升了模型的表达能力。

在实践应用中,为了同时满足模型效果和线上性能要求,我们对中高频流量进行离线打分和缓存,并且利用MT-BERT-Large蒸馏得到的双塔模型进行线上实时预测以覆盖长尾流量。最终,在保证广告平台收入的前提下,有效降低了搜索广告Badcase率,提升了用户在平台的搜索体验。

目前,广告相关性打分主要应用于阈值门槛,目的是端到端的过滤掉不相关广告,从而快速降低广告Badcase。在此基础上,我们期望相关性模型继续提升区分相关和一般相关广告的能力,从而在重排序中作为排序因子更好的平衡变现效率和用户体验指标,更准确的度量用户体验损失和变现效率提升的兑换关系。此外,在本地搜索类场景下,局部供给经常比较匮乏,实际召回效果对比全局供给的情况更依赖相关性打分的能力,所以我们依然需要在相关性模型上持续深入迭代,并支撑广告召回模型和策略的进一步优化。

在具体技术方向上,相关性门槛阈值设置、广告长文本表达和业务知识融合等方面依然存在优化和提升空间:

  1. 阈值搜索:目前的阈值策略需要对每个类目分别调参,缺乏整体性且难以达到全局优化效果。我们正在实验将阈值搜索看作可变现流量上的最优化问题,在限定消耗损失及其他业务约束的条件下,找到一组门槛阈值使得整体Badcase解决最大化,并已经取得初步的效果。
  2. 特征表达:目前广告Doc特征主要采用团单商品标题的关键词抽取结果,但是Doc文本仍然较长并且存在一些冗余信息,有必要对Doc信息抽取方法继续探索,比如融合外部知识进行信息抽取,或者通过优化Transformer注意力机制使模型在相关性打分时更加关注某些重要词项或者行业相关的关键词。
  3. 联合优化:Query和POI文本中的蕴含的类目信息、实体成分等对于判断相关性很有帮助,我们计划将相关性任务与搜索广告场景下其他任务联合优化,比如命名实体识别、Query类目识别等,期望通过引入辅助任务增强模型的学习能力,更全面准确的学习语义相关性。

参考资料

  • [1] Chen, Qian, et al. “Enhanced lstm for natural language inference.” arXiv preprint arXiv:1609.06038 (2016).
  • [2] Devlin, Jacob, et al. “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding.” arXiv preprint arXiv: 1810.04805 (2018).
  • [3] Pandu Nayak, “Understanding searches better than ever before.” Google blog (2019).
  • [4] Wenhao Lu, et al. “TwinBERT: Distilling Knowledge to Twin-Structured BERT Models for Efficient Retrieval.” arXiv preprint arXiv: 2002.06275 (2020).
  • [5] 李勇, 佳昊, 杨扬等. BERT在美团搜索核心排序的探索和实践.
  • [6] Ma, Xinyu, et al. “PROP: Pre-training with Representative Words Prediction for Ad-hoc Retrieval.” Proceedings of the 14th ACM International Conference on Web Search and Data Mining (2021).
  • [7] Ma, Xinyu, et al. “B-PROP: Bootstrapped Pre-training with Representative Words Prediction for Ad-hoc Retrieval.” arXiv preprint arXiv: 2104.09791 (2021).
  • [8] Cao, Qingqing, et al. “DeFormer: Decomposing Pre-trained Transformers for Faster Question Answering.” arXiv preprint arXiv:2005.00697 (2020).
  • [9] Qu, Yingqi, et al. “RocketQA: An Optimized Training Approach to Dense Passage Retrieval for Open-Domain Question Answering.” arXiv preprint arXiv: 2010.08191 (2021).
  • [10] Ren, Ruiyang, et al. “RocketQAv2: A Joint Training Method for Dense Passage Retrieval and Passage Re-ranking.” arXiv preprint arXiv: 2110.07367 (2021).
  • [11] Gao, Tianyu, et al. “SimCSE: Simple Contrastive Learning of Sentence Embeddings.” arXiv preprint arXiv: 2104.08821 (2021).
  • [12] Hinton, Geoffrey, Oriol Vinyals, and Jeff Dean. “Distilling the knowledge in a neural network.” arXiv preprint arXiv:1503.02531 (2015).
  • [13] Sanh, Victor, et al. “DistilBERT, a distilled version of BERT: smaller, faster, cheaper and lighter.” arXiv preprint arXiv:1910.01108 (2019).
  • [14] Jiao, Xiaoqi, et al. “Tinybert: Distilling bert for natural language understanding.” arXiv preprint arXiv:1909.10351 (2019).
  • [15] Humeau, Samuel, et al. “Poly-encoders: Transformer architectures and pre-training strategies for fast and accurate multi-sentence scoring.” arXiv preprint arXiv:1905.01969 (2019).
  • [16] Khattab, Omar, and Matei Zaharia. “Colbert: Efficient and effective passage search via contextualized late interaction over bert.” Proceedings of the 43rd International ACM SIGIR conference on research and development in Information Retrieval. (2020).

作者简介

  • 邵雯、春喜、晓俊、程佳、雷军等,来自美团广告平台技术部。
  • 杨扬、任磊、金刚、武威等,来自美团平台/搜索与NLP部。