在文章正式开始前,先看一下术语说明:
实现端到端的机器学习(ML)生命周期的自动化,即使是对于一个特定的预测任务,也是一件既不容易也不明确的事情。人们一直在谈论机器学习工程(MLE)是软件工程的一个子集,或者应该被这样对待。但在过去15个月的博士研究生阶段,我一直在通过数据工程的视角来思考MLE。
有两种类型的关键业务机器学习工程师(MLEs)。第一种是任务型机器学习工程师(Task MLEs),他们负责在生产中维持一个特定的ML管道(或一小套ML管道)。他们关注关键业务任务的特定模型。他们是那些在顶线指标下降时被呼唤的人,负责“修复”一些东西。他们是最有可能告诉你一个模型最后一次被重新训练是什么时候,如何被评估的人,等等。
Task MLEs 有太多的事情要做。数据科学家对模型进行原型设计并提出功能想法,而 Task MLEs 需要将其“生产化”。这需要编写管道,将数据转化为模型输入,训练和重新训练模型,评估模型,并将预测结果输出到某个地方。然后,Task MLEs 需要负责部署,这通常需要一个分阶段的过程,包括测试、上线等流程。然后,Task MLEs 需要做“监控”,快速诊断和应对 ML 相关的错误。
我曾经是一个 Task MLE。我做了所有这些事,非常糟糕。当我离开公司去读博士,进行工作交接的时候,我花了大约一个月的时间来创建详细的笔记,详细描述端到端ML生命周期是如何运作的。在写文档的时候,我经常想为什么我当时要这样做,比如为什么在模型重新训练的时候,训练集会自动刷新,而评估集却保持不变,需要我去手动刷新它?我从来没有想过要在科学上不严谨,但我经常遇到自己模型开发过程中的实验代码,其中模型训练时的假设在评估阶段并没有继续保持,更不用说之后的部署上线了。
有时,我的科学性太强,以至于企业亏损。我把一个超参数调整程序自动化,根据时间把训练和验证集分成许多折(多折交叉验证),并挑选出在所有集上平均表现最好的超参数。我只是在事后才意识到这是多么愚蠢。我应该选择在最新评估集中产生最佳模型的超参数。
我现在对生产机器学习(Production ML)做了足够的研究,知道对最新的数据进行简单的过度拟合并不断重新训练是一种有效提升模型效果的小技巧。成功的公司都是这样做的。
当人们说小公司不能每天重新训练,因为他们没有像 FAANG(即Facebook, Amazon, Apple, Netflix, Google)巨头的预算时,我很困惑。重新训练许多 xgboost 或 scikit-learn 模型最多也就花几美元。大多数模型都不是大型语言模型。我在做 ML 监测研究时,迂回地了解到这一点。我问过许多小公司的 Task MLEs,他们是否以及如何监测他们的管道的分布偏移(distribution shifts)问题,他们中的大多数都提到了每小时、每天或每周的重新训练计划。
“我知道这并没有真正解决数据漂移(data drift)的问题”,一个 Task MLE 曾经羞涩地告诉我,就像他们坦白了一个他们不敢在绩效评估中写的秘密。
“模型的性能回升了吗?”,我问道。
“嗯,是的… ”,他拖长了声音说到。
“那么它是在解决数据漂移问题”,我实事求是地说,带着一种身为研究人员的膨胀的自信。
像这样的轶事真的让我心烦意乱。我想这是因为我认为重要而有趣的问题,现在只剩下有趣了。研究人员认为分布偏移(distribution shift)非常重要,但源于自然分布偏移的模型性能问题在重新训练后突然消失了。
我很难在数据漂移中找到有用的事实,即实际问题。现在看来很明显:数据和工程问题——突然的漂移的情况——引发了模型性能的下降。有可能是昨天生成内容相关特征的工作失败了,所以我们只能用旧的内容相关特征。有可能是一个数据源被破坏了,所以一堆特征变成了空值。有可能是是这样,有可能是是那样,但最终的结果都是一样的:数据看起来不同,模型表现不佳,业务指标受到影响。
现在感觉是介绍第二种机器学习工程师的好时机:平台型机器学习工程师(Platform MLEs),他负责帮助 Task MLEs 将他们工作的繁琐部分自动化。Platform MLEs 建立管道(包括模型),支持多个任务,而 Task MLEs 解决具体的任务。这类似于,在软件工程师世界中,建立基础设施与在基础设施之上建立软件。但我称他们为 Platform MLEs,而不是 Platform SWE,因为我认为如果不对 ML 有足够的了解,就不可能实现 ML 完全的自动化。
当一个组织有一个以上的 ML 管道时,对 Platform MLEs 的需求就会实现。Platform MLEs 和 Task MLEs 区别的一些例子包括一下几点:
Platform MLEs 负责创建功能的管道;Task MLEs 负责使用功能的管道;
Platform MLEs 负责训练模型的框架;Task MLEs 负责为模型架构和重新训练计划编写相应的配置文件;
Platform MLEs 负责触发 ML 性能下降警报;Task MLEs 负责对警报采取行动。
Task MLEs 并不只存在于那些渴望达到 FAANG 规模的公司。它们通常存在于任何拥有一个以上 ML 任务的公司。这就是为什么,我认为,机器学习运营(MLOps)目前被猜测为非常有利可图的部分。每个 ML 公司都需要功能、监控、可观察性等等。但对于 Platform MLEs 来说,自己构建大部分的服务是比较容易的:(1) 写一个管道,每天刷新特征表;(2) 在所有 ML 工具中使用标准化日志;(3) 保存数据集的版本信息。具有讽刺意味的是,MLOps 初创公司试图用付费服务取代 Platform MLEs,但他们却要求 Platform MLEs 将这些服务整合到他们的公司。
作为一个旁观者,一些 MLOps 公司试图向 Task MLEs 销售服务,但 Task MLEs 忙于照看模型,无法经历销售周期。照看模型是一个艰难的工作,需要大量的注意力和关注。我希望这种情况在未来会有所改变。
此刻,我最吸引我的 Platform MLEs 职责是监测和调试突然发生的数据漂移问题。Platform MLEs 有局限性,即他们不能改变与模型相关的任何东西(包括输入或输出),但他们却需要负责找出它们在什么时候以及如何被破坏掉了。最先进的解决方案是监测各个特征(即输入)和模型输出的覆盖率(即缺失部分)和分布随时间的变化。这就是所谓的数据验证。当这些变化超过某个阈值时(例如,覆盖率下降25%),Platform MLEs 会触发警报。
数据验证实现了巨大的召回(Recall)。我敢打赌,至少有95%的突然漂移,主要是由工程问题引起的,会被数据验证警报所捕获。但是,它的精确性(Precision)很差(我打赌大多数任务的精确性低于20%),而且它需要一个 Task MLEs 来列举所有特征和输出的阈值。在实践中,精度可能更低,因为 Task MLEs 有警报疲劳症,并使大多数警报保持沉默。
我们可以用牺牲召回率的方式来换取精度吗?答案是否定的,因为高召回率是监控系统的全部意义所在。为了捕捉bug。
你必须监测每个功能和输出吗?不,但警报需要在一个列的层面上,否则它们对 Task MLEs 来说将是不可操作的。例如说PCA成分#4漂移了0.1是没有用的。
你可以通过触发重新训练来忽略这些警报吗?不能,对无效数据进行重新训练是没有价值的。
有一段时间,我认为数据验证是 ML 指标(如准确率 accuracy、精确率 precision、召回率 recall)监测的代理。由于缺乏数据真实的标签,ML 指标监测几乎不可能实时进行。许多组织只在每周或每月的基础上获得标签,这两种情况都太慢了。此外,不是所有的数据都有标签。所以剩下需要监测的就只有模型的输入和输出了,这就是为什么每个人都输入输出监控的原因。
我错得不能再错了。假设 Task MLEs 有监测实时 ML 指标的能力,此时数据验证仍然是有用的,原因如下:
其一,不同任务的模型可以从相同的特征中读取。如果一个 Platform MLEs 能正确地触发一个特征损坏的警报,那么多个 Task MLEs 都能受益。
其次,在现代数据栈时代,模型特征和输出(即特征存储)经常被数据分析师使用,因此需要保证数据的正确性。我曾经在 Snowflake 中匆忙地执行了一堆查询,却没有意识到一个与年龄有关的列中有一半是负值,并无耻地将这些信息介绍给了一位 CEO。
我了解到,犯这种错误是可以的。大数据可以帮助你讲述你想要的任何故事,无论对错。唯一重要的是,你要坚定不移地坚持自己不正确的见解;否则人们会怀疑你的能力。别人又不会审查你在 Untitled1.ipynb 中的使用 Pandas 数据框架的技巧。他们不会知道你已经搞砸了。
我希望上面那段话是个谎言。我只是在半开玩笑。
对 ML 数据和模型质量的保证(即服务级目标,简称 SLO)的需求把我带到了我第一年研究的核心:MLE的角色,无论是任务型还是平台型,都是为了确保这种 SLO 被满足。这让我想起了数据工程,比其他任何角色都更有意义。简单地说,数据工程师负责将数据浮现给其他员工;ML 工程师负责确保这些数据及其附属应用(如ML模型)不是垃圾。
我想了很多关于拥有良好的模型质量意味着什么。我讨厌质量这个词。这是一个定义模糊的术语,但现实是,每个组织都有不同的定义。许多人认为质量意味着 “不陈旧”,或者确保特征生成管道每次都能成功运行。这是一个好的开始,但我们也许应该做得更好。
通过数据 SLO 的视角,数据验证是一个成功的概念,因为它以二进制的方式明确定义了每个模型输入和输出的质量。要么特征至少有一半缺失,要么没有。要么年龄是正数,要么不是。要么记录符合预定义的模式,要么不符合。要么满足 SLO,要么不满足。
假设每个组织都能明确定义他们的数据和模型质量 SLO 。在 ML 环境中,我们应该在哪里验证数据?传统上,以数据为中心的规则是由DBMS 执行的。在介绍 Postgres 数据库的论文中,Stonebraker 简明扼要地阐述了数据库执行规则的必要性:规则很难在应用层执行,因为应用通常需要访问比交易所需更多的数据。例如,论文中提到一个雇员数据库,其规则是Joe和Fred需要有相同的工资;与其让应用程序查询Joe和Fred的工资,并在每次需要Joe或Fred的工资时断言相等,不如在数据管理器中强制执行。
一年前,我的导师告诉我“保证 ML 管道健康需要约束和触发器”这句话,尽管我并不完全理解其中的含义,但还是记住了。作为一个前 Task MLE,我认为这意味着用代码来记录平均值、中位数和各种输入和输出的聚合,并在数据验证检查失败时抛出错误,这些都是我在工作中做的事情。
现在,我有了更多作为 Platform MLEs 的经验,我认为 Task MLEs 不应该做这些事。Platform MLEs 拥有数据管理能力,而 Task MLEs 拥有应用能力或负责ML管道的下游部分。Platform MLEs 应该在特征表中执行规则(例如,数据验证),以便 Task MLEs 在查询时被提醒是否有任何错误。Platform MLEs 应该执行触发器,就像 Task MLEs 在向客户展示预测结果之前对其进行的各种临时后处理。
我也想了很多关于如何让人们更容易理解“模型质量”。组织上对模型质量的具体定义有助于解释为什么 ML 公司有自己的 Production ML 框架(例如:TFX),这些框架有些是开源的,有些是封闭的。许多新的框架正在出现,作为 MLOps 初创公司的一部分。
我曾经认为,人们不会切换到一个新框架的原因是重写所有管道代码很麻烦,这种思想是正确的,但 webdev 生态系统是一个反例:如果人们得到好处时,他们会重写代码。唯一的区别是,目前的 ML 管道框架很少是独立的,不能轻易插入各种数据管理后端。
ML 管道框架需要与了解 ML 工作负载的 DBMS 紧密耦合,DBMS 需要知道 Task MLEs 想要什么类型的触发器,了解数据验证和调整警报,以具有良好的精确率和召回率,并且保证一定的可扩展性。也许这就是为什么我最近与许多人交谈时,似乎正在转向 Vertex AI(一个类似数据库一样,可以做任何事情的服务)。
对这一切做研究感觉很奇怪。它不像我的许多朋友的博士学位,在那里我应该提出一系列科学问题,并进行一堆实验来得出结论。我的博士论文感觉更像是一种探索,在那里我研究数据管理是如何运作的,成为一个工艺的历史学家,并试图提出关于它将如何在 MLE 生态系统中发挥作用的观点。它感觉是接地气的理论,我不断地根据我学到的新信息来更新我的观点。
说实话,感觉我在频繁地改变自己的想法,这让人很不舒服;我不知道到底该怎么描述。一个我很亲近的人告诉我,这就是研究的本质。我们在一开始就不知道所有的答案,更不用说问题了,但我们会制定一个过程来发现它们。然而,为了我的理智,我期待着我什么时候能少改变我对 Production ML 的想法。
— 推荐阅读 —
《新程序员001-004》已全面上市
扫描下方二维码或点击进入立即订阅