夜深人静伸手不见五指一盏台灯下默默码字的地方 2019年 我们打了几场硬仗 (下)

simple · April 26, 2020 · Last by 陈子昂 replied at July 09, 2020 · Last modified by admin 陈恒捷 · 12483 hits
本帖已被设为精华帖!

5. 模型算法监控体系

绝大多数测试同学可能接触不到这方面的测试,只是为了记录下团队一年的成果,感谢小伙伴们的奋力拼搏!
发现已经写了1万多字了,新起一篇,方便大家阅读

提到模型算法方面的测试,往事浮现,历历在目。
记得商业化大老板跟我们说:“测试的同学能不能把测试工作再做的深入一些?不要局限于广告投放平台UI上面的点点点,而是把模型效果给测一测,因为平台交互的问题只会影响到一部分商户的体验,而模型效果的影响可能是数十万、几百万的用户,我更关心这方面的质量”,大老板非常委婉的Diss了测试,如芒在背。
我们去找模型算法的研发负责人沟通,测试人员有没有能介入的地方,我现在还记得他坐在对面歪着嘴笑(不是贬义,他平时笑起来也是嘴巴歪向一边),看着我们缓缓地摇头,当时的情景下深深的感觉测试被鄙视了,只不过我们没有放弃测试深入化这件事,方法总比困难多。

5.1 业界调研

通过跟研发同学沟通,我们发现研发同学评估新模型的效果会有两种办法,第一种是本地环境离线实验,第二种是线上小流量灰度测试,这两种方法都不需要测试太多的干预。我们在想如果不直接干预测试,还有其他事情能做吗?
老规矩,先去外面看看业界前辈是如何做的,找了一圈我们发现基于模型和算法的测试案例真的寥寥无几。正在我们苦思冥想的时候,我们发现研发每天都会把实验数据录入到wiki中,当作实验日志来记录。突然萌生了一个念头,这种碎片化的数据是不是可以连续跟踪呢?经过跟小伙伴们讨论后发现,我们有一个很重要的事情可以做,那就是“模型监控”

5.2 场景分析

广告引擎系统非常的复杂,不知道是否会涉密,所以我从网上找了个类似的架构图帮助大家理解,实际架构要复杂许多,可以参考刘鹏博士写的《计算广告》中提到的在线广告架构图:

(图片来源于百度)

5.2.1 基本概念分割线

这里稍微科普一下,在线商业广告有很多种类型:

  • 合约广告
  • 竞价广告
  • 程序化交易广告
  • 原生广告

一条广告从创建到召回,再到展示用户面前,会经历一系列复杂的处理,整个过程中都需要测试同学来参与验证,而目前我们对模型算法的测试还是空白,我们来看一下示意图:

召回引擎主要负责广告被召回的逻辑,比如在什么场景下,在什么广告位上,提供什么样的广告类型,并提供广告物料。
算法侧是根据当前的用户画像,计算广告展示策略,比如什么样的广告优先展示,广告的排序队列是怎样的。

广告涉及到的一部分算法类型:

  • 分类算法:决策树、贝叶斯、神经网络……
  • 聚类算法:K-means、K-mediods……

涉及到的部分模型分类:分类模型、聚类模型、回归模型、预测模型……

我们每天要接触的素材是:算法、模型、样本、特征、指标……


言归正传,通过一段时间的沟通和分析,我们对模型训练周期进行了摸排和分解,并对每个环节曾经或可能出现的风险进行分析:

在真正了解到模型算法这块的流程后,我们一度想要放弃,因为难度确实超乎我们的想象,场景比我们想的要复杂。
由于算法模型的黑盒性、难解释性,不再是我们过去测试的true 或 false的情况,业界能借鉴的案例也极少。除此之外,还有一些坑等着我们跳:

  • 超大规模的样本和特征(某个模型的样本量约5亿)
  • 问题定位不确定性太多,研发自己做也非常耗时
  • 离线训练需要大数据计算的背景知识和技能
  • 不同的场景有不同的算法模型,应用场景多样化决定了数据表现的多样性

5.3 测试体系

附上我们整体的测试体系和过程。

模型算法方面的测试我们划分为“生产环境”“测试环境”两套。针对生产环境,模型从生产到上线大抵可以划分为六个环节:

  1. 数据来源
  2. 特征提取
  3. 离线训练
  4. 模型Build
  5. 发布上线
  6. 实时预估

