打造一家模型驱动型公司- Tubi 数据与机器学习平台简介

avatar
HR @Tubi

Tubi 是北美最大的免费流媒体 (AVOD) 公司。我们公司的小目标是给全世界带来观看不尽的乐趣。我们既没有 Netflix 庞大的技术部门,也没有 Disney 对超优质内容的垄断,更没有 Apple 有钱任性。作为一家中小型创业公司,Tubi 的秘诀到底是什么呢?答案说起来很简单 —— 我们正在努力通过数据工程和机器学习把 Tubi 打造成一个模型驱动公司。在这里我们给大家简单介绍一下 Tubi 从数仓基建到机器学习自动化等大数据相关的项目,之后我们也计划围绕各个项目做更多详细的分享。

何为模型驱动?

在大数据时代,“数据驱动”已经成为一个人人必提的概念,那“模型驱动” [1] 是什么呢?对我们来说,模型驱动包含以下三个理念:

  1. 数据是静态的,面向过去的,聚焦在回顾;模型是动态的,面向未来的,专注于前瞻;

  2. 模型驱动公司的每个决策都要经过严谨分析和线上验证,而不是拍脑袋然后去数据湖里钓鱼[2] ;

  3. 模型驱动的核心在于生产化数据科学和机器学习,从大量的实验和反馈中不断的找到优化的方向。

数仓的命门在前端

数据是现代企业的命脉,Tubi 也不例外。我们投入了大量资源搭建和维护一个高质量的数据仓库,其构成了我们业务决策的基石。由于坚信 “垃圾进垃圾出”,我们摒弃了读时模式 (schema on read)[3] 。首先,我们设计了一套和自然语言接近,能够记录用户交互行为的语法。我们使用不同的事件描述各类用户行为,这个设计相对牺牲了一定的灵活性,但是保证了数据质量,从长远看降低了维护成本,增加了我们分析使用这些数据时的信心。

图片

CTO 马老师带我们重温一堂语法课

虽然这一设计大大地提升了事件的信息量,也避免了很多重复事件,但我们每天依然需要处理数十亿条事件。首先,后端数据处理服务把客户端的原始事件从 JSON 格式转换成 protobuf 格式,同时也会进行基本的解析,清洗,以及校验等等。而主要的事件处理是在这之后的数据增强服务 (Scala + Akka),加入多个用户或内容相关的元数据字段。这样在下游进行数据分析时就无需各种复杂的多表间的 JOIN,使人和系统的效率都大幅提升。

图片

事件增强服务架构

从客户端发出的原始事件历经九九八十一难,终于来到它们的归宿 —— 数据仓库。除了存储之外,数仓必须要提供高效率的 ETL 系统来创建和维护众多下游分析所需的聚合,会话,及过滤等种种表和视图。虽然 Spark 的功能很齐全,但是对于大部分分析人员来说,它的复杂度和维护成本都过高。所以我们的数仓只在需要对数据进行复杂处理的个别场景下使用 Spark,而其余绝大部分的需求都通过一个名为 DBT[4] 的工具来实现。这个工具基于 SQL,使很多 Tubi 的数据用户都能够自助地添加他们所需要的表或视图,大大减少了数据工程团队的负担。除此之外,DBT 还提供很多功能让我们快速创建增量视图,把数仓模型变得更小,更明确,更细粒度,甚至还可以自动生成数据沿袭 (data lineage) 图。对于非专家用户来说,这个设计大幅提升了数仓的可用性。

图片

DBT 自动溯源功能

数据同文,合作同轨

仅仅有数据是不够的。在 Tubi 我们还有个统一平台可以查找、处理和分析数据以支持公司的决策。无论你是经验丰富的机器学习博士,还是初入职场的数据分析师,你都需要一套有效的方式方法处理分析数据以及与他人合作。

为了实现一站式的分析,我们在 Kubernetes 上搭建了一个基于 JupyterHub 的数据平台。我们在基础的开源数据工具链之上增加了不少定制化功能,大大提高了公司内部用户的工作效率。这个平台我们称之为 Tubi Data Runtime (TDR)。

TDR 解决的第一个痛点是获取数据的延迟。我们分析数仓使用数据时发现绝大多数查询的结果都在 1GB 以内,这正是 pandas 擅长的领域。但原生 pandas-SQL 接口太慢,而且每个查询都会独占一个连接。为了解决这两个问题,我们在 TDR 里自己实现了 pandas-redshift 接口。通过 python multiprocessing[5] 模块和 Redshift 的 UNLOAD[6] 命令,我们大幅度降低了查询延迟,而且比使用 Spark 查询再运行 toPandas 更快。

可视化也是数据分析不可缺少的一个重要环节。我们为此开发了一个 JupyterLab 扩展,新增了一个 display(df) 函数,让很多简单的数据可视化都无需熟悉 matplotlib 的 API。该功能把 Nteract data explorer[7]直接整合至 JupyterLab 的 Cell 内。把这个可视化扩展和以上提到的 pandas-redshift 接口整合在一起后,大部分基本的数据分析只需一行 Python 代码:"display(df)"。另外,我们也实现了 Tubi 特有的可视化功能以便我们查看和检验推荐结果以及探索内容。

图片

无代码可视化(Jupyter + Nteract Data Explorer)

图片

我们的内容宇宙(Jupyter + Plotly Dash)