生产环境中,我们在这上面六大环节中分别做了各种定制化的监控,从而实现“全链路”的数据跟踪,同时也把所有能获取到的过程指标数据全部拿到,然后根据大数据的计算进行统计,把数据结果通过平台化的方式展现出来,提供研发人员进行问题追踪排查,同时也可以辅助算法工程师进行模型调优,最令人兴奋的是,我们的做法吸引了很多算法工程师前来,提出了大量的定制化数据需求,从而商定了很多监控报警和流程卡点机制。
测试环境上,我们搭建了一套完全模拟线上的仿真测试环境,通过流量回放技术,把线上数据引流到线下,对即将上线的新模型进行检测,查看各项指标的表现,从而预判能否发布到线上,在这个环节我们也增加了自动干预的卡点,如果出现较大的指标波动,我们就自动拦截上线。

5.4 数据监控

数据监控机制形成了四种分类:

  • 样本特征类
    • 全样本量和大小
    • 正样本量和比例
    • 新增缺失率
    • Q百分比
  • 模型内容类
    • Feature总量
    • Feature缺失率
    • Feature新增率
  • 效果评估类
    • 机器学习
    • 变现能力
    • 特征效用
  • 基础质量类
    • 上游数据
    • Build过程
    • 发布流程
    • 物理环境

上述四类,前面两类是跟模型算法内容相关的监控,而后面两类属于出于质量设计而扩展出来的能力。我们以样本特征和模型内容为例,在我们的监控环节里,需要采集到的指标有:

上图中,左侧是我们梳理和要监控的指标内容,右侧是我们需要根据这些数据提供查询的维度,其实是平台化后衍生出来的用户需求。实际上我们前后针对13个模型整理出来了44种监控指标,并且算法工程师们还在不断的增加新的指标,紧接着我们就面临了第二个挑战:大数据计算
前面有提到,某个模型的样本数据大约是5亿条,每个样本的特征项可能会有近百种。举个例子:某个用户的手机IMEI号作为其唯一的样本,对应的特征数据会有100多种,那么测试在做样本训练的时候,会遇到计算的性能问题,我们最初进行一次样本训练需要8个小时,而研发人员对样本训练的时效性要求又非常高,迫使我们不得不去解决这个问题。比如说:

  • 如何解决数据倾斜的问题?
  • 如何解决Spark任务GC时间过长的问题?

诸如此类的问题还有很多,都是需要我们去排查和解决的,通过小伙伴们不懈的努力,我们把样本训练的时间从8小时减少到1小时,最终目前可以压缩到20分钟内完成。
另外尽管我们对样本数据进行了top N的筛选,但是结果数据依然非常复杂,因为我们需要用堆叠图来展示,对前端性能要求很高,见下图:

5.5 效果评估

在上面流程里,我们不止是对模型的过程进行监控,还需要兼顾效果评估类的工作,目前我们完成的事务可分为下面几大类:

  • 机器学习相关
    • AUC
    • COPC
    • LOGLOSS
    • PCTR
    • 准确率
    • 召回率
    • ROC曲线
  • 业务相关
    • 实时收入
    • CTR
    • CVR
    • CPM
  • 特征效果相关
    • IV
    • WOE
    • 特征变现变化

基于需求,我们需要支持几个维度的数据对比,将平台能力提升到了一个新的复杂程度:

  • 不同阶段对比
  • 阶段一致性
  • 时间维度
  • 版本对比
  • 分桶
  • 分ADX

5.6 基础质量

关于基础质量,前面有提到,是我们围绕着模型算法测试干预的探索过程中,衍生出来的基于质量的行为。
这个是有惨痛的教训的,曾经发生过一个线上事故,因为上游某个特征数据推送出现问题,采用了默认的内容,从而导致了线上大面积的计算错误,虽然在数分钟内就发现了该问题,但是也产生了巨量的收入损失。
因此我们针对这种情况补充了几件事:

对于上游依赖的数据,我们会做全流程的监控,主要监控其变化异常,比如某个模型在进行训练的时候需要依赖的样本集大小,不能跟上个版本发生较大偏差,对于偏差量我们会配置一个阈值来进行监控,另外会根据样本文件的更新时间进行记录,从而避免使用默认文件的情况发生。模型生产过程也是同样的道理,只是监控的范围更大,维度更多,譬如下图中当文件出现不一致的时候发生的监控报警:

5.7 平台化

关于平台化的需求,其实是用户提出来的,也就是我们的算法工程师们,他们期望平台能够提供几个方面的支持:

  • 查询
    • 自定义场景查询
    • 配套表格数据
    • 线上部署记录查询
  • 对比
    • 同环比数据
    • 不同模型对比
    • 不同版本对比
  • 在线配置
    • 基础属性配置
    • 特征项管理
    • 报警阈值配置
    • 监控信号阈值配置
  • 交互友好
    • 更新记录可查
    • 前端性能

目前系统功能已经越来越多,不能一一截图,下图是系统的一小部分截图:

5.8 模型监控带来的收益

这部分内容相信是大家最为关心的,就是做了那么多事情,到底有哪些可预期的收益?我们从监控平台上线以来,做了一次线上事故的对比:

在回顾全年的效果时,我们发现这种做法是非常有效果的,得到了业务方的高度认可。以至于后来我们支持的算法工程师调到别的项目去的时候,第一时间就把这套监控方案引入到项目中去。最值得高兴的是我们不但得到了业务方的认可,还给其他业务线带来了帮助,甚至有个业务线上线第一天就发现了2个有效问题,直接影响了收入的提升。

6. 团队取得的落地效果

最后,请允许我用团队述职报告里面的一部分内容来总结一下我们团队2019年的组织产出(求大佬们轻喷 😫😫 ):

  • 移动广告业务从优化CI、CT、CD流程,到精准测试的研发,再到线上监控一整套解决方案的落地,把移动广告整体事故损失从去年的XXX多万降至XXX万,减少54%。

    • 打造了完整的引擎算法线上监控体系:
      • 完成算法模型深入化测试目标。监控覆盖模型全链路,44个指标,8个上线卡点,实现了测试干预模型上线的能力。有效报警和上线拦截分别20+、47次,无反馈漏报。自5.28后再无相关事故发生(除1起已告警未采纳的事故)
      • 配置文件的梳理,覆盖95%的词典文件监控,5个监控维度。有效报警15+次,发现问题种类7个。
      • 整体监控体系也辅助联盟和搜索算法的质量保证,发现了直接影响收入的问题。
      • 模型调优效率化工具已上线,预期可以将模型调优环节,由原来的零散数据分析变得更加全面体系化,且一个包含完整指标一个任务最快10分钟完成
      • 协助其他兄弟团队的3个业务线完成了引擎的相关模型算法监控方案落地
    • 精准测试探索:
      • 完成引擎算法C++准实时代码染色系统、自动化用例执行推荐、流量回放场景的diff及冗余代码标记一系列工具。
      • 辅助rd删除冗余代码1w+行,项目体积减少20%。有效辅助手工和自动化测试覆盖率的提升,自动化回归case增加218条,累计551条,核心模块ileaf 自动化覆盖率由58.8%提升至72%,dspserver 由53.9%提升至57.2%
      • Java覆盖率
        • 针对覆盖率数据,行覆盖达到75.34%,diff新增覆盖率90%以上
        • 结合实时染色功能,增加难覆盖到场景用例3条,删除1个无用文件
        • 推广到兄弟团队使用,目前已经集成使用的有1个业务,正在沟通中的有2个业务
      • PHP覆盖率
        • 完成PHP代码增量覆盖率并应用于日常项目,测试中应用系统:channel、sales、mkt、job、ka等,辅助测试查看覆盖的完整度,补充异常case,平均增量覆盖率80%;督促开发剔除本次的无效代码620多行;
      • CI、CT、CD优化:
        • 增加系统级diff,覆盖36个广告场景; 增加了动态性能报警阈值机制; 以及小流量配置机制、模块机器分配等一系列优化。
        • 全年完成2118次构建和测试。有效拦截崩溃6+次,性能下降严重或功能问题3+次,辅助rd将核心模块平均延迟从 65ms优化到30ms。

之前规划的完成情况

7. 未来规划

新的一年,团队遭遇了重大的组织结构调整,之前规划的事情可能会面临很大的修改,这里暂时就贴一张图。
不论怎么样,我们都会秉承“专业、支撑、开放”的精神持续的奋斗下去,打造一支持续创新,锐意进取,努力拼搏的团队。