最后,为了便于协同工作,我们使用 EFS[8]集中式存储共享 notebooks。为了防止丢失宝贵的分析结果,我们会定期备份这些 notebooks。此外,JupyterLab 的默认界面没有链接分享的功能,因此我们也定制了一个扩展能够生成可分享的 notebook URL。随着 Tubi Data Runtime 使用量的增加,我们还会收集更多的扩展为用户生产效率提供便利。

Tubi Data Runtime 还有不少其他特性。比如 AWS Kinesis 嗅探器用于测试和调试事件流,Spark 集群连接用于处理 TB 以上级别数据,还有 GPU 实例用于深度学习。这些我们会在以后的文章为大家细细解说。

迭代 ——** 唯快不败**

===

不依赖 996 的快速迭代是 Tubi 一直坚持的团队精神。我们的个性化推荐系统的开发过程就非常好的体现了这个理念。为了提升用户体验,我们一直在尝试不同的内容排序算法,用户群体的分类模型,以及诸多其他优化的方向。除此以外,我们还必须考虑到各种全局限制和目标,比如推荐多样性、内容冷启动和商务营销需求等等。每当你打开 Tubi 首页时你看到的都是不同算法和系统组合的结果。

杰夫·贝佐斯有句名言:我们应该尽可能想方设法减少组与组之间的沟通交流,而不是增加。这并不意味着组与组之间不应该资源共享不能够合作,而是要找到正确的技术设计和流程的组合来降低沟通成本。我们的机器学习迭代就是这样的一个例子。之前,推荐系统不同部分的实现在不同的服务上,每个服务都由不同的同事在维护,每次新的实验必须要改动线上的服务。这意味着机器学习组的每次迭代都必须经过多次和后端团队的协调并且依赖后端部署代码到线上系统。这使得每次我们上线 A/B 测试都非常痛苦。

图片

过于紧密的耦合不只是代码设计的忌讳,也是团队合作的痛点

为了解决这个痛点,我们使用 Scala 开发了两个基于 Akka[9] 的 reactive gRPC 服务。其中一个是名为 Ranking Service 的模型服务,它不仅能够提供一个低延迟高扩展性的平台来让我们的个性化模型部署上线,还支持机器学习组独立完成 A/B 测试和版本迭代。Ranking Service 内部使用了 ScyllaDB[10]作为存储,使得我们提供的个性化服务请求在无需内存型缓存的情况下仍然小于30 毫秒。启用了 Ranking Service 之后,新的机器学习实验仅需机器学习组把新的推荐结果塞到 AWS Kinesis 流中然后提供一个新的实验配置,甚至不需要重新部署。

另一个服务是名为 Popper Engine 的 A/B 测试引擎,大大优化了我们从配置、启动到协调的整个实验流程。我们旧版的服务扩展性低,也不能很好地支持我们同时进行多个实验。在参考了 PlanOut[11],Tang et al.[12],还有 Wasabi[13] 等开源软件的实现后,我们发现需要研发我们自己的服务。Popper 不仅能够满足我们当前的需求,而且有足够弹性来支持 10 倍于现状的实验量,并且延时还能够低于 5 毫秒。

图片

实验平台延时

通过 Ranking Service 和 Popper,我们迭代的速度提升了 5 倍,而这仅仅是一个开始。

自动机器学习 ——** 圣杯还是幌子?**

===

虽然市场上充斥着各种海市蜃楼般的炒作[14] ,但不意味着机器学习和人工智能没有真正的价值。那些平平无奇但能够有效地帮助企业使用机器学习的基础产品,反而是最有趣的技术创新。

除了在线服务之外,一个成功的线上机器学习平台还需考虑到更多组件。对于一个机器学习工程师来说,从有一个想法到在线上实现往往是一个令人怯步的复杂流程。他必须对数据进行分析,从多个数据源中提取特征,把特征整合进模型,对这个新的模型作线下评估和调试,最后才能推到线上进行 A/B 测试。

图片

机器学习迭代周期示意图

那么我们如何去简化这个流程呢?一、特征仓库应该在新特征加入的同时旋即自动创建候选模型来整合新加入的特征。二、模型管理系统应该对这些新的候选模型自动进行线下评估和优化。三、最优的候选模型产生后只要算法工程师审核后即可发布新的 A/B 测试到线上环境。四、我们最后还需要做好对于模型的端到端追踪,才能够支持模型监控系统去选择最优的版本。我们正在搭建这样一个“人类驾驶,机器辅助” 的自动化机器学习平台。

===

展望

过去的十年,软件吞噬了这个世界[15]。在接下来的十年,模型将主宰世界[16]。这个结构性变化对于不适应模型驱动的公司将会是一次降维打击。而 Tubi 的经验证明了只要做好准备,即使没有大公司的资源或者市场垄断能力,一个独立的小公司还是可以成功的。这一结构性变化促使我们不断解决从构建工业级分析系统到自动化机器学习实验平台等等极具挑战的问题。我们的旅程才刚刚开始,也希望和大家通过文章有更多的交流。如果你是一个热爱技术,享受挑战,谢绝 996,看重全局影响力的工程师,请加入我们这个小而精的团队吧!

图片

原文:Chang She, Tubi VP of Engineering,点击 “阅读原文” 查看英文版

译者:Huihua Zhang, Tubi Senior Data Engineer

图片