共收到 34 条回复 时间 点赞
simple 关闭了讨论 26 Apr 11:31
simple 重新开启了讨论 26 Apr 11:31

厉害,承接上一篇,继续学习👍

兄弟,这个广告的能不能再多点资料,另外,你真的很强

做得这么好,还是面临裁员,这不是技术的锅吧

simple #6 · April 26, 2020 作者
cooker 回复

😁 感谢支持~

simple #7 · April 26, 2020 作者

不是裁员,团队整合了😂

simple #8 · April 26, 2020 作者

我这个介绍的很宽泛,后面会有专门的文章发出来,包括spark如何做调优来提速类似这样的内容,目前篇幅太大了。。
感谢赞许呀,不过这些事都是团队完成的。惭愧🙏

厉害!好多地方值得学习!好多东西开了视野。。。。感谢分享!

赞,期待流量回放部分的详细介绍

太强了,虽然我看的云里雾里!

我看不下去了,牛B,我这二线城市的,怎样才能达到这水平,哈哈,玩笑,对于大数据,这方面我们也在做~效果还有在评估中~

规划和执行都很牛

320 个赞👍

simple #15 · April 27, 2020 作者
sylan215 回复

😊

  1. 太专业了,前面的几张图虽然不是不太懂,但是感觉做了很多事情,成长很快。
  2. 另外最后两张总结的图,完全可以拿来作为整个质量体系建设的模板。
陈恒捷 将本帖设为了精华贴 27 Apr 08:25

看不懂 就是感觉很高大上

qtest的工具链牛逼,兄弟,再来几篇瞻仰学习一下。

厉害啊,做的这么精细👍

赞👍!

simple #22 · April 28, 2020 作者
zailushang 回复

沾了组员们的光😂

这太厉害了,虽然看的不是很懂,真的是涨见识,测试还能这样玩,不得了啊。。膜拜大神

很强啊。

看不懂,但觉得牛b

大佬,广告的展示怎么做断言啊?你们广告sdk自动化只做接口吗?广告视频图片等等播放正不正常这些不做校验吗??

有没有啥思路给一下?

类似于什么爱奇艺,腾讯视频这种app,播放视频前给你来个几十秒的视频广告这种

simple #27 · May 08, 2020 作者

展示广告效果的我们人工验证,那个实现成本太高了,而且图片都有区别,肉眼观察的效率是最高的。目前我们自动化只投入了打点验证,因为这个打点通常是新增,修改和减少的情况不常见。但是打点验证人工极容易出错,所以我们投入了自动化测试。
视频类的SDK我们也有,但是自动化验证做的其实不太好,爱奇艺、优酷他们对视频播放的测试,和视频、游戏类广告其实类似,只是播放时间有些差异,但是从行业里面的做法来看,投入太高了,我们不具备这样的储备去研究图像识别算法,未来等方案开源了再打算弄一下

simple 回复

我有个想法,就是只验证广告展示的效果,可以全都用同一个素材,甚至是一个静态图片,视频就拿静态图片合成,每一帧都一样的

然后录屏做图像对比识别,因为都只是同一张图,搞定一张图应该比较简单吧,你觉得这个思路咋样?

触发广告就用常见的appium去点点点来触发,然后录屏对比

simple #30 · May 08, 2020 作者

这样的操作是为了验证啥呢?如果每一帧的画面都是一样的,那对于丢帧和卡顿很难辨别出来吧?另外对于视频广告的暂停,重播、暂停后继续等场景就很难区分出来了

simple 回复

大佬说的对,我觉得爱奇艺啊抖音这种,应该有点办法,但是没看到他们公司有人分享过。。。。

还有友盟这种应该也有方案的

simple #32 · May 08, 2020 作者

抖音没有,爱奇艺和优酷都在大会上分享过呢

simple 回复

那我把操作搞好,最后广告展示的时候录屏下来,到最后展示效果统一人工查看,这样你觉得呢?

34Floor has been deleted

vv 加一下

众安?

真的是太牛逼了

是记录一个帧序列和序列的比对吧,关键帧的图片验证前面60*5帧 。整体比如按5分钟 按大概1万5000帧左右。

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up