可靠的机器学习-全-
可靠的机器学习(全)
原文:
zh.annas-archive.org/md5/e0fcd9b08053b09b5e6dd11695380687译者:飞龙
序言
机器学习(ML)是一波巨大的技术创新浪潮的核心,这股浪潮只是刚刚开始。ML 继续延续了 2000 年代“数据驱动”浪潮留下的痕迹,ML 使一种新的 基于模型 的决策模式成为可能,承诺通过让机器根据最新信息,在互动点上做出几乎即时、高保真度的决策来改进组织绩效并增强客户体验。
为了支持 ML 模型的高效使用,机器学习实践不得不迅速从主要学术追求演变为一门完全成熟的工程学科。曾经只是研究员、研究科学家和数据科学家的专属领域,现在至少同样由 ML 工程师、MLOps 工程师、软件工程师、数据工程师等来负责。
在机器学习角色演变中,我们看到的部分健康变化在于,我们不再仅仅试图让模型正常运行,而是确保它们以满足组织需求的方式运行。这意味着构建允许组织高效生产和交付模型的系统,加强其抵御故障的能力,使其能够从任何发生的故障中恢复,并且最重要的是,在从一个项目到下一个项目的学习循环中帮助组织不断改进。
幸运的是,机器学习社区并没有从头开始就必须自行启动完成所有这些所需知识的过程。被称为 MLOps 的实践者们已经受益于通过传统软件项目的 DevOps 实践发展起来的广泛知识。
MLOps 的第一波浪潮集中于将技术和流程纪律应用于模型的 开发 和 部署,使机构能够更好地将模型从“试验室”移植到“工厂”,以及支持 ML 生命周期这些阶段的工具和平台的激增。
但是 MLOps 中的操作如何?在这里,我们再次受益于传统软件系统操作方面取得的进展。推动发展 DevOps 运营方面的重要因素是该社区对网站可靠性工程(SRE)的广泛认识和应用,这是在 Google 和许多其他组织中开发的一套原则和实践,旨在将工程学原则应用于操作大规模、关键任务的软件系统的挑战中。
将软件工程方法应用于机器学习并不是一件简单的事情。虽然可以从彼此那里学到很多,但实践中的关注点、挑战和解决方案可能会有相当大的不同。这就是本书的价值所在。作者们的目标不是让每个个体或团队自行确定如何将 SRE 原则应用于他们的机器学习工作流程,而是通过分享在谷歌、苹果、微软和其他组织中实际工作的成功经验,为您提供一个快速入门的机会。
说作者们在他们的任务上非常称职,一点也不为过。多年来,我的工作受到了几位作者的深刻影响和启发。
2019 年秋季,我组织了第一届 TWIMLcon:AI 平台会议,为当时新兴的 MLOps 社区提供了一个交流经验、推进构建流程、工具和平台以支持端到端机器学习工作流的场所。在我们内部,成为一个小小的笑话,我们在活动中看到多少演示展示了 D. Sculley 在其开创性论文《机器学习系统中的隐藏技术债务》中的“现实世界 ML 系统”图表。¹
在我们的第二次会议上,2021 年,Todd Underwood 加入我们,分享了“当好模型走错路:流浪模型造成的损害及其预防方法”。² 这次演讲分享了对大约 100 起事件的手动分析结果,这些事件在 10 年中跟踪记录,其中坏的 ML 模型成功或几乎成功进入生产环境。
后来,我很荣幸在《TWIML AI Podcast》上采访了 D.,标题为“机器学习中的数据债务”。³ D. 和 Todd 在这些交流中分享的丰富经验在本书中表现得淋漓尽致。
如果你来自 SRE(Site Reliability Engineering)的角度,Niall 无需介绍。他的书《Site Reliability Engineering》和《The Site Reliability Workbook》在 2016 年及以后帮助推广了 SRE,深受 DevOps 从业者的喜爱。
(尽管我之前没有接触过 Cathy 和 Kranti 的工作,但显然,她们在构建 SRE 组织和推动面向消费者大规模应用 ML 方面的经验,影响了本书的许多方面,尤其是关于实施 ML 组织和将 ML 集成到产品中的章节。)
这本书提供了一个宝贵的视角,讲述了作者在构建、运营和扩展一些最大的机器学习系统中的经验。
作者们避免了陷入试图记录一组静态架构、工具或建议的陷阱,因此成功地提供了更多内容:对团队在构建和操作——以及可操作——机器学习系统时必须导航的广泛复杂性和各种考虑的调查,以及作者们通过自己广泛的导航工作收集到的原则和最佳实践。
他们在文本的早期就明确了目标:“列举出足够的复杂性,以阻止任何读者简单地认为…‘这些东西很容易’。”
如果我们作为一个社区在过去几年中学到了什么,那就是以高效、可重复、可扩展的方式创建、交付和操作机器学习模型绝非易事。我们还学到,由于其乐于分享经验并建立在他人学习基础上的能力,机器学习社区能够迅速进步,今天困难的事情明天就变得容易起来。我很感激 Cathy、Niall、Kranti、D. 和 Todd,因为他们让我们所有人都从他们辛苦获得的经验中受益,并在这个过程中帮助推动了机器学习在生产中的发展。
Sam Charrington
TWIML 的创始人,The TWIML AI Podcast 的主持人
¹ D. Sculley 等人,“机器学习系统中的隐藏技术债务”,《神经信息处理系统进展》(2015 年 1 月):2494-2502。https://oreil.ly/lK0WR。
² Todd Underwood,“当好的模型走上歧途:偏离模型造成的损害及其预防方法”,TWIMLcon,2021 年,https://oreil.ly/7pspJ。
³ D. Sculley,“机器学习中的数据债务”,由 Sam Charrington 主持的《The TWIML AI Podcast》采访,2022 年 5 月 19 日,https://oreil.ly/887p4。
前言
这不是一本关于机器学习工作原理的书籍。这是一本关于如何让机器学习为您工作的书籍。
机器学习(ML)的工作方式非常迷人。围绕和支持 ML 的数学、算法和统计见解本身就很有趣,当它们应用于正确的数据时,所能实现的效果简直像是魔法一般。但是我们在本书中做了一些不同的事情。我们不是算法导向,而是整体系统导向。简而言之,我们谈论除了算法以外的一切内容。许多其他作品详细介绍了 ML 算法部分,但这本书有意专注于 ML 的整个生命周期,给予了它在其他地方并没有真正获得的时间和关注。
这意味着我们谈论了在正确和负责任地引导数据、可靠的模型构建、确保顺畅(且可逆)的生产路径、更新安全性以及关于成本、性能、业务目标和组织结构的担忧中涉及的混乱、复杂和偶尔令人沮丧的工作。我们试图涵盖让 ML 在您的组织中可靠发生的一切内容。
为什么写这本书
我们坚定地相信至少一些炒作:ML 和 AI 技术目前以加速的速度重塑着计算和社会。在某些方面,公众炒作还没有跟上私人现实的步伐。¹ 但我们也足够理性和经验丰富,了解到许多真实世界的 ML 系统实际上是多么令人难以信赖和有问题。技术媒体写着太空飞行,而大多数组织仍然难以保持自行车的稳定性;这些仍然是早期阶段。现在正是积极关注 ML 能够做什么以及您的组织如何从中受益的完美时机。
尽管如此,我们认识到许多组织担心错过 ML 以及它对组织可能带来的影响。好消息是,没有必要恐慌——现在就可以开始,并且可以明智和有纪律地处理与 ML 相关的工作,以成功地平衡义务和回报。坏消息是,许多组织之所以担心的原因在于复杂性曲线非常陡峭。一旦您超越了较简单的方面,许多技术和技术正在刚刚被发明,很难找到一个坚实的、铺好的道路。
本书应该帮助您应对这种复杂性。我们认为,尽管行业尚不成熟,但专注于简单性和标准化仍有很多收获,这种方法有助于更容易上手。最终,深度整合机器学习到业务中的组织将会受益——有些甚至很大程度上²——但当然,他们需要一定的复杂度来理解如何达成这一点。一个简单、标准化的基础将有助于比临时实验或者更糟糕的是一个虽然有效但没人知道如何及为何有效的系统更好地发展这种能力。
作为 ML 的 SRE 视角
已经存在大量的机器学习书籍,其中许多承诺以某种方式改进您的机器学习之旅,通常集中于使其更容易、更快速或更高效。然而,很少有书籍谈及如何使机器学习更可靠,这一属性经常被忽视或低估。³ 这正是我们关注的内容,因为通过这一视角看待如何优化机器学习具有特定的好处,其他方式所无法得到。事实上,当前的最佳实践并不直接适用于从头到尾做好机器学习的挑战。相反,通过站点可靠性工程(SRE)的视角——全面、可持续地,以客户体验为中心地看待这些问题——是更好的框架,以理解如何应对这些挑战。
您可以在构建安全可靠系统(Heather Adkins 等著,O’Reilly,2020)中找到类似的论证。一个不可靠的系统往往会被攻击者利用为系统访问的入口——安全性和可靠性密切相关。做好其中一个很难脱离另一个。同样,机器学习系统因其意外行为和间接但深远的相互关系,促使我们采用更全面的方法来决定如何整合开发、部署、生产运营和长期维护。
简而言之,我们认为,机器学习系统的可靠性捕捉了顾客、业务所有者和员工真正希望从中获得的要点。
预期读者群
我们写作的对象是希望将机器学习应用于现实世界并在组织中产生影响的任何人。因此,本书适合数据科学家和机器学习工程师,适合软件工程师和站点可靠性工程师,以及组织决策者,甚至是非技术人员,尽管本书的部分内容相当技术性:
数据科学家和机器学习工程师
我们将探讨数据、特征和模型架构的选择如何改变您的模型运行方式,以及从长远来看如何管理它们,所有这些都是为了提升模型的速度。
软件工程构建机器学习基础设施或将机器学习集成到现有产品中
我们不仅解决了如何将机器学习整合到系统中,还解决了如何编写机器学习基础设施的问题。更好地理解机器学习生命周期如何有助于开发功能、设计应用程序接口(API)并支持客户。
网站可靠性工程师
我们将展示机器学习系统通常出现的故障以及如何最好地构建(和管理)它们,以避免这些故障模式。我们还将探讨机器学习模型质量不是完全可以被可靠性工程师忽视的影响。
希望将机器学习添加到其现有产品或服务中的组织领导者
我们将帮助您了解如何最好地将机器学习整合到您现有的产品和服务中,以及所需的结构和组织模式。在做出与机器学习相关的决策时,理性评估风险和优势是重要的。
所有对开发和部署机器学习的道德、法律和隐私影响感到合理关注的人士
我们将清晰地阐述问题,并指出在这些问题导致对用户或组织造成损害之前,您可以采取的实际步骤。
有一点可能反直觉的是:许多章节对那些不是该章节主题的人可能更有价值。例如,第二章当然可以被数据科学家和机器学习工程师阅读。但对基础设施/生产工程师和组织领导者来说,它可能更有用。对于前一组,当然,对您已经在工作的内容进行微调是有用的,但对于后者来说,它可以为可能全新的主题领域提供一个新鲜而完整的介绍。
本书的组织结构
在我们详细讨论书籍结构之前,让我们提供有关我们如何选择主题及其组织的更广泛背景。这可能不是您所期望的。
我们的方法
工程师需要采用特定的方法和技术来使机器学习系统运行良好。但是,一旦在特定组织和特定目的中实施了这些方法,每种方法都会面临大量的决策。本书不可能覆盖读者通常会面临的所有或大多数实施选择。同样地,我们将减少对特定软件片段的具体建议。我们希望通过与日常工作的分离来更清晰地表达观点,但对于这种类型的书籍来说,保持平台不可知是有益的。
让我们开始吧!
尽管我们不时使用其他示例,但我们用来说明本书内容的主要方法是一个假想的在线商店——一个通过名为yarnit.ai的网站销售纺织用品的商家。这个概念在整本书中都有详细阐述,以展示一个阶段(比如数据获取或规范化)的选择对整个技术栈、业务等的影响。
这家店铺是一个单一的、相对简单的业务(购买编织和钩针产品,将它们放在网站上,并向客户进行市场营销和销售)。这显然不能完全反映出真实世界中使用机器学习的各个行业的复杂性,如制造业、自动驾驶汽车、房地产营销和医疗技术。然而,我们的例子提供了足够的洞察力(并管理了范围),使我们认为我们在这里处理的实施复杂性能够为其他领域提供可应用的教训。(换句话说,我们相信我们的例子的局限性是值得的。)
为了更深入地探讨这个例子,让我们考虑一个零售商从大量供应商采购产品,并在网站上全球销售给公众的情况。业务是吸引并维持一个购买产品、以合理利润覆盖网站运营成本并实现利润的客户群体。从某些方面来看,这是一个相当简单的业务,但复杂性几乎立即体现出来,尤其是在我们尝试添加机器学习时。在高层次上,我们关注的是提高销售、改善客户体验、降低成本、提高利润率以及使整个业务运作更加高效。
虽然最初将机器学习技术引入业务运营通常是出于狭隘和具体的目标,比如提高效率,但这并不是终点。机器学习有可能从根本上积极或消极地改变业务,改变产品的创建和选择方式、客户的识别和服务方式以及商业机会的发现方式。成功部署这些技术的采用机器学习的企业在长期内将超过竞争对手;一项由麦肯锡进行的针对超过 2,000 名高管的最新调查显示,63%的高管的机器学习/人工智能项目改善了底线,尽管组织通常对具体的改善幅度保持缄默。但在短期内,采用必须从“提高转化率”等具体而可理解的目标开始。
我们的网站yarnit.ai有许多数据来源可以实施这些初步、具体的改进和许多机器学习的潜在应用。首先,我们将考虑客户面向的例子,例如推荐(客户可能喜欢的其他产品)和预测(对于特定客户,哪些产品最有可能销售)。然后我们将转向更多在幕后的应用,例如机器学习可能被用来优化整个业务流程。具体来说,我们将通过几个例子展示机器学习如何改进我们的运营,尽管当然不限于这些需求:
网站搜索结果
客户应该在他们的搜索查询中获得最佳排名,显示出最符合这些术语并且他们最有兴趣购买的产品。
发现和建议
客户应该有机会考虑与他们正在查看或购买的产品相关的其他产品。我们可以找到可能有很高使用可能性的产品,因此被购买。
动态定价
我们应该识别那些销售速度不如预期的产品,并降低它们的价格,以清理仓库空间。同样地,如果我们对极受欢迎的产品库存紧张,我们可能需要暂时提高它们的价格以减缓销售并赚取更多利润,同时可能需要订购更多库存。
购物车遗弃
是什么促使客户将商品加入购物车但没有完成购买?我们能预测吗?有没有办法学习如何通过提醒、适时的折扣或其他提高结账完成率的功能进行干预?
库存和订购自动化
我们可能希望利用机器学习来预测如何从供应商那里订购替换产品,基于未来销售的预测和预计的交货延迟。
信任和安全
这是一个行业通用术语,用于检测可能的欺诈行为——在这种情况下,尝试的购买行为,并根据需要增加验证步骤。手动审查和启发式方法不会扩展,因此求助于机器学习是合理的选择。
边际改善
我们可以使用各种技术来试图提高每次销售的利润——从在顾客购物时建议额外高利润产品,到进行营销活动以创造更多对最高利润产品的需求。
这些只是机器学习可能被试验的一些明显场所,以确定其是否为增加的复杂性和成本带来的价值。明确地说:机器学习并不总是成功的,即使它成功了,它也不一定值得麻烦。建立一个具有严格数据格式、重要工程和专业生产操作要求的复杂管道是一个成本高昂的工作,需要为客户和业务带来明显和确定的价值。维护成本也相当可观。对于你的组织来说,所有这些努力可能都不值得。这本书将帮助你理解是否值得。
像我们的毛线商店这样的组织应该以开放的心态,但愿意实验、测量,并可能在不起作用时取消应用机器学习。这就是为什么在对商店网站基础设施进行不可逆变更之前计划评估成功概率至关重要。
为了完整起见,我们需要说,显然这只是可能发现机器学习用途的一种组织和应用的单一示例。
导读本书
我们从介绍和一般原则开始。在这里,相对于机器学习(或者机器学习在生产中)的新手可以对整个问题空间进行定位。这也是我们涵盖影响所有后续章节的关键主题的地方,如数据管理,什么是机器学习模型,如何评估其质量,特征是什么(以及为什么你会在意),以及公平性和隐私问题。
接下来,我们关注机器学习模型及其生命周期。我们解释了模型是如何创建(称为训练)和在生产中使用(称为服务)的。我们概述了了解您的模型在开发和运行时正在做什么以及如何做到这一点的重要性。在本节的最后,我们讨论了持续机器学习的问题:模型持续更新,以反映不断调整的现实。
最后,我们涉及了一个复杂的问题,即机器学习如何被引入到组织中,以及在这种情况下它们会发生什么变化。我们从具体的例子开始介绍机器学习在事件响应领域的复杂性,我们期望每个负责生产的工程师都能理解。我们探讨了关于组织如何将机器学习整合到现有(和新兴)产品中的一些关键问题,这通常是一个需要提前深思熟虑的过程。然后我们看看机器学习在组织中如何实施:集中化、分布式以及介于两者之间的各种点,接着在下一章提出了具体的指南和建议。最后,我们以全球组织中实施机器学习的真实案例结束。
经过所有这些,首先,你应该休息一下——但第二,你应该有充分的准备去理解你第一次进行机器学习时或者在你已经有经验的情况下,在你的组织内部如何精细化其工作中可能遇到的一切。
关于作者
这本书的作者们共同拥有数十年在生产环境中构建和运行各种类型机器学习系统的经验。我们参与过大规模广告定向系统的产品化;建立过大型搜索与发现系统;在机器学习在生产中的开创性研究上有过贡献;并构建和运行了围绕它们的关键数据摄入、处理和存储系统。我们共同亲眼见证了这些系统在各种惊人而迷人的方式下可能发生故障。但好消息是,我们学会了如何构建对机器学习系统最常见故障模式具有弹性的系统——无论是技术上还是组织上。
本书使用的惯例
本书使用以下排印惯例:
Italic
指示新术语、网址、电子邮件地址、文件名和文件扩展名。
Constant width
用于程序清单,以及段落内引用程序元素,如变量或函数名称、数据库、数据类型、环境变量、语句和关键字。
Constant width bold
显示应由用户直接输入的命令或其他文本。
Constant width italic
显示应由用户提供值或根据上下文确定的值的文本。
提示
此元素表示提示或建议。
注意
此元素表示一般性注释。
警告
此元素表示警告或注意事项。
致谢
作者们想借此机会感谢以下人士。
我们还要集体感谢本书的以下贡献者:Ely M. Spears,在本书的许多章节中提供了宝贵的技术和结构反馈,谢谢您帮助这本书变得更好。Robbie Sedgewick 也提供了类似的反馈,以及在我们觉得写的内容可能不会引起普通读者共鸣时的鼓励。James Blessing 迅速审阅了多个章节,并提供了有益的反馈,帮助我们改进。我们还受益于 Andrew Ferlitsch、Ben Hutchinson、Benjamin Sloss、Brian Spiering、Chenyu Zhao、Christina Greer、Christopher Heiser、Daniel H. Papasian、David J. Groom、Diego M. Oppenheimer、Goku Mohandas、Herve Quiroz、Jeremy Kubica、Julian Grady、Konstantinos (Gus) Katsiapis、Lynn He、Michael O’Reilly、Parker Barnes、Robert Crowe、Salem Haykal、Shreya Shankar、Tina H. Wong、Todd Phillips 以及 Vinsensius B. Vega S. Naryanto 细致、周到的审阅。最后,也要感谢我们在 O’Reilly 的团队:John Devins、Mike Loukides、Angela Rufino、Ashley Stussy、Kristen Brown 和 Sharon Wilkey。
Cathy Chen
感谢我的伴侣 Morgan,在我需要周末或晚上工作时一直给予爱的支持。我责怪 Todd 把我拉入这个项目,但不仅要感谢他在这个项目中的出色领导,还要感谢他给我一个很好的工作场所。感谢所有的合著者和我们那些出色的志愿者们,他们在审阅、编辑、评论以及帮助我们改进这本书方面做出了重要贡献。
Niall Richard Murphy
我将这本书献给在书写期间去世的人们。在写作这本书的时候——甚至在我将它写下来的时候,我仍然很难相信——我们都经历了全球流行病、欧洲的选择性战争以及许多政治、个人和职业事件,虽然我常常希望不是这样,但这场暴风雪似乎没有停下的迹象。因此,在此我想追忆我的父亲的继母 Winifred,她于 2020 年因 COVID-19 不幸离世,以及我在 2021 年在贝尔法斯特去世的姑姑 Esther Gray,她备受想念。在我们身边仍然健在的人中,我要感谢我母亲 Kay Murphy,她是我所能拥有的最好的母亲,在黑暗时期是一束光明的道德光芒,还有我的妻子 Léan 和我的孩子们 Oisín 和 Fiachra。自从上一次感谢部分以来,Oisín 成为了国家 U19 象棋冠军,Fiachra 的艺术作品也被收录在另一本书中,他们的父亲会永远为他们感到骄傲。最后,我还要感谢 Todd Underwood 本人,他在同样艰难的时期展现出了持续的幽默领导力。这个项目的存在归功于他,超过其他任何人。我学到了很多,发现自己知道的比想象中多,但很多我学到的东西都是从他那里学到的。
Kranti Parisa
我将这本书献给所有在 COVID-19 危机中的一线和必要工作者,他们是我们的英雄。他们对工作和人类的无比奉献真是鼓舞人心。我要感谢所有合著者和贡献者,因为他们的非凡承诺和耐心。特别感谢 Todd Underwood——你是这本书背后的伟大灵感来源。我要感谢我的朋友 Dave Rensin,让我参与这个了不起的机会,并激励我与世界分享我在大规模构建 ML 系统方面的知识和经验。最后,感谢我的父母,特别是我的母亲 Nagarani,我的妻子 Pallavi,我的小公主 Sree,以及我的朋友们,感谢他们不断的爱和支持。
D. Sculley
我要感谢我的杰出合著者和许多教给我的同事们——与我一起经历了所有的生产火灾和棘手问题。我的妻子 Jessica 和女儿 Sofia 依然是我做任何事情的灵感来源。
Todd Underwood
我将这本书献给我的家人,他们在我写作时要么受益,要么为我长时间的缺席买单。Beth、Ágatha 和 Beatrix:我不认为你们会读到这些,但我希望你们终于为我完成了这本书感到高兴。我也将它献给我的兄弟 Adam,在一场大流行中去世,我没有像希望的那样经常见到他。最后,也要感谢我的合著者们,在这个看似永远无法完成的项目中坚持不懈。我希望我们在这里做了一些有价值的事情——一些有用的,我们可以为之感到自豪的事情。
¹ 参见 “AI 和机器学习实践中的 27 个令人惊讶的例子”,Bernard Marr 提供的例子可能会让你感到惊讶。这篇 2018 年的福布斯文章在机器学习领域已经是古老的历史,而行业在多个行业和应用领域持续扩展。目前有着无数不合理的机器学习/AI 炒作,但同时也有更多实际有效的应用涉足比大多数人认识到的更多行业。
² 参见谷歌云报告 “机器学习的商业影响”,这段摘录或许是最大的原因:“标准的机器学习项目在首年实施后的投资回报率通常在两到五倍之间。”
³ 或者换个角度说,关于如何构建一个机器学习模型的材料很多,但是关于如何构建一个机器学习系统的却很少。一个模型的可靠性问题可能与系统有所不同。
第一章:介绍
我们从一个模型或框架开始,用于向网站添加机器学习(ML),广泛适用于多个领域,不仅限于这个例子。我们称这个模型为ML 循环。
ML 生命周期
ML 应用永远不会真正完成。它们也不会在任何一个地方技术上或组织上开始或停止。ML 模型开发人员经常希望他们的生活会很简单,他们只需收集数据并训练一次模型,但实际上很少会这样。
一个简单的思想实验可以帮助我们理解其中的原因。假设我们有一个 ML 模型,我们正在调查该模型是否达到足够好的效果(根据某个特定阈值)或者没有达到。如果效果不够好,数据科学家、业务分析师和 ML 工程师通常会共同合作,探讨如何理解失败并进行改进。这通常涉及大量的工作:也许修改现有的训练管道以改变某些特征,增加或删除一些数据,并重新构建模型以迭代已完成的工作。
相反,如果模型运行良好,通常组织会感到兴奋。自然而然的想法是,如果我们可以通过一个天真的尝试取得如此多的进展,想象一下如果我们更加努力并变得更加复杂,我们能做得更好。这通常涉及——你猜对了——修改现有的训练管道,改变特征,增加或删除数据,甚至可能重构模型。无论哪种方式,都会做更多或更少相同的工作,而我们做的第一个模型只是我们下一步工作的起点。
让我们更详细地看看 ML 生命周期或循环(图 1-1)。

图 1-1 ML 生命周期
ML 系统始于数据,因此让我们从图表的左侧开始,详细介绍这个循环。我们将具体查看每个阶段,并解释在我们的购物网站背景下,组织中的每个成员在每个阶段所涉及的关键活动。
数据收集与分析
首先,团队清点拥有的数据并开始评估这些数据。团队成员需要决定他们是否拥有所有所需的数据,然后优先考虑可以利用这些数据的业务或组织用途。然后他们必须收集和处理这些数据。
数据收集和分析工作几乎触及公司每一个人,尽管对他们的具体影响因公司而异。例如,业务分析师可能属于财务、会计或产品团队,并且每天使用平台提供的数据。或者数据和平台工程师可能构建可重用的工具来摄取、清理和处理数据,尽管他们可能不参与业务决策。(在较小的公司中,也许他们只是软件或产品工程师。)一些地方有正式的数据工程角色。其他公司则有数据科学家、产品分析师和用户体验(UX)研究员,他们都消费此阶段工作的输出。
对于 YarnIt,我们的网店运营商,组织中大部分人参与了这一步骤。这包括业务和产品团队,他们最了解业务优化的最高影响领域。例如,他们可以确定每笔销售利润的微小增加对业务更重要,还是稍微增加订单频率更合理。他们可以指出低利润和高利润产品的问题或机会,并讨论将客户分为更赚钱和不那么赚钱的客户。产品和机器学习工程师也会参与其中,思考如何处理所有这些数据,而站点可靠性工程师(SRE)将在整体管道上提出建议和决策,以使其更易于监控、管理和可靠。
管理 ML 数据是一个涉及广泛的主题,我们已经在第二章中专门讨论了数据管理原则,并在第四章和第十章中进一步讨论了训练数据。现在,假设设计和管理数据收集和处理系统是任何良好 ML 系统的核心是很有用的。一旦我们将数据放在适当的位置和格式中,我们将开始训练模型。
ML 训练流水线
ML 训练流水线是由数据工程师、数据科学家、ML 工程师和 SRE 设计、构建和使用的。它们是特定用途的抽取、转换、加载(ETL)数据处理流水线,读取未处理的数据并应用 ML 算法和我们模型的结构到数据上。[¹] 它们的任务是消费训练数据并生成完成的模型,准备进行评估和使用。这些模型可以一次性完整生成,也可以以多种方式逐步生成 —— 有些模型是不完整的,因为它们仅覆盖了部分可用数据,还有些模型在范围上不完整,因为它们只设计用来覆盖整体 ML 学习的一部分。
训练管道是我们机器学习系统中仅有的直接、明确使用机器学习特定算法的部分,尽管即使在这里,这些算法通常打包在相对成熟的平台和框架(如 TensorFlow 和 PyTorch)中。
训练管道也是我们机器学习系统中少数几个部分之一,最初不可避免地需要处理算法细节。一旦机器学习工程师建立并验证了一个训练管道,很可能是依赖相对成熟的库,那么其他人在重新使用和操作管道时就不需要太多的直接统计专业知识了。²
训练管道具有任何其他数据转换管道的所有可靠性挑战,以及一些特定于机器学习的挑战。最常见的机器学习训练管道故障如下:
-
缺乏数据
-
数据格式不正确
-
软件错误或实现数据解析或机器学习算法时的错误
-
管道或模型配置错误
-
资源短缺
-
硬件故障(由于机器学习计算量大且运行时间长,这种情况相对较常见)
-
分布式系统故障(通常是因为转向使用分布式系统进行训练,以避免硬件故障)
所有这些故障也是普通 ETL 数据管道(非机器学习)的故障模式特征。但是机器学习模型可能会因数据分布、数据缺失、欠采样或其他大量常见于普通 ETL 领域未知的问题而悄无声息地失败。³ 具体而言,第二章中详细讨论的一个例子是,数据子集的缺失、处理错误或其他原因无法使用,是机器学习训练管道失败的常见原因。我们将在第七章和第九章讨论监控训练管道和检测这类问题的方法(通常称为分布变化)。现在,让我们记住,与其他数据管道相比,机器学习管道确实更难以可靠地运行,因为存在这些微妙的故障模式。
如果还不清楚的话,ML 训练流水线绝对是一个生产系统,需要像服务二进制文件或数据分析一样谨慎对待。(如果你所处的环境中除了你没有人相信这一点,知道会有足够的反例来说服任何人——最终还是小安慰。)举个例子,如果你对生产过程不够重视,我们知道有些公司建立在由实习生生成的模型上,这些实习生现在已经离开公司,没有人知道如何再生成这些模型。这样说可能太简单了,但我们建议你永远不要陷入这种境地。养成写下你所做的事情并将其转化为自动化的习惯,是避免我们提到的结果的重要一步。好消息是,从小规模手动操作开始,并不需要特别的可重复性,这是完全可行的。但是,要成功就需要自动化和审计,我们认为,你能尽早将你的模型训练自动化,并通过一些简单的正确性和模型保持的检查来控制,那就更好了。
无论如何,假设我们成功构建了一个模型,我们将需要将其集成到面向客户的环境中。
构建和验证应用程序
ML 模型本质上是一组软件功能,需要解锁才能提供价值。你不能只是盯着这个模型看;你需要审问它——向它提问题。这样做的最简单方法是提供一个直接的机制来查看预测结果(或报告模型的另一个方面)。然而,更常见的情况是,我们必须与更复杂的东西集成:通常情况下,模型的任何目的最好通过与另一个系统的集成来实现。我们的应用程序集成将由产品和业务功能的员工指定,由 ML 工程师和软件工程师完成,并由质量分析员监督。有关更多详细信息,请参阅第十二章。
考虑 yarnit.ai,我们的在线购物网站,人们可以从世界各地找到最适合编织或钩针编织的优质纱线,所有这些都是基于 AI 的推荐!举个例子,让我们来看看一个向购物者推荐额外购买的模型。该模型可以使用用户的购物历史以及当前购物车中的产品列表,再加上其他因素,如他们通常运送到的国家、他们通常购买的价格范围等等。该模型可以利用这些特征生成一个排名列表,购物者可以考虑购买这些产品。
为了为公司和用户提供价值,我们必须将这个模型与网站本身集成。我们需要决定在哪里查询模型以及我们将如何处理结果。一个简单的答案可能是,在用户考虑结账时,在购物车下方的水平列表上显示一些结果。这似乎是一个合理的初步尝试,为购物者提供一些便利,可能为 YarnIt 带来额外的收入。
要确定我们的集成效果如何,系统应记录其决定展示什么以及用户是否采取了任何行动——他们是否将商品添加到购物车并最终购买?通过记录这些事件,此集成将为我们的模型提供新的反馈,使其能够基于其推荐的质量进行训练并开始改进。⁴ 在这个阶段,我们只需验证它是否有效:换句话说,模型是否加载到我们的服务系统中,查询是否由我们的 Web 服务器应用程序发出,结果是否显示给用户,预测是否已记录,并且日志是否已存储以用于未来的模型训练。接下来是评估模型质量和性能的过程。
质量和性能评估
当然,ML 模型只有在起作用时才有用。事实证明,确实需要进行相当详细的工作来真正回答这个问题——从几乎令人发笑但却绝对真实的观点开始,我们必须决定什么算是有效工作,以及我们将如何根据这一目标评估模型性能。这通常涉及识别我们试图创建的影响,并在各种子集(或切片)上测量它在代表性查询或用例中的表现。这在第五章中有更详细的覆盖。
一旦我们决定进行评估,我们应该从离线开始这个过程。最简单的思路是,我们发布我们认为是代表性查询集,并分析结果,将答案与“正确”或“真实”响应集合进行比较。这应该帮助我们确定模型在生产环境中应该工作的效果如何。一旦我们对模型基本性能有了一些信心,我们可以进行初始集成,无论是实时发布还是暗部署系统。在实时发布中,模型接收实时生产流量,影响网站和相关系统等。如果我们小心或幸运的话,这是一个合理的步骤,只要我们监控关键指标以确保不会损害用户体验。
暗部署涉及与模型协商并记录结果,但不将其直接用于用户看到的网站。这可以增强我们对模型技术集成的信心,但可能无法提供对模型质量的高度信心。
最后,有一个中间地带:我们可以在应用程序中构建能力,仅在部分用户中的某些情况下使用模型。尽管选择这一部分的话题在本书的范围之外是一个令人惊讶的高级话题⁵,但总体思想很简单:在一些查询中尝试模型,并对集成以及模型质量的信心进行评估。
一旦我们确信模型不会造成伤害,并且有助于我们的用户(希望也能带来收入!),我们几乎可以准备好发布了。但首先,我们需要集中精力进行监控、测量和持续改进。
定义和测量 SLOs
服务水平目标(SLOs)是针对特定测量预定义的阈值,通常称为服务水平指标(SLIs),用于定义系统是否按要求执行。一个具体的例子是:“99.99% 的 HTTP 请求在 150 毫秒内成功完成(返回 20x 状态码)”。SLOs 是 SREs 的自然领域,但对于产品经理来说同样关键,因为他们会明确产品需要做什么,以及如何对待其用户,同时对数据科学家、ML 工程师和软件工程师也至关重要。指定SLOs 总体上是具有挑战性的,但由于数据微小的变化,甚至是周围环境的变化,对 ML 系统的指定则更为困难。
提及到这一点,当我们考虑 ML 系统的 SLOs 时,可以使用明显的关注点分离来开始。首先,我们可以使用服务、训练以及应用本身之间的区分。其次,我们有传统的黄金四信号(延迟、流量、错误、饱和度)与 ML 操作内部之间的区分,它们本身比黄金信号明显不那么通用,但仍不完全属于特定领域。第三,我们有与 ML 增强应用本身工作相关的 SLOs。
让我们更具体地看看这些关于 SLOs 的想法如何直接适用于yarnit.ai。我们应该为每个系统设置单独的 SLOs:服务、训练和应用。对于模型的服务,我们可以简单地查看错误率,就像我们对待任何其他系统一样。对于训练,我们可能应该关注吞吐量(每秒训练的示例或者如果我们的模型复杂性相似,则可能是训练的数据字节)。我们可能还会制定一个总体的模型训练完成的 SLO,例如:95% 的训练运行在一定秒数内完成。在应用中,我们可能应该监控诸如显示推荐的数量以及模型服务器的成功调用的指标(从应用程序的角度来看,这可能与模型服务系统报告的错误率相匹配,也可能不匹配)。
请注意,然而,这些示例都与模型的机器学习性能无关。对于这一点,我们需要为应用程序本身的业务目的设定相关的 SLOs,并且这些测量可能需要在相当长的时间段内进行。对于我们网站的良好起点可能是模型生成建议的点击率和模型排名的搜索结果。我们可能还应该为由模型带来的收入建立一个端到端的 SLO,并且不仅在整体上进行测量,还要考虑我们客户的合理子集(按地理位置或可能按客户类型)。
我们将在第九章中更详细地讨论这个问题,但目前我们要求您接受,在机器学习的背景下,有合理的方法来确定 SLOs,并且它们涉及许多与非机器学习 SLO 对话中使用的相同技术(尽管机器学习的工作细节可能会使这些对话变得更长)。但是不要让复杂性妨碍基础的建立。最终,产品和业务负责人明确他们可以接受哪些 SLOs,哪些不能接受,以便组织的生产工程资源都集中于实现正确的目标上。
一旦我们收集了数据,建立了模型,将其集成到我们的应用程序中,衡量了其质量并确定了 SLOs,我们就准备进入令人兴奋的启动阶段了!
启动
现在我们将首次直接向客户获取反馈!在这里,产品软件工程师、机器学习工程师和 SRE 共同合作,为我们的最终用户发布应用程序的更新版本。如果我们在处理基于计算机或移动设备的应用程序,这将涉及软件发布以及所有这类发布所需的质量测试。然而,在我们的情况下,我们正在发布一个新版本的网站,该版本将包含我们的机器学习模型推荐和结果。
启动机器学习管道与启动任何其他在线系统有共同之处,但也有其特定于机器学习系统的一套非常独特的问题。有关一般在线系统启动的建议,请参阅《Site Reliability Engineering: How Google Runs Production Systems》第三十二章(由 Betsy Beyer 等人编辑,O’Reilly,2016)。你肯定希望基本的监控/可观察性、发布控制和回滚都得到覆盖——进行没有明确回滚计划的启动是危险的。如果您的基础设施不允许您轻松或根本无法回滚,我们强烈建议您在启动之前先解决这个问题。对于机器学习特定的问题,我们将在接下来详细介绍一些问题。
代码模型
请记住,模型和您的训练系统二进制代码、服务路径以及数据处理代码一样都是代码。部署新模型绝对可能导致您的服务系统崩溃,并破坏您的在线推荐。在某些系统中,部署新模型甚至可能影响训练(例如,如果您正在使用迁移学习来启动使用另一个模型进行训练)。重要的是要类似对待代码和模型的发布:尽管一些组织可能在(比如说)假期季节发布新模型,但模型出现问题的可能性完全存在,我们曾见过这种情况,不久之后需要代码修复。在我们看来,它们具有同等的风险,并应采取同等的缓解措施。
缓慢发布
在部署在线系统的新版本时,我们通常能够逐步进行,从所有服务器或用户的一部分开始,随着时间的推移逐步扩展,仅在我们对系统行为正确和我们的机器学习改进质量有信心时扩展。明确地说,在这里,我们试图限制损害并在两个方面获得信心:用户和服务器。如果我们恰好制造了一个糟糕的系统或模型,我们不希望将所有用户都暴露在其中;相反,我们首先向一小部分最终用户展示它,然后逐步扩展。类似地,对于我们的服务器群,如果我们恰好构建了一个不运行或运行不好的系统,我们不想一次性冒险所有计算资源的风险。
这个问题最棘手的一面在于确保新系统在部署过程中不会干扰旧系统。对于机器学习系统而言,这种情况最常见的方式是通过中间存储工件。具体来说,格式的变化和语义的变化会导致数据解释错误。这些内容涵盖在第二章中。
发布,而不是重构
尽可能少地同时进行改变的总则适用于许多系统,但在机器学习系统中尤为重要。整个系统的行为如此容易改变(通过底层数据的变化等),以至于在任何其他上下文中都很容易进行重构的重构可能会使人难以推断出问题出在哪里。
在数据层隔离发布
在进行渐进式部署时,请记住隔离必须在数据层,同时也要在代码/请求/服务层进行隔离。具体来说,如果新模型或服务系统记录的输出被旧版本的代码或模型使用,诊断问题可能会很长,并且很棘手。
这不仅仅是机器学习问题,如果未能将新代码路径的数据与旧代码路径隔离开来,多年来就会发生一些令人兴奋的故障。这可能发生在任何处理由系统的不同部分生成的数据的系统上,尽管机器学习系统的故障往往更加微妙且更难检测。
在发布期间测量 SLOs
确保您至少有一个仪表板显示最新和最敏感的指标,并在发射过程中跟踪这些指标。随着您弄清楚哪些指标最重要,哪些最有可能表明发射失败,您可以将这些编码到一个服务中,在未来如果情况变得不妙时自动停止发射。
回顾发布
无论是手动还是自动,确保在任何类型的发射过程中有人或某物进行监视。较小的组织或更大(或更不寻常)的发射可能需要由人类进行监视。随着您的信心增强,如前所述,您可以开始依赖自动化系统来执行此操作,并显著增加发射速率!
监视与反馈循环
就像对于任何其他分布式系统一样,有关我们 ML 系统正确或不正确功能的信息对于有效和可靠地操作它至关重要。明确识别“正确”功能的主要目标仍然是产品和业务人员的角色。数据工程师将识别信号,软件工程师和 SRE 将帮助实施数据收集、监视和警报。
这与之前的 SLO 讨论密切相关,因为监视信号经常直接影响到 SLO 的选择或构建。在这里,我们稍微深入探讨了各类别:
系统健康或黄金信号
这些与任何非 ML 信号没有区别。将端到端系统视为数据摄入、处理和服务系统,并相应地进行监视。进程是否在运行?它们是否在取得进展?新数据是否正在到达?等等(您将在第九章中看到更多详细信息)。ML 的复杂性很容易让人分心。然而,重要的是要记住,ML 系统只是系统:它们具有与其他分布式系统相同的所有故障模式,以及一些新颖的故障模式。不要忘记基础知识,这是监视的黄金信号方法的理念:找到代表系统整体行为的通用高级指标。
基本模型健康或通用 ML 信号
检查基本的模型健康度指标是 ML 系统中与系统健康等价的内容:它不是特别复杂或与域密切相关,但包括有关建模系统的基本和代表性事实。新模型是否符合预期大小?它们能否无错误地加载到我们的系统中?在这种情况下的关键标准是您是否需要了解模型内容以进行监视;如果不需要,您正在进行的监视就是基本模型健康的事务。在这种无上下文的方法中有相当大的价值。
模型质量或特定领域的信号
监控和仪表化的最困难之处在于模型质量。在操作上相关的模型质量问题与提升模型质量的机会之间没有明确的分界线。例如,如果我们的模型在我们的网站上为购买针而不是毛线的用户提供了糟糕的推荐,这可能是改进我们模型的机会(如果我们选择以这种质量水平发布),或者是需要立即响应的紧急事件(如果这是最近的退化现象)⁷。区别在于上下文。对于大多数 SRE 来说,这也是他们难以接受的 ML 系统的最困难方面:没有一个客观的“足够好”的模型质量衡量标准,更糟糕的是,这是一个难以衡量的多维空间。最终,产品和业务领导人必须建立实际的度量标准,指示模型是否根据其需求进行运行,并且 ML 工程师和 SRE 需要共同确定哪些质量措施与这些结果最直接相关。
作为循环的最后一步,我们需要确保我们的最终用户与模型互动的方式能够反映到下一轮数据收集中,并且准备好再次循环。ML 服务系统应该记录他们认为将来可能有用的任何信息,以便将来改进。通常,这至少包括他们收到的查询、他们提供的答案以及为什么提供这些答案的某些信息。“为什么”可以是一个简单的单维度相关性分数,或者是一个影响决策的更复杂的一组因素。
我们已经完成了第一轮循环,并准备好重新开始。到这个时候,yarnit.ai 至少应该增加了基本的 ML 功能,并且我们应该处于能够持续改进的位置,无论是通过改善第一个模型还是识别可以通过 ML 改进的站点的其他方面。
来自循环的教训
现在应该清楚了,ML 的起点和终点是数据。成功、可靠地将 ML 整合到任何业务或应用程序中,没有理解你拥有的数据以及从中提取信息的能力是不可能的。为了使这一切工作起来,我们必须驯服数据。
对于任何特定环境,实施机器学习没有固定的顺序。通常情况下,从数据开始是有意义的,但随后您需要访问每个功能阶段,甚至可能需要重新审视它们。我们想要解决的问题决定了我们需要的数据。服务基础设施告诉我们可以构建的模型。训练环境限制了我们将使用的数据类型及其处理量。隐私和伦理原则塑造了每一个这些要求。模型构建过程需要对整个循环以及整个组织本身有一个全面的视角。在机器学习领域,严格的关注点分离是不可行或不实用的。
所有这些背后都是组织的复杂性问题,以及在 ML 方面的风险承受能力。并非所有组织都准备好在这些技术上进行大规模投资,并冒险将他们的关键业务功能置于未经验证的算法上——他们也不应该这样做!即使对于具有大量 ML 经验并能够评估模型质量和价值的组织来说,大多数新的 ML 理念也应该先试验,因为大多数新的 ML 理念并不成功。在很多方面,ML 工程最好是作为一个持续实验来对待,通过部署增量变化和优化,并通过产品管理帮助评估成功标准来看看哪些方法可行。今天的软件工程尝试将 ML 视为确定性开发过程是不可能的。然而,即使考虑到当今世界的基本混乱,通过如何进行第一次试验的纪律性,您可以显著提高您的 ML 实验最终成功的机会。⁸
由于实施是循环的,这本书几乎可以按任何顺序阅读。选择一个最符合您当前关注点的章节,从那里开始。然后,找出您最迫切的问题,转到下一个章节。所有章节都广泛地交叉引用其他章节。
如果您是一种顺序读者,也可以的,您可以从数据开始。对于那些对公平性和伦理问题如何被整合到基础设施的每个部分感兴趣的人,可以直接跳到第六章。
读完这本书,您应该对如何开始将机器学习引入组织服务有一个具体的理解。您还将拥有一份变革路线图,以确保该过程成功实施。
¹ ETL 是一种常见的抽象化表示这种数据处理方式。维基百科的"Extract, transform, load"页面有一个合理的概述。
² 我们使用哪些成熟的库和系统主要取决于应用程序。如今,TensorFlow、JAX 和 PyTorch 在深度学习中广泛使用,但如果你的应用程序从不同的学习风格中受益(例如,XGBoost 是常见的),那么还有许多其他系统可供选择。选择模型架构在本书的范围之外,尽管在第三章和第七章中涵盖了其小部分内容。
³ 考虑阅读 Andrej Karpathy 在 2019 年发布的优秀博文 “训练神经网络的秘籍” 以获取更多信息。
⁴ 如果你对电子商务中的 A/B 测试概念比较熟悉,这也是确保此类测试的实现在集成测试中正确工作的适当场所。一个很好的用例是能够区分在有和没有机器学习建议的情况下的用户行为。
⁵ 幼稚地说,我们可能只是生成一个随机数并选择其中的 1% 来得到模型。但这意味着即使在同一个网络会话中,同一用户有时会得到模型生成的推荐,有时则不会。这不太可能帮助我们弄清楚模型是否有效,并且可能会产生真正糟糕的用户体验。因此,对于 Web 应用程序,我们可能会选择所有已登录用户中的 1% 来获得模型生成的结果,或者也可能是所有 cookie 中的 1%。在这种情况下,我们将很难判断模型生成结果对用户的影响,并且在当前用户与新用户选择中可能存在偏见。我们可能希望同一用户有时会得到模型生成的结果,有时则不会,或者我们可能希望一些用户总是如此,但其他用户只在特定的会话或日期上如此。关键是在这里如何随机访问 ML 结果是一个相当统计上复杂的问题。
⁶ 为了完整起见,确实有一种安全的方式来推出新的数据格式:通过在系统开始写入格式之前完成对读取格式的支持的渐进式推出。显然,这并不是在这种情况下所做的事情。
⁷ 也不要忘记数据漂移:2019 年的模型与 2020 年的模型在大多数地区对于口罩的重要性和意义会有很大不同。
⁸ “驯服长尾:改进人工智能经济的冒险” 是由 Martin Casado 和 Matt Bornstein 撰写的一篇在这一背景下有用的文章。
第二章:数据管理原则
在本书中,我们很少关注模型构建的算法细节或其结构化方式。去年最激动人心的算法发展是明年平凡的可执行内容。相反,我们对两件事情极为感兴趣:用于构建模型的数据以及将数据转换成模型的处理管道。
最终,ML 系统是数据处理管道,其目的是从数据中提取可用和可重复的见解。然而,ML 管道与传统的日志处理或分析管道有一些关键的不同和特定的约束,并以不同的方式失败。它们的成功很难衡量,并且许多失败很难检测到。(我们在第九章详细讨论这些主题。)基本上,它们消耗数据,并输出该数据的加工表示(尽管两者的形式大相径庭)。因此,ML 系统彻底和完全依赖其基础数据系统的结构、性能、准确性和可靠性。这是从可靠性角度来看 ML 系统最有用的思考方式。
在本章中,我们将深入研究数据本身:
-
数据的来源
-
如何解释数据
-
数据质量
-
更新数据源(我们如何使用它们以及如何使用它们)
-
将数据整理成适合使用的形式
我们将介绍数据的生产需求,并展示,就像模型一样,生产中的数据有一个生命周期:
-
摄入
-
清理和数据一致性
-
丰富和扩展
-
存储和复制
-
在训练中的使用
-
删除
数据和元数据定义的稳定性以及这些定义的版本控制至关重要,我们将解释如何实现它们。¹ 我们还将涵盖数据访问约束、隐私和可审计性问题,并展示确保数据来源(数据的来源)和数据血统(自我们获得以来谁负责它)的一些方法。在本章末尾,我们期望您对使数据处理链可靠且可管理的主要问题有完整但表面的理解。
数据作为负债
写作关于 ML 的几乎普遍建议数据在 ML 系统中是一个重要的资产。这种观点是正确的:没有数据,确实无法有 ML 系统。正如图 2-1 所示,通常情况下,具有更多(和更高质量)训练数据的简单(甚至简化的)ML 系统可以胜过具有较少或较不代表性数据的更复杂系统。
组织继续争相收集尽可能多的数据,希望找到将这些数据转化为价值的方法。事实上,许多组织已将此变成了一个极其成功的商业模式。想想 Netflix,其向客户推荐高质量节目和电影的能力是早期的差异化因素。据报道,Netflix 还利用这些数据,在进入内容制作业务后,根据对人们想观看什么的详细了解,确定为哪些受众制作哪些节目。

图 2-1. 数据大小、模型错误率及与数据相关的问题或风险的权衡示意图
当然,就像任何东西都可能是一种资产,在适当(不适当)的情况下,它也可能成为一种负债。对于数据来说,最重要的是说,数据的获取、收集和整理可能会揭示出数据中意想不到的微妙和复杂性。如果不考虑这些因素,可能会对我们和我们的用户造成潜在危害。所有这些方法必须根据数据类型适当地加以限定——例如,医疗记录可能需要与工作历史有所不同的处理。当然,最佳的数据整理方式成本高昂,所以这里没有免费的午餐。
这个简短部分的目的不是成为关于数据收集、存储、报告和删除实践的权威作品。这远远超出了本部分甚至本书的范围。这里的目的是列举出足够的复杂性,以阻止任何读者简单地认为“更多数据 == 更好”,或者认为“这些东西很简单”。让我们来看看数据的生命周期,看看其中一些挑战来自哪里。
首先,数据必须依照适用法律收集,这可能取决于我们组织所在地、数据来源地以及组织政策。我们肯定需要深思熟虑(并与我们可能运营的所有司法辖区的律师交流)。关于个人数据的内容有显著的限制,包括哪些算是关于人的数据、如何获得存储数据的许可、如何存储和检索已获得的许可、是否需要向提供数据的人提供访问权限以及在什么情况下需要。这些限制可能来自法律、行业实践、保险法规、公司治理政策或其他各种来源。某些司法辖区通常的限制包括禁止在未经明确书面同意的情况下收集个人可识别信息(PII),以及根据数据主体的请求删除该数据的要求。如何收集数据以及是否收集数据并非技术问题,而是政策和治理问题。(此主题的部分内容在第六章中更加详细地讨论。)
如果我们被允许收集和存储数据,必须确保防止外部访问。很少有好事发生在组织因泄露用户私人数据而导致的结果。此外,即使对员工也必须限制访问。员工不应无限制地查看或更改私人用户数据,并且必须详细记录这些操作。
减少数据访问和审计表面的另一种方法是对数据进行匿名化处理。一个相对简单且有价值的选项是使用pseudonymization(伪名化)。在这种情况下,私人标识符以可逆转的方式替换为其他标识符,并且要逆转伪名化需要访问额外的数据或系统。这保护了数据免受工作在管道上的工程师的随意检查,但如果我们发现需要逆转匿名化,则可以进行发现。伪名化还希望保留对于我们模型相关的数据特性。换句话说,如果某个数据字段在特定情况下保持某种相似性很重要(例如,考虑邮政编码,在同一城镇或同一城市的同一部分时,它们的前缀是相同的),那么我们的伪名化可能需要保留这种特性。尽管这种保护级别对于防止随意检查具有价值,但重要的是将伪名化数据视为与完全非匿名化数据一样有风险。历史上存在许多这类数据被用来暴露用户真实和私人信息的案例(请参见以下边栏)。
更好的方法是永久性地删除个人私密数据与我们用于训练的数据之间的直接连接。如果我们能永久性地消除私密数据与个人之间的关联,就能显著降低数据的风险,并增加我们处理数据的灵活性。当然,这比看起来要困难得多。³以一种不是轻而易举可逆的方式实现这一点,同时还有价值,确实很难。虽然有许多良好的技术存在,一个常见的基本想法是结合数据集,以确保没有任何一条报告的数据与任何少于某个真实人数的唯一标识符相关联。这是许多严肃的人口研究组织采取的方法,包括美国人口普查局。然而,要做到这一点,有许多微妙之处需要注意。正确的匿名化超出了本书的范围,尽管我们会提到它。
最后,我们最终需要能够删除数据。我们可能会在个别用户的请求、本地法律、欧盟的《通用数据保护条例》(GDPR)等法规或其他情况下进行此操作,即使我们不再有权限存储数据。删除数据并实际上让其被删除是非常困难的事情。
自从早期的 MS-DOS 时代以来,删除文件只是删除了对它的引用,而没有真正删除数据本身,这意味着您可以在足够的决心和运气下重建文件。如今的计算环境使删除变得更加困难,从追踪多个数据副本到元数据管理,无所不在。在大多数分布式存储系统中,数据被分成许多片段并存储在一组物理机器上。根据实现方式,可能几乎不可能确定每个可靠存储设备(硬盘驱动器或固态驱动器)可能存有数据。
确保人们希望删除他们的数据,而不是设立随意障碍,这一点非常重要。在平衡这一点时,可以在真正删除数据之前施加一段短暂的延迟。用户可能会在请求删除数据后被授予几小时甚至几天的时间来取消请求。但是,一旦确认请求是真实和合法的,我们将需要追踪到每一份数据副本并消除它。根据存储方式,数据结构、索引和备份可能需要重建,以确保访问附近数据的效率和可靠性与之前一样。
和大多数事情一样,删除数据的任务通过深思熟虑可以更好地完成。如果您的系统没有经过深思熟虑,可以使用一些变通方法。以下是两种常见的优化方法:
定期重写数据
当存在一个重新生成数据的过程时,我们可以利用先前提到的“不要立即删除数据”的建议,简单地安排“已删除”的数据,在下次数据重写时不包括这些数据。这假设数据再生周期与预期的和可接受的删除延迟相匹配。这还假设数据的重写有效地删除数据,这很可能根本不是事实。
加密所有数据并丢弃一些密钥。
这种设计方式的系统具有一些显著的优势。特别是,它保护“静止”状态的私密数据(写入持久存储)。删除数据也很简单:如果我们丢失了用户数据的密钥,我们就无法再读取这些数据。缺点大多是可以避免的,但值得认真考虑:任何采用这种策略的人都需要非常非常可靠的密钥处理系统,因为如果丢失密钥,所有数据都会丢失。这也可能使得从密钥系统的每个备份中可靠删除单个密钥变得困难。
机器学习管道的数据敏感性
机器学习管道与大多数数据处理管道的主要区别在于,机器学习管道对其输入数据的敏感性通常比大多数其他数据处理管道更高。所有数据处理管道在某种意义上都受其输入数据的正确性和数量的影响,但机器学习管道对数据分布的细微变化特别敏感。一个管道可以很容易地从大部分正确变成显著错误,只要省略了一小部分数据,而这一小部分数据不是随机的,或者在我们的模型敏感的特征范围内没有均匀采样。
在这里进行一个简单的思维实验,考虑一个像yarnit.ai这样的真实系统,它不知何故丢失了特定国家、地区或语言的所有数据。例如,如果我们删除了某一年的 12 月 31 日的所有数据,我们将失去检测跨年购物趋势的能力,这可能与 12 月和 1 月的其他日子有显著不同。在许多这些情况下,丢失了一小部分数据,结果是系统地有偏见的,会导致对我们模型的理解和预测产生显著混乱。
由于这种敏感性,聚合、处理和监控数据的能力至关重要,而不仅仅是实时系统。我们在第九章中详细讨论了数据监控,但这里提前预览一下。监控数据的一个关键见解是将数据沿着各种轴线(确定哪些轴线最适合切分数据是探索性数据分析中的重要活动,超出本书的范围)进行切片或分割。在试图追踪实时活动的系统中,我们可以根据数据的年龄分成数据桶:最近的、1 到 2 小时前的、3 到 6 小时前的等等。我们可以追踪当前正在处理数据的数据桶,以便了解我们已经落后了多少。但我们可以并且应该追踪与我们的应用程序相关的各种其他直方图。检测当全部或几乎全部子集数据消失时的能力将非常重要。
例如,在我们的购物网站yarnit.ai中,我们可能会根据搜索来训练,以预测任何给定搜索的最佳结果(其中“最佳”意味着“最有可能被购买”——毕竟我们是在销售业务中!)。我们在多个市场以多种语言运营我们的网站。假设一个广泛的支付故障只影响我们的西班牙语站点,导致使用西班牙语搜索的人完成订单的数量大幅减少。一个旨在推荐客户购买产品的模型将会学习到,与其他语言的结果相比,西班牙语结果显著减少购买的可能性。该模型将会展示更少的西班牙语结果,甚至可能开始向使用西班牙语的用户展示其他语言的结果。当然,该模型将无法“知道”这种行为变化的原因。
如果我们的网站主要是北美或欧洲网站,这可能会导致总购买量略微下降,但西班牙语的搜索和购买总数将大幅下降。如果我们基于这些数据进行训练,我们的模型可能会对西班牙语搜索结果表现出糟糕的结果。它可能会学到西班牙语查询从不购买任何东西(因为这基本上是真实的)。模型可能会开始展示探索性行为——如果所有的西班牙语结果都一样糟糕,那么任何结果可能都是好的,因此模型将尝试找到西班牙语搜索者实际可能购买的任何东西。这将导致糟糕的搜索结果和销售额下降,一旦我们的西班牙站点的支付故障解决后,后果将非常糟糕。这是一个相当糟糕的结果。(有关类似问题的更完整处理,请参见第十一章。)
查询量的变化可能在总体查询量水平上也不容易检测到,因为西班牙语的总体查询量可能与其他语言相比较小。我们将讨论如何监控训练管道,并检测这些分布变化的方法,详见第九章。这个例子只是为了激发思考,即 ML 管道确实更难以可靠地运行,因为这些微妙的故障模式。
在考虑这些限制的情况下,让我们回顾一下我们系统中数据的生命周期。我们必须从数据被创建的那一刻开始,将其视为我们的责任,直到我们删除它。
数据的各个阶段
大多数团队依赖于他们使用的平台,包括他们的数据存储和处理平台,以提供他们需要的大部分内容。YarnIt 并不是一个大型组织,但我们仍然会让负责业务管理、数据工程和运营的员工帮助我们理解和满足这里的需求。我们很幸运有 SREs 来解决与数据存储和处理相关的可靠性问题。
数据管理阶段基本上是将我们拥有的数据转换为适合后续处理阶段使用的格式和存储组织。在此过程中,我们还可能应用一系列特定于模型(或至少是模型领域特定)的数据转换,以准备数据进行训练。我们对数据的下一步操作将是训练 ML 模型、匿名化某些敏感数据项,并在不再需要或被要求这样做时删除数据。为了为这些数据操作做好准备,我们将继续从业务领导者那里获取输入,以回答关于我们数据主要用例及未来探索可能领域的问题。
与本书的大部分章节一样,要设计和运行可靠的 ML 系统,并不一定需要或有时甚至不希望深入了解 ML。然而,对模型训练的基本理解确实直接影响我们如何准备数据。在现代 ML 环境中,数据管理在将数据馈送到模型训练管道之前包含多个阶段,如图 2-2 所示:
-
创造
-
摄入
-
处理(包括验证、清洗和增强)
-
后处理(包括数据管理、存储和分析)

图 2-2. ML 数据管理阶段
创造
或许这样说会显得奇怪或显而易见,但是机器学习训练数据来自于某处。也许您的数据集来自于其他地方,比如另一个部门的同事或者来自学术项目,并在那里创建。但数据集总是通过某种过程在某一时点创建的。在这里,我们指的是数据创建作为在某些数据存储系统中生成或捕获数据的过程,但不是我们的数据存储系统。例如,这些例子包括来自服务系统日志、从事件中捕获的大量图像集、医疗程序的诊断数据等。在这个过程中隐含的是,我们希望设计新系统并改进现有系统,以生成比我们可能需要的更多的数据,以便我们的机器学习系统有东西可以使用。
有些数据集在静态时表现良好(或至少不会迅速更改),而其他数据集仅在频繁更新时才有用。例如,一个照片识别数据集在很多个月内可能是可用的,只要它合适地代表了我们想用我们的模型识别的照片类型。另一方面,如果外部照片只代表了温带气候下的冬季环境,则照片集的分布将与我们需要识别的预期图像集显著不同。因此,在这些地方春季升温时,它将不会有用。同样地,如果我们试图自动识别yarnit.ai上的交易欺诈,我们将希望不断地在最新交易上训练我们的模型,并提供关于这些交易是否欺诈的信息。否则,有人可能会想出一个难以检测的聪明办法来窃取我们所有的编织用品,我们可能永远不会教会我们的模型如何检测它。
我们收集的数据类型和我们创建的数据产物可以是非结构化、半结构化或非常结构化(图 2-3)。
结构化数据 是定量的,具有预定义的数据模型/架构,高度组织化,并以类似电子表格或关系数据库的表格格式存储。名称、地址、地理位置、日期和付款信息都是结构化数据的常见例子。由于其格式良好,结构化数据可以通过相对简单的代码和明显的启发式算法轻松处理。
另一方面,非结构化数据 是没有标准数据模型/架构的定性数据,因此无法使用传统的数据方法和工具进行处理和分析。非结构化数据的例子包括电子邮件正文、产品描述、网页文本以及视频和音频文件。半结构化数据没有特定的数据模型/架构,但包括标签和语义标记,因此是介于结构化数据和非结构化数据之间的一种结构化数据类型。半结构化数据的例子包括可以按发件人、收件人、收件箱、已发送、草稿等搜索的电子邮件,以及社交媒体内容,可以根据公开、私密和朋友分类,还可以根据用户维护的标签(如标签)进行分类。数据的内部结构特性将对我们处理、存储和使用数据的方式产生重大影响。

图 2-3. 机器学习训练数据分类
尽管模型中的偏见来自模型结构以及数据,但数据创建的环境对正确性、公平性和伦理有深远影响。虽然我们在第五章和第六章中详细讨论这一点,但我们在这里能够提出的主要建议是您应该有某种流程来确定您的模型是否存在偏见。我们可以通过多种方式做到这一点,最简单的可能是采用模型卡片方法,但是任何具备这种流程并且被组织接受的流程都比没有这种流程要好得多。这绝对是在我们开始处理机器学习系统中的伦理和公平考虑时要做的第一件事情。例如,您可以相对容易地将检测偏见的工作整合到数据溯源或数据生命周期会议或跟踪流程中。但是,每个从事机器学习的组织都应该建立某种流程,并将其作为持续改进的一部分进行审查。
回想一下,偏见来自很多来源,并且在整个过程中的多个阶段都会显现出来。没有确保数据公平性的绝对方法。在这里取得成功的一个有用前提是拥有一个包容性强的公司文化,这个文化包括来自各种背景、拥有不同和创新观点的人员。有充分的证据表明,具有非常不同背景和观点的人,在建立在信任和尊重基础上的环境中工作,比那些成员相似的团队产生更好、更有用的想法。这可以成为对通过先前描述的检查中可能出现的偏见的一种强有力的防御措施的一部分。然而,这并不会在没有过程和工具支持的情况下防止所有不良后果,正如没有系统帮助的人类努力也无法防止所有不良后果一样。
最后关于数据集创建或者说数据集增强的一个注意事项:如果我们有少量的训练数据,但不足以训练高质量的模型,可能需要增强这些数据。现有工具可以实现这一点。例如,Snorkel提供了一个编程接口,可以将少量数据点排列成更多更多样化的数据点,从本质上讲,这些数据是虚构的但在统计上是有效的训练数据。这是一个很好的起点,因为它可以帮助我们轻松地将小数据集扩展成大数据集。尽管从表面上看,这种程序生成的数据集可能不那么有价值或有用,但有充分的证据表明,这种方法可以以较低的成本获得极好的结果,尽管使用时需要谨慎。⁵
数据摄取
数据需要进入系统并写入存储以进行进一步处理。在这个阶段,必然会进行过滤和选择。由于我们不需要或不希望所有创建的数据都被摄取或收集,因此可能不会收到全部数据。
我们可以在这个阶段按类型过滤数据(即我们认为对我们的模型不会有用的数据字段或元素)。如果数据量很大,我们认为无法承担处理所有数据,我们也可以在这个阶段进行简单的抽样。由于机器学习训练和其他数据处理通常非常耗费计算资源,抽样数据可以是节省中间处理和训练成本的有效方式,但重要的是要衡量抽样的质量成本,并将其与节省的成本进行比较。数据还应该按照我们关心的每个时间段或其他切片的体积/速率进行比例抽样。这样可以避免在突发期间丢失细节。然而,抽样很可能偶尔会在某些事件上失去一些细节,这是无法避免的。
通常情况下,机器学习训练系统在使用更多数据时表现更好。吹毛求疵者会立即想到许多例外情况,但这是一个有用的起点。因此,任何数据的减少可能会同时影响质量和成本。
根据数据量和服务的复杂性,摄取阶段可能仅仅是“将一些文件倒入那个目录”或者是一个复杂的远程过程调用(RPC)端点,接收特定格式的文件并确认接收到的数据包的参考,以便能够追踪其在系统中的进展。在大多数情况下,我们希望至少通过一个简单的 API 提供数据摄取,因为这提供了一个明显的地方来确认数据的接收/存储,记录摄取过程,并应用任何关于数据的治理政策。
在摄取阶段的可靠性关注点通常集中在正确性和吞吐量上。正确性是数据在正确位置正确读取和写入的一般属性,而不会被不必要地跳过或放错地方。虽然放错数据的想法听起来有些滑稽,但这绝对会发生,并且很容易理解为什么会发生。存储中的日期或时间导向的分桶系统与摄入过程中的一个偏移错误结合起来,可能导致每天的数据存储在前一天的目录中。在摄入数据之前和期间监控数据的存在和状态是数据流水线中最困难的部分。
处理
一旦我们成功地将数据加载(或摄取)到一个合理的特征存储系统中,大多数数据科学家或建模者将进行一系列常见的操作,使数据准备好进行训练。这些操作——验证、清洗和确保数据一致性,以及丰富和扩展——将在接下来详细说明。
验证
无论我们的机器学习模型多么高效和强大,如果数据质量不好,它们都不能按照我们的期望进行。在生产环境中,数据错误的常见原因是首次收集数据的代码中存在的错误。来自外部来源的数据可能会存在许多错误,即使每个来源都有一个明确定义的模式(例如,整数字段的浮点值)。因此,在有明确定义的模式和/或能够与上次已知有效的数据进行比较时,验证传入的数据尤为重要。
验证是根据领域的通用定义进行的,即它是否符合我们的预期?为了进行此验证,我们需要存储并能够引用这些标准定义。使用全面的元数据系统来管理一致性并跟踪字段的定义,对于维护数据的准确表示至关重要。这在第四章中有更详细的讨论。
清洗和确保数据一致性
即使有了一个体面的验证框架,大多数数据仍然杂乱无章。它可能存在缺失字段、重复、错误分类,甚至编码错误。数据越多,清洗和数据一致性就越可能成为处理的一个阶段。
对许多初次这样做的人来说,这似乎很令人沮丧且不必要:建立一个完整的系统仅仅为了检查数据听起来有点夸张。事实上,我们的机器学习流水线肯定会有专门清理数据的代码。我们可以把这些代码放在一个地方,可以进行审查和改进,或者把它们放在整个训练流水线的各个环节中。第二种策略会导致流水线非常脆弱,因为关于数据正确性的假设会增多,但我们确保这些假设得到满足的能力并没有增强。此外,当我们改进某些用于验证和校正数据的代码时,我们可能会忽视在执行这些工作的所有许多地方实施这些改进。或者更糟糕的是,我们可能会适得其反。例如,我们可以多次“修正”同一数据,以消除数据中的原始信息。我们还可能存在潜在的竞争条件,即流程的不同部分在不同的方式上清理或使数据一致。
在这一部分的另一组数据一致性任务是数据的归一化。归一化通常指一组技术,用于将输入数据转换为类似的比例,这对于依赖于梯度下降或类似数值优化方法进行训练的深度学习等方法非常有用。一些标准技术如 图 2-4 所示,包括以下内容:
缩放到一个范围
将数据的所有 X 值映射到一个固定的范围,通常是 0 到 1,但有时(例如身高或年龄)也可以是其他代表常见最小和最大值的数值。
截断
截断数据的最大值。当数据集存在少数极端异常值时,这是有用的。
对数缩放
x’ = log(x)。当数据呈幂律分布,具有少数非常大的值和大量非常小的值时,这是有用的。
Z 分数标准化
将变量映射到距离均值的标准偏差数量。
需要注意的是,如果在一个具有与稍后应用它的数据集不同属性的测试数据集上计算任何范围、分布或平均值,这些技术中的每一种都可能存在风险。
最后一个相关且常见的技术是将数据放入桶中:我们将一系列数据映射到表示相同范围的一组更小的组中。例如,我们可以用年龄来衡量年龄,但在训练时,我们可以按十年为单位分桶,以便所有年龄在 30 到 39 岁之间的人都被放入“30 年代”桶中。分桶可能导致许多难以检测的错误。例如,一个系统按十年边界分桶,另一个系统按五年边界分桶。在我们分桶数据时,我们必须认真考虑保留现有数据,并为每个记录编写一个新的、正确格式的字段。如果(何时?)我们改变分桶策略,我们会很高兴我们这样做了;否则,将无法进行切换。

图 2-4. 标准化技术,如 Google Developers 的数据准备课程
丰富和扩展
在这个阶段,我们将我们的数据与其他来源的数据结合起来。最常见和基本的扩展数据的方式是通过标记。这个过程通过从外部数据源(有时是人类)确认来标识特定事件或记录。标记数据是所有监督机器学习的关键驱动因素,并且通常是整个机器学习过程中最具挑战性和昂贵的部分之一。没有足够数量和高质量的标记数据,监督学习将无法进行。(标记和标记系统在第四章中有详尽的讨论。)
但是标记只是扩展数据的一种方式。我们可能会使用许多外部数据源来扩展我们的训练数据。假设出于某种原因我们相信一个人所在位置的温度会预测他们将购买什么。⁶ 我们可以取得在用户访问网页时的大致地理位置的温度,将其加入到yarnit.ai网站搜索日志中。我们可以通过查找或创建温度历史服务或数据集来实现这一点。这将允许我们基于source temperature作为特征训练模型,看看我们可以做出什么样的预测。这可能是一个糟糕的想法,但并非完全不切实际。
存储
最后,我们需要将数据存储在某个地方。我们如何存储数据的方式和位置大部分由我们倾向于如何使用它来驱动,这实际上是一系列关于训练和服务系统的问题。我们在第四章中对此进行了更详细的讨论,但这里有两个主要关注点:存储效率和元数据。
存储系统的效率受访问模式的驱动,这些模式受模型结构、团队结构和训练过程的影响。为了对我们的存储系统做出明智的选择,这里有一些我们需要回答的基本问题:
-
我们是否仅仅在这些数据上训练模型一次,还是多次?
-
每个模型会读取全部数据还是只有部分数据?如果只读取部分数据,所选子集是通过数据类型(某些字段而非其他字段)还是通过随机抽样数据(所有记录的 30%)选择的?
-
特别是,相关团队是否读取数据中的不同字段子集?
-
我们需要按特定顺序读取数据吗?
关于数据重用,事实证明几乎所有数据都会被多次读取,因此存储系统应该以此为基础构建,即使模型所有者声称他们只会对数据训练一次模型也是如此。为什么?模型开发本质上是一个迭代过程。ML 工程师创建一个模型(读取必要的数据以完成此操作),衡量模型在设计任务中的表现,并部署它。然后,他们想出了另一个想法:如何以某种方式改进模型。在你意识到之前,他们又重新读取相同的数据来尝试新的想法。我们建立的每个系统,从数据到训练再到服务,都应该基于这样一个假设:模型开发人员将半连续地重新训练同一模型以改进其性能。实际上,当他们这样做时,他们可能每次都会读取数据的不同子集。
鉴于此,以每个特征为一列的列式存储方案是一种常见的设计架构,尤其是对于在结构化数据上进行模型训练的情况。⁷ 大多数读者熟悉行式存储,即从数据库中提取数据时检索匹配行的所有字段。这是一种适合所有使用大部分或全部数据的应用集合的架构,换句话说,是一组非常相似的应用集合。列式数据便于仅检索字段子集。这对于使用给定数据子集的应用集合(在这种情况下是 ML 训练流水线)非常有用。换句话说,列式数据存储允许不同的模型有效地读取不同的特征子集,而无需每次读取整行数据。我们在同一位置收集的数据越多,就越有可能有不同的模型使用该数据的完全不同子集。
然而,对于某些训练系统而言,这种方法实在太复杂了。例如,如果我们正在处理大量未经预处理的图像,我们实际上不需要采用列式存储系统——我们可以直接从目录或存储桶中读取图像文件。但是,假设我们正在读取更结构化的数据,例如具有时间戳、来源、引荐者、金额、商品、运输方式和支付机制等字段的交易数据日志。那么,假设某些模型将使用其中一些特征,而其他模型将使用其他特征,这将促使我们采用列式结构。
元数据帮助人类与存储进行交互。当多人在同一数据上构建模型(或同一人在一段时间内进行此工作)时,有关存储特征的元数据提供了巨大的价值。它是理解上一个模型是如何组合的以及我们可能如何组合模型的路线图。存储系统的元数据是机器学习系统中常被低估的部分之一。
本节应明确指出,我们的数据管理系统主要受两个因素驱动:
我们打算利用数据的业务目的
我们试图解决什么问题?这个问题对我们的组织或客户有什么价值?
模型结构和策略
我们计划构建哪些模型?它们是如何组合的?它们多频繁地刷新?有多少个模型?它们彼此有多相似?
我们对数据管理系统的每个选择都受到这两个因素的制约,并且也对它们施加制约。如果数据管理是关于我们如何以及为何写数据,那么机器学习训练流水线就是关于我们如何以及为何读数据。
管理
典型情况下,数据存储系统实施基于凭证的访问控制,以限制未经授权的用户访问数据。这种简单的技术只能满足基本的机器学习实现。在更复杂的场景中,特别是当数据包含机密信息时,我们需要采用更精细的数据访问管理方法。例如,我们可能希望只允许模型开发者访问他们直接工作的特征,或者以其他方式限制他们对数据子集的访问(也许只能访问最近的数据)。另外,我们可能会在数据静态存储或访问时对数据进行匿名化或伪匿名化处理。最后,我们可能会允许生产工程师访问所有数据,但只有在事故期间证明确实需要访问,并且通过一个独立团队仔细记录和监控他们的访问情况。(这些有趣的方面在第十一章中有所讨论。)
SREs 可以在生产环境中配置数据访问限制,允许数据科学家通过授权网络(如虚拟专用网络(VPN))安全读取数据,实施审计日志记录以跟踪哪些用户和训练作业正在访问哪些数据,生成报告并监视使用模式。业务所有者和/或产品经理可以根据使用案例定义用户权限。我们可能需要生成和使用不同类型的元数据来处理这些异构性维度,以最大化我们访问和修改数据以供后续阶段使用的能力。
分析与可视化
数据分析和可视化是将大量数据转换为使用统计和/或图形技术和工具易于导航的表示的过程。⁸ 这是 ML 架构和知识发现技术的基本任务,使数据变得更少混乱和更易访问。仅仅展示饼图或条形图是不够的。我们需要为人类读者提供每个数据集记录意味着什么,它与其他数据集中的记录如何关联以及它是否干净安全可用于训练模型的解释。对于数据科学家来说,要查看大型数据集而没有定义良好且高性能的数据可视化工具和流程几乎是不可能的。
数据可靠性
因为我们的数据处理系统需要正常运行,数据在穿越系统时必须具备几个特性。明确这些特性可能是有争议的。对一些人来说,它们似乎是显而易见的,而对另一些人来说,似乎是不可能真正保证的。这两种观点都错过了关键点。
阐明关于我们的数据应始终如一的不变性的意图是,它允许我们所有人在这些不真实或系统不能正确保证它们将如实时发现时采取行动以在未来做得更好。请注意,可靠性的主题,即使是数据管理系统,也是非常广泛的,这里无法完全覆盖;有关更多详细信息,请参见《站点可靠性工程:谷歌如何运行生产系统》,由 Betsy Beyer 等人编辑(O’Reilly 出版社,2016 年)。
这部分仅涵盖确保数据不会丢失(持久性)、所有副本一致性和随时间变化进行严格跟踪(版本控制)的基础知识。我们还将介绍如何考虑数据读取速度(性能)以及数据尚未准备好进行读取的频率(可用性)。对这些概念的快速概述应使我们能够专注于正确的领域。
持久性
在详细说明存储系统要求时,持久性通常是被忽视最多的,因为它被视为理所当然。持久性是存储系统拥有您的数据并且没有丢失、删除、覆盖或损坏的属性。我们绝对希望以非常高的概率拥有这种属性。
持久性通常以每年无法取回丢失的字节或块的百分比表达。在这里,良好存储系统的常见值为 11 或 12 个 9,也可以表达为“存储的字节 99.999999999%或更多不丢失”。虽然这可能是底层存储系统的提供,但我们的保证可能要逊色得多,因为我们正在编写与存储系统交互的软件。
一个重要的注意事项是,一些系统具有极其耐用的数据,即没有任何数据丢失,但却有可能出现故障模式,导致某些数据长时间无法访问。这可能包括需要从另一个较慢的存储系统(例如磁带驱动器)恢复数据,或者通过缓慢的网络连接从离线位置复制数据。如果这是原始数据并且对模型很重要,可能需要恢复它。但对于某种方式从现有原始数据派生的数据,可靠性工程师可能会考虑是否更容易仅重新创建数据而不是恢复它。
对于具有许多数据转换的机器学习存储系统,我们需要谨慎考虑这些转换的编写和监控方式。我们应该记录数据转换,并且如果负担得起的话,存储数据转换前后的副本。在数据从未管理状态转为管理状态的摄取过程中,跟踪数据是最困难的地方。由于我们建议在摄入过程中使用 API,这为确保数据存储、记录事务和确认接收数据提供了一个明确的位置。如果数据未能干净地和持久地接收,则发送系统当然可以重试发送操作,而数据仍然可用。
在数据转换的每个阶段,如果我们负担得起的话,应该存储数据的转换前后的副本。我们还应该监控转换的吞吐量以及预期的数据大小变化。例如,如果我们对数据进行 30%的抽样,则转换后的数据显然应该是转换前数据大小的 30%,除非发生错误。另一方面,如果我们通过分桶将浮点数转换为整数,根据数据表示的方式,我们可以预期结果数据大小保持不变。如果结果数据要么大得多要么小得多,那几乎可以肯定存在问题。
一致性
当我们从多台计算机访问数据时,我们可能希望保证每次读取的数据都是相同的;这就是一致性的特性。任何规模的机器学习系统通常都是分布式的。我们正在进行的大部分处理基本上是可以并行化的,并且假设从一开始就使用机器集群通常是值得的。这意味着存储系统将通过网络协议从其他计算机访问,并引入了可靠性方面的挑战。特别是,它引入了相同数据的不同版本可能同时存在的事实。很难保证数据在任何地方都是复制的、可用的和一致的。
是否模型训练系统关注一致性实际上是模型和数据的一个属性。并非所有的训练系统都对数据的不一致性敏感。就此而言,并非所有数据都对不一致性敏感。一个思考的方式是考虑数据的密集度或稀疏度。当每个数据片段所代表的信息很稀少时,数据是稀疏的。当每个数据片段所代表的信息很常见时,数据是密集的。当数据集中有大量零值时,数据是稀疏的。因此,如果yarnit.ai有 10 种畅销毛线,几乎代表了我们销售的全部内容,那么对于任何一种毛线的购买来说,数据是密集的——这不太可能教给我们太多新东西。如果一种畅销毛线的单次购买在我们的存储系统的一个副本中可读,而在另一个副本中不可读,模型基本上不会受到影响。另一方面,如果我们 90%的购买是不同种类的毛线,那么每一次购买都很重要。如果我们的某一部分训练系统看到了某种特定毛线的购买,而另一部分没有看到,我们可能会产生相对于该特定毛线或我们模型表示为与该毛线相似的毛线的不一致模型。在某些情况下,一致性很难保证,但通常情况下,如果我们可以稍等数据到达和同步,我们可以轻松地保证这一属性。
我们可以通过两种简单直接的方式消除数据层面的一致性问题。第一种是构建能够抵御不一致数据的模型。就像其他数据处理系统一样,机器学习系统也需要权衡。如果我们能够容忍不一致数据,特别是当数据最近写入时,我们可能能够显著加快模型训练速度并更便宜地操作我们的存储系统。在这种情况下的成本是灵活性和保证。如果我们选择这条路,我们就限制了自己只能无限期地在这些保证下操作存储系统,并且只能训练满足这一属性的模型。这是一个选择。
第二个选择是运行一个提供一致性保证的训练系统。对于一个复制的存储系统来说,最常见的做法是系统本身提供关于哪些数据是完全和一致地复制的信息。读取数据的系统可以消费这个字段,并选择仅在完全复制的数据上进行训练。这对存储系统来说通常更复杂,因为我们需要提供复制状态的 API。这可能也更昂贵或更慢。如果我们希望在摄入和转换后快速使用数据,我们可能需要为网络(复制数据)和存储 I/O 容量(写入副本)预留大量资源。
思考一致性需求是战略性决策。这对于平衡成本和能力具有长期影响,并且应该由机器学习工程师和组织决策者共同参与决策。
版本控制
机器学习数据集的版本管理,在许多方面与传统数据和/或源代码版本控制类似,用于书签化数据状态,以便将来应用特定版本的数据集进行后续实验。版本控制 在新数据可用进行重新训练时以及计划实施不同数据准备或特征工程技术时变得重要。在生产环境中,机器学习专家处理大量数据集、文件和指标,以进行日常操作。这些工件的不同版本需要在多次迭代中进行跟踪和管理。版本控制是管理众多数据集、机器学习模型和文件以及记录多次迭代的良好实践——即何时、为何以及做了什么修改。⁹
性能
存储系统需要足够快的写入吞吐量,以快速摄取数据而不影响转换速度。系统需要足够快的读取带宽,使我们能够根据适合我们建模行为的访问模式快速训练模型。值得注意的是,慢读取性能的代价可能相当高,因为机器学习训练通常使用相对昂贵的计算资源(如 GPU 或高端 CPU)。当这些处理器因等待训练数据而停滞不前时,它们只是在消耗周期和时间,而没有完成任何有用的工作。许多组织认为自己无法投资于其存储系统,但实际上它们无法承担不投资的后果。
可用性
我们写入的数据在我们阅读时需要存在。可用性 在某些方面是耐久性、一致性和性能的产物。如果数据存在于我们的存储系统中,并且被一致地复制,我们能够以合理的性能读取它,那么这些数据就算是可用的。
数据完整性
有价值的数据应当受到妥善对待。这意味着尊重数据的来源、安全性和完整性。¹⁰ 我们的数据管理系统将需要从一开始就设计这些特性,以便能够为我们提供的访问控制和其他数据完整性做出适当的保证。
数据完整性除了安全性和完整性外还有三个重要主题:隐私、政策合规性和公平性。值得花时间从总体角度考虑这些主题。我们需要确保理解这些领域所提出的要求,以便确保我们构建的存储系统和 API 能够提供我们所需的各种保证。
安全性
有价值的 ML 数据通常以私有数据的形式开始其生命周期。一些组织选择建立流程,从其数据存储中简单地排除所有 PII。出于几个原因,这是一个好主意。它简化了访问控制问题。它消除了数据删除请求的运营负担。¹¹ 最后,它消除了存储私人信息的风险。正如我们讨论过的,数据应该像资产一样被视为一种负债。
我们可能已经成功地从 ML 数据存储中排除了 PII。但是,出于两个原因,我们可能不应该完全依赖于此。一方面,我们可能没有像我们认为的那样有效地排除 PII。正如前面提到的,如果没有对添加到特征存储中的所有数据进行深思熟虑的人工审查,要识别 PII 是非常困难的,因此极有可能一些数据与其他数据结合在一起确实包含 PII。另一方面,对于许多组织来说,合理地从数据存储中排除所有 PII 可能根本不可行。因此,这些组织有义务强化对其数据存储的保护。
关于个人可识别信息(PII)的担忧之外,团队可能会针对特定类型的数据开发特定的使用方式。数据存储的合理使用将限制对某些数据的访问,仅允许最有可能需要和使用该数据的团队访问。深思熟虑地限制访问将实际上提高生产力,因为模型开发人员可以轻松访问(并且只访问)他们最有可能用于构建模型的数据。
在所有情况下,系统工程师应跟踪关于哪些开发团队构建了哪些模型以及哪些模型依赖于特征存储中哪些特征的元数据,这有效地形成审计跟踪。这些元数据对于操作和安全相关目的是有用的,如果不是必需的。
隐私
当 ML 数据涉及个人时,存储系统需要具有保护隐私的特性。将客户或合作伙伴的私人信息泄露是将数据从资产转变为负债的最快方式之一。
我们可以在处理私有数据方面做出两种不同的架构选择:消除或锁定。在我们仍然可以获得优秀结果的情况下,消除私有数据是一种极其合理的策略。如果我们防止 PII 数据被存储在数据存储系统中,我们就消除了大部分持有私有数据的风险。这可能会很困难——不仅因为识别私有数据并不总是容易,还因为在没有私有数据的情况下很难获得出色的结果。

图 2-5. 数据在 ML 系统中移动时的选择和处理
考虑到所有这些复杂性,将数据在摄取时进行匿名化要更好、更容易。如前所述,匿名化的话题在技术上很复杂,但每个构建机器学习系统的人都需要了解两个关键事实:
匿名化很难。
这是人们研究并发展专业知识的一个话题。不要试图随便应付。认真对待并做到完美。
匿名化取决于上下文
没有一种确保可以在不了解其他数据存在及其数据之间关系的情况下对数据进行匿名化的方法。
匿名化虽然困难,但并非不可能,而且在正确执行时,可以避免一系列其他问题。请注意,这样做会需要定期审查,以确保当前的匿名化仍符合在实施时对数据和访问权限的假设,以及每次添加新数据源时的审查,以确保数据源之间的连接不会破坏匿名化。关于这个主题,在第六章中有更详细的讨论。
策略与合规
策略和合规通常源自于你的组织之外的要求。在某些情况下,“组织之外”实际上指的是 YarnIt 的老板或律师执行外部的法律要求,而在其他情况下,它可能意味着国家政府直接介入。这些要求通常背后有痛苦而强大的理由,但通常在看待这些要求本身时并不明显。
这里有一个令人讨厌但又强有力的例子:关于浏览器中的 cookie 同意的欧洲法规经常给欧洲和非欧洲的网站用户们显得过于烦扰、侵入性或愚蠢。网站需要明确获得用户同意以在用户设备上存储标识符的想法可能看起来是不必要的。但任何了解第三方广告 cookie 侵犯隐私能力的人都可以证明,至少在一些对 cookie 的限制背后有一个非常强大的理由。虽然“对每个网站的每个用户都询问”的方式可能不是最优雅和可扩展的,但当我们更了解这些 cookie 如何被使用及保护用户隐私的难度时,这种做法就更容易理解了。
对数据存储的政策和合规要求应该认真对待。但单纯根据要求或标准的字面意思而不了解背后意图是一个错误。通常,整个咨询行业已经开发出了复杂的合规实践,而简单的方法也可能是合规的。
如前所述,匿名化是一种潜在的合规捷径。如果私人数据需要特别处理,也许可以通过确定(并记录)我们没有存储任何私人数据的方式来避免这些要求。
关于政策和治理要求,还有两件事需要注意:司法管辖区和报告。
司法管辖规则
当今世界上充斥着越来越多的政府,他们主张对存储在其地理位置中的数据处理进行控制。虽然原则上这似乎合理,但却并不完全符合过去几十年来构建网络计算机系统的方式。甚至对于一些云服务提供商来说,确保在一个国家生成的数据在该国家内处理可能都不可能。YarnIt 计划全球销售,即使我们可能最初只在少数几个国家推出。因此,我们必须仔细考虑需要遵守的数据存储和处理要求。
对于较大的组织来说,一个司法管辖区的选择比任何其他选择都更为重要:公司总部所在国家。这很重要,因为该国政府能够对存储在任何其他国家的数据行使权力。选择公司注册国可以对我们的数据管理系统产生深远的影响,但这并不是大多数人仔细考虑的因素。他们应该考虑。
报告要求
记住,合规工作需要报告。在许多情况下,报告可以融入我们监控服务的方式中。合规要求是服务水平目标(SLOs),报告包括服务水平指标(SLIs),这些指标确定了我们在合规 SLOs 方面的实施状态。这样考虑可以将这项工作与我们需要完成的其他实施和可靠性工作正常化。
结论
这是一个快速而肤浅的介绍(尽管可能并不感觉如此),以思考 ML 数据系统。此时,你可能还不太能够构建完整的数据摄入和处理系统,但应该清楚这样一个系统的基本要素。更重要的是,你应该能够识别出一些最大的风险和陷阱所在。为了在这方面取得实际进展,大多数读者将希望将他们的努力分成以下几个方面:
政策与治理
许多组织从产品或工程团队开始进行 ML 工作。正如我们所强调的,然而,长远来看,拥有一致的政策决策和一致的治理方法将至关重要。尚未开始这项工作的组织应立即着手。第六章 是一个很好的起点。
要在这个领域产生最大影响,你应该首先确定可能存在的最大问题或差距,并优先解决它们。考虑到当前我们对错误使用 ML 风险的理解及可用工具的现状,完美是不可能的。但绝对可以减少严重违规的情况,并且这是一个合理的目标。
数据科学与软件基础设施
如果我们已经开始使用机器学习,很可能我们的数据科学团队已经在组织的各个地方建立了定制的数据转换管道。清理、规范化和转换数据是正常操作,需要进行机器学习。为了避免未来的技术机器学习债务,我们应尽快开始建立软件基础设施,将这些转换管道集中起来。¹³
已经解决了自身问题的团队可能会对这种中心化产生抵触情绪。然而,通过将数据转换作为服务运行,有时可以吸引所有新用户甚至一些现有用户转移到中心化系统。随着时间的推移,我们应该努力将数据转换集中在一个单一、良好管理的地方。
基础设施
我们显然需要大量的数据存储和处理基础设施来有效管理机器学习数据。其中最重要的元素是特征存储系统(通常简称为特征存储)。我们在第四章详细讨论了特征存储系统的有用元素。
¹ 如果数据本身是可变的并且经常更新,也许还需要为数据的不同版本进行版本控制。
² 数据要想成为有用的,必须是高质量的(准确的、足够详细的、代表我们模型关心的世界事物)。对于监督学习来说,数据必须是一致且准确标记的——也就是说,如果我们有羊毛和针的图片,我们需要知道哪些是哪些,这样我们才能用这个事实来训练模型识别这些类型的图片。没有高质量的数据,我们就不能期望得到高质量的结果。
³ AOL 搜索日志案例是最著名的失败案例;详见 Michael Barbaro 和 Tom Zeller Jr.的“A Face Is Exposed for AOL Searcher No. 4417749”。这一事件也在维基百科的“AOL search log release”页面有所解释。
⁴ 与数据集的模型卡片相辅相成的方法称为数据卡片;详见数据卡片实战站点。
⁵ 更多详情请参见 Alexander J. Ratner 等人的“Learning to Compose Domain-Specific Transformations for Data Augmentation”。
⁶ 没有太多理由相信这是真的,但这个想法似乎有些合理和有趣。如果有人实现“源温度”作为一个功能,并发现它很有价值,请联系作者领取签名书。
⁷ 大多数常见的大数据存储和分析服务来自大型云提供商都是面向列的。Google Cloud BigQuery、Amazon RedShift 和 Microsoft Azure SQL Data Warehouse 都是面向列的,数据服务提供商 Snowflake 的主要数据存储也是如此。PostgreSQL 和 MariaDB Server 都有面向列的配置选项。
⁸ 数据科学家、数据分析师、研究科学家和应用科学家使用各种数据可视化工具和技术,包括信息图表、热力图、发烧图、面积图和直方图。欲知更多,请参考维基百科的“数据和信息可视化”页面。
⁹ 一些读者可能会看到“版本控制”就想到“Git”。像 Git 这样的基于内容索引的软件版本控制系统并不真正适用或必要于跟踪 ML 数据的版本。我们并非在进行数千次小而结构化的更改,而是通常在添加和删除整个文件或部分。我们需要的版本控制跟踪数据指向的内容,谁创建/更新了它,以及创建时间。许多 ML 建模和训练系统都包括一些版本控制。MLflow 就是一个例子。
¹⁰ 在“耐久性”一节中讨论的数据耐久性通常被包括为数据完整性的关键概念之一。由于整个章节都是关于数据管理的,耐久性已与可靠性概念一起分组,这里的 完整性 指的是我们可以对数据断言的属性,而不仅仅是其存在和可访问性。
¹¹ 一个有用的总结可以在 Databricks 的文章《最佳实践:使用 Delta Lake 实现 GDPR 和 CCPA 合规性》中找到,特别是关于化名处理的部分。
¹² 参见 Brendan McMahan 和 Daniel Ramage 的《联合学习:无需集中训练数据的协作机器学习》概述,以及至 2017 年该主题的合理链接。联合学习自然在那之后继续发展。
¹³ ML 系统中的技术债务通常与我们在其他软件系统中看到的情况有很大不同。详细解释这一点的一篇论文是《机器学习系统中的隐藏技术债务》,作者包括 D. Sculley(本书的共同作者)等人。
第三章:基础模型介绍
本书的大部分内容都关于管理机器学习系统和生产级别的机器学习流水线。这涉及到与许多数据科学家和机器学习研究人员通常从事的工作非常不同,后者试图花费大部分时间开发新的预测模型和方法,以提高精度的百分点。相反,在本书中,我们侧重于确保包含机器学习模型的系统表现出一致、强大和可靠的系统级行为。在某些方面,这种系统级行为独立于实际模型类型、模型有多好或其他仅与模型相关的考虑因素。然而,在某些关键情况下,它与这些考虑因素并不独立。本章的目标是为您提供足够的背景,以便在生产系统的警报开始响起或传呼机开始响起时,您能够理解自己所处的情况。
我们首先声明,我们的目标不是教你如何构建机器学习模型、哪些模型对于解决什么问题可能更好,或者如何成为数据科学家。那需要一本(或更多)书来详细讲解,并且有许多优秀的文本和在线课程涵盖了这些方面。
本章我们的目标不是过于深入地涉及细枝末节,而是提醒一下什么是机器学习模型以及它们如何工作。我们还将提供一些关键问题,供机器学习运营(MLOps)专家询问他们系统中的模型,以便他们能够理解如何适当地规划解决方案中可能出现的问题类型。
什么是模型?
在数学或科学中,术语模型指的是一种规则或指导方针,通常可以用数学或代码表达,它帮助处理输入并对未来世界可能运作的方式进行预测。例如,这里是一个你可能认识的著名模型:
E = mc²
这是一个可爱的小模型,告诉你,如果你把给定的质量(m)转化为一些超级炽热和爆炸性的东西,你可能会得到多少能量(E),而常数c²告诉你,即使只有一点点m,你也能得到相当大量的E。这个模型是由一位聪明的人精心思考了很长时间而创建的,在各种环境中表现良好。它不需要太多的维护,并且可以很好地泛化到各种设置中,甚至是最初创建时未曾设想的设置。
我们在机器学习中通常处理的模型在某些方面是相似的。它们接受输入并产生输出,这些输出通常被视为预测,使用的规则可以用数学符号或代码来表达。这些预测可以代表物理世界,比如“明天在西雅图下雨的概率是多少?”或者代表数量,比如“下个月从我们网站yarnit.ai上将卖出多少单位的毛线?”或者甚至代表抽象的人类概念,比如“这张图片对用户来说是否美观?”
一个关键的区别在于,我们通常用于机器学习的模型,不像E = mc²那样可以通过一个简洁的规则写出来,无论我们多么聪明。我们在需要考虑许多信息片段(通常称为特征)的情况下,会转向机器学习,因为这些信息片段很难事先由人类明确规定。一些可以作为特征处理的数据示例包括来自数千个位置的大气读数、图像中数千个像素的颜色值,或者最近访问在线商店的所有用户的购买历史。当处理这种复杂信息源的信息时——远不止一个质量值和一个缩放常数——通常对人类专家来说创建和验证利用所有可用信息的可靠模型是困难或不可能的。在这些情况下,我们转向使用大量先前观察到的数据。在使用数据来训练模型时,我们希望所得到的模型既能很好地适应我们的过去数据,又能在未来对新的、以前未见过的数据进行良好的预测。
基础模型创建工作流程
目前最广泛使用的用于创建机器学习模型的基本过程——正式称为监督学习——如下所示。
首先,我们收集关于我们问题领域的大量历史数据。这可能是过去 10 年太平洋西北部所有大气传感器的读数,或者是 50 万张图片的集合,或者是访问在线yarnit.ai网站的用户浏览历史日志。我们从这些数据中提取一组特征,即数据的特定可测量属性。特征以一种机器学习模型容易消化的方式表示数据的关键特性。对于数值数据,这可能意味着将值缩小以便在某些范围内很好地适应。对于结构化程度较低的数据,我们可能会设计出特定数量来识别和提取原始数据中的内容。一些示例包括可以表示诸如 1000 个传感器位置每个位置的大气压力的输入特征,或者给定毛线球的具体颜色和大小值,或者与每种可能产品对应的一组特征,如果给定用户查看了该产品则值为1,否则为0。
对于监督机器学习,我们还需要一种标签,显示我们希望我们的模型在未来看到类似情况时预测的历史结果。这可能是给定日期的天气结果,比如如果下雨则为1,如果没有则为0。或者它可以是一个尝试捕捉给定用户是否认为图像美观的分数,比如如果他们给出“赞”则为1,如果没有则为0。或者它可以是显示在给定月份销售的给定纱线产品的单位数量的值。或者纱线的颜色和尺寸等等。我们将记录每个条目的给定标签,并称每个条目为带标签的示例。
然后我们将在这些历史数据上训练一个模型,使用选择的模型类型和选择的机器学习平台或服务。目前,许多人选择使用基于深度学习,也被称为神经网络的模型类型,当提供非常大量的数据时效果特别好(想想数以百万计或数十亿的带标签示例)。¹ 神经网络根据训练中使用的示例在节点层之间建立连接。
在其他设置中,像随机森林或梯度增强决策树这样的方法在提供较少示例时效果很好。² 而更复杂、更大的模型也不总是首选,无论是出于预测能力还是可维护性和可理解性。那些不确定哪种模型类型可能最适合的人经常使用自动化机器学习(AutoML)这样的方法,它训练多个模型版本,并尝试自动选择最佳模型。即使没有 AutoML,所有模型都有必须为每个任务专门设置的调整和设置,称为超参数,通过一种称为调优的过程,这实际上只是试错的一个花哨名称。无论如何,在最后,我们的训练过程将产生一个模型,该模型将获取新示例的特征输入并生成预测作为输出。模型的内部很可能被视为不透明并抵制直接检查,通常由数千、数百万甚至数十亿个学习参数组成,显示如何结合输入特征(并可能在许多进一步的中间阶段重新组合它们)以创建最终输出预测。
从系统工程的角度来看,我们可能会注意到一些令人不安的事情。通常情况下,没有人知道什么是“正确”的模型。我们无法仅凭我们的知识查看通过训练生成的模型并知道它是好还是坏。我们能做的最好的事情是对其进行各种压力测试和验证,并希望我们提出的压力测试和验证足以捕捉模型将被要求处理的各种情况的范围。³
最基本的验证形式是从我们准备好的训练数据中随机留出一部分,称之为留出测试集。我们不使用这部分数据进行训练,而是等待并将其用于对模型进行压力测试,理由是模型在训练过程中从未见过这些留出的数据,因此可以很好地用作我们希望其进行有用预测的以前未见数据的代表。因此,我们可以将测试集中的每个示例输入到模型中,并将其预测与真实结果标签进行比较,以查看其表现如何。非常关键的一点是,这些验证数据确实应该在训练过程中留出,因为模型很容易出现过拟合,即模型完美地记住了训练数据,但在新的未见数据上预测能力很差。
一旦我们对模型的验证感到满意,就该将其部署到整体生产系统中。这意味着找到一种方法来服务模型预测,以满足需求。其中一种方法是为所有可能的输入预先计算所有可能的预测结果,并将它们写入我们的系统可以查询的缓存中。另一种常见方法是从生产系统创建输入流,并将其转换为特征,以便可以按需将其馈送到我们模型的副本中,然后将模型的结果预测反馈到更大的系统中供使用。这两种选项都可以在第八章的背景下理解。
如果一切顺利,我们就完成了。然而,世界充满了不完美,我们对世界的模型更是如此。在 MLOps 世界中,即使是最小的问题也可能造成严重后果,因此我们需要有所准备。让我们快速浏览一下可能会变成潜在问题的一些领域。
模型架构与模型定义与训练后的模型
术语模型经常被不精确地用来指称三个独立但相关的概念:
模型架构
我们在这个应用程序中使用的学习策略。这可以包括模型家族的选择,例如深度神经网络(DNN)或随机森林,以及结构选择,例如 DNN 中的层数或随机森林中的树木数量。
模型定义(或配置模型)
模型配置加上训练环境,以及我们将进行训练的数据类型和定义。这包括所有使用的特征集、所有超参数设置、用于初始化模型的随机种子,以及用于定义或复现模型的任何其他方面。可以合理地将其视为整个训练环境的封闭(详见 4),尽管许多人并未考虑到这一点的可靠性或系统影响(特别是需要非常大量的软件和数据相互版本化,以获得合理的可复现性)。
训练模型
系统配置模型的特定快照或实例化表示,在特定时间点上使用特定数据进行训练,包含一组特定的训练模型参数,例如权重和阈值。需要注意的是,我们在机器学习中使用的一些软件,特别是在分布式部署中,存在相当多的非确定性。因此,同样的系统配置模型在相同数据上训练两次可能会产生明显不同的训练模型。
尽管在本书中我们尽力避免混淆这些概念,请注意它们在整个行业中并未仔细区分,我们自身也可能偶尔不清楚。大多数人称这三个概念都为模型。即使这些术语是我们自己创造的,因为目前没有行业标准术语来区分模型的不同用法。
哪里存在漏洞?
从系统可靠性的角度来看,依赖机器学习的系统存在多个容易出错的弱点。在本节中,我们简要触及了其中的一些领域,稍后的章节将更深入地探讨这些主题。需要注意的是,这里我们讨论的不是安全漏洞,而是可能导致故障或模型质量问题的结构性或系统性弱点。本节旨在列举一些模型失败的最常见方式。
训练数据
训练数据是定义系统行为的基础要素。训练数据的质量决定了我们的模型和系统的质量和行为,而训练数据的不完美可能会以出人意料的方式放大。从这个角度看,数据在机器学习系统中的作用可以类比于传统系统中的代码。但与传统代码不同的是,传统代码可以用前置条件、后置条件和不变量描述,并且可能经过系统化的测试,而真实世界的数据通常存在有机的缺陷和不规则性。这些问题可能导致多种问题类型。
覆盖不完整
需要考虑的第一个问题是,我们的训练数据可能以各种方式不完整。想象一下,我们有大气压力传感器,在冰冻天气下停止工作,因此在寒冷天气没有数据。这对模型来说形成了一个盲点,特别是当被要求在这种情况下进行预测时。这里的一个困难是,这类问题不能通过使用保留测试集来检测,因为按定义,保留集是我们已经可以访问的数据的随机样本。发现这些问题需要仔细思考和辛勤工作的结合,以收集或合成额外的数据,这些数据可以帮助在验证时暴露这些缺陷或在训练时进行修正。
虚假相关
数据中不总是在现实世界中适用的相关性形成的特殊形式的不完整覆盖。例如,想象所有被标记为“美观”的图像都包含白色画廊墙壁,而标记为“不美观”的图像则没有。在这些数据上训练可能会导致一个模型,在保留测试数据上显示非常高的准确性,但本质上只是一个白墙检测器。在实际数据上部署这种模型可能会产生可怕的结果,尽管在保留测试数据上表现出色。
再次,揭示这类问题需要仔细考虑训练数据,并通过选择良好的示例有针对性地测试模型在各种情况下的行为。这类问题的一个重要类别可能在社会因素创建某些群体缺乏包容或代表性时发生;这些问题在第六章中有所讨论。
冷启动
许多生产建模系统随着时间在部署中收集额外的数据,并进行重新训练或更新以整合这些数据。这类系统在初始数据较少时可能会遇到冷启动问题。这种情况可能发生在最初未设置为收集数据的系统上,例如天气服务希望使用以前从未部署过的新创建的传感器网络。它也可能出现在推荐系统中,例如那些向用户推荐各种纱线产品,并观察用户交互数据进行训练的系统。这些系统在它们生命周期的最开始阶段可能几乎没有或没有训练数据,并且随着时间推出新产品,也可能会遇到个别物品的冷启动问题。
自我实现的预言和机器学习回声室
许多模型用于反馈循环中,它们过滤数据、推荐物品或选择行动,然后在未来创建或影响模型的训练数据。帮助用户推荐纱线产品的模型可能只会在实际显示给用户的前几个排名上得到未来反馈。对话代理可能只会得到它选择创建的句子的反馈。这可能导致一种情况,即未被选中的数据永远得不到正面反馈,因此在模型的估计中永远不会占据主导地位。解决这个问题通常需要有意识地探索低排名数据,偶尔选择展示或尝试模型当前认为不太好的数据或行动,以确保在全范围可能性的训练数据中保持合理的流动。
世界变化
人们很容易认为数据反映了现实,但不幸的是,它实际上只是某个特定时间世界某个部分的历史快照。这种区别在真实世界事件引起变化时可能显得有些哲学,但有时变得至关重要。实际上,如果明天发生类似 COVID 风格的封锁,没有比向组织的高管领导提出“如果明天发生另一场 COVID 风格的封锁,我们的模型会发生什么变化?”更好的方法来说服他们关于 MLOps 的重要性了。
例如,想象一下我们的模型帮助根据先前用户预订反馈推荐酒店。很容易想象这样一种情况,即 COVID 风格的封锁突然导致酒店预订大幅下降,这意味着在预封锁数据上训练的模型现在显得极其乐观。由于它在较新的数据上学习,许多较少的预订发生,很容易想象它在稍后解除封锁并且用户希望再次预订更多酒店房间时可能表现得非常糟糕——只是发现系统无法推荐任何内容。
这些基于真实世界事件的互动和反馈循环并不局限于重大世界灾难。以下是一些可能发生在各种环境中的其他情况:
-
在某个国家的选举之夜,视频的观看行为突然有所不同。
-
新产品的推出迅速引起了对某种羊毛的用户兴趣激增,但我们的模型没有任何关于它的先前信息。
-
预测股票价格的模型出现错误,对某只股票过度预测。使用该模型的自动对冲基金随后错误地购买了该股票——在真实市场中提高了价格,并导致其他自动对冲基金模型效仿。
标签
在监督学习中,训练标签提供了“正确答案”,展示了模型在给定示例中应该尝试预测的内容。标签是至关重要的指导,向模型展示了它的目标,通常定义为一个数值分数。以下是一些例子:
-
对于电子邮件垃圾邮件过滤模型,“垃圾邮件”为
1,“非垃圾邮件”为0的分数。 -
西雅图某一天的每日降雨量,以毫米为单位。
-
一组可能完成给定句子的每个可能单词的标签,如果它是实际完成给定句子的单词则为
1,否则为任何其他单词。 -
在给定图像中每个对象类别的一组标签,如果该对象类别在图像中显著出现则为
1,否则为0。 -
数值分数显示特定抗体蛋白质在湿实验室实验中与给定病毒结合的强度。
由于标签对模型训练非常重要,很容易看出,标签问题可能是许多下游模型问题的根本原因。让我们看一些例子。
标签噪声
在统计语言中,“噪音”一词是“错误”的同义词。如果我们提供的标签由于某种原因是错误的,这些错误可能会影响模型的行为。在某些情况下,随机噪音可能是可以容忍的,如果错误随时间平衡,则尽管如此,测量和评估仍然很重要。更为严重的是数据中特定部分发生的错误,例如,如果一个人类标签员经常将青蛙错误地标记为蟾蜍,用于水生图像模型,或者一组特定用户一直被某种类型的电子邮件垃圾邮件欺骗,或者在实验中发生了一种污染,使得一组给定的抗体无法结合给定类别的病毒。
因此,定期检查和监控标签的质量并解决任何问题至关重要。在使用人类专家提供训练标签的系统中,这通常意味着对任务规范的文档进行极其细致的关注,并为人类本身提供详细的培训。
错误的标签目标
机器学习训练方法倾向于极其有效地学习预测我们提供的标签,有时候甚至会揭示我们希望的标签含义与实际代表的差异。例如,如果我们的目标是使yarnit.ai网站的客户长期满意,可能很容易希望“购买”标签与满意的用户会话相关联。这可能导致一个过于关注购买的模型,也许随着时间的推移学习推广看似是好交易但实际上令人失望的产品。另一个例子,考虑使用用户点击作为用户对新闻文章满意度的信号的问题,这可能导致突出显眼的点击诱饵标题或甚至过滤泡泡效应的模型,即用户不会看到与他们预设看法相左的新闻文章。
欺诈或恶意反馈
许多系统依赖于用户的信号或观察到的人类行为来提供训练标签。例如,一些电子邮件垃圾邮件系统允许用户将消息标记为“垃圾邮件”或“非垃圾邮件”。很容易想象,一个积极的垃圾邮件发送者可能会试图欺骗这样的系统,通过向其自己控制的账户发送大量垃圾邮件,并尝试将它们标记为“非垃圾邮件”,以试图破坏整体模型。同样可以想象,试图预测某种产品在用户评论中将收到多少颗星的模型可能潜在地易受到恶意行为者的攻击,这些人可能会试图高估自己的产品,或低估竞争对手的产品。在这种情况下,谨慎的安全措施和对可疑趋势的监控是长期系统健康的关键组成部分。
除了开发完整和代表性数据集或正确标记示例的问题之外,我们在模型训练过程中还可能遇到对模型的威胁。标签和标记系统在第四章中会更详细地讨论。
训练方法
一些模型只训练一次,然后很少或从不更新。但大多数模型在其生命周期的某个时刻会更新。这可能每隔几个月一次,例如从抗体测试中获得另一批湿实验数据,或者每周一次,以整合新的图像数据和相关的物体标签,或者在流媒体设置中每隔几分钟一次,根据用户浏览和购买各种羊毛产品的新数据进行更新。平均而言,每次新的更新都预期会改善整体模型,但在特定情况下,模型可能会变得更差甚至完全失效。以下是一些可能导致这种头痛的原因。
过拟合
如同我们在典型模型生命周期简要概述中所讨论的,一个好的模型能够很好地推广到新的、之前未见过的数据,并不仅仅是狭义地记忆训练数据。每次重新训练或更新模型时,我们需要使用留出的验证数据来检查过拟合情况。但如果我们始终重复使用同样的验证数据,那么就有可能潜在地对这些重复使用的验证数据过拟合的风险。
因此,定期更新验证数据并确保我们不会自欺欺人非常重要。例如,如果我们关于yarnit.ai上的购买验证数据集从未更新,而我们的客户行为随时间改变以偏爱更亮的羊毛,我们的模型将无法跟踪到这种购买偏好的变化,因为我们会评分那些学习这种行为的模型为“质量较低”的模型,而不是不学习这种行为的模型。重要的是,模型质量评估要包括对模型性能的现实世界确认。
缺乏稳定性
每次重新训练模型时,无法保证其预测从一个模型版本到另一个版本是稳定的。一个版本的模型可能在识别猫方面表现出色,但在狗方面表现较差,而另一个版本在狗方面可能更好,但在猫方面可能不太好——即使两个模型在验证数据的整体准确率上相似。在某些情境下,这可能成为一个重要问题。
例如,想象一个用于检测信用卡欺诈并关闭可能已被损害的卡片的模型。一个精度为 99%的模型在一般情况下可能非常好,但如果模型每天重新训练,并在不同的 1%用户中出现错误,则在三个月后,潜在地整个用户群可能会因为错误的模型预测而受到不便。评估我们关心的预测的相关子集上的模型质量非常重要。
深度学习的特殊性
近年来,深度学习方法因其在许多领域中实现极强的预测性能而变得非常重要。然而,深度学习方法也伴随着一套特定的脆弱性和潜在的漏洞。因为它们被广泛使用,并且从 MLOps 的角度看具有特定的特殊性和关注点,所以我们特别详细地介绍了深度学习模型。
当从头开始训练深度学习模型——没有任何先验信息时,它们从一个随机的初始状态开始,并且以随机顺序接收大量的训练数据,通常是小批量的。模型做出其当前的最佳预测(初始阶段通常很糟糕,因为模型尚未学到很多知识),然后显示正确的标签。一旦计算出数学上的损失梯度,模型的内部就应该更新。使用这个损失梯度时,会对模型的内部进行小的更新,试图让模型稍微好一点。这种在随机顺序的小批量上进行小修正的过程被称为随机梯度下降(SGD),并且重复进行数百万次或数十亿次。我们在决定模型在留置验证数据上表现良好后停止训练。
关于这个过程的关键见解如下:
深度学习依赖于随机化。
在初始的随机状态中,数据以随机顺序显示。在大规模并行设置中,由于网络和并行计算效应,更新的方式甚至在处理方式上也有随机性。因此,使用相同的设置和数据反复训练相同的模型可能会导致最终模型有显著不同。
很难确定训练何时“完成”。
在保留验证数据上,随着额外的训练步骤,模型的性能通常会提高,但有时在早期会反弹,后来如果模型开始过度拟合训练数据,性能往往会显著恶化。当性能收敛到良好水平时,我们停止训练并选择最佳模型,通常选择显示中间良好行为的 检查点 版本。不幸的是,我们现在看到的性能是否是训练进一步继续时能够达到的最佳性能,目前没有正式方法能够知晓。事实上,最近针对广泛模型发现的 双峰 现象表明,我们以前对何时停止训练的概念可能不是最优的。⁵
深度学习模型有时在训练中会爆炸。
我们采取小步而非大步的原因在于,很容易在数学上掉入悬崖,并将模型内部置于难以恢复的状态。事实上,爆炸梯度 是一个表示适当危险的技术术语。陷入此状态的模型通常在预测或中间计算中产生 NaN(不是一个数)值。这种行为也可能表现为模型的验证性能突然恶化。
深度学习对超参数非常敏感。
正如前面提到的,超参数是必须调整的各种数值设置,以使机器学习模型在任何给定任务或数据集上达到最佳性能。其中最明显的是 学习率,它控制每次更新步骤的大小。步长越小,模型爆炸或产生奇怪预测的可能性就越小。但是训练时间越长,使用的计算量就越大。其他设置也会产生显著影响,如内部状态的大小或复杂性、小批量的大小以及如何强力地应用各种抑制过拟合的方法。深度学习模型对这些设置非常敏感,这意味着需要进行大量的实验和测试。
深度学习资源消耗大。
SGD 的训练方法在生成良好模型方面非常有效,但依赖于极其庞大数量的微小更新。实际上,用于训练某些模型的计算量可能相当于数千个 CPU 核心连续运行数周。
当深度学习方法出错时,可能会出错得很严重。
深度学习方法对其训练数据进行外推,这意味着新的、之前未见的数据点越不熟悉,极端预测的可能性越大,可能完全偏离基准或超出典型行为范围。这类高度自信的错误可能是系统级误行为的重要源头。
现在您已经了解了模型创建可能出现的问题结构,可能有必要从更广泛的视角看待首先训练模型所需的基础设施。
基础设施和流水线
模型只是更大的机器学习系统中的一个组件,这些系统通常由显著的基础设施支持,用于支持一个或多个流水线中的模型训练、验证、服务和监控。因此,这些系统继承了传统(非机器学习)流水线和系统的所有复杂性和脆弱性,以及机器学习模型的复杂性。我们不会在这里详述所有传统问题,但将重点介绍一些传统流水线问题在基于机器学习的系统中凸显出来的领域。
平台
现代机器学习系统通常构建在一个或多个机器学习框架之上,例如 TensorFlow、PyTorch 或 scikit-learn,甚至是诸如 Azure 机器学习、Amazon SageMaker 或 Google Cloud Vertex AI 这样的集成平台。从建模的角度来看,这些平台使开发人员能够以极快的速度和灵活性创建模型,并在许多情况下利用诸如 GPU 和 TPU 或基于云的计算而无需额外的工作。
从系统角度来看,使用这些平台会引入一组通常超出我们控制范围的依赖关系。我们可能会遇到包升级、修复可能不兼容旧版本的问题,或者组件可能不兼容新版本的问题。发现的错误可能难以修复,或者我们可能需要等待平台所有者优先接受我们提出的修复措施。总体而言,使用这些框架或平台的好处几乎总是超过这些缺点,但仍然必须考虑并纳入任何长期维护计划或 MLOps 策略中。
另一个需要考虑的因素是,由于这些平台通常是作为通用工具创建的,因此我们通常需要创建大量的适配器组件或粘合代码,帮助我们将原始数据或特征转换为平台使用的正确格式,并在服务时与模型进行接口交互。这些粘合代码很快就会在大小、范围和复杂性上变得重要,并且重要的是像系统的其他组件一样进行测试和监控支持。
特征生成
从原始输入数据中提取信息性特征是许多机器学习系统的典型部分,可能包括以下任务:
-
在文本描述中进行单词标记化
-
从产品列表中提取价格信息
-
将大气压力读数分成五个粗略桶(通常称为量化)
-
查找用户帐户的最后登录时间
-
将系统时间戳转换为当地的时间
大多数这些任务都是将一种数据类型转换为另一种的简单转换。它们可能像是将一个数字除以另一个数字那样简单,也可能涉及复杂的逻辑或请求其他子系统。无论如何,重要的是要记住,在特征生成中的错误可能是机器学习系统中最常见的错误来源。
特征生成之所以成为漏洞的焦点有几个原因。首先是特征生成中的错误通常不会通过聚合模型性能指标(如保留测试数据上的准确性)可见。例如,如果我们的温度传感器读数分桶方式存在 bug,它可能会稍微降低准确性,但我们的系统也许会通过更依赖其他特征来弥补这个 bug。特征生成代码中的 bug 被发现并在生产环境中运行数月甚至数年而未被检测到,这种情况可能会出奇地常见。
特征生成错误的第二个来源是,在训练时间和服务时间计算相同逻辑特征的方式不同。例如,如果我们的模型依赖于设备模型的本地化时间,当训练数据计算时可能通过全局批处理作业计算,但在服务时间可能直接从设备查询。服务路径中的 bug 可能会导致预测错误,由于缺乏地面真实验证标签,这些错误可能难以检测。我们在第九章中介绍了这一重要情况的一组监控最佳实践。
特征生成错误的第三个主要来源是我们的特征生成器依赖于一个上游依赖项,而该依赖项出现故障或遭遇中断时会出现问题。例如,如果我们用于生成羊毛购买预测的模型依赖于向另一个服务的查找查询,该服务报告用户评价和满意度评级,那么如果该服务突然下线或停止返回合理的响应,我们的模型将遇到严重问题。在实际系统中,我们的上游依赖项通常也有它们自己的上游依赖项,我们确实容易受到它们全部影响的风险。
升级和修复
特别微妙的一个领域是,在我们的模型中,上游依赖项可能因为上游系统进行升级或修复 bug 而导致问题。修复 bug 会导致问题似乎有些奇怪。要记住的原则是更好不一定是更好,更好是不同的——而不同可能是坏的。
这是因为我们模型期望看到与某些数据相关联的特征值分布的任何更改可能会导致错误行为。例如,假设我们在天气预测模型中使用的温度传感器在代码中有错误,当应该报告摄氏度时报告华氏度。我们的模型学习到 32 度是冰冻的温度,90 度是西雅图附近的炎热夏日。如果聪明的工程师注意到这个 bug,并修复温度传感器代码以发送摄氏度值,模型将看到 32 度的值并假设世界是冰冷的,而实际上是炎热和晴朗的天气。
这种漏洞形式有两个关键的防御措施。第一个是与上游依赖方就在其发生之前告警这类变更达成强有力的一致。第二个是创建特征分布的监控,并对变更进行警报。这也在第九章中更详细地讨论。
有关任何模型的一组有用问题
研究人员和学者往往关注 ML 模型的数学特性。在 MLOps 中,我们可以找到不同一套问题集,这些问题将帮助我们理解我们的模型和系统可能出错的地方,如何在问题发生时修复问题,以及如何预防性地为长期系统健康进行工程设计:
训练数据从何而来?
这个问题是概念性的——我们需要完全理解训练数据的来源以及它们应该表示的内容。如果我们正在寻找电子邮件垃圾邮件,我们是否能够访问路由信息,并且这些信息是否能够被恶意行为者篡改?如果我们在建模用户与纱线产品的互动,它们以什么顺序显示,并且用户如何在页面中移动?我们没有访问的重要信息是什么,以及其原因是什么?是否有关于数据访问或存储的政策考虑,尤其是涉及隐私、伦理考虑或法律或监管限制的问题?
数据存储在哪里,如何进行验证?
这是上一个问题的更直接的一面。数据存储在一个大型平面文件中,还是跨数据中心共享?最常见或最有效的访问模式是什么?是否应用了任何聚合或抽样策略,可能会降低成本但会丢失信息?隐私考虑如何执行?给定数据存储多长时间,如果用户希望从系统中删除他们的数据会发生什么?我们如何知道存储的数据没有以某种方式被损坏,信息源是否不完整,以及我们可以应用哪些健全性检查和验证?
特征是什么,它们是如何计算的?
特征,我们从原始数据中提取的信息,以便机器学习模型轻松消化,通常是模型开发人员采用“越多越好”的方式添加的。从运维的角度来看,我们需要全面了解每个单独的特征,它是如何计算的,以及验证结果的方式。这很重要,因为特征计算层面的错误可以说是系统层面问题的最常见源头。与此同时,这些错误通常是传统机器学习验证策略难以检测到的最困难的部分——一个留置的验证集可能会受到相同特征计算错误的影响。正如之前建议的,最阴险的问题通常是在训练时由一个代码路径计算特征——例如为了优化内存效率——而在实际部署的服务时由另一个代码路径计算特征——例如为了优化延迟。在这种情况下,模型的预测可能会出错,但我们可能没有地面真实验证数据来检测这一问题。
模型在哪些类型的例子上表现最差?
几乎所有的机器学习模型都是不完美的,在某些类型的例子上预测会出错。花时间查看模型在错误预测上的数据是很重要的,理解任何共同点或趋势,这样我们可以确定这些失败模式是否会在重要的下游用例中产生影响。这通常需要一定的手动工作,实际的人类查看实际的数据以完全理解,除了更高层次的摘要之外。
模型如何随时间更新?
一些模型很少更新,例如在大批量数据上训练的自动翻译模型,每隔几个月推送到设备应用程序一次。其他模型则更新非常频繁,例如邮件垃圾过滤器模型,必须始终保持最新状态,因为垃圾邮件发送者会不断演变并开发新的技巧以尝试避免检测。然而,可以合理地假设所有模型最终都需要更新,并且我们将需要建立结构来确保在任何模型新版本投入使用之前进行全套验证检查。我们还需要与组织内的模型开发人员达成明确的协议,确定谁负责评估模型性能是否足够,以及如何处理预测准确性问题。
我们的系统如何适应更大的环境?
我们的 ML 系统很重要,但与许多复杂数据处理系统一样,它们通常只是更大系统、服务或应用的一部分。我们必须深入了解我们的 ML 系统如何适应更大的整体架构,以防止问题并在问题出现时进行诊断。我们需要了解所有在训练时和服务时为我们的模型提供数据的上游依赖项,并了解它们可能如何更改或失败,以及发生这种情况时我们如何收到警报。同样,我们需要知道我们模型预测的所有下游消费者,以便在我们的模型遇到问题时适时地通知它们。我们还需要了解模型预测如何影响最终用例,如果模型是任何反馈环路的一部分(直接或间接),以及是否存在任何循环依赖,如时间、星期几或年度效应。最后,我们需要了解像准确性、新鲜度和预测延迟等重要的模型质量在更大系统背景下的重要性,以确保这些系统级要求得到良好的建立并随着时间推移得到满足。
最坏的情况是什么?
或许最重要的是,我们需要知道如果 ML 模型在任何方面失败,或者针对给定输入给出最坏的预测时,更大系统会发生什么情况。这种知识可以帮助我们定义防护栏、备用策略或其他安全机制。例如,股价预测模型可能会在几毫秒内使对冲基金破产⁶,除非制定了限制某些购买行为或金额的具体防护栏。
一个示例 ML 系统
为了帮助我们对基本模型的介绍有所了解,我们将漫游一些示例生产系统的结构。我们将在这里详细讨论,以便您开始看到前面列出的一些重要问题的答案,但我们也将深入研究这个示例的特定领域。
Yarn 产品点击预测模型
在我们的虚构 yarnit.ai 网站上,ML 模型应用于许多领域。其中之一是预测用户选择给定羊毛产品列表的可能性。在这种设置中,良好校准的概率估计对于排列和排序可能的产品(包括毛线、各种针织针类型、图案以及其他毛线和针织配件)非常有用。
特征
在这种设置中使用的模型是一个深度学习模型,它以以下一组特征作为输入:
从产品描述文本中提取的特征
这些包括文本的标记化单词,但也特别识别特征,例如纱线量、针的尺寸和产品材料。由于这些特征在来自不同制造商的产品描述中以各种方式表达,因此每个特征由专门训练的单独组件模型预测,以识别产品描述文本中的该特征。这些模型由一个独立的团队拥有,并通过一个有时会中断的网络服务提供给我们的系统。
原始产品图像数据
将原始产品图像输入模型之前,首先将其归一化为 32 × 32 像素的正方形格式,方法是将图像压缩至适合正方形并平均像素值以创建低分辨率近似。如图 3-1 所示,以前大多数制造商提供的图像几乎是正方形的,并且产品很好地居中于图像中。近年来,一些制造商开始提供更宽的横向格式图像,必须更多地压缩才能变成正方形,而且产品本身通常显示在额外的环境设置中,而不是在纯色背景上。

图 3-1. 变尺寸和格式的原始产品图像(图片由 Vecteezy 提供)
前用户搜索和点击行为
基于用户接受的带有适当隐私控制的 cookie 的记录历史被转换成功能,显示用户以前查看、点击或购买的先前产品。因为一些用户不接受使用 cookie,所以并非所有用户在训练或预测时都有这种形式的信息可用。
与用户搜索查询或导航相关的功能
用户可以输入诸如“粗黄色丙烯酸纱线”或“木质 8 号针”的搜索查询,或者通过点击上一页中列出的各种主题标题、导航栏或建议到达某个页面。
与产品在页面上的放置相关的功能
因为出现在列表结果较高位置的产品比列表较低的产品更可能被查看和点击,因此在训练时有功能来显示产品在数据收集时的列表位置非常重要。然而,请注意,这引入了一个棘手的依赖性问题——在服务时我们无法知道这些功能的值,因为页面上结果的排名和排序取决于我们模型的输出。
功能标签
我们模型的训练标签是一个简单的映射,如果用户点击了产品则为1,如果用户没有点击则为0。然而,在时间上我们需要考虑一些细微之处——用户可能会在任务中间分心一段时间,然后稍后返回并点击产品,时间间隔可能会达到几分钟甚至几个小时。因此,对于这个系统,我们允许一个小时的窗口期。
此外,我们已经检测到一些不道德的制造商试图通过重复点击他们的产品来提升其产品列表的排名。其他一些更微妙但同样不良意图的制造商则试图通过发出许多查询来降低其竞争对手的排名,而不实际点击它们。[⁷] 这两者都是欺诈或垃圾行为的尝试,在将这些数据用于训练模型之前需要进行过滤。这种过滤是通过每隔几小时运行的大型批处理作业来完成的,以查找趋势或异常,并避免复杂情况。然而,有时这些过滤作业会失败,这可能会给我们的系统引入显著的额外延迟。
模型更新
我们常把我们的模型描述给高管们听作是“持续更新的”,以便适应新的趋势和新产品。然而,系统中存在一些固有的延迟。首先,我们需要等待一个小时来确认用户是否确实没有点击给定的结果。接着,我们需要等待上游处理流程尽可能地过滤掉垃圾或欺诈行为。最后,生成训练数据的特征提取作业需要批处理资源,并且会引入数小时的延迟。因此,实际上,我们的模型会在用户查看或点击给定产品后约 12 小时进行更新。这是通过合并更新模型的数据批次来实现的。
从头开始完全重新训练模型需要回到历史数据并按顺序重新审视这些数据,目的是模仿随时间推移新数据的同一序列。这是在系统中添加新模型类型或额外功能时由模型开发人员不时执行的操作。有关更多详细信息,请参阅第十章。
模型服务
幸运的是,我们的在线商店非常受欢迎——我们每秒收到数百个查询,这对于全球针织产品市场来说并不差。对于每个查询,我们的系统需要快速评分候选产品,以便在用户开始感知等待时间之前的两到三十分之一秒内返回一组产品列表。因此,我们的机器学习系统需要低延迟服务。为了优化这一点,我们在基于云的计算平台上创建大量的服务副本,以便请求不必要地排队等待。每个副本每隔几小时重新加载以获取模型的最新版本。(我们将在第八章中更详细地讨论模型服务的各个方面。)
因为模型在运行中实时更新并提供服务,我们的系统有几个需要监控的领域,以确保实时性能继续良好。这些领域包括以下内容:
模型新鲜度
模型是否定期更新?新的检查点是否成功被服务副本接收?
预测稳定性
随着时间的推移,聚合统计数据大致与最近的历史相符吗?我们可以查看基本可验证的内容,如每分钟进行的预测数量和平均预测值。我们还可以监控随时间变化的点击数是否与随后看到的点击数相匹配。
特征分布
我们的输入特征是系统的生命线。我们监控每个输入特征的基本聚合统计数据,以确保这些数据随时间保持稳定。对于某个特定特征的值突然变化可能表明上游故障或其他需要管理的问题。
当然,这只是一个起始集合——我们将在第九章中详细讨论监控选项。
常见故障
思考最坏情况有助于我们做好准备。每种情况通常与整体产品需求和要求相关,因为最终影响到我们整体产品生态系统的才是真正重要的。这些最坏情况如下:
无限延迟
可能发生的一种坏事是我们的模型永远不返回值。也许是因为服务副本超负荷或全部因某些原因关闭。如果系统无限期挂起,用户将永远无法获得任何结果。基本的超时和合理的后备策略将在这里有所帮助。一种后备策略可以是在超时情况下使用成本更低、更简单的模型。另一种可能是预先计算一些最受欢迎项目的预测,并将其用作后备预测。
所有预测都为零
如果我们的模型对所有产品评分为0,则不会向用户显示任何产品。当然,这表明模型存在问题,但如果情况出现异常,我们需要监控平均预测并切换到另一个系统。
所有预测都不好
想象一下我们的模型被损坏,或者输入特征信号变得不稳定。在这种情况下,我们可能会得到任意或随机的预测结果,这会令用户困惑,导致用户体验不佳。为了应对这种情况,一个方法可能是同时监控预测的总体方差和平均值。这也可能发生在预测的子集中,因此我们可能需要监控相关预测的子集。
模型偏好于仅仅少数几个
想象一下,一些产品恰好获得了非常高的预测值,而其他一切都获得了低预测值。天真地说,这可能会导致其他产品,或者随着时间推移的新产品,永远没有机会展示给用户,从而也无法获得点击信息来帮助它们在排名中上升。在这些情况下,小量的随机化可以有所帮助,以确保模型获得一定量的探索数据,这将使模型了解以前未展示的产品。这种探索数据形式也对监控很有用,因为它允许我们验证模型的预测,并确保当模型表示某个产品不太可能被点击时,这在现实中也是正确的。
显然,许多其他问题可能出现,幸运的是,MLOps 人员在这方面往往有强大和积极的想象力。通过这种方式思考场景,使我们能够健壮地准备我们的系统,并确保任何故障不会是灾难性的,并且可以迅速解决。
结论
在本章中,我们已经介绍了一些机器学习模型的基础知识,以及它们如何适应依赖机器学习的整体系统。当然,我们只是初步涉及了这些主题领域的表面。在后续章节中,我们将更深入地探讨我们在这里提到的几个主题。
这里有几点希望您能记住:
-
模型的行为是由数据决定的,而不是由正式的(程序)规范决定的。
-
如果我们的数据发生变化,我们的模型行为也会发生变化。
-
特征和训练标签是我们模型的关键输入。我们应该花时间理解和验证每一个输入。
-
机器学习模型在可理解程度上可能有所不同,但我们仍然可以监控和评估它们的行为。
-
灾难确实会发生,但通过慎重的预见性和计划,可以将其影响最小化。
-
MLOps 人员需要与其组织中的模型开发人员建立牢固的工作关系和协议。
¹ 神经网络 这个术语源于它们的构建方式与大脑中神经元的工作方式之间的类比。深度学习 这个术语之所以流行,部分原因是有很多人指出,与大脑中神经元的类比并不特别准确。
² 许多机器学习生产工程师或 SRE(Site Reliability Engineers)不需要详细了解神经网络、随机森林或梯度提升决策树的工作原理(尽管刚开始看起来可能并不可怕或困难)。然而,与这些系统一起工作的可靠性工程师确实需要了解这些系统的要求和典型性能。因此,在此我们讨论高级结构。
³ 模型质量或性能评估是一个复杂的主题,将在第五章中进行讨论。
⁴ 另一种说法是“重新生成训练环境所需的所有元数据和数据”。
⁵ OpenAI 在“深度双峰”(Deep Double Descent)中提供了对这一现象的简明描述,同时提供了有用的参考文献,详见Preetum Nakkiran 的博客。
⁶ 这是当今股票价格交易的时间框架。更多信息请参阅迈克尔·刘易斯的《闪电男孩》(W. W. Norton & Co., 2014)。
⁷ 这种方法有效的原因是,每当产品展示但未被点击时,模型就会学习到该产品在该客户的情境下不是好结果,或者至少学习到该产品不是最佳结果。当然,这种情况对所有产品都经常发生,但如果竞争对手能够通过数百万甚至更多次展示产品而不点击来淹没系统,模型将学习到客户总体上并不喜欢该产品。
第四章:特征和训练数据
作者:Robbie Sedgewick 和 Todd Underwood
到这一点应该很明确,模型来自数据。本章讨论的是数据:它是如何创建、处理、标注、存储以及最终用于创建模型的。您将看到,管理和处理数据为可重复性、可管理性和可靠性带来了特定的挑战,我们将就如何应对这些挑战提出一些具体建议。如需背景知识,请确保参阅(如果尚未阅读)第二章和第三章。
本章涵盖了接收来自源头数据并为训练系统准备数据的基础设施。我们将讨论涉及此任务的三个基本功能子系统:特征系统、人类标注系统和元数据系统。我们在上一章节已经稍微讨论了特征;另一种思考方式是,它们是输入数据的特征,特别是我们确定与我们关心的某些事物有预测性的特征。标签是我们最终要训练的模型所需的特定输出案例。它们用作训练模型的示例。另一种思考标签的方式是,它们是模型将学习的特定数据实例的目标或“正确”值。标签可以通过将数据与另一个独立事件相关联的日志中提取,或者可以由人类生成。我们将讨论在规模上生成人类标签所需的系统,通常称为标注。最后,我们将简要介绍元数据系统,该系统跟踪其他系统的工作细节,并对使它们可重复和可靠至关重要。
这些系统的几个方面通常在特征和数据系统之间共享,尤其是元数据系统。由于元数据(关于我们正在收集和标注的数据的数据)在我们知道如何处理数据之后才能更好地理解,所以我们将在探讨了特征和标签系统的要求和特征之后讨论这些系统。
特征
数据就是数据。特征是使其对机器学习有用的因素。¹ 特征是我们确定在实现模型目标中有用的数据的任何方面。这里,“我们”包括构建模型的人类,或者很多时候现在可以包括自动特征工程系统。换句话说,特征是数据的具体可测量的方面,或者是其功能。
特征用于构建模型。它们是将模型与用于组装模型的数据连接起来的结构。此前我们曾说过,模型是一组规则,它接受数据并用它来生成关于世界的预测。这对于模型架构和配置过的模型都是正确的。但是训练过的模型在很大程度上是一个组合特征的公式(基本上是用于从真实数据中提取特征值的特征定义——我们稍后在本章中更全面地讨论这个定义)。特征通常不仅仅是原始数据的片段,而是涉及某种预处理过程。
这些具体的特征示例应该能提供一些关于它们的直觉:
-
从网络日志中获取有关客户的信息(例如,浏览器类型)。
-
人类输入到应用程序中的文本中的单个词或词组。
-
图像中的所有像素集合,或其结构化子集。
-
加载页面时客户位置的当前天气情况。
-
任何特征的组合或变换本身也可以成为一种特征。
通常,特征包含从底层训练数据中提取的较小结构化数据部分。随着建模技术的不断发展,更多的特征可能开始类似于原始数据,而不是这些提取的元素。例如,当前在文本上进行训练的模型可能会训练单词或单词的组合,但我们预期未来会看到更多对段落甚至整篇文档的训练。当然,这对建模有重要影响,但是构建生产型 ML 系统的人员也应该意识到训练数据增加和结构变得更少对系统的影响。
在 YarnIt,我们有几个模型,其中一个模型是在客户在网站上购物时为不同或额外的产品提供建议。这个推荐模型在购物会话期间由网页应用程序调用,无论是客户正在查看单个产品的主产品页面,还是在购物车确认页面上,当客户刚刚将产品添加到购物车中时。Web 服务器调用模型询问在这些情况下应向该客户显示哪些附加产品,希望能够向客户展示他们可能需要或想要的其他东西,并增加我们对该客户的销售。
在这种情况下,我们可能会考虑以下一些有用的特征,我们希望模型在查询附加产品时能够使用这些特征:
-
产品页面或购物车确认页面。用户是在浏览还是购买?
-
用户当前查看的产品,包括来自当前产品名称、可能来自当前产品图片的信息,产品类别、制造商和价格的信息。
-
如果我们知道顾客的平均购买金额或每年的总购买量,这可能是顾客支出程度的指标。
-
编织者还是钩针者?有些顾客从不钩针,而其他人则只钩针。了解这一点可能有助于我们推荐正确的纱线、针和图案。我们可以让顾客自我确认这一特征,也可以根据之前的购买或浏览行为进行推断。
-
顾客的国家。某些产品可能只在某些地方流行。而且有些国家比其他国家更冷,这可能是一个信号。
这些只是一些想法,以体现特征可能的范围。重要的是要注意,在没有实际数据的情况下,我们不知道这些特征是否有用。它们看起来确实可能有帮助,但许多看似有效的特征实际上并不奏效。大多数情况下,这些特征只能稍微预测,并且它们预测的东西可能被我们已有的另一个特征更好地预测。在这些情况下,新特征只增加了成本和复杂性,但并没有增加任何价值。请记住,特征会在系统的许多部分增加维护成本,而这些成本会一直存在,直到特征被移除。我们应该谨慎添加新特征,特别是那些依赖于新数据源或数据源,现在必须被监控和维护的特征。
在我们进一步讨论之前,我们需要澄清“特征”这个术语的两个完全不同的用法及其区别:
特征定义
这是描述我们从底层数据中提取信息的代码(或算法或其他书面描述)。但它不是该数据被提取的任何特定实例。例如,“当前顾客的源国家由取得顾客的源 IP 地址并在地理位置数据服务中查找而获得”是一个特征定义。例如,“多米尼加共和国”或“俄罗斯”都不是特征定义。
特征值
这是应用于传入数据的特征定义的具体输出。在上述示例中,“多米尼加共和国”是一个特征值,可能是通过确定当前顾客的源 IP 地址最常用于该国而获得的。
这在目前还不是行业标准术语,但在本节中我们采纳它,以区分我们正在尝试从数据中提取信息的方法和我们到目前为止提取了什么。
特征选择和工程
特征选择 是我们确定将在模型中使用的数据特征的过程。特征工程 是我们从数据中提取这些特征并将其转换为可用状态的过程。换句话说,通过这些活动,我们找出了对我们尝试完成的机器学习任务重要的内容,以及不重要的内容。特征的构建和管理多年来发生了变化,并将继续发展,从完全手动的过程转变为大部分自动化的过程,甚至在某些情况下完全自动化。在本章中,我们将选择和转换特征的过程统称为特征工程。
在人驱动的特征工程中,该过程通常从基于对问题领域的理解或人类直觉出发,或至少与专家进行详细咨询开始。想象一下,试图构建一个关于* yarnit.ai *客户可能购买什么的预测模型,却不知道什么是纱线,或针,或编织,甚至更糟糕的是,根本不了解在线零售如何运作。理解潜在问题领域至关重要,而更具体的理解则更佳。之后,机器学习工程师会花时间与数据集和问题一起,并使用一套统计工具来评估特定特征,或多个特征组合在任务中是否有用。接下来,机器学习工程师通常进行头脑风暴,生成可能特征列表。范围非常广泛。一天中的时间可能是预测客户将购买哪些纱线的特征。当地的湿度可能是一个特征。价格可能是一个特征。在这三个特征中,有一个比其他的更有可能有用。人类利用机器学习平台和模型指标来生成和评估这些想法。
对于算法特征工程来说,有时作为自动机器学习的一部分,该过程相对自动化且与数据绑定紧密。自动机器学习在第三章中详细描述,不仅能够从已识别的特征中进行选择,还能够以编程方式应用常见的转换(如对数缩放或阈值处理)到现有特征上。还有其他方式可以通过算法学习数据的某些内容(如嵌入),而无需明确指定。然而,算法通常只能识别数据中存在的特征,而人类可以想象可能相关的新数据。微妙之处在于,但也许更重要的是,人类理解数据收集过程,包括任何可能的系统偏见。这可能会对数据的价值产生实质性影响。尽管如此,特别是在限定特定类型问题时,算法特征工程和评估可能比人工特征工程更为有效。这是一组不断发展的技术,我们应该预期人类与计算机之间的平衡在这方面会继续发展。
特征的生命周期
在考虑特征的生命周期时,特征定义与特征值之间的区别变得尤为重要。特征定义被创建来满足需求,根据该需求进行评估,并在模型被丢弃或找到更好的特征来实现相同目标时最终被丢弃。这里是特征生命周期的简化版本(包括定义和代表值):
1. 数据收集/创建
没有数据,我们就没有特征。我们需要收集或创建数据才能创建特征。
2. 数据清洗/归一化/预处理
即使特征创建过程本身可以被视为某种数据归一化过程,这里我们指的是更粗粒度的预处理:消除明显格式错误的示例,将输入样本缩放到一组共同的值,并可能删除出于政策原因不应训练的特定数据。这可能看起来超出了特征工程的范畴,但在数据存在且处于可用形式之前,特征无法存在。数据归一化和预处理的话题非常广泛,超出了本书的范围,但建立基础设施以保持一致地进行该预处理并监控其执行是一个重要的责任领域。
3. 候选特征定义创建
使用专业主题知识加上人类想象力或自动化工具,开发假设,确定哪些数据元素或其组合可能实现我们模型的目标。
4. 特征值提取
我们需要编写代码来读取输入数据并从中提取我们需要的特征。在某些简单情况下,我们可能希望在训练过程中内联执行此操作。但是,如果我们预计会多次在相同数据上进行训练,最好是从原始数据中提取特征并将其存储以便后续高效且一致地读取。重要的是要记住,如果我们的应用涉及在线服务,我们需要这样一段代码的版本,以从提供的值中提取相同的特征,以便在我们的模型中执行推断。在理想情况下,相同的代码可以为训练和服务提取特征,但在服务中可能会有额外的约束条件,而这些约束条件在训练中是不存在的。
5. 在特征存储中存储特征值
这就是我们保存特征的地方。特征存储只是一个地方,用于写入提取的特征值,以便在训练模型期间可以快速且一致地读取。这在 “特征存储” 中有详细介绍。
6. 特征定义评估
一旦我们提取了一些特征,我们很可能会使用它们构建模型,或者将新特征添加到现有模型中,以评估它们的工作效果。特别是,我们将寻找证据表明这些特征是否提供了我们希望的价值。请注意,对特征定义的评估分为两个明确的阶段,二者相互关联。首先,我们需要确定该特征是否有用。这是一个粗粒度的评估;我们只是试图决定是否继续在模型集成该特征上工作。下一个阶段发生在我们决定保留该特征时。此时,我们需要一个过程来持续评估特征的质量和价值(与成本相比)。这将是必要的,以便我们能够确定它是否仍然按照预期工作,并在未来数年内提供我们预期的价值。
7. 使用特征值进行模型训练和服务
这似乎是显而易见的,但拥有特征的整个目的是将它们用于训练模型,并使用生成的模型达到特定目的。
8. (通常)更新特征定义
我们经常需要更新特征的定义,无论是修复错误还是简单地改进它们的某些方面。如果我们添加并跟踪特征定义的版本,这将更加容易。我们可以更新版本,然后选择性地重新处理旧数据,以为新版本创建新的特征值集。
9. (有时)删除特征值
有时我们需要能够从特征存储中删除特征值。这可能是出于政策/治理原因;例如,我们可能不再被允许存储这些特征值,因为某人或政府已经撤销了该权限。这也可能是出于质量/效率原因:我们可能会认为这些值在某些方面有问题(损坏的、以偏见方式采样的,例如),或者仅仅是因为太旧而无用。
10. (最终)终止特征定义
一切都有尽头,包括有用的特征。在模型生命周期的某个时刻,我们将找到更好的方式来提供这个特征定义提供的价值,或者发现世界已经发生足够的变化,以至于这个特征不再提供任何价值。最终,我们将决定彻底废弃特征定义(及其值)。我们需要删除任何引用该特征的服务代码,删除特征存储中的特征值,取消从数据中提取特征的代码,并继续删除特征代码。
特征系统
要成功管理数据流经我们系统的过程,并将数据转化为能被我们的训练系统使用和我们的建模人员管理的特征,我们需要将工作分解为几个子系统。
正如在本章节引言中提到的,其中一个系统将是一个元数据系统,用于跟踪有关数据、数据集、特征生成和标签的信息。由于在大多数情况下,这个系统将与任何标记系统共享,我们将在本章末尾讨论它。现在,让我们从原始数据开始,逐步讲解特征系统,最终以一种可供训练系统读取的格式存储特征。
数据摄取系统
我们将不得不编写软件,从原始数据中读取数据,将我们的特征提取代码应用于该数据,并将生成的特征值存储在特征存储中。在一次性提取的情况下,即使对于大量数据,这可能是一个相对临时的过程,设计的代码只需运行一次。但在许多情况下,提取数据的过程是一个独立的生产系统。
当我们有许多用户或数据摄取系统的重复使用时,它应该被构建为一个按需、可重复、监控的数据处理管道。就大多数管道而言,最大的变量是用户代码。我们需要一个系统,使特征作者能够编写代码来识别特征并将其提取存储到特征存储中。我们可以让特征作者自行运行其代码,这会给他们带来很大的运营负担,或者我们可以接受这一挑战并为他们提供开发工程环境。这有助于他们编写可靠的特征提取代码,以便我们可以在数据摄取系统中可靠地运行该代码。
我们需要构建一些系统来帮助特征作者编写可靠且正确的特征。首先,我们应该注意到特征应该是有版本的。随着时间的推移,我们可能会显著改变一个特征,也许是因为它与合并的数据或其他与我们正在收集的数据相关的因素的变化。在这些情况下,特征版本有助于保持过渡的清晰,并避免改变的意外后果。
接下来,我们需要一个测试系统,检查特征提取代码的基本正确性。然后,我们需要一个分段环境来运行提议的特征提取在一定数量的示例上,并将其提供给特征作者,以及基本的分析工具,以确保特征提取的内容符合预期。在这一点上,我们可能希望允许特征运行,或者可能希望进行额外的人工审查以解决可靠性问题(例如对外部数据的依赖)。我们在这里做的工作越多,特征作者的生产力就越高。
最后,重要的是要注意,一些标签可以在数据摄入时从我们已有的数据中有效计算或生成。在 YarnIt 中的一个很好的例子是建议产品和销售。我们建议产品以便销售更多。特征是产品的特性或关于客户的特征,而标签是客户是否购买它。只要我们能将建议日志与订单对接,我们在构建特征时就会有这个标签。在这种情况下,数据摄入系统还将为这些特征生成标签以及特征本身,并且两者可以一起存储在一个共同的数据存储中。我们将在《标签》章节中更详细地讨论标签系统。
特征存储
特征存储是一种设计用于存储提取的特征(和标签)值的存储系统,以便在训练模型期间甚至推断期间快速且一致地读取它们。大多数机器学习训练和服务系统都有某种特征存储,即使它不被称为特征存储²。然而,在更大、集中管理的服务中,特别是当特征(定义和值都是)被多个模型共享时,它们尤其有用。认识到将我们的特征和标签数据放在一个单一、良好管理的位置的重要性显著提高了工业中机器学习的生产就绪性。但特征存储并不能解决所有问题,很多人对它们的期望超过了它们能提供的。让我们回顾一下特征存储解决的问题以及它为您的训练系统提供的好处。
特征存储的最重要特性是其 API。不同的商业和开源特征存储具有不同的 API,但它们都应该提供一些基本功能能力:
存储特征定义
通常这些被存储为代码,该代码从原始数据格式中提取特征并以所需格式输出特征数据。
存储特征值本身
最终,我们需要以易于写入、易于阅读和易于使用的格式编写特征。这将在很大程度上由我们提议的用例决定,通常分为有序和无序数据,但我们在“生命周期访问模式”中涵盖了细微差别。
服务特征数据
在适合任务的性能水平上,快速高效地提供对特征数据的访问是必要的。我们绝对不希望昂贵的 CPU 或加速器因等待从特征存储中读取而停滞不前。这是浪费昂贵资源的无意义方式。
与元数据系统协调元数据写入
为了充分利用我们的特征存储,我们应该在元数据系统中保留有关存储数据的信息。这有助于模型构建者。注意,关于特征的元数据与管道运行的元数据略有不同,尽管两者在故障排除和问题再现中都很有用。特征元数据对于模型开发者最有用,而管道元数据对于 ML 可靠性或生产工程师最有用。
许多特征存储还提供数据摄取时的基本归一化,以及存储中数据的更复杂的转换。最常见的转换包括存储中的标准化分桶和内置特征转换[³]。
特征存储 API 需要根据使用情况进行精心校准。在思考我们在特征存储中需要什么时,我们应考虑以下问题:
-
我们是否按特定顺序读取数据(时间戳的日志行)或者读取顺序无关紧要(云存储系统中的大量图像集合)?
-
我们是否经常读取特征,或者只在训练新模型时读取?特别是,读取的字节/记录与写入的字节/记录的比率是多少?
-
特征数据是摄取一次,不追加且很少更新?还是数据经常追加,而旧数据不断删除?
-
特征值是否可以更新,还是仅追加存储?
-
我们存储的数据是否有特殊的隐私或安全要求?在大多数情况下,带有隐私和使用限制的数据集的提取特征也会有隐私和使用限制。
在考虑了这些问题之后,我们应该能够确定我们对特征存储系统的需求。如果幸运的话,我们可以使用市场上现有的商业或开源特征存储之一。如果没有,我们将不得不自己实现这些功能,无论是以不协调的方式还是作为更一致系统的一部分实现。
一旦我们明确了 API 的要求,并对我们的数据访问需求有了更清晰的理解,一般来说我们会发现我们的特征存储落入两个桶中之一:⁴
列
数据是结构化的,并可分解为列,其中并非所有列都会在所有模型中使用。通常,数据也按某种方式排序,通常是按时间排序。在这种情况下,面向列的存储方式是最灵活和高效的。
二进制大对象(Blobs)
这是二进制大对象的缩写,尽管常见的英文单词也有描述性的含义。在这种情况下,数据基本上是无序的,大部分是非结构化的,最好以更高效存储一堆字节的方式进行存储。
许多特征存储需要部分或完全复制,以便在训练和服务堆栈附近存储数据。由于 ML 计算需求通常相当大,我们通常喜欢将数据复制到能够以最佳性价比获取训练所需价值的地方或地方。将特征存储实现为服务有助于管理这种复制。
特征质量评估系统
随着我们开发新特征,我们需要评估这些特征与现有特征组合在一起对整体模型质量的贡献。这个话题在第五章中有详细介绍。此时需要了解的一般概念是,我们可以结合使用略有不同的模型、A/B 测试和模型质量评估系统的方法,有效评估正在开发中的每个新特征的益处。我们可以快速且成本相对较低地做到这一点。
一种常见的方法是通过使用单个附加特征重新训练现有模型。对于像 YarnIt 这样的 Web 应用程序,我们可以将一部分用户请求定向到新模型,并评估其在任务中的性能。例如,如果我们为模型添加了一个用户所在国家的特征,我们可以将 1% 的用户请求(无论是通过请求还是通过用户)定向到新模型。我们可以评估新模型是否更有可能推荐用户实际购买的产品,这样做可以决定是否保留新特征或取消它并尝试其他想法。
请记住,即使一个特征增加了价值,但其收集、处理、存储和维护成本可能并不值得。对于除了最微不足道的明显特征外的所有特征,计算每个新特征添加到系统中的大致投资回报率(ROI)是个好习惯。这将帮助我们避免有用的特征仍然比其添加的价值更昂贵的情况。
标签
虽然特征看起来是数据中最重要的部分,但有一件事更为重要:标签。到此为止,您应该对特征的作用以及在管理大量特征时应考虑的系统因素有了坚实的理解。但特别是在监督学习模型中,需要标签。
标签是用于训练机器学习模型的另一类主要数据。虽然特征用作模型的输入,标签则是正确模型输出的示例。它们在训练过程中用于设置(许多!)模型的内部参数,调整模型以便在推断时对其输入的特征产生期望的输出。保留样本和标签(未用于训练的标签)也用于模型评估,以理解模型质量。
正如我们之前讨论的那样,对于某些问题类别,例如我们的推荐系统,标签可以从系统日志数据中通过算法生成。这些特征几乎总是比人工标记的特征更一致和更准确。由于这些数据通常是从系统日志数据中生成的,并且通常与特征数据一起使用,这些标签通常存储在特征系统中用于模型的训练和评估。事实上,所有的标签都可以存储在特征存储中,尽管由人类生成的标签需要额外的系统来生成、验证和校正这些标签,然后再存储用于模型的训练和评估。我们将在下一节讨论这些系统。
人工生成的标签
因此,让我们把注意力转向需要人类注释以提供模型训练数据的大类问题。例如,构建一个分析和解释人类语音的系统需要人类注释来确保转录准确,并理解说话者的意图。图像分析和理解通常需要示例标注图像来解决图像分类或检测问题。在训练机器学习模型所需的规模上获得这些人类注释,从实施和成本的角度来看都是具有挑战性的。必须致力于设计高效的系统来生成这些注释。我们现在将专注于这些人类注释系统的主要组成部分。
举一个涉及我们虚构的毛线店 YarnIt 的具体例子,考虑一个先进新功能的情况,该功能可以根据毛线图像预测用于制作该图像的钩针钩法。这样的模型需要有人设计一组钩针钩法供模型预测,并由钩针专家标记大量的毛线图像,标记出用于制作这些图像的钩针钩法。利用这些专家标签,模型可以训练以对新的毛线图像进行分类并确定使用的钩针钩法。
这不是便宜的。人类需要在任务上接受培训,并且每张图片可能需要多次标注,以确保我们获得可信赖的结果。由于获取人工生成标签的成本巨大,训练系统应设计为尽可能充分利用它们。一种常用的技术是数据增强:对特征数据进行“模糊化”,改变特征但不改变标签的正确性。⁵ 例如,考虑我们的缝合分类问题。常见的图像操作如缩放、裁剪、添加图像噪声和改变色彩平衡不会改变图像中缝合的分类,但可以大幅增加模型训练所需的图像数量。类似的技术可以用于其他类别的问题中。然而,必须小心,不要在两个从同一源图像模糊化生成的图像上进行训练和测试,因此任何这种类型的数据增强都应由训练系统完成,而不是在标注系统中进行(或者不这样做,如果有充分的理由,比如非常昂贵的模糊算法)。
一个重要的注意事项是:尽管某些极为复杂的数据最好由人类进行标注,但另一些类型的数据绝对不能由人类来标注。通常这些是抽象数据,具有高维度,使得人类难以迅速确定正确答案。有时候,人类可以借助增强软件来辅助完成这些任务,但有时候他们只是进行标注的错误选择。
注释工作队
人工标注问题经常遇到的第一个问题是谁来进行标注。这是一个规模和公平性的问题。⁶ 对于简单模型,通常只需要少量数据来训练模型,通常是模型构建者自己进行标注,经常使用简陋的自制工具(并且有显著的偏见标签的可能性)。对于更复杂的模型,专门的注释团队则用来提供在其他情况下不可能的规模的人工标注。
这些专门的注释团队可以与模型构建者共同工作,也可以由第三方注释提供者远程提供。团队规模从一人到数百人不等,他们为单一模型生成注释数据。亚马逊的机械土耳其服务曾经是最初用于这一目的的平台,但自那以后,众包平台和服务数量激增。一些服务采用有薪志愿者,而另一些则使用员工团队来标注数据。
在选择标注时会产生成本、质量和一致性的权衡。众包标注通常需要额外的工作来验证质量和一致性,但支付的标注工作人员可能成本高昂。这些注释团队的成本往往可以轻易超过训练模型的计算成本。我们在第十三章中讨论了管理大型注释团队的一些组织挑战。
测量人类注释质量
由于任何模型的质量仅取决于用于训练模型的数据,因此必须从一开始就设计系统质量。随着注释团队规模的增长,这一点变得越来越重要。可以通过多种方式实现质量,具体取决于任务,但最常用的技术包括以下几种:
多次标注(也称为共识标注)
同一数据分配给多个标注者以检查他们之间的一致性。
黄金测试集问题
可信的标注者(或者模型构建者)生成一组测试问题,随机包含在未标注数据中,以评估生成标签的质量。
单独的质量保证步骤
一小部分标注数据由更可信的质量保证团队审查。(谁质量保证质量保证团队?也许是模型构建者,但根据情况,这可能是一个独立的质量保证团队、政策专家或其他具有领域专业知识的人。)
一旦进行测量,质量指标可以得到改进。管理注释团队时,最好怀着谦卑的态度,并理解到他们在拥有以下条件时将产生更高质量的结果:
-
更多的培训和文档
-
认可质量而不仅仅是吞吐量
-
工作日内的各种任务
-
易于使用的工具
-
具有平衡答案集的任务(没有大海捞针的任务)
-
提供工具和指导反馈的机会
通过这种方式管理的注释团队可以提供高质量的结果。然而,即使是最好的、最认真的标注者偶尔也会漏掉一些东西,因此应设计流程来检测或接受这些偶尔的错误。
注释平台
标注平台组织数据流以进行注释,并提供注释结果的质量和吞吐量指标。在其核心,这些系统主要是工作排队系统,用于在标注者之间分配注释工作。允许标注者查看数据并提供注释的实际标注工具应具有灵活性,以支持任何任意的注释任务。
对于同时处理多个模型的团队或组织,同一标注团队可以在多个标注项目之间共享。此外,每个标注员可能具有不同的技能集(例如语言能力或对钩织知识的了解),排队系统可能相对复杂,并需要仔细设计,以避免问题,如可伸缩性问题或队列饥饿。允许一个标注任务的输出作为另一个任务的输入的流水线对于复杂的工作流程非常有用。使用前面讨论过的技术进行质量测量应该从一开始就设计到系统中,这样项目所有者就可以了解他们所有标注任务的标注吞吐量和质量。
尽管历史上许多公司已经实现了他们自己的标注平台,并具备一整套这些功能,但现在有许多预构建的标注平台选项可供选择。主要的云服务提供商和许多较小的初创公司提供标注平台服务,可与任意注释工作队合作,并且许多注释工作队提供其自己的平台选项。这是一个变化迅速的领域,现有平台不断增加新功能。公开可用的工具已经超越了简单的排队系统,并开始提供用于常见任务的专用工具,包括 AI 辅助标注(请参阅下一节)。在决定任何新技术平台时,必须考虑数据安全性和集成成本,以及平台的能力。
如“特征存储”中所述,在许多情况下,将完成的标签存储在特征存储中是最明智的选择。通过将人工注释视为它们自己的列,我们可以利用特征存储提供的所有其他功能。
主动学习和 AI 辅助标注
主动学习技术可以将注释工作集中在模型和人工注释者意见不一致或模型最不确定的情况下,从而提高整体标签质量。例如,考虑一个图像检测问题,标注员必须在图像中注释特定对象的所有出现。主动学习标注工具可以使用现有模型预标注图像,并提出该对象的检测建议。标注员随后会批准正确的检测建议,拒绝错误的建议,并添加任何遗漏的检测。虽然这可以极大地提高标注员的吞吐量,但必须小心操作,以免为模型引入偏见。这种主动学习技术实际上可以提高整体标签质量,因为模型和人类往往在不同类型的输入数据上表现最佳。
半监督系统允许模型构建者使用不完美地预测某些数据标签的弱启发式函数来引导系统,然后利用人类训练模型,使这些不完美的启发式函数转变为高质量的训练数据。对于需要快速且频繁重新训练模型的复杂、频繁变化的类别定义问题,这类系统尤其有价值。
针对特别复杂的标注任务的高效标注技术是一个持续的研究领域。特别是在处理常见标注问题时,从云和标注提供商那里快速查看可用工具是值得花时间的,因为它们经常添加新的 AI 辅助标注功能。
标签员的文档和培训
文档和标签员培训系统是标注平台中常被忽视的部分之一。虽然标签指导通常起步简单,但随着数据的标注和各种特殊情况的发现,它们不可避免地变得更加复杂。继续我们之前的 YarnIt 示例,也许一些钩针编织没有在标签指导中提到,或者织物由多种不同的针法制成。即使是概念上简单的标注任务,比如“标记图像中的所有人”,最终也会有大量关于各种特殊情况的正确处理指令(如反射、人物照片、人物在汽车窗后面等)。
当发现新的特例时,应更新标注定义和指导方针,并通知标注和建模团队有关更改的信息。如果更改很大,可能需要重新标注以更正使用旧指导方针标注的数据。标注团队经常有较大的人员流动,因此投资于使用标注工具和理解标注指导方针的培训几乎总能带来标签质量和产量的显著提升。
元数据
特征系统和标注系统都受益于对元数据的有效跟踪。现在您对特征或标注系统提供的数据类型有了相对完整的理解,可以开始考虑在这些操作期间产生的元数据。
元数据系统概述
元数据系统的设计旨在跟踪我们正在做的事情。在特征和标签的情况下,它至少应该跟踪我们拥有的特征定义及每个模型定义和训练模型使用的版本。但是,值得暂停片刻并尝试展望未来:我们最终对元数据系统有什么期望,是否有办法提前预见?
大多数组织在构建其数据科学和机器学习基础设施时,没有一个坚实的元数据系统,只会在后来感到后悔。接下来最常见的方法是构建多个元数据系统,每个系统针对解决特定问题。这正是我们要做的:为跟踪特征定义和特征存储映射创建一个系统。即使在这本章节中,你将会看到我们需要存储关于标签的元数据,包括它们的规范以及何时将特定标签应用于特定的特征值。之后,我们还需要一个系统来将模型定义映射到训练好的模型,并包含有关负责这些模型的工程师或团队的数据。我们的模型服务系统还需要跟踪训练模型版本以及它们何时投入生产。任何模型质量或公平评估系统都需要从所有这些系统中读取数据,以便识别和跟踪影响模型质量变化或违反我们提出的公平度量的可能原因。
我们的元数据系统选择相对简单:
一个系统
建立一个系统来跟踪所有这些来源的元数据。这样可以简化跨多个子系统的相关性分析和报告。从数据架构的角度来看,设计这样一个大系统很难做到完美。当我们发现需要跟踪的数据时,我们将不断添加列(并在现有数据上回填这些列)。稳定这样的系统并使其可靠也将是困难的。从系统设计的角度来看,我们应确保我们的元数据系统永远不处于模型训练或模型服务的实时路径中。但是很难想象在没有功能的元数据系统的情况下进行特征工程或标注,因此它仍然可能给我们的从事这些任务的人员带来生产问题。
多个协同工作的系统
我们可以为每个识别出的任务构建单独的元数据系统。也许我们可以有一个用于特征和标签的系统,一个用于训练,一个用于服务,一个用于质量监控。解耦系统提供了解耦总是提供的标准优势和成本。它允许我们单独开发每个系统,而不必担心其他系统,使它们更灵活和更容易修改和扩展。此外,一个元数据系统的故障对其他系统的生产影响有限。但成本是增加了跨这些系统的分析和报告的难度。我们将需要在特征、标注、训练和服务系统之间联合数据的过程。多个系统应始终设计成允许它们的数据进行关联,这意味着创建和共享唯一标识符或建立一个跟踪数据字段关系的元元数据系统。
如果需求简单且易于理解,请优先选择单一系统。⁷ 如果领域发展迅速且我们的团队预计会继续扩展跟踪和工作方式,则多个系统将随着时间推移简化开发。
数据集元数据
关于特征和标签的元数据,以下是我们应确保包含的几个具体元素:
数据集溯源
数据来源何处?根据数据来源,我们可能有各种系统的日志查找表,外部数据提供者的关键数据及其下载日期,甚至是生成数据的代码引用。
数据集位置
对于某些数据集,我们将存储原始未处理数据。在这种情况下,我们应存储一个指向数据集存储位置的引用,以及可能关于数据来源的信息。我们定期为自己创建一些数据,例如系统日志,因此在这些情况下,应存储日志或数据存储引用,或者我们被允许从中读取的地方。
数据集负责人员或团队
我们应该追踪负责数据集的人员或团队。一般来说,这是选择下载或创建数据集的团队,或拥有生成数据的系统的团队。
数据集创建日期或版本日期
通常有必要知道特定数据集首次使用的日期。
数据集使用限制
许多数据集由于许可或治理限制而受到使用限制。我们应在元数据系统中记录这一点,以便日后进行简便的分析和遵从性检查。
特征元数据
跟踪我们特征定义的元数据是使我们能够可靠使用和维护这些特征的一部分。该元数据包括以下内容:
特征版本定义
特征定义是对代码或其他持久性描述的引用,用于说明特征读取什么数据以及如何处理数据以创建特征。应在每个更新版本的特征定义时更新此信息。正如前面所述,对这些定义进行版本控制(并限制使用的版本)将使最终的代码库更可预测和可维护。
特征定义负责人员或团队
存储这些信息有两个很好的用例:确定特征用途和找到能帮助解决可能导致特征故障的事件的人员。在这两种情况下,存储特征的作者或维护者信息非常有用。
特征定义创建日期或当前版本日期
这可能相当明显,但获取特征最近更新和最初创建的更改历史非常有用。
特征使用限制
这是重要的,但存储起来更为棘手。某些情况下可能限制特征的使用。例如,在某些司法管辖区可能会禁止使用特定特征。年龄和性别可能是汽车保险风险模型的合理预测因子,但保险业受到严格监管,我们可能不被允许考虑这些字段。对于特定用途禁止特定字段的实施和跟踪是困难的,但限制可能更加微妙。例如,年龄可能可以考虑,但只能使用特定的分桶(如低于 25 岁,25-64 岁,65-79 岁和80 岁以上)。在这种特定情况下,更容易定义一个基于age列的转换特征,满足这些分桶要求,并禁止一般的age特征用于保险目的,同时允许使用insurance_bucketed_age特征。但根据治理要求存储和应用特征限制的一般情况极为困难,目前尚无理想的设计或解决方案。
标签元数据
我们还应该跟踪有关标签的元数据。这旨在帮助维护和开发标签系统本身,但也可能被训练系统用于使用标签时:
标签定义版本
切换到与标签相关的元数据,类似于特征,我们必须存储任何标签定义的版本,以了解标签是使用哪些标签说明生成的。
标签集版本
除了标签定义的更改,由于修正错误标签或添加新标签,标签的更改也可能发生。如果数据集用于与旧模型比较,则可能希望使用旧版本的标签,以进行更为公正的比较。
标签来源
尽管通常不需要用于训练,但有时需要知道数据集中每个标签的来源。这可能是特定标签许可的来源,生成标签的人员(以及应用于标签的任何质量保证),或者如果使用了自动标记方法,则是生成标签的算法。
标签置信度
根据标签生成的方式,我们可能对不同标签的正确性置信度有不同的估计。例如,我们可能对由自动化方法生成的标签或由新的标签生成器生成的标签的置信度较低。使用这些标签的用户可能会选择不同的阈值来决定在训练模型时使用哪些标签。
流水线元数据
本节涵盖了一种我们不会花太多时间讨论的最终类型的元数据:关于管道过程本身的元数据。这是关于我们拥有的中间产物、它们来自哪些管道运行以及哪些二进制文件产生了它们的数据。这种类型的元数据由某些机器学习训练系统自动产生;例如,ML Metadata(MLMD)自动包含在 TensorFlow Extended(TFX)中,用于存储关于训练运行的工件。这些系统要么集成到这些系统中,要么稍后实现起来相对困难。因此,在这里我们不会过多涉及它们。
更普遍地说,元数据系统经常被忽视或降低优先级。但它们不应该被忽视。它们是机器学习系统中最有效和直接的数据利用贡献者之一。元数据释放了价值,应优先考虑。
数据隐私与公平性
特征和标记系统引发了深刻的隐私和伦理考虑。虽然这些主题在第六章中有更详尽的讨论,但在此明确指出一些特定的主题仍然值得一提。
隐私
我们接收的数据以及对数据的人工标注很可能包含 PII。虽然处理私人信息的最简单方法是简单地禁止私人或敏感信息进入我们的特征存储系统,但这通常不实际。
PII 数据和特征
如果我们计划在特征中使用 PII 数据,我们希望至少提前计划执行以下三项任务:
-
最小化我们处理和存储的个人身份信息(PII)数据
-
限制和记录包含私有特征的特征存储器的访问
-
计划尽快删除私有特征
最好是提前规划正确处理 PII 数据的方式。在考虑收集 PII 数据之前,应建立明确的用户同意获取流程:用户应知道他们提供了哪些数据以及将如何使用。许多组织发现编写计划,详细说明将收集的数据、处理方式、存储位置以及可以访问和将被删除的情况非常有价值。这使得可以进行内部(可能最终是外部)审查程序,以确保符合相关法律法规。大多数组织将希望记录关于规划 PII 数据的程序,并定期对员工进行这些程序的培训。
请记住,从组织角度看,私人数据比资产更具有责任。因此,我们应完全确信包含私人数据的特征是必需的,即它们产生的价值足以抵消处理和存储私人数据的风险。正如总是情况一样,可以将不同的非私人数据组合在一起以创建私人数据元素。
私有数据与标记
人工注释 PII 数据如果处理不当,会引入一系列法律或声誉风险。如何正确管理这类数据用于人工注释系统是极其具体的情境,超出了本书的范围。通常,处理 PII 数据的最佳方式是将数据拆分,使得进行注释的人只能访问数据的非 PII 部分。这是特定问题的解决方案。任何标记 PII 数据都应该在项目领导层的高度关注和意识下谨慎进行。
使用人工注释者还会带来另一个风险,即模型无意中学习注释说明或团队本身的文化偏见。最好通过深思熟虑的文档记录和考虑潜在混淆领域、与注释团队的强有力沟通以及聘请多样化的注释团队来应对这种潜在偏见。积极的一面是,训练有素的注释团队可以是过滤具有潜在偏见的数据源、理解和消除偏见的最有效方法之一。
公平性
公平性是一个重要的主题,在第六章中有更广泛和更彻底的讨论。在考虑特征及其标签时,考虑公平性非常重要。选择确保生成的机器学习系统只能公平使用的特征和特征集合并不容易。虽然我们确实需要避免选择不具代表性和有偏见的特征和数据集,但仅此还不足以确保总体公平性。对于那些对公平性特别感兴趣的人来说,现在是阅读(或重新阅读)第六章的好时机。
结论
生产型机器学习系统需要有效和一致地管理训练数据的机制。训练数据几乎总是由特征组成的,因此拥有一个结构化的特征存储显著地促进了特征的编写、存储、读取和最终删除。许多机器学习系统还涉及人工注释数据的组件。进行数据注释的人类需要他们自己的系统来促进快速、准确和经过验证的注释,最终需要将其集成到特征存储中。
我们希望我们已经更清楚地解释了这些组件以及在选择或者在最坏情况下构建它们时应考虑的因素。
¹ 我们知道深度学习的一个承诺是有时可以使用原始数据训练模型,而无需明确识别特征。对于某些用例,这一承诺部分属实,但目前主要适用于感知数据,如图像、视频和音频。在这些情况下,我们可能不需要从底层数据中提取特定的特征,尽管我们仍然可能从元数据特征中获得良好的价值。对于其他情况,现在仍然需要特征化。因此,即使是深度学习建模者也将从对特征的理解中受益。
² 例如,在移动设备上进行的 ML 训练仍然需要对一些数据进行训练,但不需要有一个结构化的、受管理的特征存储,因为没有必要为其他设备上的用户调解数据。
³ 分桶只是将连续数据放入离散类别的过程。转换特征是计算得出的一个或多个其他特征的组合的结果特征。简单的例子包括在提供日期特征时返回星期几,或从存储地球上某点的纬度和经度的特征返回国家名称。更复杂的例子可能包括修复图片的色彩平衡或为 3D 数据选择特定的投影。也许最常见的例子之一是将 32 位数(整数或更糟的是浮点数)转换为 8 位数,以显著减少处理它们所需的空间和计算资源。
⁴ 有些例子将包含来自两个存储桶的特征。例如,图像中的图片是最好作为非结构化数据访问的大块,但是关于图像的元数据(拍摄它的相机、日期、曝光信息、位置信息)是结构化的,如果包括像date这样的字段,甚至可能是有序的。
⁵ 这也是一种通过算法扩展训练数据集的技术。
⁶ 组织需要确保人工标记者得到公平对待,并且为他们的工作支付合理的报酬。
⁷ 行业中存在许多具有多个元数据系统的组织,每个系统都认为自己是唯一的系统。如果需求简单且明确,可以优先选择一个系统,但应采取措施确保它是唯一的系统,除非你超出了它的需求。
第五章:评估模型的有效性和质量
好的,所以我们的模型开发人员已经创建了一个他们认为可以投入生产的模型。或者我们有一个更新版本的模型需要替换当前在生产中运行的版本。在我们打开开关并在关键环境中开始使用这个新模型之前,我们需要回答两个广泛的问题。第一个是确定模型的有效性:新模型会破坏我们的系统吗?第二个是关于模型的质量:新模型是否好用?
这些是简单的问题,但可能需要深入调查才能回答,通常需要各种专业领域的人员合作。从组织的角度来看,对我们来说很重要的是制定并遵循健全的流程,以确保这些调查被仔细和彻底地执行。借用我们内心的托马斯·爱迪生,可以说模型开发是 1%的灵感和 99%的验证。
本章深入探讨了有效性和质量的问题,并提供了足够的背景,使得 MLOps 从业者能够参与这两个问题。我们还将花时间讨论如何构建流程、自动化以及围绕确保这些问题得到适当关注、关怀和严谨对待的强大文化。
图 5-1 概述了模型开发的基本步骤以及质量在其中的角色。虽然本章重点介绍了评估和验证方法,但重要的是要注意这些过程可能会在时间上以迭代的方式重复进行。更多信息请参阅第十章。

图 5-1。模型开发重复周期的简化视图
评估模型的有效性
有人说所有人类都渴望以某种方式获得验证,我们 MLOps 从业者也不例外。事实上,有效性 是 MLOps 的核心概念,在这个背景下,我们涵盖了模型是否在投入生产时会导致系统级故障或崩溃的概念。
我们考虑有效性检查的事物与模型质量问题是不同的。例如,一个模型可能准确度极低,错误地猜测每张显示的图像都应该被标记为chocolate pudding,但不会导致系统级崩溃。同样地,一个模型在离线测试中可能表现出色,但依赖于当前生产堆栈中不可用的特定功能版本,或者使用某个 ML 包的不兼容版本,或者偶尔产生导致下游消费者崩溃的NaN值。验证有效性是第一步,确保模型不会对我们的系统造成灾难性危害。
在验证模型不会使我们的系统陷入困境时,有些需要测试的事项如下:
是否是正确的模型?
令人惊讶易被忽视的是,确保我们打算服务的模型版本确实是我们实际使用的版本是非常重要的。在模型文件中包含时间戳信息和其他元数据是一个有用的后备方案。这个问题突显了自动化的重要性,并展示了随意手动过程可能带来的困难。
模型能在生产环境中加载吗?
为了验证这一点,我们创建生产环境的副本,然后简单地尝试加载模型。这听起来很基础,但这是一个很好的起点,因为在这个阶段出现错误是令人惊讶地容易。正如你在第七章中所学到的,我们通常会获取模型的训练版本,并将其复制到另一个位置,该位置将用于离线批处理的评分,或者根据需求在线提供实时流量的服务。无论哪种情况,模型通常会以特定格式的文件或文件集合的形式存储,然后进行移动、复制或复制以供服务。这是必要的,因为模型往往体积较大,而且我们也希望有版本化的检查点,可以作为服务和未来分析的工件,或者在发生意外危机或错误时作为恢复选项。问题在于,随着时间的推移,文件格式往往会略有变化,而且模型保存的格式可能与我们当前的服务系统兼容的格式不同。
另一个可能导致加载错误的问题是,模型文件可能过大,无法加载到可用内存中。这在内存受限的服务环境中尤为可能,例如设备设置中。但是,当模型开发者热衷于增加模型大小以追求更高的准确性时,这也可能发生,这在当今的机器学习中越来越常见。重要的是要注意,模型文件的大小和内存中实例化的模型的大小是相关的,但通常只是松散相关,并且绝对不相同。我们不能仅仅查看模型文件的大小来确保生成的模型足够小,以便在我们的环境中成功加载。
模型能在不崩溃基础架构的情况下提供结果吗?
再次,这似乎是一个直截了当的要求:如果我们向模型提供一个最小的请求,它是否会给我们返回任何类型的结果,还是系统会失败?请注意,我们故意说“一个最小的请求”,而不是许多请求,因为这类测试通常最好从单个示例和单个请求开始。这既可以最小化风险,又可以使调试更容易,如果确实出现故障的话。
为一个请求提供结果可能会导致失败,原因有几种:
平台版本不兼容
特别是在使用第三方或开源平台时,服务堆栈可能会轻易地使用与训练堆栈不同的平台版本。
特征版本不兼容
生成特征的代码在训练堆栈和服务堆栈中通常是不同的,特别是当每个堆栈具有不同的内存、计算成本或延迟要求时。在这种情况下,导致一个给定特征在这些不同系统中失去同步的代码可能导致失败——这是通常被称为训练-服务偏差问题类别的一种形式。例如,如果一个字典用于将单词标记映射到整数,那么服务堆栈在为训练堆栈创建新字典后可能仍在使用过时版本的字典。
损坏的模型
错误发生了,作业崩溃了,最终我们的机器是物理设备。模型文件可能因写入时的错误或在训练时未进行足够的健全性检查而出现某种方式的损坏,或者在磁盘上写入 NaN 值。
缺失的管道连接
假设模型开发人员在训练中创建了一个功能的新版本,但忽略了实现或连接管道,使该功能可以在服务堆栈中使用。在这些情况下,加载依赖该功能的模型版本将导致崩溃或不良行为。
结果超出范围
我们的下游基础设施可能要求模型预测在给定范围内。例如,考虑一下,如果一个模型应返回一个介于 0 和 1 之间(不包括)的概率值,但实际上返回了 0.0 的分数,甚至是-0.2。或者考虑一个模型应返回 100 个类中的一个以表示最合适的图像标签,但实际上返回了 101。
模型的计算性能是否在允许范围内?
在使用在线服务的系统中,模型必须即时返回结果,这通常意味着必须满足严格的延迟约束。例如,一个旨在进行实时语言翻译的模型可能只有几百毫秒的预算来响应。而在高频股票交易上使用的模型可能会更少。
因为这些约束通常互相冲突,对于模型开发者在寻求提高准确性的更改中,测量部署前的延迟非常关键。在这样做时,我们需要牢记生产环境可能存在的硬件或网络方面的特殊性,这些可能会导致不同于开发环境的瓶颈,因此延迟测试必须尽可能接近生产环境进行。同样地,即使在离线服务的情况下,总体计算成本可能是一个重要的限制因素,在启动大批处理作业之前评估任何成本变化是很重要的。最后,正如之前讨论的,存储成本,例如模型在 RAM 中的大小,是另一个关键限制,必须在部署之前进行评估。这样的检查可以自动化进行,但手动验证以考虑权衡也可能很有用。
对于在线服务,模型是否会在生产环境中经过一系列渐进的金丝雀级别?
即使我们对新模型版本在验证检查基础上有了一些信心,我们也不希望只是翻转开关,让新模型突然承担全部生产负载。相反,如果我们首先要求模型仅服务一小部分数据,并在确保模型在服务中表现如预期后逐渐增加数据量,我们的整体压力将会减少。这种金丝雀渐进上升的方式是模型验证和模型监控的交集,正如在第九章中讨论的那样:我们的最终验证步骤是在生产中进行控制的渐进升级,并进行仔细监控。
评估模型质量
确保模型通过验证测试是重要的,但这本身并不能回答模型是否足够好来完成其工作。回答这类问题将使我们进入评估模型质量的领域。当然,理解这些问题对于模型开发者很重要,但对于组织决策者以及负责保持系统平稳运行的 MLOps 人员同样至关重要。
离线评估
正如在第二章中讨论的模型开发生命周期的快速导览中所述,模型开发者通常依赖离线评估,例如查看在保留测试集上的准确性,作为评判模型好坏的一种方式。显然,这种评估方式有其局限性,正如我们在本章稍后将讨论的那样——毕竟,在保留数据上的准确性并不等同于幸福或利润。尽管存在局限性,这些离线评估是开发生命周期的主要内容,因为它们在成本低效率高的甜蜜点上提供了一个合理的代理,使开发者能够快速连续测试多个更改。
现在,什么是评估呢?评估由两个关键组成部分组成:性能指标和数据分布。性能指标包括准确率、精确率、召回率、ROC 曲线下面积等等——如果这些还不熟悉,稍后我们会详细讨论其中几个。数据分布则是诸如“从与训练数据相同的数据源中随机抽样的留出测试集”,我们之前讨论过,但留出测试数据并非唯一重要的分布。其他可能包括“特定于雪天路况的图像”或“挪威用户的纱线店查询”或“生物学家尚未确认的蛋白质序列”等等。
评估总是由性能指标和数据分布两者共同组成——评估展示了模型在该分布中数据上的性能,由所选指标计算得出。这一点很重要,因为在机器学习领域,有时人们会使用简化说法,比如“这个模型的准确率更高”,而不澄清使用的数据分布是什么。这种简化说法对我们的系统是危险的,因为它忽略了在评估过程中使用的数据分布的具体情况,可能导致忽视重要案例的文化。实际上,2010 年代末出现的许多关于公平性和偏见的问题很可能可以追溯到在模型评估中未充分考虑数据分布的具体情况。因此,当我们听到“准确率更高”的说法时,我们总是可以通过问“在哪个数据分布上?”来增加价值。
评估分布
在理解机器学习系统中,也许没有比决定如何创建评估数据更重要的问题了。以下是一些常用的分布以及一些考虑其优势和劣势的因素。
留出测试数据
最常用的评估分布是留出测试数据,我们在第三章中介绍了它,当时正在回顾典型的模型生命周期。表面上看,这似乎是一个容易考虑的事情——我们随机选择一些训练数据,将其保留并仅用于评估。当训练数据中的每个示例具有等概率且独立地放入留出测试数据时,我们称之为IID 测试集。IID术语是统计学术语,意味着独立同分布。我们可以将 IID 测试集过程简单地理解为针对训练数据中的每个示例基于结果像是抛一枚(可能是有偏的)硬币或掷一颗骰子,并根据结果保留其中的每一个示例用于 IID 测试集。
使用 IID 测试数据已被广泛接受,这不是因为它一定是创建测试数据的最具信息性的方式,而是因为它尊重了支持一些监督机器学习理论保证的假设。然而,在实践中,一个纯粹的 IID 测试集可能不合适,因为它可能会给出一个在部署中模型预期性能的不现实的乐观视图。
举例来说,想象我们有一个大量股价数据的数据集,我们希望训练一个模型来预测这些价格。如果我们创建一个纯粹的 IID 测试集,我们可能会在训练数据中有来自某一天 12:01 和 12:03 的数据,而 12:02 的数据却在测试数据中。这会造成这样一种情况:模型可以更好地猜测 12:02,因为它已经看到了 12:03 的“未来”。实际上,一个关于 12:02 的模型是无法访问这种信息的,所以我们需要小心地创建我们的评估方式,不允许模型在“未来”数据上进行训练。类似的例子可能存在于天气预测或纱线产品购买预测中。
这里的重点不是说 IID 测试分布总是不好,而是这些细节确实很重要。我们需要在创建评估数据时应用谨慎的推理和常识,而不是依赖固定的配方。
渐进式验证
在具有基于时间排序数据的系统中——就像我们前面的股价预测示例一样——使用渐进式验证策略可能非常有帮助,有时也称为回测。基本思想是模拟训练和预测在真实世界中的工作方式,但是按照数据最初出现的顺序将数据通过模型。
对于每个模拟时间步骤,模型展示下一个示例并要求做出最佳预测。然后记录该预测并将其合并到总体评估指标中,然后才将示例展示给模型进行训练。通过这种方式,每个示例首先用于评估,然后用于训练。这有助于我们看到时间顺序的影响,并提出诸如“去年选举日这个模型会怎么做?”的问题。
缺点是,如果我们的模型需要多次通过数据进行良好训练,这种设置有些难以适应。第二个缺点是,我们必须小心比较基于完全相同时间范围的评估数据的模型。最后,不是所有的系统都会在一个可以有意义地按照规范顺序排序数据的环境中运行,比如时间。
黄金集
在不断重新训练和使用某种形式的渐进验证的模型中,很难确定模型性能是否正在改变,还是数据变得更容易或更难预测。控制这种情况的一种方法是创建一组金标准数据,模型永远不允许在其上进行训练,但数据是从特定时间点获取的。例如,我们可能决定去年 10 月 1 日的数据被设置为金标准数据,无论何种情况下都不得用于训练,而是单独保留。
当我们设置金标准数据时,还会将该数据集通过我们的模型运行的结果,或者在某些情况下,人类对金标准数据进行评估的结果与之保持一致。有时我们可能会把这些结果视为“正确的”,即使它们实际上只是从特定过程和特定时间点的这些示例的预测结果。
金标准数据的性能评估能够显示模型质量的突然变化,这对于调试大有裨益。需要注意的是,金标准评估并不特别适用于评判模型的绝对质量,因为随着时间的推移,其对当前性能的相关性会逐渐降低。如果我们无法长时间保留金标准数据(例如,为了遵守某些数据隐私法律或响应删除或访问到期请求),还可能会出现另一个问题。金标准的主要好处在于识别变化或错误,因为通常情况下,随着新训练数据被整合到模型中,模型在金标准数据上的表现只会逐渐改变。
压力测试分布
在现实世界中部署模型时,一个担忧是它们在现实中遇到的数据可能与训练时展示的数据大不相同。(文献中有时将这些问题描述为不同的名称,包括协变量转移、非稳态或训练-服务偏差)。例如,我们可能有一个主要基于北美和西欧图像数据进行训练的模型,但后来将其应用于全球各国。这会产生两个可能的问题。首先,模型可能在新类型的数据上表现不佳。其次,更为重要的是,我们可能并不知道模型表现不佳的原因,因为数据在提供(据称为 IID 测试数据)的源中未被代表。
这类问题在公平和包容的角度尤为关键。假设我们正在建立一个模型,根据提供的人像图像预测用户偏好的纱线颜色。如果我们的训练数据不包括具有各种肤色的人像图像,那么 IID 测试集可能无法充分代表,以揭示模型在具有特别深色皮肤人群的图像上表现不佳的问题。(这个例子回溯到 Buolamwini 和 Gebru 的开创性工作。)在这种情况下,创建特定的压力测试分布是非常重要的,其中精心构建的测试集各自探索模型在不同肤色上的性能。类似的逻辑适用于测试模型在实践中可能关键的任何其他性能领域,从适用于温带气候中开发的导航系统的雪地街道,到适用于多数英语工作场所中开发的语音识别系统的广泛语音和语言。
分析切片
有一个有用的技巧需要考虑,即任何测试集——即使是 IID 测试集——都可以被切片,以有效地创建各种更有针对性的压力测试分布。通过切片,我们指的是根据某个特定特征的值对数据进行过滤。例如,我们可以切片图像,查看仅具有雪地背景的图像的性能,或者是市场上第一周交易的公司的股票,或者是仅为红色的纱线。只要我们至少有一些符合这些条件的数据,我们就可以通过切片评估每种情况下的性能。当然,我们需要注意不要切片得太细,否则我们所看到的数据量在统计意义上将会太小,无法得出任何有意义的结论。
对事实进行反事实测试
了解模型更深层次性能的一种方法涉及学习,即如果数据不同,模型将如何进行预测。这有时被称为反事实测试,因为我们最终提供给模型的数据与某种方式上的实际数据相悖。例如,我们可能会问,如果给定图像中的狗不是在草地背景上,而是在雪地或云层背景下,模型会预测什么。我们可能会问,如果申请人住在不同的城市,模型是否会推荐更高的信用评分,或者如果电影中主演的代词从他变为她,模型是否会预测出不同的评分。
这里的诀窍在于,我们可能没有符合这些情景的任何示例,如果是这样的话,我们会采取创建合成反事实示例的步骤,通过操纵或改变我们可以访问到的示例来进行。当我们想要测试某个给定的改变是否不会显著改变模型预测时,这种方法往往非常有效。每一个这样的测试都可能揭示关于模型及其依赖的信息源的一些有趣的事情,从而使我们能够判断模型行为是否恰当,以及是否需要在发布前解决任何问题。
一些有用的指标
在机器学习领域的某些角落,有一种倾向于将单一指标视为评估给定任务上模型性能的标准方法。例如,多年来,准确率一直是评估 ImageNet 留存测试数据上模型的唯一方式。事实上,在基准测试或竞赛设置中,这种心态通常最为常见,因为单一指标简化了不同方法之间的比较。然而,在现实世界的机器学习中,只单纯考虑一个指标通常是不明智的。最有效的方法往往是考虑多样化的指标和评估,每个指标都有其独特的优势、劣势、盲点和特异性,就像没有一个最佳的观日出的地方一样,也没有一个最佳的指标来评估一个给定的模型。
在这里,我们将试图建立对一些较常见指标的直觉。我们将它们分为三大类别:
金丝雀指标
擅长指出模型存在问题,但不太有效地区分好模型和更好模型。
分类指标
帮助我们理解模型对下游任务和决策的影响,但需要复杂的调整,可能会使模型之间的比较更加困难。
回归和排名指标
避免这种调整,使得比较更容易理解,但可能会忽视某些错误成本较低的具体折衷方案。
金丝雀指标
正如我们所指出的,这组指标为我们提供了一种有用的方法来判断我们的模型是否存在严重问题。就像传说中的煤矿中的金丝雀一样,如果任何一个指标的表现不如预期,那么我们肯定有问题需要解决。另一方面,如果这些指标看起来不错,并不一定意味着一切都好或者我们的模型完美无缺。这些指标只是潜在问题检测的第一道防线。
偏差
这里使用的偏差是指统计意义上的,而不是道德意义上的。统计偏差是一个简单的概念——如果我们根据模型的预测加总所有我们期望看到的东西,然后加总实际数据中我们实际看到的东西,结果是否相同?在理想的情况下,应该是相同的,通常一个运行良好的模型将展现出非常低的偏差,意味着对于给定的预测类别,预期值和观察到值之间的差异非常小。
作为一个评估指标,偏差的一个好处是,与大多数其他指标不同,我们期望大多数模型能够达到的“正确”值是 0.00。这里偏差的偏差甚至一两个百分点的差异通常都是某些问题存在的迹象。偏差经常与切片分析结合起来作为一种评估策略,以揭示问题。我们可以使用切片分析来识别模型在某些数据部分上表现不佳的地方,作为开始调试和改善整体模型性能的方法。
以偏差作为评估指标的缺点在于,创造一个完全零偏差的模型是微不足道的,但那是一个糟糕的模型。作为一种思想实验,可以通过让模型只返回每个示例的平均观察值来实现这一点——总体上偏差为零,但完全没有信息价值。像这样病态糟糕的模型可以通过在更细粒度切片上观察偏差来检测,但更重要的问题仍然存在。偏差作为一个指标是一个很好的指示器,但仅仅有零偏差并不能表明模型质量高。
校准
当我们有一个预测概率值或回归估计的模型,比如用户点击给定产品的概率或明天温度的数值预测时,创建一个校准图可以对模型的整体质量提供重要的洞察。这主要可以分为两步进行,大致可以理解为首先将我们的评估数据分桶,并计算每个桶中模型的偏差。通常,分桶是通过模型分数来完成的——例如,模型预测中最低十分之一的示例放入一个桶中,接下来的十分之一放入下一个桶中,以此类推——这种方式让人想起之前讨论的切片分析的概念。这样,校准可以被看作是结合偏差和切片分析方法的一种系统扩展。
校准图可以显示系统效应,如在不同区域的过度预测或欠预测,并且可以是特别有用的可视化工具,帮助理解模型在其输出范围极限附近的表现。总体而言,校准图可以帮助显示模型可能系统性地过度预测或欠预测的区域,通过绘制观察到的发生率与它们的预测概率。这对于检测模型评分更可靠或不太可靠的情况非常有用。例如,在 图 5-2 中的图表显示,该模型在中间范围内有良好的校准,但在极端情况下表现不佳,在实际低概率示例上过度预测,在实际高概率示例上欠预测。

图 5-2. 一个示例校准图
分类指标
当我们考虑模型评估指标时,分类指标如准确度通常是首先想到的。广义上说,分类指标 帮助衡量我们是否正确地识别了给定示例属于特定类别(或 类 )。类别标签通常是离散的——比如 click 或 no_click,或者 lambs_wool、cashmere、acrylic、merino_wool——我们倾向于将预测判断为二进制的正确或错误,是否正确得到了给定的类别标签。
因为模型通常为给定的标签报告一个分数,比如 lambs_wool: 0.6、cashmere: 0.2、acrylic: 0.1、merino_wool: 0.1,我们需要调用某种决策规则来决定何时预测一个给定的标签。这可能涉及一个阈值,比如“每当 acrylic 的得分在给定图像中超过 0.41 时,预测为亚克力”,或者询问哪个类别标签在所有可用选项中得分最高。这些决策规则是模型开发者的选择,通常是通过考虑不同类型错误的潜在成本来设置的。例如,错过识别停止标志可能比错过识别美利奴羊毛产品显著更为昂贵。
有了这些背景知识,让我们看一些经典的指标。
准确度
在对话中,很多人使用 准确度 这个术语来表示一种总体的良好感,但准确度也有一个正式的定义,显示了模型预测正确的比例。这满足了我们的直觉需求——我们想知道我们的模型多频繁地正确。然而,这种直觉有时候在缺乏适当的背景信息时可能会误导我们。
要将准确度度量放入背景中,我们需要理解总是预测最普遍类别的天真模型有多好,还要了解不同类型错误的相对成本。例如,99% 的准确率听起来很不错,但如果目标是弄清楚何时安全地穿过繁忙的街道,那可能会很糟糕——我们很可能很快就会发生事故。类似地,0.1% 的准确率听起来很糟糕,但如果目标是预测中奖的彩票号码组合,那将是惊人的表现。因此,当我们听到一个准确率值时,第一个问题应该始终是:“每个类别的基础率是多少?”还值得注意的是,看到 100% 的准确率或任何指标的完美表现通常更多是引起关注而不是庆祝,因为这可能表明过度拟合、标签泄露或其他问题。
精确率和召回率
这两个指标通常成对出现,并且在一个重要的方面相关。这两个指标都有一个正例的概念,我们可以将其视为“我们努力寻找的东西”。这可以是为垃圾邮件分类器找到垃圾邮件,或者为毛线商店模型找到与用户兴趣匹配的毛线产品。这些指标回答以下相关的问题:
精确率
当我们说一个例子是正例时,这种情况确实发生了多少次?
召回率
在我们的数据集中的所有正例中,我们的模型识别了多少个?
当数据中正例和负例不均匀分布时,这些问题特别有用。与准确率不同,90% 的精确率或者 95% 的召回率意味着什么的直觉在一定程度上是合理的,即使正例只是总体数据的一小部分。
尽管如此,重要的是注意这些指标之间存在一种有趣的紧张关系。如果我们的模型没有足够的精确度,我们可以通过增加它用于做出决策的阈值来提高其精确度。这会导致模型仅在更加确信时才说“正例”,对于合理的模型,这将导致更高的精确度。然而,这也意味着模型更少地说“正例”,即它识别的正例总数更少,召回率更低。我们也可以在另一个方向进行权衡,降低阈值以增加召回率,但代价是精确度降低。这意味着必须考虑这些指标的综合使用,而不是孤立地考虑它们。
AUC ROC
有时这仅仅被称为曲线下面积(AUC)。ROC是接收者操作特征的缩写,这是一个最初用于帮助测量和评估第二次世界大战中雷达技术的指标,但这个缩写已经普遍使用。
尽管名称令人困惑,AUC ROC 具有独立于阈值的模型质量度量的优良特性。请记住,准确率、精度和召回率都依赖于分类阈值,这些阈值必须进行调整。阈值的选择可以显著影响度量的值,使得模型之间的比较变得棘手。AUC ROC 将这个阈值调整步骤从度量计算中剔除。
从概念上讲,AUC ROC 是通过创建一个图表来计算的,该图表显示了给定模型在每个可能的分类阈值下的真正率和假正率,然后找出该曲线下的面积;参见图 5-3 作为示例。(听起来很昂贵,但可以使用高效算法来进行此计算,而无需实际运行大量不同阈值的评估。)当这条曲线下的面积缩放到 0 到 1 的范围时,这个值也提供了以下问题的答案:“如果我们从数据中随机选择一个正例和一个负例,那么我们的模型给出高分预测分数给正例而不是负例的概率是多少?”
然而,没有完美的指标,AUC ROC 也有其弱点。它容易被模型改进所欺骗,这些改进改变了远离任何合理决策阈值的示例的相对排序,例如将已经排名低的负例进一步降低。

图 5-3. 展示模型在一组分类上性能的 ROC 曲线
精度/召回率曲线
就像 ROC 曲线在不同决策阈值下映射出真正率和假正率之间的权衡空间一样,许多人绘制精度/召回率曲线,这些曲线在不同决策阈值下映射出精度和召回率之间的权衡空间。这对于在一系列可能的权衡中获取两个模型的整体比较是有用的。
与 AUC ROC 不同,计算的精度/召回率曲线下的面积没有理论上的统计含义,但在实践中常被用作概述信息的快速方式。在强烈的类别不平衡情况下,可以认为精度/召回率曲线下的面积是一种更具信息性的度量。³
回归指标
与分类度量不同,回归度量不依赖于决策阈值的概念。相反,它们查看代表模型预测的原始数值输出,例如给定毛线的预测价格,用户可能花在阅读描述上的秒数,或者给定图片包含小狗的概率。它们通常在目标值本身是连续值时使用最多,但在离散值标签设置中也有用,如点击预测。
均方误差和平均绝对误差
当将模型的预测与实际值进行比较时,我们可能首先关注的指标是我们的预测与现实之间的差异。例如,在某种情况下,我们的模型可能预测某个例子实际上有 4 颗星,但实际上只有 4.3 颗星,而在另一种情况下,它可能预测某个例子实际上有 5 颗星,但实际上只有 4.7 颗星。如果我们不加思考地聚合这些值,这样我们可以查看许多值的平均值,我们将遇到一个轻微的烦恼,在第一个例子中差异是 0.3,在第二个例子中是-0.3,因此我们的平均误差看起来是 0,这对于一个明显不完美的模型来说可能会误导。
其中一个修复方法是取每个差异的绝对值——创建一个称为平均绝对误差(MAE)的度量来对这些值进行平均。另一个修复方法是平方误差——将它们提升到二次幂——以创建一个称为均方误差(MSE)的度量。这两个度量具有一个有用的特性,即值为 0.0 表示一个完美的模型。MSE 比较大的误差要比较小的误差惩罚更严厉,这在不希望犯大错误的领域中可能是有用的。如果数据包含噪声或更好地忽略的异常值示例,那么 MAE 可能是一个更好的度量。特别是计算这两个度量并查看它们是否为两个模型之间的比较提供了质量上不同的结果,这可以提供有关深入理解它们差异的线索。
Log loss
有些人将对数损失视为逻辑损失的缩写,因为它源自logit函数,它等同于两种可能结果之间的对数比率。更方便的思考方式可能是将其视为我们在考虑我们的模型输出为实际概率时想使用的损失。概率不仅仅是限制在 0.0 到 1.0 范围内的数字,尽管这是一个重要的细节。概率还有意义地描述了某个事情发生的可能性是真实的机会。
Log loss 在概率方面表现出色,因为它能够凸显出预测为 0.99、0.999 和 0.9999 之间的差异,并且如果预测错误,将更严重地惩罚每个更自信的预测结果——对于预测为 0.01、0.001 和 0.0001 等极端概率也是如此。如果我们确实关心使用模型输出作为概率,这一点非常有帮助。例如,如果我们正在创建一个风险预测模型,预测事故发生的机率,那么操作的可靠性为 99% 和 99.99% 之间存在巨大差异——如果我们的指标不能凸显出这些差异,我们可能会做出非常糟糕的定价决策。在其他情境下,我们可能只是大致关心一张图片中包含小猫的可能性,而 0.01 和 0.001 的概率可能都最好解释为“基本不太可能”,在这种情况下,对于最终指标来说,对数损失将是一个不合适的选择。最后,需要注意的是,如果我们的模型预测的值恰好是 1.0 或 0.0 并且出错,对数损失可能会产生无限的值(显示为 NaN 值并破坏平均值)。
将验证和评估操作化
我们刚刚快速浏览了评估模型有效性和模型质量的世界。我们如何将这些知识转化为可操作的内容?
评估模型的有效性是任何关心生产的人都应该知道如何做的事情。即使你不是每天进行模型评估,也可以通过结合培训、检查清单/流程以及简单情况下的自动化支持代码(这本身可以为更复杂的情况节省人类的专业知识和判断)来实现这一点。
对于模型质量评估的问题,情况可能更加模糊。显然,对于 MLOps 人员来说,熟悉对于我们系统中评估模型质量最关键的各种分布和指标是非常有用的。一个组织可能会经历几个阶段。
在组织进行模型开发的最早阶段,最大的问题通常更多地集中在使某事起作用上,而不是如何评估它。这可能导致相对粗糙的评估策略。例如,在开发羊毛店产品推荐模型的第一个版本时,主要问题更有可能是围绕创建数据管道和服务堆栈,而模型开发人员可能没有精力仔细选择各种分类或排名指标之间的差异。因此,我们的第一个标准评估可能只是预测用户在保留测试集中点击的 AUC ROC。
随着组织的发展,对给定评估可能存在的缺陷或盲点的理解逐渐加深。通常情况下,这导致开发额外的度量或分布,帮助揭示模型性能的重要领域。例如,我们可能会注意到一个冷启动问题,即新产品未在留存集中表示,或者我们可能决定查看校准和偏差指标,跨国家或产品列表类型的范围,以更多了解我们模型的性能。
在后期阶段,组织可能开始回顾和质疑基本假设,例如所选择的度量标准是否充分反映了业务目标的真实性。例如,在我们想象中的纱线店中,我们可能会意识到优化点击并非等同于优化长期用户满意度。这可能需要全面重构评估堆栈,并仔细重新考虑所有相关度量。
这些问题是否属于模型开发人员或 MLOps 人员的领域?对此的看法可能有所不同,但我们认为,一个健康的组织将鼓励多种观点,并对这些问题进行充分讨论。
结论
本章重点是建立模型有效性和模型质量的初始观点,这两者在将模型新版本投入生产之前都至关重要。
有效性测试有助于确保模型的新版本不会破坏我们的系统。这些测试包括与代码和格式的兼容性,以及确保计算、内存和延迟的资源需求都在可接受的限度内。
质量测试有助于确保模型的新版本将提高预测性能。这通常涉及评估模型在某种形式的留存或测试数据上的表现,选择适合应用任务的评估指标。
这两种测试形式共同确立了对模型的相当程度的信任,并将是许多静态训练的机器学习系统的合理起点。然而,将机器学习部署在连续循环中的系统将需要额外的验证,详细信息见第十章。
¹ 详见 Joy Buolamwini 和 Timnit Gebru 的“性别阴影:商业性别分类中的交叉准确性差异”。
² 例如,详见 Kai Xiao 的“噪声还是信号:图像背景在对象识别中的作用”。What-If Tool也是一个允许进行反事实探索的优秀工具的例子。
³ 详见 Tam D. Tran-The 的“在不平衡数据中,精确度-召回曲线比 ROC 更具信息性:餐巾数学及更多”。
第六章:公平性、隐私和道德机器学习系统
作者:艾琳·尼尔森
本章讨论了在创建或部署机器学习系统时涉及的道德考虑和法律义务相关的主题。我们无法在这些主题上提供详尽的指导,但这份资源可以为您指明正确的方向。在本章结束时,您应该对机器学习部署的基本道德考虑有了良好的理解,以及可以让您开始在与您自己工作最直接相关的领域进行更深入教育的具体语言和概念类别。
注意
编者注:当我们整理 MLOps 需要真正了解的主题列表时,公平性、隐私和人工智能以及机器学习系统中的道德问题位居榜首。然而,我们也知道,一个具有强烈行业背景的作者团队很难提供关于这些复杂问题的真正无偏见的观点。因此,我们邀请了艾琳·尼尔森(Aileen Nielsen),《实用公平性》(O'Reilly,2020)的作者,独立撰写这一章节。虽然我们就清晰性提供了草稿反馈,但这里的观点完全是她的,她对本章有完全的编辑控制权。你将直接从一个世界级专家那里获取这些信息!
我们还应该从一开始就指出,人工智能和机器学习中的公平性和道德仍然是高度争议的话题。事实上,目前一个合理的立场是,在计算系统中促进公平性的一种相当可行的方法 不 使用人工智能/机器学习。然而,对于那些发现自己被迫这样做,或者相信在特定使用案例中可以克服算法解决方案怀疑的人来说,本章提供了理解如何正确执行的起点。
此外,需要认识到,在某些情况下,现有或传统的问题解决方案在算法前时代(例如,指定人类决策者,或没有明确的决策者)并不总是很好。¹ 例如,大量经验研究表明,种族影响法官的判决决策,甚至店员关于是否允许顾客退货的非正式决策。因此,当我们考虑人工智能和机器学习中的公平性和道德时,我们也必须承认,在某些情况下,它们可能确实相对于人类决策者有所改进。因此,尽管本章中可能会发现一些忧愁和悲观情绪,但我们也从一开始就认识到,虽然尚无明确的解决方案能够使人工智能和机器学习在全球范围内保持公平和正义,但有些算法的使用确实在提高整体公平性方面取得了巨大成功。
本章节中,你会发现专注于特定热门话题的部分,特别是公平性、隐私和负责任人工智能。我们认识到这些话题在公众意识和关注度以及工业和学术界的关注度方面的重要性。在这些领域正在发生许多发展,我们希望能够为你提供一个良好的初始背景,使你能从本章节中获取这些话题的信息。在本章中,我们还提供了关于如何在你的组织中考虑重构工作的笔记,以实际方式增强你在 AI/ML 工作中的公平性和道德性。
公平性(也称为抗击偏见)
算法公平性及其各种变体,长期以来一直是机器学习中的热门话题。当你阅读关于这个主题的内容时,最常见的是公平性被用作直接与偏见相关的概念——即公平性被定义为没有偏见,而偏见则是不公平的状态。²
长期以来,机器学习研究人员、法律学者和活动家们一直对机器学习可能会延续现有社会偏见,甚至创造新的偏见形式表示关注。在这些讨论中,许多人强调,这可能发生的原因是用于训练机器学习系统的数据可能来自有偏见的系统或以有偏见的方式收集。简而言之,人们提出了类似于“垃圾进,垃圾出”的观点。
但你应当注意到,“垃圾进”并不一定指的是糟糕的数据。垃圾指的是由于不具代表性的训练数据或算法偏见而导致的结果。这是一个关键点:重要的是要意识到偏见的根本源头可以来自机器学习流程中的多个步骤,包括糟糕的数据,也包括糟糕的建模选择。以下是一些常被引用的偏见来源的非详尽列表:
抽样偏见
在抽样偏见中,数据收集过程本身就带有系统性偏见。一个常见的例子是,白人和黑人美国人之间的大麻使用率被认为大致相等,但是关于大麻持有的逮捕率对黑人美国人远高于白人美国人。这几乎可以肯定是由于抽样偏见造成的(除其他原因外)。由于种族主义在个体决策和系统层面上的显现,黑人美国人要比白人美国人更有可能因大麻持有而被警方搜索(有些人可能熟悉相关的种族主义表现,开车时是黑人)。
与机器学习相关的例子:
犯罪预测算法,例如那些用来影响警察巡逻分配的算法,很可能受到抽样偏差的影响。³ 在许多国家和大陆,警务工作往往集中在低社会经济地位的社区。由于这种过程产生的数据在某些地区或人口群体中过度抽样犯罪,因此很可能在不同社区中误代表犯罪的基础率。然而,这种以偏见方式抽样的数据,又为更多机器学习模型分配未来警务巡逻创建了新的偏见输入。由于这种算法,警察往往会过于频繁地回到同一地区,因为其他地区没有以同样的方式过度抽样。
不平等对待
偏见可能源于对个体明确地进行不同对待。当没有合理理由时,政府和某些私营部门的规范区域都禁止不平等对待。在几乎所有关于基于种族的不平等对待的例子中(如种族隔离学校或只雇佣白人的政策),法院都没有找到正当理由支持这种歧视(民权运动后)。在基于性别的不平等对待中,法院有时认为为性别不同的理由(例如对体能测试的不同表现门槛)可能由于强制性利益而被证明是正当的。
ML 相关示例:
机器学习算法常常因其发现超越人类能力的模式而受到赞誉。然而,有时这些模式只是显而易见的性别歧视。亚马逊曾开发但未部署⁴ 一种内部招聘算法,该算法对就读女子学院的女性应聘者应用了强烈的负参数。⁵ 因此,我们看到了算法在做出决策时使用无关因素,直接对一个群体(在这种情况下是去女子学院的女性)进行歧视的案例。如果这种算法被使用,这将看起来像是一种不平等对待的案例。
制度性偏见
与前述例子相比,这种偏见的来源在识别和减轻方面可能更具挑战性。广义上来说,我们可以将系统偏见视为许多因素的集合,这些因素很可能在个别情况下不能作为解释特征被识别,但在集合层面上,显然影响个人结果的差异,这些差异是由于结构性限制(这些限制已经融入到我们的社会、教育和就业系统中,等等)。人工智能系统无法脱离其构建的社会背景,因此没有理解背景的人工智能可能会加剧系统偏见。事实上,即使是人工智能应用的特定问题本身,通常也被视为系统偏见的表现。例如,一些人问为什么长期以来积极使用预测警务来预测社会经济弱势群体中的犯罪,而用于识别或预测警察不当行为的算法系统相对较少。
与机器学习相关的例子:
在培训机器学习系统时,有时会选择某些特征,因为它们似乎提供了“常识”示例,例如某些雇主或教育机构可能概念化了这种观念的“优点”。例如,中产阶级高中学生经常被告知要参加课外活动,以显示他们是高度积极的领导者。然而,如果在算法或人类决策中使用有关参与课外活动的数据,没有额外的背景信息,这将促成一个奖励中产阶级学生的系统,因为他们能够接触到这样的可能性。这种系统同样会使得无法参加这些活动的低收入学生处于劣势,因为他们需要工作或履行家庭义务。因此,对于不熟悉不同社会背景并且不了解系统偏见后果的人来说,所谓的“常识”一旦融入到分析中,可能看起来相当偏见。
多数暴政
这种偏见的来源与使用的培训过程形式相关。在许多常用的建模系统中,数值上的多数类别通常通过总数对训练损失影响最大。因此,如果建模过程没有考虑到这一点,许多类型的模型实际上会偏向于多数群体,并且相比于少数群体,更直接地将错误最小化。同样的担忧有时会激励设计政治系统,以保护少数群体的利益,而不是仅仅依靠多数规则。
与机器学习相关的例子:
众所周知,使用不涉及相对平等特征分布的数据来训练机器学习系统(不平衡数据集)可能会非常具有挑战性,如果我们希望为所有类别实现良好的性能。当处理包含不同类人群的数据集时,这种情况很可能会发生,因为大多数数据集在性别、种族或其他人类多样性形式(如地理或语言)上都存在某种形式的数据不平衡。因此,建模人类行为应该特别注意确保模型对每个人都公平对待,而不是根据事实上只对大多数类别中的某个人相对准确的原型进行建模。
不幸的是,这些偏见形式(及其他许多形式)在广泛的机器学习应用中仍然频繁出现,即使有关算法公平性的媒体关注日益增加。这种情况存在许多原因。社会偏见普遍存在,并不总是在个体层面上显现出来。某人可能认为自己在做出不带偏见的决定,既因为他们没有关于做出决定的系统所有细节,也因为他们自己的无意识偏见。这不是一个可以通过一章书解决的问题,但却是一章书可以让读者意识到并且有动力采取行动的问题。
机器学习/人工智能研究社区一直在开发方法和技术,系统地识别和纠正这些偏见。试图开发负责任和公平的人工智能系统的从业者应该了解这些新兴工具可能会有所帮助。更重要的是,机器学习/人工智能很可能提供一种前进的方式,使系统比使用不负责任的人类更加公平,只要机器学习的开发是谨慎的,并在针对适当问题时带有适当的保障。
公平性的定义
在机器学习社区中,我们尚未围绕公平性形成单一的定义,但存在一些常见类别,这些类别具有直观和吸引人的描述。例如,一些关于公平性的定义强调个体公平。这些公平性的概念认为,对于除了无关因素(种族、性别等)外“相同”的两个个体,这些个体应该被同等对待。⁶ 其他公平性的定义强调机器学习应该在群体层面上看待公平性。也就是说,错误率应该在各个群体中相同且质量相同,并且总体上性能水平在各个群体中也应该同样高。还有其他的公平性定义可能会更加复杂,并试图建立因果机制来理解是什么驱使个体成功或失败,然后再试图算法地对其进行分类。
两种常见的公平性类别是直观和吸引人的组公平和基于校准的评估。这些远非公平性的唯一概念,但我们选择这两种讨论的原因有两个。首先,每个定义都很直观,并且具有很强的吸引力。其次,每个都突出了公平的两个不同概念。
如其名,组公平 强调公平作为基础上组进行比较的问题。它强调应该至少部分地基于他们身份的敏感属性来审视个体的结果,尤其是法律保护的属性,如性别和种族,但也包括一些可能不受法律保护但某些人认为在道德上重要的属性,如经济地位。这样做有很好的理由,包括我们在看世界时,这些特征通常在实际结果中影响深远。
另一方面,校准 强调个体公平,这是我们大多数人都认为相当直观和吸引人的另一个价值观。同样,我们坚信个体应该根据他们是谁以及他们作为个体的所做所为来对待,而不是基于他们来自何处。
在哲学上看来,这两种公平性定义似乎不需要互相对立。在一个完美的世界中,群体和个体都得到公平对待,我们会得到相同的结果。不幸的是,在我们不完美的世界中,由于各种原因,包括基本的数学限制,情况并非如此。(参见 7)因此,至少目前,从业者必须选择他们的公平定义。正如我们将要描述的那样,不同的用例将有不同合理的公平定义。
在不同情况下应用不同的公平概念可能看起来很奇怪,成熟的读者将意识到我们在现实生活中同样应用相同的原则。考虑美国,一个强烈市场驱动的经济体。在很大程度上——即使在我们当前的民粹主义时代——在劳动市场上,存在着普遍的个性化公平观念。美国人似乎认为人们应该在开放市场上得到他们能得到的东西,尽管对工资不要过低有些担忧(因此有法定最低工资),同样对于最高支付率过高也有一些担忧(通过对不断增加的不平等和亿万富翁阶级崛起的担忧表明)。另一方面,当涉及到医疗保健时,大多数美国人认为每个人都应该获得良好的医疗护理,而不管个体健康或先天遗传的差异。
看起来(至少对我们这些坐在家里的人类学家来说),在某种程度上,美国人似乎对经济利益的分配方式感到舒适,可能在某种程度上是基于天生的能力,但当涉及医疗福利的分配时则不然。因此,事实上,普通人似乎确实常常在生活的不同领域应用不同的公平观念,我们认为在 ML 的不同上下文或使用案例中,同样可能是如此。
警告
似乎 ML 伦理社区应该试图在公平 的单一定义上达成一致。当我们看到公平的不同定义在实践中是分歧甚至矛盾的时候,这种观点似乎尤为正确。目前,鉴于行业和该领域的成熟程度,几乎可以肯定的是,目标并不是收敛于一个单一的公平定义。这有两个原因。
首先,我们不需要这样做。目前部署在现实世界中的大多数模型的技术水平仍然在任何度量标准下基本上是不公平的(或至少是未经审查的公平)。我们有许多有用的公平定义可以选择,并且选择一个或几个来努力实现使我们有机会立即取得快速进展,而不需要等待进一步的理论或法律发展。
第二,从结构上看,目前 AI 和 ML 理论领域主要由社会中主导群体的人控制。这些人最有可能忽视 AI 和 ML 系统可能对无权或代表性不足群体产生负面影响的方式。毫无疑问,这些人不应该成为未来将公正定义为排斥其他一切的仲裁者。
组平等 公平性定义要求算法性能的相关比率在各种群体中相同。例如,一个组平等要求可能要求所有族裔的雇佣率相同,但也可能要求在诊断低氧时,无论皮肤颜色如何,准确度也相同。这个想法很引人注目和直观,因为它描绘了我们许多人希望看到的社会图景——一个不幸或机会平等分配给社区的社会。
与组平等相反,校准 公平性定义要求 ML 模型对所有个体工作效果一样好。虽然这不能直接衡量,但可以衡量的是,对于任何群体,模型得分对个体意味着相同。因此,一个以校准为导向的公平定义将要求对于任何群体,ML 得分的含义都是相同的。
这听起来令人生畏和高度技术化,但通过一个具体的例子可能更容易理解。校准的常见示例是用于许多美国州刑事法院的《矫正罪犯管理倾向评估替代刑罚》(Correctional Offender Management Profiling for Alternative Sanctions)或COMPAS再犯评分算法。因为已经显示该算法在种族类别上正确校准,因此对于黑人和白人数据对象来说,相同的 COMPAS 分数(比如 0.5)意味着相同的事情:即,一个白人罪犯和一个黑人罪犯,如果有相同的风险评分,则有相同的再犯概率。⁸ 以通俗的英语理解,这也似乎很直观——即模型分数应该对每个人都有相同的含义,无论他们属于哪个群体。
你可能会想知道,公平有多种定义是否是一个问题。毕竟,在其他情境中,描述世界的正确和直观方式有很多,那么为什么在公平的情况下不行呢?困难在于——至少在我们目前生活的世界中——这些公平的定义会发生冲突。COMPAS 算法是一个引人注目的例子。该算法并非一定是随意实施的,而实际上有时是作为减少刑事司法系统偏见运动的一部分而采用的。该算法通过被认为是确保公平和非歧视的黄金标准的校准检查。
然而,《非营利新闻室》(ProPublica)的记者后来证明,尽管进行了这种校准,该算法在标记黑人被告为高风险时有更高的虚警率,并且在标记白人被告为低风险时有更高的漏警率。换句话说,与白人相比,黑人被告更有可能被标记为有高概率再犯的可能性,但实际上未再犯;而白人更可能被标记为低概率再犯,但实际上再犯。
这引发了公众的强烈抗议,促使许多数学家和计算机科学家致力于解决这个问题。然而,学者们很快意识到,他们的目标——制定一个同时展示校准和统计平等的风险评分——在大多数真实世界数据中是不可能的。统计平等和校准不能在同一时间数学上满足,除非每个群体的事件基础率相同。然而,在现实世界中,基础率的平等是一个很少满足的条件。⁹
在数学上,不同的公平性定义在现实世界的条件下不可能同时满足。我们必须决定在机器学习环境中追求哪些公平性目标,并决定是否专注于特定的公平性指标甚至可能减少朝向本质视角的倾向,这本来可能更有助于增强公平性和其他伦理价值。
目前,我们认为对于特定的机器学习工具,选择和强调特定的公平性指标可能是合理的,同时要认识到不可能同时满足所有直观和规范上期望的公平性概念。
我们不希望完美成为良好的敌人。相反,从业者们发现,有多种公平性定义比没有更具操作性,并且努力朝着公平性指标的方向努力,广泛来说也可能增强许多其他形式的公平性。更重要的是,一些研究人员意识到,不同的情况可能需要不同的公平性指标,考虑到算法特定用例的相对伤害或政策目标,因此有兴趣的读者可以找到如何根据特定任务选择公平性指标的有用指导,考虑到各种错误可能导致的后果。
争取公平性
具体地说,经典的机器学习设置有三种工作模式,以朝向更公平(更少偏见)的结果。在这里,我们简要介绍它们的工作原理,以便您可以通过概览的方式探索文献,并了解不同方法的利弊:
预处理
这些方法在数据而非模型中进行干预。预处理方法采用多种方法来减少机器学习训练输入中的不公平性。最直接的是,数据点可以被重新标记。例如,一些方法,比如Kamiran 和 Calders (2011),提供了识别应重新标记数据的方式,因为数据表明存在偏见结果。¹⁰
另一个较少激进的方法是寻求降低有关个体所属群体信息的数据表示;例如,Zemel 等人(2013)首倡的方法建议描述数据,使得无法准确猜测个体的敏感属性。因为这些方法看待数据为干预点,它们不依赖于模型。一个经验法则是,在机器学习管道的尽早阶段介入最有可能产生最佳结果(并为后续的额外干预留下选项)。
但是,对预处理方法存在有效的关注。激进更改数据标签挑战了数据驱动学科(如机器学习),从根本上删除信息。同样,寻求“转换”数据而不是直接操纵标签的方法,在故意删除或更改数据时也挑战了数据驱动方法的基本原则。此外,很难确定由于更改数据而导致模型变化的具体原因,因为在大多数情况下,将无法清楚地知道所有影响重新标记少数数据点的事实。
在处理中
这些方法干预模型训练过程。这可以表现为任何实际步骤训练模型时受公平性考虑的影响方式。在许多情况下,这已通过调整模型训练中使用的损失函数来解决。可以添加各种“惩罚”,以反映由偏见结果造成的公平成本,正如Kamishima 等人(2011)的工作所反映的那样。这些方法类似于正则化技术。
另一种方法类似于预处理中描述的方法(学习公平的表示),其动机在于从模型对敏感属性的知识中移除识别信息。同时训练对抗模型和感兴趣的模型,使得对抗模型的目标是猜测输出与哪个敏感类别相关联。感兴趣的模型被训练为一项任务,但也被优化以减少其输出传输给对抗模型的信息量。其中一些方法,例如Zhang 等人(2018)的工作,可以是模型无关的。
后处理
这些方法干预模型的标签而不是直接干预模型本身。通过这种方式,它们根据达到某些目标来纠正模型的输出结果。后处理的一个例子是引入随机化,例如Hardt 等人(2016),在没有这种随机化的情况下,假阴性可能在不同群体之间不同(这是应用组平等的一个例子)。
另一个后处理的例子是为不同的群体设置不同的阈值,例如信用评分或大学入学分数,以便使用分数做出的预测或决策对不同群体同样准确。¹¹因为这些方法在模型运行后介入,所以它们是模型无关的。
选择哪种干预方法取决于多种因素。在某些情况下,组织可能需要应用特定的干预阶段,因为这是他们可以控制的干预方式。例如,一个组织可能已经获得了一个预训练的神经网络,他们将对其进行微调。由于该组织无法访问原始训练数据或方法,后处理可能是一个更可行的选择。
另一方面,另一个组织可能会发现后处理提供的选项在规范上存在问题,因为它们违反了一些人们持有的某些基本价值观。例如,人们可能对为不同群体明确设定不同的分数截止点感到不适,他们也可能对用随机数字替换那些算法输出的确实可能是正确的内容的想法感到不适。
到目前为止,监管机构或著名的伦理领袖尚无关于最佳干预方式的明确指导方针¹²,我们认为这将需要进行高度依赖于情境的分析。但高度情境化的案例决策需求并不异于组织运作的其他要素或影响他人生活的决策。算法将有助于提高效率和一致性,但在所有情况下都没有一个单一的算法公平解决方案。
公平作为一个过程而不是一个终点
这是一系列棘手的话题,了解到 AI 可能会造成如此多的伤害可能会极大地泄气。但不要因此不再去思考精心设计的 ML/AI 系统能够带来的所有优势。关于公平性的消息并不一定是坏消息。
让我们考虑两个问题:
-
就公平而言,你不可能让每个人都满意。在任何算法公平性挑战中,都没有“完全”公平的解决方案(至少目前还没有被确认出来)。
-
同样地,即使你确定了公平的特定定义(即,定义一个度量并不保证你能使模型完全符合该度量,或指示你应该如何尝试这样做),也没有完美的强制公平的方式。
让我们从你在 ML 建模中做出选择的角度来反驳这两点:
-
你有许多良好的公平定义可以选择。
-
任何朝着公平目标努力的过程都比忽视这些问题的世界要好——因为忽视并没有带来好的结果。
将公平视为一个过程而不是一个特定的终点可能会有所帮助。对于那些希望通过构建机器学习算法来解决业务问题并前进的人来说,这可能令人失望。现实更加复杂。产品需要维护有很多原因。世界在变化,因此部署条件也在变化,因此模型必须不断发展。公平性并不例外。
一个快速的法律声明
在这项工作中提供法律指导远超出范围,这正是你公司法律部门的职责!尽管算法公平性似乎是一个新课题,但歧视的概念在法律中的重要性和明确性已经有了几个世纪的历史。今天最前沿的话题,如种族和性别平等,同样在几十年来一直在法律中占据着突出的地位。特别是在被理解为人类生活核心的市民生活领域,如就业、教育、医疗、住房和金融信贷服务的访问。如果您从事涉及这些核心领域的机器学习工作,您很可能需要对公平性 — 尤其是您国家反歧视法律中的公平性 — 深感关切。
隐私
隐私 是一个在学术界证明极其难以定义的概念。因此,隐私措施在未来保护方面尤为困难。大数据的兴起正是一个明显的例子。
专家曾认为去标识化数据是适当和安全的。这些数据会移除被认为是可识别信息的内容,如姓名或地址,这些信息很容易与一个人匹配。然而,与特定人的身份看似不直接相关的其他因素的信息仍然被发布,如生日、种族或邮政编码。
随着大数据的出现,许多数据集被编制,通常涉及重叠的人群,因此可以使用不同的数据集一起使用来识别脱身信息中的人们。例如,对于大多数美国人来说,仅凭知道他们的生日、邮政编码和性别就可能在去标识化数据集中识别他们¹³。此外,世界越来越充满新的数据集,有时是由于数据泄露,而其他时候是由于人们自愿分享关于自己的信息 — 这些信息变得非常容易获取对于任何随意的恶心跟踪者。我们可能希望认为世界是一个匿名的地方,但今天情况并非如此。
这里描述了隐私的两个关键理念,既涉及到它们与隐私概念的关系,也涉及到如何将含有个人信息的现有数据集转化为可以使用或发布而不会泄露个体身份的数据集:
k-匿名性
k-匿名性的理念是,在给定的数据集中,对于任何感兴趣的组合类别,至少应有* k *个个体(外部指定)属于任何给定的桶。例如,我们可以将 k-匿名性应用于按城镇列出个体的数据集,要求数据被分桶,以确保对于任何邮政编码/出生信息/性别类别,至少有 10 个个体。可能有许多实现这一目标的方法。两个潜在的机会之一是报告月份或年份级别的生日,另一个是只报告邮政编码的前四位数字而不是全部五位。
这种隐私和预防措施的概念本质上将隐私概念化为在数据集中不处于太小的群体中。建议的大小 在医疗领域至少为 5,尽管已经报道的k大小远大于 50。k的适当大小将取决于特定领域,这可能涉及数据的敏感性、能够使用具有大k的有用数据集的可能性,以及考虑其他已知可能可链接数据集的再识别可能性。
差分隐私
这种数学方法向数据添加噪声,以便可以就可能性(或更重要的是,不可能性)在访问到这些噪声化数据时推断出关于特定个体的信息做出概率性保证。差分隐私的理念是,一个人的包含或不包含对数据集的操作(例如计算平均值或其他统计数据)产生影响,使得基于聚合报告可以推断出数据集的信息。例如,如果报告一个班级的平均年龄和组的大小,可以知道该个体的年龄。然而,如果应用了差分隐私,在概率上将不可能以预定的精度水平和给定的查询预算推断出该个体的年龄。^(14)差分隐私可以广泛应用,不仅适用于聚合统计数据的计算,还适用于 ML 模型的训练,通过确保模型的输出或训练不依赖于特定数据点的包含。
这些隐私概念可能显得相当技术性,但与真实的隐私问题相关,例如管理负责和保护隐私的开放数据集的发布,或确保法律权利具有有意义的技术转化。例如,欧盟的 GDPR 赋予个人数据删除权利。然而,如果一个机器学习模型已经被训练过,删除权利可能并不完全具有意义。例如,个人删除其数据的权利是否意味着他们也能强迫一家公司证明其机器学习模型也已经“遗忘”他们的数据?¹⁵
一些人已经探讨了如何通过差分隐私训练模型来解决这一问题。然而,技术挑战依然存在,因为在保证差分隐私和高性能之间达到平衡是相当具有技术挑战性的。¹⁶
保护隐私的方法
先前描述的 k-匿名性和差分隐私的定义和场景涉及非常具体的隐私和计算措施。事实上,隐私本身是一个高度技术化和专业化的领域,最好由专家来实施。¹⁷ 然而,有各种易于实施且有意义的可访问的增强隐私措施。你应该将它们包含在自己的工作流程中,并可能需要根据实际情况进行定制。
系统管理员和涉及合规问题的人员可能已经熟悉这些概念。然而,对于数据科学家和机器学习工程师来说,这些概念有时会非常陌生。我希望它们将成为基本项目规范和日常实践的一部分,今后会得到重视。
技术措施
以下是一些保护隐私的技术措施:
访问控制
保护隐私和减少威胁的一个关键方法是实施强大的访问控制。数据库中关于个人的任何数据都应被视为“需要知道”的资源,机器学习工程师应该根据具体目的请求访问,而不是自由访问或浏览数据。同样,访问权限应定期审查,以确保员工没有因为已无有效理由而继续访问数据。
访问日志
跟踪谁在何时访问特定形式的数据。这样可以了解数据使用模式,看到某人可能在不适当地访问数据,并在后来被提出不适当使用的指控时保留证据。对这些日志的分析也可能表明数据存储模式可以重构以减少不同使用模式可以访问的数据量。例如,如果一个 ML 模型需要访问敏感数据表的一个列,考虑将该数据列拆分出来,而不是授予访问完整表格的额外但不必要的信息访问权限。
数据最小化
应尽量减少数据的收集和使用。数据不应仅仅因为“将来可能有用”而收集。只有在存在该数据的即时用例时(最好对被收集数据的个体有一些益处),才应记录数据。
数据分离
需要用于合法业务用途的数据应与不太可能对创建 ML 模型有用的敏感数据(如姓名和地址)分开。例如,为了预测用户的点击,似乎没有理由知道用户的姓名或地址。¹⁸ 因此,没有理由将这些信息存储在可能对特定预测任务有用的信息(如过去的浏览历史或人口统计信息)中。¹⁹ 正如之前所述,研究您的数据访问日志可以帮助您识别可以重构以最小化数据暴露给 ML 应用程序的方式。
机构措施
这里也有一些机构措施可供选择:
道德培训
每个人进入新领域时都需要道德培训,为设计 ML 产品也是如此。 ML 工程师应该得到——但通常不会得到——全面审查,不仅包括一般的道德培训(如数据中的偏见可能性),还包括为特定用例构建算法时的领域特定培训。太多时候,组织没有任何关于隐私或伦理更广泛讨论或培训,即使基础培训,无论多么“俗气”,也有助于突显问题。
数据访问指南
除了已经描述的技术措施外,制定明确的规则,即使在何时访问数据和使用数据以及明确禁止的用例方面,也是有意义的。缺乏明确和明确的伦理规则可能导致缺乏问责制的机构文化。组织应在一个显而易见和可访问的地方制定清晰的数据访问和适当数据使用指南。
隐私设计
隐私设计是一组设计原则,适用于任何数字产品,包括机器学习流水线和机器学习驱动的产品。隐私设计的概念是隐私不应仅仅是附加到已存在流程的最后阶段。相反,隐私应从设计考虑的开始就内在于其中,并且应该是所有工作阶段中要考虑和关注的问题。隐私设计可以为在机器学习开发的所有元素中确保隐私提供一种灵活但全面的方式。
尽管这些可能都看起来是基本和显而易见的观念,但很少有组织,无论是大型还是小型,采取这些基本措施,甚至追求任何类似隐私或公平议程的内容。无论您是在初创公司、学术机构还是大型企业,几乎肯定都可以为增强您组织的机器学习流水线中的隐私做出贡献。
简而言之,有多种方法可以通过在您的组织中采取具体步骤来保护隐私。不幸的是,很少有人采取这些步骤,但它们可以简单而有效。通过在您自己的工作流程中采取这些简单措施,您将无所失(而有很多可以获益)。
一个快速的法律声明
超出本工作范围的内容是对通常影响数字产品的隐私法律进行详尽审查。在这里,我们重点介绍与隐私和机器学习相关的几类关键法律:
数据泄露通知法律
数据泄露通知法律要求那些持有数据的人在数据泄露中数据受到损害时通知他们持有数据的人。为确保合规性,这类法律通常对数据持有者在意识到数据泄露但未进行适当通知时施加严格处罚。这类法律有时也适用于本应意识到数据泄露的数据持有者,以确保企业不能简单选择保持无知。迄今的实证研究表明,这些法律并未阻止数据泄露随时间变得越来越普遍,甚至呈指数增长。尽管如此,这类法律在提供消费者何时因其个人数据曝光而处于最高风险的通知方面仍然非常有用。
数据保护和个人隐私法律
数据保护法律中最显著的例子是欧盟的 GDPR。全球许多国家都有数据保护法律,赋予人们基本权利,例如知道在线场所收集了哪些关于他们的数据,这些场所如何处理这些数据,以及这些数据是否正确。一些法律甚至进一步赋予消费者选择退出数据收集的权利,或者甚至赋予消费者删除数据或阻止数据销售的权利。不幸的是,实证研究表明,这类法律似乎在面向消费者的应用中被广泛忽视。尽管如此,这类法律为消费者提供了积极的方式,可以采取措施保护其隐私。
反不正当和欺骗行为的法律
在美国的背景下,这类更普遍的消费者保护法律至关重要,因为美国缺乏全面的国家个人数据隐私制度。美国联邦贸易委员会,作为消费者保护执法的重要来源,有时会采取行动,发现公司在业务实践中未能遵守公平或诚实的基本期望,以保护消费者隐私。这种情况的一个关键例子是那些甚至不尊重他们自己制定并放在网站上的隐私政策条款的公司。因此,至少有必要确保,在您的组织构建数据收集和机器学习建模能力时,这些实践与面向公众的隐私政策和服务条款一致。
负责任的人工智能
负责任的人工智能已经成为我们在训练或部署机器学习系统时应考虑的伦理关切的总称。这是一个日益增长的领域,可以安全地假设,无论是工业界还是学术界,都还没有完全掌握应由负责任的人工智能处理的伤害范围。在这里,我们在这一框架下讨论了一些近年来引起广泛关注的附加问题。然而,我们强调这里的问题只是一些亮点。我们并不打算提供负责任的人工智能价值观的详尽清单。
解释
ML 模型解释是分析和展示关于 ML 系统的信息以描述该系统运作方式的过程。这一过程及其使模型易于人类理解的目标通常简称为可解释性,在 ML 方面是一个关键领域。许多人希望理解 ML 系统为何以某种方式工作,这是理解其对其影响的特定结果的一部分的愿望。²⁰
出于技术和伦理原因,希望有能够“解释”ML 模型工作方式或为何在特定案例中达成特定结果的方法是可取的。解释 AI 的技术动机与控制模型质量以及通过模型了解数据有关。开发模型解释的技术人员可以深入了解为什么他们的模型运行良好或不佳,并可能了解到关于数据基础领域的一些内容。寻求可解释 ML 的伦理学家和倡导者出于不同的原因有类似的关注。他们发现了解模型是如何得出结论的对于那些受其影响的人来说是有帮助的,甚至可以在 ML 的结论不合理时提出质疑。
然而,解释并不是一件简单的事情。解释可以服务于许多目的,因此,根据所需目的和准备的受众,解释所包含的信息可能多种多样。从这个角度看,模型解释可能会感觉很像高度训练的专业人士(如医生或律师)在尝试向特定受众提供建议或诊断真实世界情况时面临的问题。例如,当医生解释推荐的治疗及其相关风险时,他们会根据受众调整解释。他们可能会向一位同行医生提供一个解释,向一个已知拥有生物工程学位的患者提供另一个不那么技术性但仍严谨的解释,并向患有痴呆症但仍可能能够作出自己医疗决定的人提供另一个解释。因此,我们可以看出,解释取决于那个解释的受众或消费者。
提供的解释还取决于其目的。如果机器学习解释的目的是检查模型质量,例如确保模型出于正确原因做出正确决策,则可能更喜欢全局解释。全局解释指出模型通常如何工作以及为什么会遵循某些一般决策规则。另一方面,如果解释的目的是让某个特定被拒绝信用(或遭遇其他不良结果)的人了解为什么以一种方式,可以帮助她将来改善机会,那么此人会希望得到局部解释。局部解释解释了为什么特定的人被拒绝以及可能在将来采取的最具可操作性的调整。
我们暂时不会详细讨论解释。在这里,我们希望您了解以下关键点:
-
模型的解释没有单一正确的解释。
-
解释需要根据受众和目的进行调整。
-
解释需要有用,有时还需要采取行动。
在具体实施方面,您在开始了解机器学习解释技术时可能需要采取的最低步骤如下:
-
至少,对于最终用户来说,知道算法使用的输入是有帮助的(即使这些最小信息通常不可用)。如果您能提供相关特征重要性的列表,那就更好了。如果能够将其放在显著位置,并用易于理解的语言编写,以便普通人可以看到和理解模型,那将是最有意义的。
-
另一种获取直观和具体信息的简单方法是生成测试输入,也许是反事实配对,并查看它们的情况。例如,对于某些用例,某些反事实配对不应该影响决策(例如,性别反事实应该不会改变信用决策),而对于其他用例,它们很可能会(例如,体重反事实可能经常会改变医疗干预决策)。这些可以构成基本的“嗅探”测试,同时也是为决策主体提供示例解释的一种方式。
-
考虑你是否能够提供全局(解释整体模型)或局部(解释特定 ML 模型决策/分类)的解释,并探索一些实现这些解释的技术。某种技术是否特别适合您的受众以及您的 ML 产品正在做出的决策类型?
随着各种解释技术的出现,一些研究人员提供了有关什么系统可能为不同目的服务并且适合使用的有用指导。²¹ 最重要的考虑因素是确定解释的最终用户的复杂程度以及提供解释的目的。从这里开始,通常可以识别至少一个,通常更多的技术选项,一些是开源的并已由专家实施。²²
效果
ML 效果 — 即,ML 产品实际上达到其预期目标,并且出于正确的原因 — 是负责任地部署 ML 的关键。然而,正如凯西·奥尼尔在她的《数学毁灭武器》(Crown,2016)中所强调的那样,ML 的一个特别令人担忧的元素是,在许多部署场景中,ML 可能会成为一个自我实现的预言:ML 看起来可能有效,但这可能完全是基于错误的原因。
考虑一下,就像奥尼尔所做的那样,用于招聘目的的 ML 产品,其中候选人可能会被标记为自动拒绝。也许 ML 算法正确地认为某人会是一位糟糕的雇员,但很有可能,我们永远不会知道某人是否会成为一位优秀的雇员,因为我们没有雇用他们。但是,如果各种 ML 算法都使用相同的逻辑来不雇用特定候选人,那么该候选人永远不会有机会获得一份工作,我们也永远无法真正知道该候选人是否能够胜任工作(系统性缺失数据)。
如果某人被一个机器学习算法以某种特定方式标记,有时这个标记会被信任以解决问题,即使人类应该在一定程度上进行监督。²³ 在就业场景中,某人可能被标记为不合格的候选人,并且因为使用算法辅助决策的人认为他们不适合被雇用。也许这个求职者之所以不被雇用,并不是因为他们实际上是不合适的选项,而是因为算法标记他们为不合格选项。也许在许多潜在雇主中使用相同或类似的算法使得这种情况变得更糟。也许这个求职者将面临许多潜在雇主都在使用的相同算法,因此可能面临延长甚至无限期的失业。在某些时候,他们长期的失业本身可能会成为机器学习算法使用的另一个标志来反对雇佣某人的因素。
这个问题不仅仅限于 O’Neil 在潜在轶事中提到的情景。立法者们也很关注。例如,在最近提出的2021 年算法公正和在线平台透明法案中,美国参议员埃德·马基和美国众议员多丽丝·松井提议,只有安全有效的算法才能合法。算法的有效性将通过展示机器学习算法“具有产生其期望或预期结果的能力”来确立。²⁴
鉴于这项法律或类似的有效性要求,我们可以思考一下 O’Neil 提到的自我实现招聘算法的例子可能如何发展。招聘机器学习算法的设计者应该展示该算法实际上预测了谁会是一个优秀的员工,而不仅仅是谁不太可能被聘用。从某种角度来看,这就是 外部有效性 —— 即,算法驱动的发现或结论是否可以转化为一个重要的泛化到真实世界的概念。展示有效性的要求类似于算法的逻辑具有外部有效性,即它在合理程度上具有普遍性。
当然,自我实现的算法并不是与算法有效性相关的唯一问题。与这一概念相关的其他一些术语在此简要描述:
鲁棒性
算法只有在能够抵抗可预见的攻击或滥用,并且设计为限制或防止这种可预见的滥用时,才能发挥有效作用。
验证的性能
模型必须在其部署的使用案例中发挥作用。每当在新情况下部署模型时,如在新的人群中或者只是在长时间内应用时,都应检查模型的性能是否良好。
逻辑
尽管有些人因为这些模型可以“发现人类看不见的模式”而庆祝 ML,有时候识别出的模式却毫无意义,或者由于错误的原因而有意义。如果特定输入的相关逻辑不通过基本的“嗅觉测试”,那么现在是提出问题的时候了。要求一定程度的逻辑也与与效果相关的负责任 AI 目标保持一致。
社会和文化的适当性
用于负责任地使用 ML 的另一个考虑因素是技术在社会情境中或在社会影响方面的一般可接受性。机器作为观察者或决策者的所有角色是否都适用?例如,您想通过算法被告知将死于可怕的疾病吗?同样,您希望您的孩子被 ML 产品“监视”还是由人类保姆?也许答案是您不在乎,也许答案是您在乎。有时候,人们拒绝算法产品是因为与人类尊严或社会尊重相关的想法,而不是对算法产品的安全性问题。也就是说,仅仅因为某事可以很好地自动化,并不保证人们在与算法交互时会感到受到尊重。
关于人类尊严的这些文化关切可能适用于 ML 产品的用户,而不仅仅是对象。例如,考虑最近的 Twitter 负责任 AI 研究,在这项研究中,团队最终得出结论,使一个功能公平(在这种情况下是一个照片裁剪功能)的最佳方式是删除这个功能,而不是完善它,部分原因是为了鼓励发布照片的人的自主权和代理权。有时候,最好的解决方案是移除一个技术“解决方案”。
负责任 AI 沿着 ML 管道
我们之前讨论过的与负责任 AI 相关的各种具体问题将在现实世界的 ML 管道中必然重叠。在本节中,我们包括特定的考虑点,涉及您应该根据您所处 ML 管道的位置向自己和团队提出的实际问题。
用例头脑风暴
如果您正在进行潜在用例的头脑风暴,也许是因为您看到一个新的商业机会或看到获取新数据的可能性,您应该考虑与您的潜在项目相关的以下基本问题:
-
这是一个可能会损害隐私的用例吗?如果是,您将如何从一开始就采取预防措施来构建隐私保护?
-
这是一个涉及到人类尊严或社会期望基本关注点的用例吗?这可能会对算法方法的适用范围增加额外的限制吗?
-
机器学习决策或分类是否是一个重要决策,公平性应特别受到保护,如果是,是否有迹象表明这可以实现?什么构成重要会有所不同,但有时这些被理解为具有法律效力或类似法律效果的决策(如招聘或教育)。另一种定义重要的方式是首先确定你自己组织中那些会对决策结果产生最重大影响的领域的模型。
数据收集和清洗
在管道的这一阶段,你已经确定了一个使用案例,并正在寻找数据并为建模做准备。现在,应解决以下问题:
-
数据是否以一种尊重知情同意的方式获取?²⁵ 你是否以合理的信息透明方式向受试者披露将使用数据的目的?
-
是否以促进隐私并最大程度减少意外披露的方式存储数据?
-
你是否进行了数据的探索性分析,以查找数据中的潜在偏差?
模型创建和训练
现在你已经收到数据,是时候进行一些建模了:
-
你是否制定了积极的计划来监测和解决偏见?你将如何根据偏见可能带来的潜在危害以及你的使用案例的特定规范价值或法律限制,选择各种公平干预形式?
-
你是否以一种方式进行训练,可以减少训练模型的数据泄漏,并增强对恶意攻击的鲁棒性?
-
在你的损失函数中,是否考虑了不同错误造成的相对危害程度,而不是懒惰地将所有错误都设置为相同的损失值?
-
在选择模型架构(例如,不透明的神经网络与可解释的线性函数)时,是否通过理解准确性和可解释性对你的特定应用的相对重要性来做出选择?
-
如果你的领域有类似具有强预测价值的科学法则,你是否在模型架构和培训选择中包含了这些领域知识?
模型验证和质量评估
在管道的这个阶段,你可能会收到一个被告知在准确性方面已经达到最佳的模型。你的工作是以理性的方式检查并决定是否批准此模型继续前进,或者将其送回进行训练:
-
你是否询问过模型是否是在代理上训练的,如果是,是否有数据可证明使用该代理的合理性?
-
你是否在现实挑战情况下,充分测试了模型,使用了公正选择的保留数据集?基本准确性仍然是道德义务,也是商业目标和技术指标。
-
你能否全局识别和理解推动模型的逻辑,并在需要时生成个体解释?(有关更多信息,请参见第九章。)
模型部署
现在是时候让模型按计划使用了:
-
你是否已经建立了监控程序,持续评估系统在实际使用中的性能?这样的性能评估可以根据传统性能指标(如准确性)以及公平性指标(如前面讨论的那样)进行评估。
-
你是否已经建立了事先的标准来评估模型是否按预期工作?²⁶
-
你是否尝试在线模式运行模型,以便您可以提前观察其如何表现,即使是在实际产品发布之前的反事实情况?或者您可以维护一个影子模型,在用户看不到结果的情况下对生产数据进行预测。这可以作为理解可能的部署性能的中间步骤,而无需承担实际部署所带来的风险。
市场产品
无论模型是用于内部还是外部使用,它们都需要符合公平性和隐私保护的同样标准。但是,直接由外部用户访问的模型通常有一组额外的必须满足的要求。
如果您的模型最终目标是直接由人类用户访问,请考虑以下几点:
-
你是否会提供救济或挑战决定的方法?如果会,具体是怎样的方法?
-
你是否会提供关于机器学习系统如何运行的解释,甚至可能为个人提供关于他们成果形成方式的具体指导?²⁷
-
你将如何检测到未预料到的事件或问题?你将如何了解你目前不知道的那些你不知道的内容?
结论
我们已经审查了许多涉及设计、训练和部署现实世界机器学习系统的公平性、隐私和其他伦理考量。这些话题都非常复杂。本章应该为您和您的组织提供了一些关键问题的示例,您应该在设计和部署机器学习系统时考虑这些问题。要进一步了解,您可以找到许多优秀的学习资料和学术研究论文,涵盖所有这些话题,供您获取更多信息。²⁸
与此同时,这种复杂性不应使您气馁!我们建议采取以下步骤:
-
在工作场所创建基本的机构规则和保障措施。
-
与计算技术相比,人类可读的变更可能更容易理解和更透明。
-
组织变革鼓励人们在会议上提出伦理关切。公平最好不要在黑暗角落中。试着举手提出你的公平关切。从小事情开始(数据访问、追索接口、统计平等),随着时间推移,你可以逐步提高到更复杂的目标。随着时间的推移,组织甚至可以更进一步,例如创建一个红队,有意识地和积极地尝试操纵产品或识别有害结果。
-
伦理指南也可以作为启动新项目或批准已完成产品发布的高层次但实用的检查清单。
-
在产品初始阶段定期解决公平、隐私和伦理问题。
-
大多数机器学习中的公平、隐私和其他伦理问题都源于产品的概念和创建阶段。在考虑一个项目是否甚至是一个好主意时,开始提出相关问题是非常重要的。
-
你是否在合法和道德的方式获得了公平的数据?来自Gebru 等人 (2021)的指导可以为记录你的数据及其适当使用提供一个很好的框架。
-
是否有适当的工作条件来维护数据的安全和隐私?
-
如果你成功实现你提出的目标,这对整个世界来说会是一个好事(或至少是中立的)吗?
-
创建负责任人工智能实践的良性循环。
-
学到的越多,保持负责任的人工智能关注的时间越长,你的机器学习管道和机器学习产品将反映良好的公平实践。
-
如果你能承诺每周学习一点关于负责任人工智能的内容,并且在自己的工作中慢慢实施它,在一年结束时你会注意到显著的进展。
祝你好运,因为你开始采取实际步骤,让世界变得更美好,从你的机器学习产品开始(有时,包括不使用它们)。
¹ 指定的人类决策者的例子包括法官作为法律裁决的正式决策者,或大学教授作为评分决策的正式决策者。没有明确决策者的例子包括“扁平”组织,在这些组织中有时不清楚谁持有最终决策权。
² 一般而言,我们对公平概念的不适当缩窄表示反对,并且为了明确沟通,我们解决了许多其他问题,我们认为这些问题与公平相关,在“负责任人工智能”部分中,我们重点讨论了作为与偏见相关的公平的主流用法。
³ “机器偏见”由 Julia Angwin 等人撰写,是 ProPublica 发布的开创性研究,揭示了这种偏见。这项工作讨论了在美国刑事司法系统中使用算法风险评分的情况,对理解 AI 可能造成的伤害以及发起负责任 AI 运动具有基础性意义。文章讨论了在美国刑事司法系统中使用算法风险评分的情况。这些有偏见的风险评分最常用于确定在负担过重的刑事司法系统中,被告是否应该在等待审判期间获得自由。在这种情况下,被预测的因素应该是被告是否会出庭并且在此期间是否会犯罪,而不是一般将来的任何时候。目前尚不清楚“将来是否会被指控犯罪”的单一预测能否在保释、判刑和假释决策中有用。本文讨论了稍后在本章节中详细讨论的 COMPAS 算法。
⁴ 这是一些因素之一,导致一些政府,尤其是纽约市政府,提议对在招聘中使用的 AI 进行规范。参见 Tom Simonite 的“纽约市提议规范招聘中使用的算法”。
⁵ 关于歧视是“品味导向”还是“统计导向”的辩论更为广泛。一些人认为决定就读女子学院可能在某种程度上表明与雇佣决策相关的人格类型。然而,这样的假设似乎不太可能适用。有兴趣了解更多的人可以查阅法律和经济学中关于歧视机制和动机的研究文献,包括不平等对待。
⁶ 我们在这个句子中使用引号,因为当然,定义“相同”或“同等的价值”的内容本身就是一种判断的行为,而不是客观的真理。
⁷ 为了清楚地展示校准与群体平等之间的冲突,强烈推荐阅读 Alexandra Chouldechova 的“具有不同影响的公平预测:关于刑事再犯预测工具偏见的研究”。
⁸ 参见上文脚注中提到的Chouldechova 文章。
⁹ 如果我们广泛寻找和解释关于算法公平性的问题,其他不可能定理与公平性关切相关。例如,阿罗不可能定理表明,在特定形式的投票中,三个直观的公平性标准不能同时满足。这三个标准,粗略地说,分别是:(1)在两个选项之间普遍共享的个人偏好必然会转化为反映该偏好的选举结果,(2)稳定的个人偏好会导致稳定的选举结果,以及(3)没有单一选民会拥有决定选举结果的权力。因此,无论是跨学科还是技术或组织机制,我们并非总能在公平性上一举两得。非常感谢 Niall Murphy 提供的这个例子。
¹⁰ 例如,来自受青睐群体的个人,他们由于他们的优点而获得了难以置信的有利结果。
¹¹ 有时这可以理解为校正缺乏校准的方式。例如,有充分证据表明,在美国使用的信用评分在不同种族群体中的还款意愿方面似乎并不相同。因此,完全依赖评分而不调整阈值的银行可能会无意中标记出不同种族群体的信用申请者存在不同的假阴性率。然而,为不同群体设定不同的阈值必然引起其他法律和道德上的关切。因此,读者可以看到,在现实世界中,公平性确实是非常具有挑战性的。
¹² 在本书即将出版的时刻(2022 年 8 月),欧洲已经针对数字环境中公平性等一系列问题提出了一系列开创性的立法。尤其值得注意的是,欧盟于 2021 年 4 月发布了一项提议的 AI 监管框架,该框架将实施基于风险的一系列规定,不同的 AI 使用案例将有不同的法律要求。该提议法律还将禁止某些高风险使用情形,包括社会信用评分。同样地,中国于 2022 年 3 月实施了全面的新 AI 法规,以规范包括个人信息价格歧视和内容聚合算法在内的多种常见损害消费者利益的做法。
¹³ 早期的重新识别案例可以参见 Nate Anderson 的“‘Anonymized’ Data Really Isn’t—And Here’s Why Not”,描述了 Latanya Sweeney 在这一主题上的工作。
¹⁴ 多次查询差分私密数据集可能会导致违反差分隐私保证。这是因为这些保证仅在给定的隐私预算下有效,该预算限制了可以进行的查询次数,同时确保差分隐私保证。
¹⁵ 理论上,我们可以在每次将培训数据标记为删除时完全重新训练模型。实际上,这将是极其浪费和不切实际的——也可能是不必要的。在这个领域还需要做更多工作,以了解技术需求、可持续性问题和个人隐私权如何成功共存。
¹⁶ 差分隐私模式未能达到最高精度水平的一个原因与用于创建差分隐私模型的方法有关。一个关键技术是注入噪音,这从定义上来说会降低准确性。
¹⁷ 一个推荐的起点是TensorFlow Privacy,其中包括差分私密模型的训练算法。
¹⁸ 单独的问题是,当点击预测是一个有用的活动,而当它引起令人担忧的 AI 问题时。毫无疑问,预测某人的偏好或兴趣具有益处,就像许多点击预测的例子一样。另一方面,关于人类偏好的可变性以及在线环境中行为和偏好操纵的具体场景的增加研究,也指出了混淆代表偏好适应(给予人们他们想要的东西)与偏好操纵(让人们想要你所拥有的东西)的危险。后者显然存在大量的公平性问题,并且与关于黑暗模式的增长文献有关,这些是数字设计模式,倾向于引导数字产品的用户做违背他们利益的事情(但符合那些产品设计者的利益)。
¹⁹ 当然,包含人口统计信息可能会带来问题,因为一些数据集可能在看似匿名信息与 PII 之间具有强烈的预测关系,这应该考虑在数据分离方式中。
²⁰ 了解负责 AI 的可解释性的核心性的一个好的起点,但同时也要理解把握正确的复杂性,是 Brent Mittelstadt 等人的“在 AI 中解释解释”。
²¹ 由 Kasun Amarasinghe 等人撰写的“公共政策中的可解释机器学习:用例、空白和研究方向”提供了一个极好且易于访问的示例,涉及哪些解释类型可能是有用的考虑因素。
²² IBM 的AI 可解释性 360 库是一个易于使用的开源库,包括多种前沿研究方法用于模型解释。该工具包提供了 API 以及通过可解释性 API 应用库方法的多种示例用例教程。
²³ 以波兰将分类算法推广至失业求职者分类为极端案例。理论上,工作人员可以偏离初步的算法评估。实际上,他们在 0.58%的情况下偏离算法标签。详见 Jędrzej Niklas 等人的“波兰失业人员概况”。
²⁴ 法案的完整引用如下:“如果在线平台采用或以其他方式利用算法过程,且已采取合理措施确保算法过程能够产生其预期或预期结果,则算法过程有效。”
²⁵ 值得注意的是,定义同意可能会很复杂。毕竟,没有人喜欢欧盟一般数据保护条例(GDPR)后广泛出现的所有弹出同意通知。在这里,同意应该以广义而非狭义的词义来解释。
²⁶ 最好事先明确这些,这样你就不能在事后“作弊”或以其他方式合理化表现不佳。这不一定要严格遵循这些标准,但即使随时间重新评估这些标准,它也会使你对什么构成良好工作保持诚实。
²⁷ 如前所述,模型卡是实现这一目标的一种系统。
²⁸ 作为毫不掩饰的自我推广,可以考虑阅读 Aileen Nielsen 的关于实用 ML 伦理的书籍长篇介绍:实用公平性,另一本 O'Reilly 出版的书籍。
第七章:训练系统
ML 训练是我们将输入数据转换为模型的过程。我们获取一组输入数据,几乎总是经过预处理并以高效方式存储,然后通过一系列 ML 算法处理它。输出是该数据的表示,称为模型,我们可以集成到其他应用程序中。有关模型的更多详细信息,请参阅第三章。
训练算法描述了软件如何读取数据并更新模型以尝试表示这些数据的具体步骤。而训练系统则描述了围绕该算法的整套软件。最简单的 ML 训练系统的实现是在单台计算机上运行的单个进程上读取数据,对数据进行一些清理并对数据进行一致性处理,然后应用 ML 算法,并通过从数据中学到的内容创建具有新值的数据模型表示。在单台计算机上进行训练是构建模型的最简单方法,而大型云服务提供商确实提供强大的单机配置的租赁服务。但请注意,许多在生产中使用 ML 的有趣应用处理大量数据,因此可能受益于不止一台计算机的处理能力。分布式处理带来了规模,但也带来了复杂性。
部分原因是由于我们对 ML 训练系统的广泛概念,跨不同组织和模型构建者,ML 训练系统在各自的最终 ML 系统的不同部分之间可能没有太多共同之处。在第八章中,您将看到即使在不同的用例中,服务系统的许多基本要求也是广泛相似的:它们将模型的表示加载到 RAM 中,并回答从应用程序发送的关于该模型内容的查询。在服务系统中,有时该服务是针对非常小的模型(例如手机上的模型)。有时它是针对无法全部安装在单台计算机上的巨大模型。但问题的结构是相似的。
相比之下,训练系统甚至不一定生存在我们 ML 生命周期的同一部分(见图 1-1)。有些训练系统最接近输入数据,几乎完全离线于服务系统。其他训练系统嵌入在服务平台中,并与服务功能紧密集成。当我们观察训练系统维护和表示模型状态的方式时,会出现额外的差异。由于合法且结构良好的 ML 训练系统之间存在显著的差异,因此不合理涵盖所有组织训练模型的方式。
相反,本章涵盖了一个稍微理想化的简单分布式 ML 训练系统的版本。我们将描述一个存在于 ML 循环中的特定部分的系统,该系统与数据并行,并生成供模型质量评估系统和服务系统使用的工件。尽管你在现实世界中遇到的大多数 ML 训练系统与此架构有很大的不同,但将其分离出来将使我们能够专注于训练本身的特点。我们将描述一个功能齐全且易于维护的训练系统所需的元素,并描述如何评估额外理想特性的成本和收益。
要求
一个训练系统需要以下元素,尽管它们可能以不同的顺序或与其他元素组合出现:
训练用数据
如果有人类标签和注释,这包括它们。这些数据在使用时应预处理并标准化。通常,它们将以一种在训练期间进行高效访问优化的格式存储。请注意,“在训练期间进行高效访问”可能因我们的模型而异。数据还应存储在一个受访问保护且执行政策的环境中。
模型配置系统
许多训练系统都有一种方式来表示单个模型的配置,将其与整个训练系统的配置分开。¹ 这些配置应该在具有有关创建模型团队和模型使用数据的元数据的版本化系统中存储。稍后这将非常方便。
模型训练框架
大多数模型创建者不会手动编写模型训练框架。最可能的情况是,大多数机器学习工程师和建模者最终将专门使用训练系统框架,并根据需要进行定制。这些框架通常具有以下功能:
管理
系统的不同部分需要在不同的时间运行,并且需要彼此通知。我们称之为编排。有些系统还包括以下两个元素,但这些功能可以分开组装,因此在这里将它们分开。
作业/工作调度
有时候,作业调度的一部分,指的是实际在计算机上启动二进制文件并跟踪它们。
训练或模型开发软件
这些软件处理通常与构建 ML 模型相关的常规样板任务。当前的常见示例包括 TensorFlow、PyTorch 和许多其他框架。关于哪个框架最好的争论有时甚至会引发类似宗教战争的辩论,但它们都能完成帮助模型开发者更快速、更一致地构建模型的工作。
模型质量评估系统
有些工程师认为这不是训练系统的一部分,但它必须是。模型构建的过程是迭代的和探索性的。模型构建者尝试各种想法并且舍弃了其中的大部分。模型质量评估系统提供了对模型性能的快速和一致的反馈,并允许模型构建者快速做出决策。
警告
这是训练系统中最常被忽略的部分,但确实是强制性的。
如果我们没有一个模型质量评估系统,那么我们每个模型开发者都将为自己构建更加临时和不可靠的系统,并且这样做会给组织带来更高的成本。这个主题在第五章中有更详尽的覆盖。
将模型同步到服务中
我们对模型的最后一步通常是将其发送到下一个阶段,通常是服务系统,但也可能是另一种分析系统。
如果我们有一个系统来满足这些基本需求,我们将能够为模型开发者提供一个最低限度的生产技术环境。除了这些基本元素外,我们还希望增加专门用于可靠性和可管理性的基础设施。在这些元素中,我们应该包括对监控这个多阶段管道的仔细思考,团队对特性和模型的所有权的元数据,以及一个完整的特性存储系统。
基本训练系统实现
图 7-1 描述了一个简单但相对完整和可管理的机器学习训练系统的建议架构。²

图 7-1. 基本机器学习训练系统架构
在这个简化的训练系统中,数据从左侧流入,模型从右侧出现。在此过程中,我们清理、转换和读取数据。我们使用一个机器学习框架,该框架应用训练算法将数据转化为模型。我们评估刚刚生成的模型。它是否格式良好?它是否有用?最后,我们将这个模型的可服务版本复制到我们的服务系统中,这样我们就可以将其集成到我们的应用程序中。在此期间,我们在一个元数据系统中跟踪我们的模型和数据,确保管道持续工作,并监控整个过程。接下来,我们将详细讨论每个组成部分的角色。
特性
训练数据 是关于我们认为对我们的模型有关联的世界事件或事实的数据。特征 是这些数据的具体可度量的方面。具体来说,特征是我们认为在建模、分类和预测未来事件时,在类似情况下最有用的数据方面。为了有用,特征需要在整个机器学习系统中,包括特征存储、训练、质量评估和服务中,具有一致的定义、一致的归一化和一致的语义。详细信息,请参阅第四章。
如果我们考虑像“购买价格”这样的 YarnIt 购买数据特征,我们很容易理解如果我们不小心会出现问题。首先,我们可能需要将购买行为标准化为同一货币,或者至少在我们的模型中不混合使用不同货币。所以让我们假设我们将所有金额转换为美元。我们需要确保我们根据特定时间点的汇率进行转换——比如我们查看数据的那一天伦敦交易日结束时的收盘汇率。然后,我们必须存储用于可能需要重新转换原始数据的转换值。我们可能应该对数据进行归一化,或者将其放入更大的桶或类别中。我们可以将所有小于 1 美元的金额放入第一个桶中,1 至 5 美元放入下一个桶中,依此类推,每 5 美元递增一个桶。这样做可以使某些类型的训练更加高效。这还意味着我们需要确保在训练和服务之间有标准的归一化,并且如果我们改变归一化方式,我们需要仔细同步更新所有地方。
特征和特征开发是我们在制作模型时进行实验的关键部分。我们试图弄清楚数据的哪些方面对我们的任务很重要,哪些不相关。换句话说,我们想知道哪些特征能够让我们的模型更好。随着模型的开发,我们需要简便的方法来添加新特征,在我们对现有日志中要查找的新想法时,对旧数据生成新特征,并删除证明不重要的特征。特征可能会很复杂。
特征存储
我们需要存储这些特征,毫不奇怪,我们用来存储这些特征的系统最常见的名称就是特征存储。即使我们的模型训练系统每次都会读取原始数据并提取特征,特征存储的特性仍然存在。大多数人会发现,将提取的特征存储在某种专门的系统中是方便的,尤其是作为重要的可靠性奖励。这个主题在第四章中有详细介绍。
这种情况下常见的数据架构是目录中的一堆文件(或对象存储系统中的一堆桶)。这显然不是最复杂的数据存储环境,但有一个巨大的优势,能够快速启动训练,并似乎促进对新特征的实验。长期来看,这种非结构化的方法却有两个巨大的缺点。
首先,确保整个系统始终正确运行是极其困难的。像这样具有非结构化特征工程环境的系统经常遭受训练-服务特征偏差(即在训练和服务环境中定义特征不同的情况),以及即使在训练系统中也存在随时间不一致的特征语义问题。
第二个问题是,非结构化的特征工程环境实际上会妨碍协作和创新。这使得更难理解模型中特征的来源,以及添加它们的人员、时间和原因。³ 在协作环境中,大多数新的模型工程师将极大受益于理解前人的工作。通过能够从效果良好的模型向后追溯,直至模型定义,最终到使用的特征,这一点变得更加容易。特征存储提供了一个一致的位置,用于理解特征的定义和作者,并且可以显著提升模型开发中的创新能力。
模型管理系统
模型管理系统 至少可以提供三组功能:
模型的元数据
配置、超参数和开发者的作者身份
训练模型的快照
通过使用迁移学习更高效地引导相同模型的新变体,以及在意外删除模型时用于灾难恢复的非常有用。
特征的元数据
每个模型具体使用的特征的作者和用途
虽然这些功能在理论上可以分开,而且软件产品中通常是分开的,但它们一起构成了一个系统,允许工程师理解正在生产中的模型,它们是如何构建的,由谁构建的,以及它们所依赖的特征是什么。
就像特征存储一样,每个人都有一个基本的模型管理系统,但如果它仅仅是“领导模型开发者家目录中的配置文件和脚本”,可能需要检查这种灵活性是否仍然适合组织的需求。有合理的方法可以启动模型管理系统,以降低负担。它并不需要复杂,但可以成为信息的重要来源,从服务端一直到存储端进行关联。如果没有这些数据,就不总是可能找出生产环境中出现问题的原因。
编排
编排 是协调和跟踪培训系统所有其他部分的过程。这通常包括安排和配置与训练模型相关的各种作业,以及跟踪培训何时完成。编排通常由与我们的机器学习框架和作业/进程调度系统紧密耦合的系统提供,但不一定如此。
在这里的编排中,请把 Apache Airflow 当作一个例子。许多系统在技术上是工作流编排系统,但专注于构建数据分析流水线(例如 Apache Beam 或 Spark,或 Google Cloud Dataflow)。这些系统通常对你的任务结构有很多假设,并且具有额外的集成和许多内置的限制。请注意,Kubernetes 不是一个流水线编排系统:Kubernetes 有一种编排容器和在其中运行的任务的方式,但通常本身不提供帮助我们指定数据如何通过流水线移动的语义。
作业/进程/资源调度系统
在分布式环境中运行机器学习训练流水线的每个人都有一种启动进程、跟踪它们并在其完成或停止时注意到的方式。有些人很幸运能够在提供调度作业和任务的本地或云端集中服务的组织中工作。否则,最好使用其中一个流行的计算资源管理系统,无论是开源还是商业的。
资源调度和管理系统的例子包括先前提到的软件,如 Kubernetes,尽管它还包括许多其他功能,如设置容器之间的网络并处理对容器的请求。更普遍且传统的是,Docker 可以通过提供一种配置和分发虚拟机(VM)映像到 VM 的方式被视为资源调度系统。
机器学习框架
机器学习框架 是算法操作的地方。机器学习训练的目的是将输入数据转换为该数据的表示,称为 模型。我们使用的机器学习框架将提供一个 API 来构建我们需要的模型,并处理读取特征并将其转换为适合模型的数据结构的所有样板代码。机器学习框架通常是相当低级的,虽然它们讨论和辩论很多,但最终在组织的整体机器学习循环中占据相当小的部分。
质量评估
ML 模型开发过程可以被看作是持续的部分失败后紧随的适度成功。很少有人的第一个尝试的模型能成为最好的,甚至是对特定 ML 问题合理的解决方案。因此,模型训练环境的一个基本要素是一种系统化的评估刚刚训练的模型的方法。
在某 模型质量评估在某种程度上必须与特定模型的目的密切相关。视觉模型能正确分类图片,语言模型则解释和预测文本。在最基本的层面上,模型质量评估系统提供了一种执行质量评估的方法,通常由模型开发者编写,并以一种可以与同一模型的先前版本进行比较的方式存储结果。这种系统的运作角色最终是足够可靠,能够作为自动门,防止“糟糕”的模型被发送到我们的生产环境中。
评估始于诸如验证我们是否加载了正确版本的正确模型,并确保模型在我们的模型服务器中加载。评估还必须包括性能方面,以确保模型可以在我们可用的内存和计算资源中提供服务。但是,我们还必须关心模型在我们认为代表我们将获得的请求上的性能。有关此主题的更详细信息,请参见第五章。
监控分布式数据处理管道是困难的。生产工程师可能关心的那些简单的事情,例如管道是否足够快速地处理数据,对于分布式系统来说很难准确而有意义地产生。查看最老的未处理数据可能没有意义,因为可能会有一个单独的旧数据块卡在一个其余已经完成处理的系统中。同样地,仅仅看数据处理速率本身可能不太有用,如果某些类型的数据比其他数据显著更昂贵,那么这种评估就更加复杂。
果某些类型的数据比其他类型显著更昂贵,则不一定是有效的。
本书有一个完整的监控章节(第九章)。更难的问题将在那里解决。对于本节而言,跟踪和警报的最重要的指标是训练系统的吞吐量。如果我们有一个有意义的长期趋势,能够快速处理各种条件下的训练数据,我们应该能够设置阈值,以在出现问题时提醒我们。
一般可靠性原则
在制定和操作系统的构建过程中,如果我们记住几个一般原则,事情通常会更顺利。
大多数故障不是机器学习的故障。
ML 训练系统是复杂的数据处理管道,对它们处理的数据非常敏感。它们通常分布在许多计算机上,尽管在最简单的情况下可能只在一台计算机上。这并不是一个能够长期保持可靠性的基本状态,生产工程师通常会关注这些数据敏感性引发的最常见故障。然而,有经验的从业者在长期观察机器学习系统的故障时发现,大多数故障并非机器学习特有的[⁴]。它们通常是在这种分布式系统中普遍发生的软件和系统故障。这些故障通常具有机器学习特有的影响和检测挑战,但其根本原因通常并非机器学习特有。
这些故障的有趣例子包括一些非常直接的事情,比如“训练系统失去读取数据的权限,因此模型在没有数据的情况下训练”,以及“我们复制到服务中的版本并非我们所认为的那个版本”。大多数情况下,这些故障是由于错误监控和管理数据管道引起的。更多例子详见第十一章和第十五章。
要使机器学习训练系统可靠,首先要解决系统和软件错误,并对其进行缓解。关注软件版本管理和部署、权限和数据访问要求、数据更新策略和数据组织、复制系统以及验证。基本上,在开始任何机器学习特定工作之前,要做好使一般分布式系统可靠的所有工作。
模型将被重新训练。
或许这一部分应该更加强调:模型必须重新训练。一些模型开发者会从数据集中训练一个模型,检查结果,将模型部署到生产环境,并声称完成了工作。他们会指出,如果数据集没有变化并且模型达到了目的,那么该模型已经足够好,没有必要再次进行训练。
不要相信这一点。最终,无论是在一天还是一年之后,该模型开发者或其继任者都会有新想法,想要训练同一模型的不同版本。也许会发现或创建一个涵盖类似案例的更好数据集,然后模型开发者会希望在其上进行训练。或许只是出于灾难恢复的原因,您希望证明如果错误删除了模型的每一个副本,您可以重新创建它。您可能只是想验证训练和验证工具链是否完整。
出于所有这些原因,假设每个模型都会重新训练,并据此制定计划——存储配置并进行版本控制,存储快照,并保留有版本的数据和元数据。这种方法具有巨大的价值:关于所谓的“离线”和“在线”模型的大部分争论实际上是关于在有新数据存在的情况下重新训练模型的争论。通过创建一个严格的生产要求,即模型可以重新训练,技术环境在很大程度上有助于定期重新训练所有模型(包括快速重新训练)⁵。
提示
假设每个模型都会重新训练。
模型将会有多个版本(同时存在!)
模型几乎总是以队列方式开发,这显而易见是因为我们希望使用不同的超参数训练不同版本。一种常见的方法是给一个命名模型添加多个小的变化。有时这些变化会在开始时迅速集中出现,而其他时候则会随时间逐渐到来。但正如模型将会重新训练一样,它们也将会随时间的推移而发生变化和发展。在许多环境中,我们希望同时提供同一模型的两个或更多个版本,以确定不同条件下模型的不同版本如何工作(对于熟悉传统网页开发用户体验的人来说,这本质上是模型的 A/B 测试)。
同时托管同一模型的多个版本需要特定的基础设施。我们需要使用我们的模型管理基础设施来跟踪模型元数据(包括模型系列、模型名称、模型版本和模型创建日期等内容)。我们还需要有一个系统,将部分查询路由到一个版本的模型而不是另一个版本。
好的模型会变坏
我们应该假设我们生产的模型将很难复制,并且将来可能会出现微妙和严重的可靠性问题。即使一个模型在启动时表现良好,我们也必须假设模型或者世界可能以某种难以预测的方式发生变化,从而在未来几年给我们带来巨大的麻烦。制定备份计划。
第一个备份计划是为我们的模型制定一个非 ML(或至少是“更简单的 ML”)回退路径或“故障安全”实现。这将是一个确保我们的应用程序在 ML 模型无法提供复杂预测、分类和洞见时至少提供一些基本功能的启发式算法或默认设置。实现这一目标的常见算法是简单而极为普遍的,但至少比没有稍微好一点。我们之前提到的一个例子是,在yarnit.ai商店的推荐系统中,当我们没有定制的推荐模型可用时,我们可能简单地默认显示流行商品。
然而,这种方法存在一个巨大的问题:它限制了您能够让您的机器学习模型有多好。如果模型比启发式或默认设置要好得多,您将会对它们依赖如此之深,以至于没有任何备份足以实现相同的目标。依赖于默认设置和启发式是大多数在机器学习采用生命周期早期的组织所选择的一条完全适当的道路。但这是一个依赖关系,如果您真的想在组织中实际利用机器学习,您应该摆脱它。
另一个备份计划是保留同一模型的多个版本,并计划在需要时回退到旧版本。这将涵盖一些由于某种原因新版本模型显著较差的情况,但当整个世界已经改变,因此所有版本的这个模型都不是很好时,它将无济于事。
最终,第二个备份计划结合能够同时提供多个模型并快速开发现有模型的新变体的能力,为理解和解决未来模型质量问题提供了一条路径,当世界以一种使模型表现不佳的方式改变时。对于传统的生产人员来说,重要的是注意,在这种情况下,模型开发和生产之间不存在固定或可辩护的障碍。模型质量既是生产工程问题,也是模型开发问题(可能紧急发生在生产中)。
数据将不可用
在尝试读取时,用于训练新模型的部分数据将不可用。数据存储系统,特别是分布式数据存储系统,有包括少量实际数据丢失和更高量的数据不可用在内的故障模式。这是一个值得提前考虑的问题,因为它肯定会发生。
大多数机器学习训练数据集已经从另一个更大的数据集中抽样,或者仅仅是从我们开始收集数据的时间或方式的全部可能数据的一个子集。例如,如果我们在yarnit.ai的客户购买行为数据集上进行训练,这个数据集从一开始就是不完整的,至少有两个明显的方面。
首先,有一些日期是我们没有收集这些数据的日期(或者在某些日期之前我们选择不使用数据,无论出于什么原因)。其次,这实际上只是我们网站上的客户购买行为,不包括其他网站上类似产品的客户购买行为。这并不奇怪,因为我们的竞争对手不与我们共享数据,但这意味着我们已经看到的几乎肯定是相关训练数据的一个子集。对于非常高容量的系统(例如 Web 浏览日志),许多组织在训练之前也会自动对这些数据进行子采样,以减少数据处理和模型训练的成本。
鉴于我们的训练数据已经进行了子抽样,可能以多种方式进行,当我们丢失数据时,我们应该回答这个问题:数据的丢失是否存在某种偏差?如果我们以完全随机的方式删除每一千个训练记录中的一个,这几乎可以肯定可以忽略对模型的影响。另一方面,失去所有来自西班牙人或者上午购物的人的数据,或者大型针织会议前一天的数据,这些都是不能忽略的。它们很可能会在我们训练的数据与我们不训练的数据之间造成新的偏差。
一些培训系统会在问题出现之前尝试预先解决整个系统的缺失数据问题。只有在所有模型具有类似的约束和目标时,这种方法才会奏效。这是因为缺失数据的影响对每个模型都很重要,只有在其对每个模型影响的背景下才能理解。
缺失数据还可能具有值得考虑的安全属性。一些系统,特别是那些旨在防止欺诈和滥用的系统,将受到外部恶意方的持续观察和攻击。对这些系统的攻击包括尝试不同类型的行为来确定系统的响应,并利用出现的漏洞或弱点。在这些情况下,训练系统可靠性团队需要确保没有外部方面可以系统性地偏置哪些特定时间段在训练过程中被跳过。攻击者找到的方式,例如在短时间内创建大量重复交易,以淹没数据处理系统并尝试命中系统中的高丢弃启发式策略,这是每个处理数据丢失场景的人都需要事先考虑的一种情景。
模型应该可以改进
模型会随着时间变化,不仅仅是通过添加新数据。它们还会经历更大的结构性变化。改变的要求来自多个方向。有时我们会向应用程序或实现添加一个新特性,该特性不仅提供新数据,还需要模型的新特性。有时候我们的用户行为会发生足够大的变化,以至于我们需要修改模型来适应。在描述的训练系统中,程序上对模型训练最具挑战性的变化是添加一个全新的特性。
特征将被添加和更改
大多数生产 ML 训练系统都会有某种形式的特征存储来组织 ML 训练数据。(特征存储提供了许多优势,并在第四章中详细讨论。)从训练系统的角度来看,我们需要注意的是,随着时间推移,模型开发的重要部分通常是向模型添加新特征。这种情况发生在模型开发人员对可能与现有数据结合使用以有用地改进模型的某些数据有新想法时。
添加特征将需要更改特征存储模式,这是特定于实施的,但也可能受益于“回填”特征存储的过程,通过重新处理过去的原始日志或数据为以前的示例添加新特征。例如,如果我们决定我们认为顾客正在购物的城市的当地天气是预测他们可能购买的一种显著方式,我们将不得不向特征存储添加customer_temperature和customer_precipitation列。[⁷] 我们可能还会重新处理过去一年的浏览和购买数据,以在过去添加这两列,以便验证我们的假设这是一个重要的信号。向特征存储添加新列以及更改过去数据的模式和内容是两项活动,如果变更未经精心管理和协调,可能会显著影响训练系统中所有模型的可靠性。
模型可能训练得太快。
有时,ML 生产工程师会惊讶地发现,在某些学习系统中,模型可能训练得太快。[⁸] 这可能有点取决于确切的 ML 算法、模型结构以及实施系统的并行性。但完全有可能出现这样一种模型:当训练得太快时,产生垃圾结果;但当训练得更慢时,产生的结果则更准确。
以下是可能发生的一种方式:模型状态有一个分布式表示,由分布式的学习过程集合使用。学习过程读取新数据,查询模型的状态,然后更新模型的部分状态以反映它们刚刚读取的数据。[⁹] 只要在这个过程中有锁定(慢!)或没有更新正在更新的特定键(在规模上不太可能),一切都很好。
问题在于可能存在多个竞争条件,其中两个或多个学习任务同时查询模型,读取某些数据,并将更新排队到模型。一个非常普遍的情况是更新可以堆叠在一起,导致模型的某个部分在某个方向上移动得太远。下次一群学习任务查询模型时,它们发现它在某个方向上的偏差很大,与它们正在读取的数据相比,因此它们排队更新以使其大幅朝另一个方向移动。随着时间的推移,这部分模型(以及其他部分模型)可能会偏离正确的值而不是收敛。
警告
对于分布式训练设置来说,多个竞争条件是一个极为常见的失败来源。
对于机器学习生产工程学科来说,确定模型是否训练得“太快”并没有简单的方法。有一个现实世界的测试是不方便和令人沮丧的:如果你以更快和更慢的速度训练同一个模型(通常是用更多和更少的学习任务),并且慢速模型在某些质量指标上“更好”,那么你可能是在训练得太快了。
缓解这个问题的主要方法是通过在任何学习过程中将模型状态与存储状态密切同步,从而结构性地限制“正在进行中”的更新次数。这可以通过在非常快速的存储(RAM)中存储当前模型状态以及限制多个进程更新模型的速率来实现。当然,也可以为每个关键字或模型的每个部分使用锁定数据结构,但这些通常会施加太高的性能惩罚,难以认真考虑。
资源利用至关重要
这应该简单明了地说明:机器学习的训练和服务是计算昂贵的。我们关注机器学习训练资源效率的一个基本原因是,如果没有有效的实施,机器学习可能没有商业意义。考虑到机器学习模型提供的某些业务或组织价值与其提供的价值成比例,除以创建模型的成本。尽管最初的成本主要是人力和机会成本,但随着我们收集更多数据,训练更多模型并更多地使用它们,计算基础设施成本将占据越来越大的开支份额。因此,早期关注这一点是有意义的。
具体而明确地说,利用率描述如下:
这是浪费的反义词,衡量我们如何有效使用我们付费的资源。在一个日益云化的世界中,这是一个早期跟踪的重要指标。
资源利用也是可靠性问题。与我们可用的资源相比,我们有更多余地来重新训练模型,整个系统的韧性就越强。因为我们能够更快地从停机中恢复过来。这一点不论是在单台计算机上还是在大型集群上训练模型都成立。此外,利用率也是创新问题。模型训练得越便宜,我们在给定的时间和预算内能够探索的想法就越多。这显著增加了我们在所有糟糕的想法中找到好想法的可能性。在细节层面很容易忽视这一点,但我们实际上不是在这里训练模型 —— 我们是为了在我们的组织和客户中产生某种不同。
因此,我们关心资源的有效使用。以下是一些简单的方法,可以使机器学习训练系统在这方面表现良好:
批处理处理数据
在可能的情况下(依赖于算法),同时对数据块进行训练。
重建现有模型
早期阶段的机器学习训练系统通常会在新数据到达时从头开始重建模型。这从配置和软件角度来看更简单,但最终可能效率极低。增量更新模型的这种想法还有几个其他变体:
-
使用迁移学习通过利用现有模型构建一个模型。¹⁰
-
使用多模型架构,其中包括一个长期模型,大且不经常重新训练,以及一个较小的短期模型,便宜且频繁更新。
-
使用在线学习,即每个新数据点到达时增量更新模型。
诸如此类简单步骤可以显著影响组织的计算成本,用于训练和重新训练模型。
利用率 != 效率
要知道我们的机器学习工作是否有用,我们必须衡量过程的价值,而不是提供它所花费的 CPU 周期。效率度量包括以下几点:
成本可以通过两种方式计算,每种方式都提供了我们努力的不同视角。以金钱为索引的成本是我们在资源上花费的美元数。在这里,我们只计算用于训练模型的总金额。这样做的优点是对大多数组织来说,这是一个非常实际的数字。但它的缺点是资源定价的变化可能会使我们难以区分由建模和系统工作引起的变化与来自我们资源提供者的外生变化。例如,如果我们的云服务提供商开始对我们目前使用的 GPU 收费更多,我们的效率会因为我们没有做出任何改变而下降。当然,了解这一点很重要,但它并不能帮助我们建立一个更高效的训练系统。换句话说,金钱成本是衡量效率最重要的长期指标,但具有讽刺意味的是,并不总是识别项目以提高效率的最佳方式。
相反,以资源为索引的成本是以恒定美元的术语衡量的。做到这一点的一种方法是识别最昂贵和最受限制的资源,并将其用作资源索引成本的唯一元素。例如,我们可以将成本测量为CPU 秒或GPU 秒。这样做的优点是,当我们使我们的训练系统更加高效时,我们将能够立即看到它,而不受当前定价细节的影响。
这引发了一个困难的问题,那就是我们的机器学习工作的价值究竟是多少。同样,我们可能要衡量的价值有两种:每个模型和整体。在每个模型的粒度水平上,价值可能不如我们预期那样宏伟。我们不需要衡量每个训练模型的实际业务影响。相反,为了简单起见,让我们假设我们的训练系统是值得的。在这种情况下,我们需要一个指标来帮助我们比较在训练相同模型的不同实现之间创建的价值。一个运作良好的指标可能是
训练的特征数量
或者甚至
处理的示例数量
或者
训练的实验模型数量
因此,对于每个模型、以资源为索引的、成本效率的指标,我们可能有这样一个:
这将帮助我们轻松地看到使阅读和训练更加高效的努力,而无需我们了解模型实际上做了什么。
相反,整体价值试图衡量在整个机器学习模型培训计划中的价值,考虑到我们为将价值增加到整个组织中所付出的成本。这将包括员工成本、测试模型以及生产模型的培训和服务成本。它还应试图衡量模型对我们组织的整体价值。我们的客户是否更满意?我们是否赚更多的钱?机器学习训练系统的整体效率是以整个计划或整个组的基础上衡量的,并且是以月为单位而不是秒为单位衡量的。
没有效率概念的组织最终会错误地分配时间和精力。有一个略微不准确但可以改进的测量指标远比根本不测量效率要好得多。
故障包括恢复
这显然是一个显而易见的事实,但还是值得清楚地指出:ML(机器学习)的故障包括从故障中恢复所需的时间。这对监控、服务水平和事故响应有着巨大和直接的影响。例如,如果一个系统能够容忍培训系统的 24 小时故障,但是在发现任何问题需要 18 小时,并且在发现问题后需要 12 小时来训练新模型,我们就不能可靠地在 24 小时内完成。很多人在建模生产工程响应培训系统故障时完全忽视了包括模型恢复时间。
常见的训练可靠性问题
现在您已经了解了培训系统的基本架构,并查看了关于培训系统的一般可靠性原则,让我们看看一些特定的培训系统失败场景。本节涵盖了 ML 训练系统三个最常见的可靠性问题:数据敏感性、可重复性和容量不足。对于每个问题,我们将描述失败情况,然后在 YarnIt 的情景中给出一个具体的例子。
数据敏感性
正如反复提到的,ML 训练系统对输入数据的小变化和数据分布的变化非常敏感。具体来说,我们可能有相同数量的训练数据,但在数据覆盖不同子集的方式上存在显著差异。想象一个试图预测全球购买行为的模型,但只有美国和加拿大的交易数据。或者考虑一个图像分类算法,其中没有猫的图片,但有许多狗的图片。在每种情况下,由于仅在有偏见的数据集上进行训练,模型对现实的看法都会存在偏差。这些训练数据覆盖的空白可能从一开始就存在,也可能随着时间推移而出现,因为我们在训练数据中经历了空白或变化。
输入数据缺乏代表性是 ML 模型中偏见的常见源头;这里我们使用 偏见 一词既是在技术上指模型预测值与正确值之间的差异,也是在社会上指对某一人群有偏见或有损害的含义。数据中的奇怪分布也可能引起许多其他更为普通的问题。有关一些微妙且有趣的案例,请参阅 第十一章,但现在让我们考虑 YarnIt 的一个明显的数据敏感性问题。
在 YarnIt 的示例数据问题
YarnIt 使用 ML 模型来对最终用户搜索结果进行排名。客户访问网站并输入一些产品名称的关键词。我们生成一个简单而广泛的候选产品列表,这些产品可能与搜索匹配,并使用设计用于预测每个产品对正在进行此查询的用户有用程度的 ML 模型对它们进行排名。
模型将具有“产品名称中的单词”,“产品类型”,“价格”,“查询的原产地”,以及“用户的价格敏感性”等特征。这些特征将帮助我们为用户排名一组候选产品。我们每天重新训练这个模型,以确保我们正确地排名新产品,并适应购买模式的变化。
在一个案例中,我们在 YarnIt 的定价团队创建了一系列促销活动,以清理库存产品。建模团队希望分别捕获折扣前价格和销售价格,因为这些可能是不同的用户购买行为信号。但由于数据格式的变化,他们在将折扣价格添加到数据集后错误地排除了所有折扣购买记录,直到他们注意到这一点,模型将完全基于全价购买进行训练。从 ML 系统的角度来看,折扣商品似乎永远不再被任何人购买。因此,模型最终将停止推荐折扣产品,因为我们的日志、数据和训练系统中再也找不到任何人购买它们的证据!在训练期间数据处理中的这种非常小的错误可能会导致模型中的重大错误。
可复制性
ML 训练通常不是严格可复制的;在现代大多数 ML 训练框架工作方式下,几乎不可能在完全相同的训练数据和二进制文件上生成完全相同的模型,甚至可能无法得到大致相同的模型。请注意,虽然学术上的 ML 中的“可复制性”是指在已发布论文中重现结果,但这里我们指的是更为简单和更为关键的问题:在相同的数据集和模型上重现我们自己的结果。
ML 可复制性的挑战来自几个来源,其中一些可解决,另一些则不行。重要的是先解决可解决的问题。以下是一些导致模型不可复制的最常见原因:
模型配置,包括超参数
模型精确配置的微小变化,特别是选择的超参数,可能会对生成的模型产生重大影响。解决方案很明确:对模型配置进行版本控制,包括超参数,并确保使用完全相同的数值。
数据差异
尽管听起来显而易见,但大多数机器学习训练特征存储系统经常更新,很难保证在同一模型的两次运行之间数据完全没有任何变化。如果遇到可重现性挑战,消除训练数据差异的可能性是至关重要的一步。
二进制更改
即使是对机器学习训练框架、学习二进制文件或编排或调度系统的微小版本更新,也可能导致生成的模型发生变化。在调试可重现性问题时,保持这些内容在训练运行期间保持不变。¹¹
除了那些可修复的无法重现的原因外,至少还有三个原因不容易修复:
随机初始化
许多机器学习算法和大多数机器学习系统使用随机初始化、随机洗牌或随机起点选择作为它们工作的核心部分。这可能导致训练运行中的差异。在某些情况下,可以通过在多次运行中使用相同的随机种子来减少这种差异。
系统并行性
在分布式系统(甚至是具有多个线程的单机训练系统)中,作业将被安排在大量处理器上,并且它们每次学习的顺序都会有所不同。根据以何种顺序更新哪些键,会产生顺序效应。在不牺牲分布计算的吞吐量和速度优势的情况下,没有明显的方法可以避免这一点。请注意,一些现代硬件加速器架构提供了比其他网络技术快得多的定制高速芯片之间的互连。例如,NVIDIA 的 NVLink 或 Google 的 Cloud TPU 之间的互连就是其中的例子。这些互连减少了但并未消除在计算节点之间传播状态时的延迟。¹²
数据并行
正如学习任务被分布式处理一样,数据也是如此,假设我们有大量数据。大多数分布式数据系统在不加入显著性能约束条件下,不具备强有序性保证。我们必须假设,即使是从有限数量的训练任务中读取训练数据,也会以略有不同的顺序进行阅读。
处理这三个原因是昂贵且具有挑战性的,几乎是不可能的。在机器学习训练过程中,某种程度上无法精确复现完全相同的模型是一个必要的特征。
YarnIt 的可重现性问题示例
在 YarnIt,我们每晚重新训练我们的搜索和推荐模型,以确保我们定期调整它们以适应产品和客户行为的变化。通常,我们会对前一天的模型拍摄快照,然后在此之后训练新的事件。这样做更加经济,但最终意味着每个模型实际上是在相当长时间之前训练的模型的数十或数百次增量训练运行之上。
定期地,我们的训练数据集会随着时间而发生小的变化。最常见的变化是由于欺诈而产生的费用。发现一笔交易是欺诈可能需要多达几天的时间,到那时我们可能已经用包含该交易的新模型进行了训练。最彻底的修复方式将是将原始交易重新分类为欺诈,并重新训练每个曾经包含该交易的模型,从一个旧的快照中。每次发生欺诈交易时这样做的成本将非常昂贵。我们可能最终会不断重新训练最近几周的模型。另一种方法是试图从模型中撤销欺诈交易。这很复杂,因为在大多数机器学习模型中没有绝对可靠或精确的方法来撤销交易。¹³ 我们可以通过将检测到的欺诈视为新的负面事件来近似这种变化,但得到的模型将不会完全相同。¹⁴
所有这些都是针对当前正在生产中的模型。同时,YarnIt 的模型开发人员不断开发新模型,试图提高它们预测和排名的能力。当他们开发新模型时,他们会从头开始用所有新模型结构的数据进行训练,然后将其与现有模型进行比较,看看它是否在实质上更好或更差。可能显而易见的是,问题在于如果我们从头开始对当前数据重新训练当前的生产模型,那么该模型很可能与当前正在生产的生产模型显著不同(后者是随时间迭代地在相同数据上训练的)。先前列出的欺诈交易将永远不会被训练,而是在一段时间后被删除。事实上,情况甚至比这更不确定:即使我们对完全相同的数据使用完全相同的模型进行训练而没有任何变化,我们也可能会有非常显著的差异,一个模型一次性训练,另一个则在数次更新中逐步训练。¹⁵
这种真正令人不安的问题正是为什么模型质量必须由模型、基础设施和生产工程师共同负责。面对这个问题的唯一真正的可靠解决方案是将每个训练的模型视为该模型的柏拉图理想的略有不同的变体,并彻底放弃训练过的模型之间相等的观念,即使它们是由相同的计算机在相同数据上连续两次训练的相同模型配置。当然,这可能会大幅增加回归测试的成本和复杂性。如果我们绝对需要它们更加稳定(注意这并不是“相同”,因为在大多数情况下我们无法做到这一点),那么我们可能不得不开始考虑使用同一模型的复数副本集合,以便我们在时间上尽量减少变化。¹⁶
计算资源能力
就像它是非 ML 系统中停机的常见原因一样,缺乏足够的训练能力也是 ML 系统停机的常见原因。我们需要训练新模型的基本能力包括以下内容:
I/O 能力
这是特征存储的能力,以便我们能够快速读取输入数据。
计算能力
这是训练作业的 CPU 或加速器,以便我们能够从输入数据中学习。这需要相当数量的计算操作。
内存读写能力
在任何给定时间点,模型的状态存储在某个地方,但通常是在 RAM 中,因此当训练系统更新状态时,系统需要内存带宽来执行此操作。
ML 训练系统能力问题的一个棘手和令人困扰的方面之一是输入数据分布的变化,而不仅仅是其大小,可以导致计算和存储能力问题。为 ML 训练系统的能力问题进行规划需要周密的架构设计以及细致和一致的监控。
YarnIt 的容量问题示例
YarnIt 每天更新多个模型。这些模型通常是在网站使用最低的时间段训练的,这个时间段是大多数用户的夜间,并且预计在第二天忙碌期开始前更新。按照这种方式进行训练使得我们可以在在线服务和 ML 训练系统之间重复利用一些资源。至少,我们需要读取由服务系统产生的日志,因为 YarnIt 每天训练的模型读取前一天网站的搜索、购买和浏览历史。
和大多数 ML 模型一样,某些类型的事件在计算上比其他事件更简单。我们特征存储中的一些输入数据需要连接到其他数据源,以便完成一些训练操作的输入。例如,当我们展示由我们合作伙伴而不是 YarnIt 直接列出的产品购买时,我们需要查找有关该合作伙伴的详细信息,以便继续构建准确预测客户对该合作伙伴产品偏好的模型。如果由于某种原因,我们从合作伙伴那里的购买比例随时间增加,我们可能会在从合作伙伴信息数据集读取方面看到显著的能力不足。此外,这可能会导致我们似乎已经耗尽了计算能力,而实际上 CPU 正等待来自合作伙伴数据存储系统的响应。
此外,一些模型可能比其他模型更为重要,我们可能需要一个系统来优先处理那些资源受限、需要更多资源集中的重要模型训练任务。这种情况通常发生在故障后。假设我们在训练系统的某个部分经历了 48 小时的故障。那时,我们拥有的模型已经过时,代表着我们两天前对世界的最佳视角。由于停机时间如此之长,合理地预期我们需要时间来赶上进度,即使我们使用了所有可用的机器资源。在这种情况下,了解哪些模型需要快速更新是极其有用的。
结构可靠性
一些 ML 训练系统的可靠性问题并不是来自代码或训练系统的实现,而是来自其实施的更广泛背景。这些挑战有时对系统和可靠性工程师来说是不可见的,因为它们不会在模型或系统中显示出来,而是显示在组织和人员中。
组织挑战
许多添加机器学习能力的组织首先雇佣某人来开发模型。仅在此后才加入机器学习系统和可靠性工程师。这在某种程度上是合理的,但为了完全提高生产力,模型开发者需要在一个稳定、高效、可靠且良好工具化的环境中运行。虽然在行业中有相对较少有生产工程师或 ML 系统 SRE 经验的人员,但事实证明,几乎所有与 ML 系统相关的问题都是分布式系统问题。任何曾经构建和维护过类似规模的分布式系统的人,经过一段时间和经验积累后,应该能够成为我们 ML 系统上有效的生产工程师。
这将足够让我们开始将机器学习应用于我们的组织。但是,如果我们从前面的失败案例中学到了什么,那就是有些案例非常简单,但其他案例确实涉及理解模型结构和学习算法的基础知识。为了长期成功,我们不需要成为机器学习生产工程师的专家,但我们需要那些对机器学习感兴趣并致力于了解其工作细节的人。我们不能简单地把所有模型质量问题都委托给建模团队。
最后,我们还将面临资历和可见性问题。机器学习团队更有可能得到比许多其他同样规模或范围的团队更多的高级关注。这至少部分原因是因为当机器学习成功时,它被应用于我们业务中最有价值的部分:赚钱、使客户满意等。当我们在这些方面失败时,高级领导会注意到。整个生态系统中的机器学习工程师需要学会在组织中更高级别地进行沟通,并与对他们工作有兴趣的非技术领导人合作,当出现问题时可能会带来严重的声誉和法律后果。对于一些工程师来说,这是不舒服的,但是建立机器学习团队的经理应该为这种可能性做好准备。
关于除了训练系统之外的组织考虑的更深入讨论,请参阅第十三章和第十四章。
道德和公平考量
机器学习可以很强大,但也可能造成巨大的损害。如果我们组织中没有人负责确保我们正确使用机器学习,我们很可能最终会遇到麻烦。机器学习训练系统是我们可以看到问题(模型质量监控)并实施治理标准的地方之一。
对于刚开始实施机器学习的组织来说,模型开发者和机器学习训练系统工程师可能需要共同负责实施最基本的隐私、公平和道德检查。至少,这些检查必须确保我们在每个运营司法管辖区内使用数据隐私和使用方面符合当地法律要求。他们还必须确保数据集的创建和管理是公平的,并且模型经过了最常见的偏见检查。
一个常见且有效的方法是,组织采用一套负责任的 AI 原则,随后逐步建立系统和组织能力,确保这些原则在组织内所有 ML 使用中得到一致和成功的应用。考虑如何在模型层面(第五章)、政策层面(第六章)保持一致,同时将原则应用到数据(第四章)、监控(第九章)和事故响应(第十一章)。
结论
虽然 ML 训练系统的实施者仍然需要做出许多选择,但本章应该能清晰地说明这些选择的背景、结构和后果。我们已经概述了训练系统的主要组成部分以及影响我们对这些系统使用的许多实际可靠性原则。有了对训练模型创建过程的这种视角,我们现在可以把注意力转向 ML 生命周期中的以下步骤。
¹ 在许多现代框架中(特别是 TensorFlow、PyTorch 和 JAX),通常使用的配置语言是实际的代码,通常是 Python。这对于 ML 训练系统世界的新手来说是一个重要的头疼来源,但确实提供了灵活性和熟悉度的优势(对于某些人来说)。
² 几种类型的 ML 系统(尤其是强化学习系统)与本文框架有很大不同。它们通常具有额外的组件,如代理和模拟,并且把预测放在我们这里称为“训练”的环节。我们并不忽视这些差异,但选择了最常见的组件来简化这次讨论。你的系统可能会以不同的顺序拥有这些组件,或者可能有额外的组件。
³ 更糟糕的是,当无法追踪数据来源时,我们将面临治理问题(合规性、伦理、法律)。例如,如果我们无法证明我们训练的数据是我们拥有或已获许可用于此用途,我们可能会面临误用数据的指控。如果我们无法展示创建数据集的连接链条,我们无法证明遵守隐私规则和法律。
⁴ 例如,请参阅“ML 如何失败:十年来一个大型 ML 管道的失败” by Daniel Papasian and Todd Underwood。
⁵ 这个建议有一个有趣的例外,但不适用于绝大多数从业者:大型语言模型。大型 ML 中心组织正在训练多个非常大的语言模型,以便跨多种语言和数据类型提供复杂查询的答案。这些模型的训练成本如此之高,以至于它们的生产模型明确是一次性训练,然后“永久”使用(直接或通过迁移学习)。当然,如果降低这些模型的训练成本或出现其他算法进步,这些组织可能会发现自己仍需训练新版本的这些模型。
⁶ 统计学家将数据的这些不同属性称为完全随机缺失(数据点缺失的倾向完全随机);随机缺失或MAR(数据缺失的倾向不与数据相关,但与另一变量相关—这真是一个统计术语的不幸命名);以及非随机缺失(数据缺失的倾向与数据中的某些因素相关)。在这种情况下,我们描述的是 MAR 数据,因为任何给定数据点缺失的倾向都与另一个变量相关(例如地理位置或时间)。
⁷ 添加这些功能可能会对隐私造成重大影响。这些问题在第四章中简要讨论,而在第六章中则更加详尽。
⁸ 这在使用梯度下降并具有显著并行学习的模型架构中最为常见。但这对于大型 ML 训练系统来说是一种极为常见的设置。一个不会遇到这个问题的模型架构示例是随机森林。
⁹ 一个模型参数存储的架构被 Mu Li 等人在《“Scaling Distributed Learning with the Parameter Server”》中描述得很好,并在《深入深度学习》(Joanne Quinn 等人著,Corwin,2019)的第十二章中详细讨论。这种架构的变体已成为大规模 ML 训练系统分布式学习的最常见方式。
¹⁰ 迁移学习通常涉及将一个任务的学习应用到另一个相关的任务上。在生产环境中,迁移学习通常涉及从已经训练好的早期版本模型的快照开始学习。我们要么只训练新特征,这些特征未包含在快照中,要么只训练自快照训练后出现的新数据。这可以显著加快学习速度,从而显著降低成本。
¹¹ 敏锐的读者可能会注意到这是多么令人恐惧。另一种解读是“我的模型可能会在我随时更新 TensorFlow 或 PyTorch,即使是一个新的小版本时改变。” 这基本上是真的,但并不常见,而且差异通常并不显著。
¹² 只要处理器(无论是 CPU 还是 GPU/加速器)及其本地内存的操作速度显著高于我们从网络连接中访问该状态的速度,传播该状态总会有延迟。当处理器根据他们学到的输入数据更新模型的部分时,始终会有其他处理器在使用模型中这些键的较旧版本。
¹³ 有关从机器学习模型中删除数据的大量研究工作正在进行中。读者应该参考一些这方面的研究,以更好地了解不同方法及其删除先前学习数据的后果。一篇总结这一主题上一些最新工作的论文是 “Making AI Forget You: Data Deletion in Machine Learning”,但请注意这是一个活跃的研究领域。
¹⁴ 第六章 讨论了一些我们希望从已经训练过的模型中删除私有数据的案例。简而言之,如果数据是真正私密的,并且包含在我们的模型中,除非在模型构建过程中使用了差分隐私并提供了关于如何查询模型的谨慎保证,否则我们可能需要从头开始重新训练模型。事实上,每当有人请求删除其数据时,我们都必须这样做。这一点单独就是确保我们的模型不包含私人数据的一个强有力的论点。
¹⁵ 为什么会出现这种情况的详细内容与模型和机器学习框架有关,并且超出了本书的范围。但通常归结为机器学习框架中的非确定性加上数据并行处理中的非确定性。在您自己的环境中复现这种非确定性能带来巨大的教育意义,但也会有些许恐惧。是的,这个脚注确实鼓励读者复现不可重现性。
¹⁶ 集成模型 就是由多个其他模型组成的模型集合。它们最常见的用途是将多个非常不同的模型结合到一个单一目的中。在这种情况下,我们会将多个相同模型的副本组合起来。
第八章:服务
你已经创建了一个模型;现在你必须让它进入世界,并开始预测事物。这个过程通常被称为模型服务。这是一个常见的简称,用来描述“创建一个结构,以确保我们的系统可以要求模型对新示例进行预测,并将这些预测返回给需要它们的人或系统”(所以你可以看到为什么会发明这个简称)。
在我们的yarnit.ai在线商店示例中,我们可以想象我们的团队刚刚创建了一个可以很好地预测给定用户购买特定产品可能性的模型。我们需要一种方式让模型与我们的整体系统分享其预测结果。但是,确切地说,我们应该如何设置这个?
我们有各种可能性,每一种都有不同的架构和权衡。它们在方法上有很大的不同,所以看到这个列表时可能并不明显,这些都是解决同一个问题的尝试:我们如何将我们的预测与整体系统集成?我们可以做以下任何一项:
-
将模型加载到爱荷华州得梅因市的 1,000 台服务器中,并将所有传入的流量发送到这些服务器。
-
预计算模型对 100,000,000 个最常见的羊毛产品组合和用户查询的预测,使用一个大型离线批处理作业。每天将这些写入一个共享数据库,并对不在列表中的内容使用p = 0.01 的默认分数。
-
创建模型的 JavaScript 版本,并将其加载到网页中,以便在用户的浏览器中进行预测。
-
创建一个嵌入模型的移动应用程序,以便在用户的移动设备上进行预测。
-
有不同版本的模型,具有计算成本和准确性的不同权衡。创建一个分层系统,其中模型的不同版本在云中可用,使用不同成本的不同硬件。将简单的查询发送到成本更低(准确性更低)的模型,将更难的查询发送到成本更高(准确性更高)的模型。
这一章致力于帮助我们制定从诸如此类选择中选择的标准。在此过程中,我们还将讨论一些关键的实际问题,比如确保在服务中使用的特征流水线与训练中使用的兼容,并更新服务中的模型的策略。
模型服务的关键问题
我们可以考虑许多在模型周围创建支持服务的结构的方法,每种方法都有不同的权衡集。为了帮助导航这个领域,思考一些关于我们系统需求的具体问题是很有用的。
我们的模型负载会是多少?
关于我们的服务环境,首先要理解的是我们的模型将要处理的流量水平——通常在按需进行查询时称为每秒查询数(QPS)。为每天数百万用户提供预测的模型可能需要处理数万次每秒的查询。运行在移动设备上监听“Hey YarnIt”等唤醒词的音频识别器模型可能只需几个 QPS。预测房地产服务中房价的模型可能根本不会按需提供,而可能作为大型批处理流水线的一部分运行。
几种基本策略可以解决大流量负载问题。第一种是将模型复制到多台机器上并并行运行——可能使用基于云的平台来实现流量分发和根据需求扩展。第二种是使用更强大的硬件,比如像 GPU 或其他专用芯片这样的硬件加速器。这些通常需要将请求批量处理以最大化效率,因为这些芯片非常强大,它们可能更多地受限于输入和输出而不是计算模型预测本身。¹
我们还可以调整模型本身的计算成本,例如使用较少的特征,或者深度学习模型使用较少的层或参数,或者采用量化和稀疏化等方法使内部数学操作成本更低。模型级联也可以有效降低成本——这是指使用廉价模型对简单示例进行初步决策,只有更困难的示例才会发送到更昂贵的模型。
我们的模型对预测延迟有什么需求?
预测延迟是我们发出请求到收到答复的时间间隔。可接受的预测延迟在不同应用中可能差异巨大,是服务架构选择的主要决定因素。
对于像yarnit.ai这样的在线网络商店,我们可能只有半秒钟的总时间预算,从用户输入类似“美利奴羊毛线”这样的查询到他们希望看到完整推荐产品页面的时间。考虑到网络延迟和构建加载页面所需的其他处理,这可能意味着我们只有几毫秒的时间让模型对候选产品进行所有预测。其他非常低延迟的应用可能包括用于高频交易平台的模型,或者实时引导自动驾驶车辆的模型。
在另一方面,我们可能有一个模型,用于确定最佳的石油钻探点,或者尝试指导蛋白质序列的设计,用于创建新的抗体治疗方法。对于这些应用,延迟并不是一个主要的关注点,因为使用这些预测结果(例如实际建造石油钻机或在湿实验室中测试候选蛋白质序列)可能需要几周或几个月的时间。其他应用方式内含有隐含的延迟。例如,如果用户每天早上检查他们的收件箱,则电子邮件垃圾过滤模型可能不需要毫秒级响应时间。
综合考虑,延迟和流量负载定义了我们机器学习系统的整体计算需求。如果预测延迟过高,我们可以通过使用更强大的硬件来减轻问题,或者通过使我们的模型计算成本更低来解决问题。然而,需要注意的是,通过创建更多模型副本来进行并行化通常不是解决预测延迟的方法,因为通过模型的单个示例的端到端时间不受简单拥有更多模型版本的影响。
真实系统通常会产生延迟值的分布,这是由网络效应和整体系统负载引起的。关注尾延迟,如最坏的几个百分比,而不是平均延迟,这样我们就不会错过注意到一部分请求可能被丢弃的情况。²
模型需要存储在哪里?
在我们现代世界中,定义为信息流动和虚拟机等概念的流动,我们很容易忘记计算机是物理设备,并且模型需要存储在具体位置的物理设备上。我们需要确定我们模型的主要存储位置(或多个位置),这个选择对整体服务系统架构有重要的影响。以下是一些考虑的选项。
在本地机器上
虽然这并不是一个真正的生产级解决方案,在某些情况下,模型开发人员可能在他们的本地机器上运行模型,可能在需要时调用小批处理作业来处理数据。这不推荐用于除小规模原型设计或定制使用外的任何情况。即使在这些情况下,很容易在早期阶段依赖这一点,并在需要迁移到生产级环境时产生比预期更多的麻烦。
在我们组织拥有或管理的服务器上
如果我们的组织拥有或运营自己的服务器,我们可能会在同一平台上运行我们的模型。在特定的隐私或安全问题需要考虑时,这可能尤为重要。如果延迟是一个超级关键的问题,或者运行我们的模型需要专用硬件,那么这可能是正确的选择。然而,这个选择可能会限制在能力上的灵活性,无论是扩展还是收缩,都需要特别关注监控。
在云端
通过使用基于云的提供商来提供我们的模型,可以轻松地扩展或缩减我们的整体计算印记,同时还可以选择多种硬件选项。这可以通过两种方式实现。首先,我们可以在自己的虚拟服务器上运行模型服务器,并控制我们使用多少个服务器,这本质上与之前使用我们组织拥有或管理的服务器的选项无异。在这种情况下,也许稍微容易一些扩展或缩减服务器的数量,但管理开销在其他方面是类似的。这里我们更感兴趣的是第二种情况:使用托管推理服务。
在托管推理服务中,一些监控需求可能会自动解决——尽管我们仍然可能需要独立验证和监控整体模型质量和预测性能。由于网络成本的原因,往返延迟可能会较高。根据实际数据中心的地理位置不同,这些成本可能会高低不一,如果我们要全球处理请求,可能可以通过在多个主要地理位置使用数据中心来缓解部分问题。隐私和安全需求在这里也被突显出来,因为我们将通过网络发送信息,并且需要确保适当的保护措施已经到位。最后,除了隐私和安全问题外,我们可能出于治理原因而对使用特定云提供商保持谨慎:一些在线活动受国家政府监管的方式要求某些数据必须保留在特定司法管辖区。在制定服务布局计划之前,请确保您了解这些因素。
在设备上
当今世界充满了成为我们日常生活一部分的计算设备。从手机到智能手表,数字助理,汽车,恒温器,打印机,家庭安全系统,甚至是运动设备,这些设备都具有令人惊讶的计算能力,开发人员几乎在所有这些设备中找到了机器学习应用。当这些环境需要模型时,很可能需要将模型存储在设备本身上,因为另一种选择是访问云中的模型,这需要持续的网络连接,并可能存在复杂的隐私问题。这些“边缘服务”设置通常对模型大小有严格的限制,因为内存有限,并且可能由模型预测消耗的电量也有限制。
在这些设置中更新模型通常需要通过网络推送,并且不太可能及时更新所有此类设备;某些设备甚至可能根本不会接收任何更新。由于难以进行修复和推送更新,测试和验证在这些设置中变得尤为重要。在某些关键用例中,例如一个需要不断扫描输入音频以检测特定命令的模型,甚至可能需要在硬件级别而不是软件级别对模型进行编码。这可以带来巨大的效率提升,但会增加更新的难度,甚至可能不可能。
我们模型的硬件需求是什么?
近年来,出现了一系列计算硬件和芯片选项,这些选项极大地提升了各种模型类型的服务效率。了解这些选项对于指导我们的整体服务架构非常重要。
在服务中了解深度模型的主要内容是它们依赖于密集矩阵乘法,这基本上意味着我们需要以计算密集的方式进行大量乘法和加法运算,但在内存访问模式方面也非常可预测。³ 构成一个密集矩阵乘法运算的小乘法和加法操作可以很好地并行化。这意味着传统的 CPU 在执行良好方面会遇到困难。在撰写本文时,典型的 CPU 大约有八个核心,每个核心拥有一个或者最多几个算法逻辑单元(ALU),这些是芯片中知道如何进行乘法和加法运算的部件。因此,CPU 通常只能同时并行化少数这些操作,并且它们在处理分支、内存访问和各种计算操作方面的优势并没有真正发挥出来。这使得在 CPU 上运行深度学习模型的推断速度变慢。
服务深度学习模型的一个更好选择是称为硬件加速器的芯片。最常见的是 GPU,因为这些芯片最初是为处理图形而开发的,图形处理同样依赖于快速的密集矩阵乘法。⁴ GPU 的主要洞察是,如果少数 ALU 是好的,那么成千上万个肯定更好。因此,GPU 在专门的密集矩阵乘法任务上表现出色,但通常不适合其他任务。⁵
当然,GPU 也有其缺点,其中最明显的是这些都是专门的硬件。这通常意味着我们要在组织上投资,以便使用 GPU 为深度模型提供服务;或者我们正在使用提供 GPU 的云服务(可能会相应收费);或者我们正在使用本地可用 GPU 的设备。
GPU 的另一个主要缺点是它们不太适合不涉及大量密集矩阵乘法的操作。稀疏模型就是一个例子。稀疏模型在我们只需要从大量可能性中选择少量重要信息时非常有用,例如给定句子或搜索查询中出现的具体词语,而这些词语又来自所有可能词语的大量可能性。通过适当的建模,稀疏性可以在这些设置中被使用以显著减少计算成本,但是 GPU 不能轻易从中受益,而 CPU 可能更为适合。稀疏模型可能包括非深度方法,例如稀疏线性模型或随机森林。它们也可以出现在深度学习模型中作为稀疏嵌入,可以将稀疏输入数据(例如文本)转换为更容易在深度模型中使用的密集表示。
服务模型将如何存储、加载、进行版本控制和更新?
作为物理对象,我们的服务模型具有特定的大小需要存储。在离线环境中提供服务的模型可能存储在磁盘上,并且通过特定的二进制文件在批处理作业中加载,每当需要进行新的预测时。主要的存储需求因此是保持模型所需的磁盘空间,以及从磁盘加载模型的 I/O 容量,以及将模型加载到内存中进行使用所需的 RAM——在这些成本中,RAM 可能更昂贵或容量更有限。
用于实时在线服务的模型需要存储在专用机器的 RAM 中,并且在高吞吐量服务和延迟关键设置中,该模型的副本可能会并行存储和提供在许多复制机器中。正如我们在第十章中讨论的那样,大多数模型最终需要通过在新数据上进行重新训练来更新,有些模型每周、每天、每小时甚至更频繁地更新。这意味着我们需要用新版本替换在给定机器上当前用于服务的模型版本。
如果我们希望在此过程中避免生产中断,我们有两种主要策略。第一种是为服务作业分配两倍的 RAM,这样在旧版本仍在提供服务时,新版本的模型可以加载到机器中,然后一旦新版本完全准备就绪,就可以热替换使用哪个版本。这种方法效果很好,但在大多数时间内模型未加载或交换时会浪费 RAM。第二种策略是根据机器副本数的百分比过度配置,然后逐步将一定比例(例如 10%)的机器下线以更新模型。这种更渐进的方法还允许更优雅的错误检查和金丝雀发布。
还要记住,如果我们希望系统支持 A/B 测试(大多数开发者都希望使用),那么创建一个允许同时提供模型的 A 版本和 B 版本的架构非常重要。事实上,开发者可能希望在同一时间运行多种类型的 B 版本进行 A/B 测试。决定支持多少个版本以及以何种容量支持是一项重要的架构选择,需要平衡资源、系统复杂性和组织需求。
我们的服务特征管道会是什么样子?
特征需要在服务时和训练时处理。任何在训练时对数据进行的特征处理或其他数据操作几乎肯定需要在发送给我们模型的所有示例中重复执行,并且这可能需要相当大的计算资源。在某些情况下,这可能仅仅是将图像的原始像素值转换为密集向量以供图像模型使用。在更典型的生产设置中,可能需要实时合并多个信息源。
例如,对于我们的yarnit.ai商店,我们可能需要为产品推荐模型提供以下内容:
-
用户查询的标记化标准化文本,来自搜索框输入。
-
过去的购买历史信息,来自存储的用户信息数据库。
-
产品价格和描述信息,来自存储的产品数据库。
-
地理信息、语言和时间信息,来自本地化系统。
每种信息来源不同,并且在查询到查询或会话到会话之间可能有不同的预计算或重用机会。在许多情况下,这意味着用于将这些信息转换为我们的 ML 模型在服务时间使用的特征的实际代码可能与训练时间用于类似任务的代码不同。这种区别是经典的训练-服务偏差错误和错误的主要来源之一,而这些错误通常难以检测和调试。关于这种偏差及其他类型的更深入讨论,请参见第九章。
现代特征存储的一个承诺是它们在单一逻辑包中同时处理训练和服务。这一承诺的实际情况可能因系统和用例而异,因此确保在任何情况下进行强大的监控非常重要。
还值得注意的是,在服务时间为我们的模型创建特征是延迟的一个主要来源,在许多系统中可能是支配性因素。这意味着服务特征管道远非一种事后想法,实际上通常是整个服务堆栈中最关键的部分。
模型服务架构。
考虑到前面的问题,我们现在将详细研究四种广泛的服务架构。显然,每种都需要根据具体的用例进行定制,有些服务系统可能会使用多种方法的组合。话虽如此,我们注意到大多数架构和部署方法可归为以下四类:
-
离线
-
在线
-
模型即服务
-
边缘服务
我们现在详细查看每个。
离线服务(批量推理)
离线服务通常是实现最简单和最快的架构。直接面向最终用户的应用程序不会直接暴露给模型。模型通常提前训练好,通常称为批量推理。
批量推理是一种避免主机模型以在需要时进行预测的问题的方法。它通过加载模型并针对预定义的输入数据离线执行其预测来工作。因此,模型的预测被存储为简单的数据集,可能存储在数据库或.csv文件或其他存储数据的资源中。一旦需要这些预测,问题就变成了从数据存储加载静态数据资源的标准问题。本质上,通过离线计算模型预测,您将按需模型预测转换为更标准的简单数据查找问题(图 8-1)。
例如,可以在离线计算yarnit.ai上每个产品的流行度,针对给定的用户子集—也许在方便的低负载时间进行,如果某种方式的开销较大—并在需要时用作排序功能助手,以在任何时候根据需要呈现页面。

图 8-1. 通过数据存储进行离线模型服务
如果用例要求不高,我们甚至可以避免通过数据库存储和提供模型预测的复杂性,将预测写入平面文件或内存数据结构,并在应用程序中直接使用它们(图 8-2)。例如,我们的网店可以使用搜索查询意图分类器(特定产品与广泛类别),帮助查询引擎高效地重写查询以检索搜索结果。 (当然,您当然可以通过构建类似结构的近似值来索引纱线,例如通过包含羊毛、棉花、丙烯酸、混合物等的散列,或者反向散列。)

图 8-2. 通过内存数据结构进行离线模型服务
优点
离线服务的优点如下:
较少复杂
这种方法不需要特殊的基础设施。通常可以重用已有的东西,或者开始一些小而简单的东西。运行时系统的移动部件较少。
方便使用
促进使用案例的应用可以根据数据存储执行简单的键值查找或 SQL 查询。
更好的性能
预测是快速提供的,因为它们已经预先计算。这可能是某些关键任务应用的首要考虑因素。
灵活
通过基于标识符的单独表格或记录,此方法提供了一个灵活且简便的方式来推出和回退各种模型。
验证
在使用之前验证所有模型预测的能力是建立正确操作的重要优势。
缺点
离线服务的缺点在这里列出:
数据的可用性(训练)
训练数据需要提前准备好。因此,模型增强将需要更长时间才能部署到生产系统中。此外,关键的上游数据故障可能导致过时的模型、数天的延迟、永久丢失的数据,以及昂贵的回填过程来“赶上”离线作业到当前状态。
数据的可用性(服务)
实际上,服务数据需要提前准备好;为了完全正确的运行,系统需要事先知道每一个可能查询的可能。在许多使用案例中,这是不可能的。
扩展
扩展很困难,特别是对于依赖大型数据集或大查询空间的使用案例。例如,无法处理长尾搜索查询空间——即许多不同的查询,其中大部分不常用——以高准确度和低延迟。
容量限制
将多个模型输出存储在内存中或应用程序数据库中会有存储限制和/或导致性能问题。这将影响同时运行多个 A/B 测试的能力。只要数据库和查询资源需求的扩展速率相似,并且我们有足够的资源来提供,这可能不会造成真正的问题。
选择性较少
由于模型和预测是预先计算的,我们无法通过使用在线上下文影响预测。
在线服务(在线推理)
与前述方法相比,在线服务 不依赖于固定查询空间的预先计算输出。相反,我们通过摄取/流式传输实时数据样本,通常来自用户活动,实时提供预测。在我们的网店示例中,我们可以通过使模型不断学习实时用户行为来建立更个性化的购物体验,通过使用当前上下文以及历史信息来进行预测。当前上下文可能包括位置、对预先计算推荐的视图/印象、最近的搜索会话、查看的物品或添加到购物篮和从购物篮中删除的物品。
因为所有这些活动可以在预测时考虑到,这使得如何响应具有显著的灵活性成为可能。由离线模型生成的推断驱动的应用程序加上实时训练补充模型以获取额外参数(图 8-3)提供了巨大的好处和显著的业务影响。

图 8-3. 混合在线模型服务与离线生成预测的结合
优点
在线服务的优点包括以下几点:
适应性
在线模型在学习过程中不断进步,因此大大减少了模型重新训练和部署所需的周期。模型不是在部署时适应概念漂移,而是在推断时适应概念漂移,从而提高了客户模型的性能。
可供补充模型适用
我们可以调整更多情境特定的模型,而不是训练和更改一个全局模型,只需使用一小部分实时数据(例如用户或位置特定的模型)。
缺点
这里是在线服务方法的一些缺点:
需要延迟预算
模型需要访问所有相关特征。它需要快速访问新的查询,以便将其转换为特征,并进一步查找存储在其他地方的相关特征。如果我们需要为单个训练示例发送的所有数据不能作为 API 调用负载的一部分发送到服务器,则需要在毫秒级别从其他地方获取这些数据。通常,这意味着使用某种内存存储(例如,Redis)。
部署复杂性
由于预测是实时进行的,因此在容器编排环境(如 Kubernetes)中部署模型更改非常具有挑战性。
受可扩展性约束
因为模型可能会随时更改,所以它不具备水平扩展性。相反,我们可能需要构建一组单模型实例的集群,这些实例可以尽快消耗新数据,并将学习到的参数集作为 API 响应的一部分返回。
需要更高的监督要求
这种方法需要更先进的监控和调整/回滚机制,因为实时变化可能包括生态系统中由恶意行为者引起的欺诈行为,并且它们可能以某种方式与模型行为互动或影响。
需要更高的管理要求
除了强大的监控和回滚机制之外,正确执行这一点还需要非常复杂的专业知识和精细调整,既包括数据科学又包括产品工程。因此,这种方法可能仅对关键的业务线应用程序值得,通常对业务有很高的经济影响。
当在线提供模型与我们在下一节中讨论的模型即服务方法相结合时,其能力更加强大。我们顺便提一句,实时预测可以同步或异步提供。虽然同步模式更直接简单,更容易理解,但异步模式使我们在处理结果传递方式时更加灵活,并且能够启用通过推送或拉取机制发送预测的方法,具体取决于应用程序和最终客户端(浏览器、应用程序、设备、内部服务等)。
模型即服务
模型即服务 (MaaS) 方法类似于软件即服务,并固有地支持微服务架构。使用 MaaS,模型存储在专用集群中,并通过明确定义的 API 提供结果。无论传输或序列化方法如何(例如 gRPC 或 REST),⁶ 由于模型作为微服务提供,它们相对于主应用程序是相对隔离的(见图 8-4)。因此,这是最灵活和可扩展的部署/服务策略,因为不一定需要进程内交互或紧密耦合。

图 8-4. 作为单独的微服务提供模型
鉴于行业中 X 即服务方法的广泛流行,我们将更多关注这种特定方法,并将在本章后续详细探讨通过 API 提供模型预测的各个方面。
优势
以下是 MaaS 的优势:
利用上下文
根据 MaaS 上下文的定义,我们有能力通过使用实时上下文和新功能实时提供预测。
关注点分离
采用单独服务方法允许 ML 工程师以更稳定的方式进行模型调整,并应用于管理操作问题的众所周知的技术。大多数 MaaS 类型的模型可以以无状态方式组织,没有任何共享配置依赖。在这些情况下,增加新的模型服务能力就像向服务架构添加新实例一样简单,也称为横向扩展。
部署隔离
与任何开发架构一样,在其中 RPC 是唯一的通信方法,技术堆栈的选择可能会在应用程序和模型服务层之间变化,允许各自团队根据需要进行非常不同的开发。也可以遵循独立的部署周期,更容易在不同的时间轴上部署版本,或者在多个环境中进行部署:QA、staging、金丝雀发布等。
版本管理
版本控制很容易扩展,因为我们可以在同一集群中存储多个模型版本,并根据需要指向它们;例如,在 A/B 测试中非常方便。关于使用的模型的版本标识信息通常也可以设计为服务响应数据的一部分。此外,这还允许滚动部署,因为利益相关者系统可以依赖模型标识符来跟踪、路由和汇总由使用 ML 模型引起的任何事件数据,例如在 A/B 测试中用于服务特定结果的模型。
集中化有助于便捷的监控
由于模型架构是集中化的,因此比较容易监控系统健康、容量/吞吐量、延迟和资源消耗,以及每个模型的业务指标,如印象、点击、转化等。如果我们设计包装输入/输出和标准化识别模型并从配置加载它们的架构组件,那么可以通过插入其他提供这些常规微服务的 SRE “黄金四”类型的可观察性指标的预定义工具来“免费”获得许多这些指标。
缺点
MaaS 的缺点如下所示:
管理开销
当您加入微服务列车时,要安全且良好地保持在车上是困难的,并且需要大量的开销。然而,这种开销至少有一个优点,即被充分记录和理解。
组织合规性
当我们依赖于标准框架部署微服务时,最初可能会得到许多“免费”的东西,例如日志聚合、指标抓取和仪表板、跟踪容器和计算使用的元数据,以及将代码构建或发布转换为真正部署的管理交付软件。但是,我们也会收到改变请求,以遵守隐私、安全标准、身份验证、审计、资源限制以及各种迁移。
需要延迟预算
在任何有效将您的调用堆栈外部化的微服务架构中,延迟成为一个关键且不可忽视的约束条件。由于用户感知的延迟需要保持在合理紧凑的限制内(理想情况下为亚秒级),这对您将与之通信的所有其他系统施加了性能相关的约束。它还可能在用户感知性能周围创建组织盲点,因为(在分离的企业中默认情况下)没有一个团队会整体拥有那个性能。因此,选择底层数据存储、语言、组织结构和模式变得非常重要。
分布式可用性
建立在分布式微服务上的架构必须能够鲁棒地容忍部分故障。当模型服务不可用时,调用服务必须有合理的后备方案。
边缘服务
当模型部署到边缘设备上时,使用一种稍少见的服务架构(参见图 8-5)。边缘设备可能是从物联网(IoT)门铃到自动驾驶车辆等各种设备。如今,具有互联网连接的大多数边缘设备是现代智能手机。

图 8-5。模型在边缘和服务器上作为单独的微服务提供
这些模型通常不会独立存在:某种服务器端的补充模型有助于填补空白。同时,大多数边缘应用程序主要依赖设备上的推理。这种情况可能会随着联合/协作学习等新技术的出现而发生变化。⁷ 较接近用户的优势对某些应用来说是一个很大的优势,但我们在这种架构中经常面临严重的资源限制。
优势
边缘提供的优势包括:
低延迟
将模型放在设备上可以加快速度。对于某些应用程序,几乎即时的响应(没有丢包的风险等)非常关键:在自动驾驶车辆中,高延迟或抖动可能导致事故、伤害甚至死亡。在边缘设备上运行模型在这里实际上是强制性的。
更高效的网络使用
你能够本地回答的查询越多,就越少需要通过网络发送。
提高隐私和安全性
在本地进行推断意味着用户数据及其上的预测变得更难被攻击。这对于个性化搜索或需要个人身份信息(PII)如用户配置文件、位置或交易历史的推荐非常有用。
更可靠
当网络连接不稳定时,能够在本地执行某些以前在远程执行的操作变得更加可取,甚至有时是必要的。
能源效率
边缘设备的一个关键设计要求是能源效率。在某些情况下,本地计算消耗的能量比网络传输要少。
缺点
以下是边缘提供的缺点:
资源限制(专业化)
在计算能力有限的情况下,边缘设备只能执行少数任务。非边缘基础设施仍应处理大型模型的训练、构建和服务,而边缘设备则可以使用较小的模型进行本地推理。
资源限制(准确性)
机器学习模型可能会消耗大量 RAM 并且计算成本高昂;将它们适配到内存受限的边缘设备上可能会很困难或不可能。好消息是,目前有大量研究正在进行以寻找替代方法来解决这个问题;例如,像 SqueezeNet 和 MobileNet 这样的参数高效神经网络正是为了保持模型小巧高效而不牺牲太多准确性的尝试。
设备异构性(特定于设备的编程语言)
例如,想出一种确保 iOS 和 Android 上的边缘服务和设备内训练完全一致的方法是一个重大挑战。在移动开发最佳实践的背景下高效完成这项工作,还涉及到两个高度专业化的团队(ML 工程师和移动工程师)的交叉,这可能会对稀缺的共享专业团队造成组织压力,或者阻止采用全栈开发的标准化团队模型。类似的交互集合存在于将软件部署为面向公众使用的服务时。例如,一个在 Web 上可用的会计服务将要求具有建立会计系统经验的软件工程师与具有在生产环境中运行软件经验的生产工程师打交道。这里的差异主要是程度上的:ML 工程师和移动工程师来自极不同的世界和技术背景,如果不加努力,可能不太可能有效沟通。
设备软件版本由用户控制
除非您使用后端代理服务设计模式将各种调用从设备路由到服务器端后端,否则边缘设备的所有者将控制软件更新周期。我们可能在 iOS 应用程序中推出一个关键的改进,但这并不意味着数百万现有用户必须更新其 iPhone 上的版本。他们可能会继续等待并继续使用过时版本,直到他们愿意为止。因为部署到边缘设备的任何 ML 模型可能需要稳定运行,并且其预测和设备上学习设置可能需要长时间继续工作,这是一个巨大的架构承诺,可能带来大量未来技术债务和遗留支持,并且应该谨慎选择。
注意
在生产中为 ML 模型提供服务时需要跟踪的重要属性之一是版本控制。反馈循环数据、备份、灾难恢复和性能测量都依赖于它。我们将在第九章中更详细地讨论这些想法。特别是,在两个部分中我们将查看建议的测量:服务和 SLOs。
选择架构
谈论了各种架构选项之后,我们现在需要选择正确的架构!根据用例的不同,这可能是一件复杂的事情;模型生命周期、格式等之间的差异是考虑的一个方面,更不用说存在的广泛实施景观了。
我们推荐的方法是首先考虑应用程序所需的数据量和数据速度:如果极低的延迟是优先考虑的,使用离线/内存服务。否则,使用 MaaS,除非您在边缘设备上运行,在这种情况下,在边缘提供服务(显然)是最合适的。
本章的其余部分专注于 MaaS,因为它更加灵活,并且从教学角度来看更好,因为它受到的约束较少。
模型 API 设计
通常,生产规模的 ML 模型通常使用各种编程语言、工具包、框架和定制软件构建。当试图与其他生产系统集成时,由于 ML 和软件工程师可能需要学习新的编程语言或编写新数据格式的解析器,这些差异限制了它们的可访问性,以及它们的互操作性,需要数据格式转换器和多语言平台。
改进可访问性和互操作性的一种方式是通过 Web 服务提供抽象接口。基于资源的架构(ROAs)符合 REST 风格的设计哲学,适合隐藏实现特定细节的愿望。⁸ 部分支持这一观点,我们近年来在 ML Web 服务领域看到了快速增长的情况,例如 Google Prediction/Vision APIs、Microsoft Azure Machine Learning 等。
大多数面向服务的架构(SOA)最佳实践也适用于 ML 模型/推理 API。⁹ 但是对于模型,您需要注意以下几点:
数据科学与工程技能
许多组织拥有纯数据科学团队,几乎没有在生产中运行服务的经验。然而,为了获得 DevOps 的所有好处,您将希望授权数据科学团队全权负责将其模型发布到生产环境中。他们不会把模型“移交”给另一个团队,而是与运维团队合作,共同完成从头到尾的流程。
表示和模型
甚至特征分布的轻微变化也可能导致模型漂移。对于足够复杂的模型,创建这种表示可能意味着大量的数据管道、数据库,甚至是上游模型。对于许多 ML 团队来说,处理这种关系是非常棘手的。
规模/性能特征
通常情况下,管道的预测部分在服务环境中是纯计算绑定的,这在服务环境中是相当独特的。在许多情况下,工作流程的表示部分更多地受到 I/O 绑定的影响,特别是当我们需要通过加载数据/特征来丰富输入,或检索我们试图进行预测的图像/视频时。
我们认为推动推理服务设计中许多设计模式的压倒性因素是——也许令人惊讶的是——组织支持和技能集。在要求数据科学团队完全负责生产部署的所有端到端组件与完全将生产问题与数据科学团队分开以便其专注于模型训练和模型优化的领域专业化之间存在根本的紧张关系。
在任何方向上都走得太远可能都不利。如果要求数据科学团队承担过多责任,或者与运维支持团队没有密切合作伙伴关系,可能会因为处理没有接受过训练的生产问题而感到不堪重负。如果数据科学团队承担的责任过少,可能会脱离模型必须适应的生产系统的限制或实际情况,无法纠正错误、协助关键错误修复或参与架构规划。
因此,当我们准备在生产环境中部署模型时,实际上部署了两种不同的东西:模型本身以及用于查询模型并获取给定输入的预测的 API。这两个方面还会生成大量遥测数据和信息,稍后将用于帮助我们监视生产中的模型,尝试检测漂移或其他异常,并反馈到机器学习生命周期的训练阶段。
测试
在将模型部署和提供服务到生产环境之前,测试模型 API 非常关键,因为模型可能具有显著的内存占用,并且需要大量计算资源来提供快速响应。数据科学家和机器学习工程师需要与软件和质量保证工程师,产品和业务团队密切合作,以估算 API 的使用情况。至少需要执行以下测试:
-
功能测试(例如,对于给定输入的预期输出)
-
统计测试(例如,对 1,000 个未见请求进行 API 测试,预测类的分布应与训练分布匹配)
-
错误处理(例如,请求中的数据类型验证)
-
负载测试(例如,n个同时用户每秒调用x次)
-
端到端测试(例如,验证所有子系统是否按预期工作和/或记录)
服务的准确性还是韧性?
当为机器学习模型提供服务时,性能提升并不总是意味着业务增长。通过监控并将模型指标与业务关键绩效指标(KPI)相关联,有助于弥合性能分析与业务影响之间的差距,整合整个组织以更高效地朝着共同目标运作。重要的是要通过业务 KPI 来看待机器学习管道中的每一项改进;这有助于量化哪些因素最为重要。
模型性能是评估模型在执行任务时的准确性能力,不仅使用样本数据,还使用实际用户数据在生产设置中实时运行。必须评估性能以发现任何错误预测,如检测中的漂移、偏差和增加的数据不一致性。检测之后,根据其行为调试以缓解这些错误,确保部署的模型在用户端进行准确预测,并且对数据波动具有弹性。ML 模型指标是根据用户所服务的模型类型(例如,二元分类、线性回归等)来进行测量和评估,生成统计报告列出所有 KPI,成为模型性能的基础。
尽管改进这些指标(如减少对数损失或提高召回率)会提升模型的统计性能,但我们发现业务所有者往往更少关心这些统计指标,而更注重业务关键绩效指标(KPI)。我们将寻找能够详细展示特定组织表现以及为优化决策制定分析基础的 KPI。在我们的yarnit.ai网店示例中,主要的 KPI 可能如下:
每次访问的页面浏览量
这度量用户在单次访问期间平均浏览页面的数量。较高的值可能表明用户体验不佳,因为用户必须进行大量搜索才能找到他们想要的内容。或者,非常低的值可能表明用户对网站感到无聊或沮丧,并且可能导致流失。
回头客订单
这度量现有客户的订单数量,对于追踪品牌价值和增长至关重要。
一个弹性模型,虽然在数据科学指标如准确性或 AUC 方面并非最佳模型,但在除了训练集之外的广泛数据集上表现良好。它也将在更长时间内表现更好,因为它更加鲁棒和不容易过拟合。这意味着我们不需要不断监控和重新训练模型,这可能会干扰模型在生产中的使用,甚至可能造成组织损失。虽然没有单一的 KPI 来衡量模型的弹性,但我们可以通过以下几种方式来评估模型的弹性:
-
交叉验证运行中较小的标准偏差
-
在生产模型中,较长时间内的类似错误率
-
测试和验证数据集的错误率之间的差异较小
-
模型受输入漂移影响的程度
我们在第五章中详细讨论了模型质量和评估,以及 API/系统级 KPI,如延迟和资源利用率在第九章中。
缩放
我们通过 API 端点公开了模型,以便为业务和客户提供价值。这很好,但这只是一个开始。如果一切顺利,模型端点可能会在不久的将来看到显著增加的工作负载。如果组织开始为更多用户提供服务,这些增加的需求可以迅速导致 ML 服务/基础设施的崩溃。
部署为 API 端点的 ML 模型需要响应这种需求变化。在请求增加时,为服务模型的 API 实例数应增加。当工作负载减少时,实例数应减少,以避免在集群中资源被低效利用,并且我们可以潜在地节省大量运营费用。这类似于现代软件架构中任何云计算环境中的自动缩放。在 ML 环境中,缓存也可以效率高效,就像传统软件架构中一样。让我们简要讨论一下这些。
自动缩放
自动缩放 根据工作负载的变化动态调整模型分配的实例数量。自动缩放通过监控目标指标(例如 CPU 或内存使用情况)并将其与我们监控的目标值进行比较来工作。此外,我们可以配置最小和最大缩放容量以及冷却期来控制缩放行为和价格。在我们的 yarnit.ai 网店示例中,用于支持搜索用例的每语言拼写校正模块可以与基于客户购买历史推荐新/类似产品的个性化推荐模块的扩展独立扩展。
缓存
考虑在我们的 yarnit.ai 网上商店中预测类别和子类别的问题。用户可能搜索“cable needles”,我们可能会预测他们的预期购物区域是设备 → 针织针,来自我们商店类别布局的内部分类系统。在这种情况下,与其每次遇到重复查询如“cable needles”时重复调用昂贵的 ML 模型,我们可以利用缓存。
对于在缓存中有少量查询的简单情况,通常可以通过简单的内存缓存来解决,可能直接定义在应用逻辑中或模型的 API 服务器中。但是,如果我们处理大量客户查询以适应缓存,我们可能需要将我们的缓存扩展到独立可独立扩展和监控的单独 API/服务中。
灾难恢复
MaaS 通过 ML 服务与其他软件即服务(SaaS)平台具有相同的故障恢复要求:生存单个数据中心的丢失,多样化基础设施风险,避免供应商锁定,快速回滚糟糕的代码更改,并确保良好的断路器以避免贡献于故障级联。除了这些标准服务故障考虑因素外,ML 系统对训练和数据管道(无论在线还是离线)的深度依赖性还带来了额外的要求,包括适应数据架构变化和数据库升级,接入新的数据源,以及在面对缺失数据或上游数据 ETL 作业中断时优雅地失败等等。
数据在数据仓库、数据湖和流数据源中不断变化和增长:在产品/服务中添加新特性或增强现有特性会创建新的遥测,可能会添加新的数据源来补充新模型,现有数据库经历迁移,某人在上个模型版本中意外地从 1 开始初始化计数器而不是 0 等。任何这些变化都给生产中的 ML 系统带来更多挑战。
在第七章中讨论了数据可用性方面的挑战。在没有适当的故障恢复措施的情况下,经历未知数据变化或数据中断的机器学习模型可能需要从生产环境中移除,并进行长达数月甚至更长时间的离线迭代。在架构审查的早期阶段,务必多问关于系统如何应对异常数据变化以及如何增强系统健壮性以保证其继续在生产环境中运行的问题。此外,我们无可避免地希望通过添加额外的数据特征来扩展成功模型的范围或优化表现不佳的模型。在早期架构考虑中,将这种数据可扩展性视为关键因素至关重要,以避免因为新数据在生产中的处理逻辑而导致模型无法接收新特征的失败场景。
此外,为了确保高可用性,我们可能希望在云计算世界中的多个数据中心和/或可用性区域/地区中运行模型 API 集群。这将使我们能够在特定集群发生故障时快速路由流量。这些部署架构决策基本上受到组织服务水平目标(SLOs)的驱动。我们在第九章中对 SLOs 进行了更详细的讨论。
就像应用数据一样,我们需要有备份策略,不断地对当前模型数据进行快照,并在需要时使用最后一个已知的良好副本。这些备份可以离线用于进一步分析,并且可能会通过训练流水线来增强现有模型,衍生新特征。
道德和公平考虑
第六章详尽讨论了公平和道德(以及隐私)的总体主题。这是一个广泛的领域,使系统实施者可能会感到不知所措。我们强烈建议您阅读该章节,了解一般介绍以及一些具体建议。
然而,对于服务而言,我们应考虑以下具体要点:
组织支持和透明度
在生产中提供 ML 模型时,涉及道德和公平问题,我们需要在开发和部署框架中建立检查和平衡,并且对内部利益相关者和客户透明,说明所收集数据的用途。
减少隐私攻击面
当我们通过模型 API 处理请求时,请求和响应模式应尽量避免或至少减少对用户个人、人口统计信息的需求。如果这些信息是请求的一部分,我们需要确保在提供预测时不在任何地方记录这些数据。即使是为了提供个性化的预测服务,对道德和隐私非常承诺的组织也经常使用短期的用户标识符/令牌与服务基础设施交互,而不是追踪唯一标识符如用户 ID、设备 ID 等。
安全端点
除了数据隐私,特别是处理个人身份信息(PII)时,产品/业务所有者和 ML/软件工程师应投入更多时间和资源来保护模型 API 端点,即使它们仅在内部网络中可访问(即,用户请求首先由应用服务器处理,然后调用模型 API)。
每个人的责任
公平和道德是每个人的责任,不仅仅是伦理学家,关键是 ML 服务系统的实施者和用户必须接受这些主题的教育。这些关键问题的治理不仅仅是 ML 工程师的领域,必须全面地由组织中的其他成员,包括法律顾问、治理和风险管理、运营和预算规划以及所有工程团队的成员来综合考虑。
结论
提供可靠的服务很难。让模型对数百万用户可用,同时保持毫秒级延迟和 99.99%的正常运行时间是非常具有挑战性的。建立后端基础设施,以便在出现问题时通知合适的人员,并找出问题所在,也很难。但我们可以通过多种方式成功应对这种复杂性,包括在开始时对系统提出正确的问题,选择正确的架构,并特别关注您可能实现的 API。
服务并非一次性活动。一旦开始服务,我们就需要持续监控和评估成功(和可用性)。有多种方法来衡量 ML 模型和产品对业务的影响,包括来自关键利益相关者、客户和员工的反馈,以及以收入或其他组织相关度量标准衡量的实际 ROI。有关此内容以及部署、日志记录、调试和实验的其他主题的提示,请参阅第九章,而在第五章中有更完整的模型衡量覆盖。
¹ 然而,在某些情况下,您关于如何安排计算的选择是固定的,无法更改。必须在设备上提供服务的模型就是一个例子。假设我们正在部署一个模型,用于在移动应用程序中使用图像识别从手机摄像头拍摄的图片中识别毛衣的编织图案。我们可以选择在移动设备上直接实现图像识别,避免将图片发送到其他服务器,这样可以改善延迟和可靠性,甚至可能改善隐私保护——尽管对于移动设备来说,ML 计算通常会消耗电池电量。
² 尾延迟 指的是查询模型时观察到的延迟分布的最长延迟。如果我们多次查询模型并按照响应时间从短到长排序,我们可能会发现一个分布,其中中位数响应时间非常快。但在某些情况下,我们可能会遇到一长串长得多的响应时间。这就是尾部,而这些持续时间就是尾延迟。更多详情请参阅 Jeffrey Dean 和 Luiz André Barroso 的《规模尾部》。
³ 想象一下,为了从深度神经网络进行一次预测,可能需要进行数百万或数十亿个单独的算术操作。
⁴ 虽然 GPU 在训练和服务中是最常见的 ML 硬件加速器类型,但许多其他专用加速器架构专门为 ML 设计。像谷歌、苹果、Facebook、亚马逊、高通和三星电子这样的公司都有 ML 加速器产品或项目。这个领域正在快速变化。
⁵ 实际上,GPU 在计算方面非常出色,以至于它们通常不是在执行矩阵乘法时成为瓶颈,而是在于获取和输出数据的带宽。将请求批处理以摊销输入和输出成本可以是一种非常有效的策略,在许多情况下,这样做可以使我们处理数百个请求与处理单个请求具有相同的墙钟延迟。批处理的唯一问题是,我们可能会因等待足够的请求组成足够大的批次而变慢,但在高负载环境中,这通常不是问题。
⁶ gRPC是一种由 Google 最初开发的开源 RPC 系统。当开发者创建 Web API 时,表现状态转移(REST)是一种广泛使用的模式。
⁷ 联邦学习是一种方法,通过多个断开的边缘设备训练模型。详细内容请查看TensorFlow。
⁸ 资源导向的架构(与面向服务的架构相比)扩展了用于构建 Web API 的 REST 模式。资源是具有可以分配给统一资源定位符(URL)的状态的实体。关于这方面的概述,请参阅 Joydip Kanjilal 的《“An Overview of Resource-Oriented Architectures”》。
⁹ 类似地,面向服务的架构是一种方法,通过该方法将应用程序分解为一系列服务。这是一个有些被过度使用的术语,在业界通常代表不同的含义(正如 Cesar de la Torre 等人在《“Service-Oriented Architecture”》中反映的那样)。
¹⁰ SLO(服务级别目标)在《Site Reliability Engineering: How Google Runs Production Systems》中有详细介绍,并且在《Implementing Service Level Objectives》(Alex Hidalgo 著,O’Reilly 出版,2020 年)中有更详细的覆盖。
第九章:监控和可观察性的模型
作者:Niall Murphy 和 Aparna Dhinakaran
贡献者/审阅者: Ely Spears,Lina Weichbrodt,Tammy Le
图表: Joel Bowman
管理生产系统介于艺术和科学之间。在这种混合学科中加入机器学习的复杂性,它看起来更像一门艺术而不是科学。今天我们所做的很大程度上是前沿,而不是一个定义明确的领域。尽管如此,本章概述了我们对如何监控、观察和警报机器学习生产系统的了解,并建议在您自己的组织中发展这一实践。
什么是生产监控以及为什么要进行监控?
本章讨论如何监控正在进行机器学习的系统,而不是使用机器学习来监控系统。后者有时被称为AIOps;我们专注于前者。
说了这么多,让我们通俗地讨论一下生产监控,不涉及机器学习的复杂性,以便更容易理解——开始的地方又何处比定义更好呢?监控,在最基本的层面上,提供有关您的系统性能的数据;这些数据可以以某种合理的方式存储、访问和显示。可观察性 是软件的一个属性,意味着当正确编写时,发出的监控数据——通常通过标签或标记方式扩展或扩展——可以用于正确推断系统的行为。¹
为什么你会在意?事实证明有很多原因。最紧迫的是,监控可以帮助你确定你的系统是否真正正常工作。如果你自愿购买并阅读这本书,你可能已经理解这一点的重要性。甚至连 DevOps 运动的联合创始人安德鲁·克雷·沙弗(Andrew Clay Shafer)都曾经 写道,“如果系统崩溃了,软件就没有价值。” 如果你不认为这很重要,或者你理解了这些论点但不相信,我们建议你阅读詹姆斯·特恩布尔(James Turnbull)的《监控的艺术》(2016 年)。不过,在本章的其余部分,我们假设你理解你需要监控(和对系统状态进行警报),讨论的是如何最好地实现这一点。
当然,情况比这复杂得多。首先,系统通常不会像布尔值那样表现,完全是开或者完全是关;通常情况下,它们可能在从极好到非常糟糕的全谱上表现。显然,监控需要能够处理这种情况并正确地反映现实。
监控本身非常重要,但监控的一个分支绝对至关重要:警报。一个有用的简化是,当出现问题时,会向人类发出警报以修复它们,而在本段中,警报因此既定义了“事情出了问题”的条件,又能可靠地通知相关人员有些不对劲 —— 例如,呼叫。这是帮助“保护用户体验”的关键技术。
较少紧急但仍然至关重要的是长期趋势分析、容量规划以及对服务范围的整体理解的监控。您使用这类监控数据来回答诸如以下问题:我的服务是否具有成本效益?它是否有任何不明显的性能断层?是否存在数据分布漂移?例如,服务延迟如何与用户在周末与工作日的行为有关?所有这些问题等等在没有监控和可观察性的情况下很难得到很好的回答。
它看起来是什么样子?
如我们所提到的,要进行监控,您必须拥有一个监控系统以及要监控的系统(这里称为目标系统)。如今,目标系统会发出指标 —— 一系列通常是数字的数据,带有标识名称 —— 然后由监控系统收集并以各种方式转换,通常通过聚合(在多个实例或机器间生成总和或速率)或装饰(例如,将事件详细信息添加到相同的数据上)。这些聚合指标用于系统分析、调试以及前面提到的警报。
一个具体的例子是具有总请求数量度量的 Web 服务器;这种指标有一个名称 —— 比如,在这种情况下是 server.requests_total。(当然,它可以是任何请求/响应架构,比如一个 ML 模型!)监控系统通常通过推送或拉取获得这些指标,这取决于是否从目标系统拉取指标或者目标系统推送指标。然后这些指标被汇总、存储,并可能以某种方式处理,通常作为时间序列。不同的监控系统会对如何接收、存储、处理等做出不同选择,但数据通常是可查询的,而且(非常频繁地)通常有一种图形方式来绘制监控数据,以便利用我们的视觉比较硬件(眼睛、视网膜、视神经等等)来理解实际发生的情况。
扩展来说,可观察系统使用这些基本理念,但更进一步:与其仅仅获取总请求数计数器不同,您会得到关于该指标的标记²数据,事实上大多数指标都是如此。具体来说,标记数据意味着您不仅仅获取计数器;您还可以获取该指标的子集或切片。因此,例如,您不仅仅有server.requests_total;您还有server.requests_total{lang=en},这意味着“对于所有客户端请求以英语渲染页面的请求,总请求数是多少?”当然,并不只是{lang=en},还有{lang=fr}、{lang=pt}、{lang=es}、{lang=zh}等等。一个完全可观察的系统允许在极其细粒度的边界上对这些数据进行切片和切块,以至于可以构建查询来查看过去 12 天以来,发生在罗马尼亚的查询,导致 HTTP 404 返回代码,在 1200 毫秒延迟之后.³
监控本质上有许多微妙之处,特别是在聚合方式和结果使用方面,但这是一个合理的高层次描述,至少是在非 ML 系统监控方面。当您将 ML 系统作为目标系统添加到这个图景中时,不仅仅是前面提到的所有问题,还有 ML 的特殊关注点;图 9-1 可能会有所帮助。

图 9-1. 可观察性层和系统要求
ML 对监控带来的关注
一个重要的关注点不一定是监控 ML 本身的任务,而是模型开发社区对监控行为的感知。我们是什么意思呢?
嗯,我们相信模型开发社区非常清楚软件有输入和输出,并且应该进行观察以弄清楚发生了什么。(模型开发的整个过程可以被视为指标提取、控制和优化的过程,首先!)然而,有时候缺少的是对模型开发完成并投入生产后发生的事情的认识和参与。我们看到关于 ML 监控的思维方式问题,部分源于术语的使用方式——从语义上讲,监控既可以指模型开发中的检查活动,也可以指对生产系统的持续观察。实际上,这个术语在两个情境中都被使用。
换句话说,许多模型开发者并没有意识到,在模型在生产环境中运行时,检查需求的确可以和应该和在开发中一样。这个差距尤其明显,如果您的背景是使用指标进行优化,而不是进行检测。检测事实上是一个非常关键的用例,而监控活动应该适用于整个模型生命周期。
这不仅仅是感知问题。事实上,机器学习在可解释性方面已经存在困难——特别是在生产执行的时候。部分原因是机器学习本身的特性,部分是现今模型开发方式的结果,部分是生产操作的本质,还有一部分反映在检查工具通常只专注于模型开发上。所有这些因素共同导致了监控机器学习变得更加困难。
持续进行机器学习可观测性——在生产中
从你的模型中获取的可观测性数据对业务至关重要——无论是战术操作还是战略洞察。我们已经提到,有关监控和可观测性缺失的负面后果,已经有很多文章写过,但也有积极的结果。
我们喜欢使用的一个例子是延迟与在线销售之间的关系。在 2008 年,亚马逊发现每增加 100 毫秒的延迟会导致销售下降 1%,反之亦然——因此,越快越好。⁴ Akamai Technologies、Google、Zalando 等也证实了类似的结果。我们断言,如果没有可观测性,就不可能发现这种影响,而且肯定无法确定是改善了还是恶化了情况!
最终,可观测性数据确实是业务结果数据。在机器学习时代,这不仅让你能够检测和响应故障,还能理解对你的业务发生的非常重要的事情。如果忽视这一点,你将会付出代价。
机器学习生产监控的问题
机器学习模型开发仍处于初级阶段。工具不够成熟,概念框架不完善,纪律性不足,因为每个人都在争先恐后地试图尽快建立某种模型——任何一种模型!——并解决实际问题。时间紧迫,出货压力巨大,这是实实在在的。
特别是模型开发,由于其困难性,因为它涉及调和各种矛盾关注点,所以随着紧迫感迫使开发人员和数据科学家专注于这些难题,并忽视更广泛的视角。更广泛的视角通常涉及监控和可观测性的问题。
这导致我们对模型开发和生产服务之间差异的两个重要观察。其中一个是关于所有生产环境的通用观察,恰好在机器学习领域尤为复杂和困难。另一个是关于当前广泛适用但未来可能不再如此的模型开发特定情况,尽管如此,作为后续内容的基础,这仍值得一提。
开发与服务的困难之处
第一个问题是,即使在专门用于此任务的独立环境中(如测试、预发布等),在开发中有效模拟生产也极其困难。这不仅是因为可能的服务架构种类繁多(模型池、共享库、边缘设备等,以及您可能或可能未运行的相关基础设施),还因为在开发中,出于速度原因,您经常直接调用预测方法或只需很少的代码量。而在生产中运行通常意味着您无法任意操作输入、日志级别、处理等,这导致在调试、复现问题配置等方面遇到巨大困难。最重要的是,测试中拥有的数据不一定像模型在生产中遇到的数据分布那样分布,而对于机器学习来说,数据分布确实非常重要。
第二个问题有些不同。在传统软件交付中,行业已经掌握了已知能够提高吞吐量、可靠性和开发速度的工作实践。其中最重要的可能是连续集成/连续部署(CI/CD)、单元测试、小改变以及尼科尔·福斯格伦等人在《加速》(IT Revolution Press, 2018)中最好描述的一些其他技术的集合。(见⁵)不幸的是,今天我们在模型开发中缺少这种类似于 CI/CD 的机制,还不能说我们已经达到了一套好的(与遥测相关或其他)模型训练和验证工具的标准。我们预计随着现有工具(如 MLflow 和 Kubeflow)的推广、供应商将更多这些关注点纳入其平台,以及整体或全生命周期监控思维的更广泛接受,这种情况将会有所改善。
必须改变心态
尽管今天我们面临许多技术挑战,但组织和文化上的挑战可能是对整体监控最具影响力的。特别是,模型开发人员通常不会考虑部署后问题的检测,而是考虑部署前的 KPI 性能建模——而 KPI 性能建模并不一定直接与业务 KPI 连接!(见⁶)
这显然对整个生命周期的监控构成了问题,因为预部署和后部署都变得重要,就像成功的软件一般,后部署通常比你想象的时间长。专注于快速开发和部署模型的团队通常对严格的交付框架感到不耐烦,好像这些交付框架会阻止他们以最方便的方式组织培训和服务。当然,它们确实在某种程度上做到了。但是它们通过提供一套在生产环境中难以实现并仅以特定的特定方式部署的监控和管理保证来实现这一点。
如果我们接受这个框架,我们应该做的最重要的事情是努力寻找一个合理灵活的解决方案,以在整个生命周期内维护模型行为的最广泛有用的视图,并使其适应你自己的情况。由于今天用于模型开发的特殊工具(如 TensorBoard、Weights & Biases 等)通常不会自然地转化为生产本身,当前使用的特定监控系统等等,我们必然需要自己制定一些内容。鉴于此,本章的总体目标是推荐一种全生命周期的监控方法,特别是建议一个默认的监控事项集,除了模型旨在改进的特定业务指标,因为它们已经得到了很好的理解。
机器学习模型监控的最佳实践
让我们从几个框架假设开始:在本章的目的下,模型开发通常是循环进行的。我们选择数据,对其进行训练,建立模型,进行基本的测试/验证,调整,重新训练,最终发布到生产环境,了解模型的行为,并开始下一个循环,以改进的想法。
在服务中的监控可以分为模型、数据和服务(也称为基础设施)。这种分离是有用的,因为我们不必在每个层次处理每个细节,尽管我们承认某些交叉存在。
可解释性——理解模型分类的原因,预测的原因等——是一个重要的主题,随着机器学习在更多行业中发挥更大作用,它可能变得越来越重要。详细解释可解释性以及最佳实践概述超出了本章的范围,也超出了本书的范围。一些伦理原则在第六章中有所涉及,大多数读者应该查阅该章节。
然而,仅从模型监控的更实际角度来看,可解释性在预生产阶段和越来越多的生产阶段是重要的。可解释性的具体情况因模型类型、阶段、业务策略等而异。但通常情况下,在生产中使用 ML 用于安全关键或社会重要方式,并且在理解导致结果的原因方面可能存在法律或道德兴趣。这里的主要目标是尽可能找到平滑模型开发和服务之间差异的方法。
通用的预服务模型建议
我们在第三章中有更多讨论,但从监控的角度来看,最重要的是牢记与模型开发相连的业务目标,并将其 KPI 连接到导出的指标以供监控目的使用。对于你没有业务洞察力但有大量基础设施洞察力的模型来说,它几乎无用,同样地,你了解在开发中工作良好但对于其在生产中行为没有洞察力的模型,可以说可能比无用还要有害。
最重要的建议是,您的业务关键绩效指标(KPI)应与模型指标相关联;您应能够从开发到生产阶段连续追踪这些指标。例如,如果您是一家打车应用公司,并且正在预测乘车的预计到达时间(ETA),那么接驳地点是您在整个期间内明确希望可用的内容。在监控数据完整性时,因此模型的最重要特征应优先考虑。
可解释性和监控
如前所述,可解释性是一个重要领域,但特别是在监控方面,它会带来一些问题。就像调试或一般的可观察性一样,完整的可解释性通常在生产环境中比在开发中需要更多资源(并且更慢、更昂贵等)。然而,你通常最急需的是在生产环境中的可解释性。
负责机器学习模型的人有几个原因需要可解释性:确定哪些特征应优先考虑数据完整性,调查特定预测或特定预测片段,并响应一般的可解释性业务要求。由于这是如此昂贵,并且商业人士可能没有理解所需背景的全部知识,有效的方法通常涉及与他们讨论他们真正关心的问题。通常情况下,您可以回应他们的关切(甚至可能构建特殊的监控解决方案),而无需深入具体的建模细节,这种对话有时可能会偏离主要问题。
然而,在某些情况下,可解释性对于故障排除至关重要。让我们以借贷案例为例:假设预测被拒绝,因为请求具有一个特征的唯一值,而这个值并不常见——在这种情况下,例如,一个申请日期是二月二十九日。申请日期通常不是我们所有预测中前十个最重要的特征之一,但是如果由于某种原因我们的训练数据集中只有很少的二月二十九日的申请,并且这些申请在中间几年里都是较差的风险,我们可以想象一个模型会使用申请日期来严重影响决策以拒绝。
在这种情况下,可解释性可以揭示驱动个体预测结果的因素。这可以通过定期记录预测摘要来实现,通过 LIME 和 SHAP(本质上是使用概念上类似的差分密码分析方法的替代或重复模型)⁷或另一种更定制化的方法来暴露内部机制。通常,这些解释不仅被模型开发人员使用,还被风险和合规团队使用,并且可以帮助非技术用户理解模型的系统问题。不幸的是,这在生产中大多数情况下都是太昂贵的。
训练与重新训练
从经典的监控角度来看,训练阶段通常是最容易处理的。在监控训练时,最重要的事情是保持全局视角,最重要的指标是从开始训练到生成(希望工作的)模型所需的时间。
尽管模型回滚是解决生产问题最常见的策略,但有时会使用重新训练——在这种情况下,您可以将其视为模型的前进:即用最新版本的一切替换生产中的内容,希望或期望这样做可能会为我们解决问题。
通常在回滚未奏效或无法奏效时(参见“验证中的回退”),或者如果对您的基础设施来说,前进比回退更容易时,会使用重新训练。⁸ 同样,在两种情况下,重新训练都有缺点。首先,在重新训练时,会在与训练旧模型使用的完全相同的数据上执行(在这种情况下,您会广泛期待相同的行为,因为这是相同的输入)。其次,重新训练需要花费很长时间,无法用来战术性地解决故障。 (这是您可能希望自动定期运行重新训练的一个原因,如果对您来说,这样做是可行的话。)
对于第一个问题,你有时可以通过一点“技巧”来稍微“操作”情况——无论是通过使用全新的语料库,替换一些不良数据,添加丢失的数据等。(当然,这里训练过程中的重要变量包括改变我们训练的数据范围,以及是否改变任何权重,但希望决定这些事项相对较快。)⁹
在监控环境中,训练非常重要,不仅因为重新训练,还因为这是大多数开发者建立其基准线的地方,之后广泛用于比较点。(10)
具体建议
接下来,我们概述了一些监控基础覆盖的事项列表。我们认为最低限度和强制性的事项,我们用斜体突出显示;如果你必须从某个地方开始,就从那里开始。当然,你可以花费很多精力来监控,也许在某些情况下是值得的,但在某些情况下则不是。因此,我们建议在实施以下所有检查之前,仔细考虑成本/效益权衡。(如果你想找到更高级的决定重要性的指南,我们建议你查看为你的训练流水线和模型编写 SLOs——详见“ML 监控中的 SLOs”了解更多详情。)
-
输入数据
-
与预期大小相比,输入数据集有多大? 将训练数据集与上次训练此模型的情况进行比较,或者使用另一个外生度量来指示粗略大小。如果数据集意外地缩小了 50%,那通常是个不好的迹象。
-
你正在比较原始输入数据和特征数据吗?(一些问题只有在将字段组合成特征时才会出现。)
-
最年轻和最老的输入数据分别是什么?它们符合预期吗? 如果额外加分,开始查看年龄分布直方图。在分布式训练情况下,有时可能会有少量非常老的数据,而其他所有数据都已经被处理得干净有效。
-
在这种情况下,基数是多少(总元素或示例的数量),以及数据是如何分布的? 这个分布与预期分布非常不同吗——无论是与我们上次训练这些数据的情况相比,还是与其他生成的预期分布相比?
-
在批处理场景中,你能枚举数据并确保它已经完成了吗?(你能保证所有来自特定日期——比如昨天——的事件都已经到达并包含所有相关字段吗?你有来自前一天或今天的任何异常值吗?)
-
在流处理场景中,传入数据的到达速率是多少? 你是在每个“包裹”到达时处理,还是在收集到固定大小后处理(在这种情况下,你应该跟踪处理被调用的频率)?
-
如果数据访问是经过中介的,访问率是多少?是否存在大量失败(特别是与身份验证相关的失败)?
-
如果数据是从其他地方复制到,比如特征存储中,并且模型是从特征存储中构建的,那么复制是否正确进行?
-
-
处理
-
有多少处理作业正在运行?它们上次运行是什么时候?它们是否按时完成?重新启动率和成功作业完成率是多少?有未处理单元的积压吗?未处理单元的年龄分布如何?
-
处理速率是多少(比如每秒处理的输入数据元素数量?) 处理速率的 50th、90th 和 99th 百分位是多少?(特别关注长时间运行的分片—即,如果您将工作分布到多个处理作业中,通常会看到其中一个运行时间较长—参见前面关于输入分布的评论。)与前一次迭代相比如何?或者为了更准确的比较,您如何确保正确考虑季节性效应以定义前一次迭代?¹¹
-
为了生成模型,CPU、内存和 I/O 这三个维度的资源总共消耗了多少? (这可能很难确定,但对于找出瓶颈非常关键—特别是如果您增加了任何资源,您是否知道系统会变得更快?)
-
-
全面视角
-
整个运行过程—从整理输入数据到生成模型—需要多长时间,无论是绝对时长还是比较时长?
-
输出模型的大小是多少?如果有多个文件,是否每个应该存在的文件都存在?
-
模型是否能够成功加载并进行简单预测?
-
对于在单独环境中进行测试的人来说,模型是否通过了测试流程?
-
将模型投入生产并处理查询所需的时间是多少?
-
对于在生产环境进行测试的人来说,模型是否经过用户曝光? 新模型是否以意外方式影响了您在生产中跟踪的业务或使用指标?
-
您是否了解将模型投入生产中的最大贡献是什么? 是手动操作还是自动操作?(您可能需要添加装饰或注释信息来实现此目标:例如,标记特定时期为网络负载较重的时间。)
-
最后,我们注意到,其中一些建议可能也可以有用地应用于您培训管道的子组件。例如,往往在将其复制到其他地方进行更完整处理之前,各种数据着陆区可能已经应用了一些非常简单的检查(例如,考虑到经常使用的相对不灵活的电子资金转移或 EFT 过程的纱线供应商交付清单)。了解如果这些减少了 50%的大小是否有用。类似的论点可能适用于特征存储假设之前的特征预处理链等等。我们无法提前描述每种可能的架构,但我们可以说,业务风险分析可以帮助您了解在哪里最好地配置您稀缺的资源。
模型验证(投入使用之前)
模型通常被设计来实现某种业务影响,也称为改善指标。因此,业务验证可以理解为试图了解模型的业务影响,¹² 例如,查看它如何影响利润和损失(有时也称为盈亏曲线),或者使用混淆矩阵,试图理解模型错误分类的情况,应该是"是"而模型分类成"否",等等。当然,我们始终需要注意用户行为可能会有噪声,但主要目标是找出模型是否从基准改善了某个指标。
次要目标是尝试确定新模型是否比我们已有的更好。为此,我们不仅需要针对历史数据进行测试(我们可能已经在做了),还需要将两个模型彼此比较。¹³ 我们可以选择至少两种好方法之一:
-
在预生产环境中进行测试(有时称为沙箱),并根据您的能力并行或串行运行模型,以比较其行为。
-
在生产中进行测试,使模型获取一小部分实际用户流量(通常在 1%到 5%之间),有时称为金丝雀测试。
第二种方法还有一个好处,即在全面推出之前暴露模型对用户流量的反应问题。但是,这确实需要您有某种方式来工程化流量,以便特定版本只获取子集流量——并非所有基础设施都支持此功能。但如果您有此功能,它对允许从旧模型到新模型的安全过渡非常有益,并且与 A/B 测试完美重叠。(通用模型更新也可以很好地适应这种框架,并且事实上,当代软件部署广泛使用此方法。)
混合方法是将一些数据发送到本地模型,同时将相同数据发送到在生产环境中运行的模型(尽管采用这种方法,本地模型不能完全处理生产流量;它只是处理你的测试流量)。这有助于暴露建模和服务之间的特征代码差异、配置差异等。最后,有些人将生产流量发送到模型,但不将结果提供给最终用户,这样可以测试服务路径的许多组件,而不会给用户带来风险。这被称为影子模式,在正确性和风险之间提供了另一个平衡点。
验证中的备用方案
由于各种原因,强烈建议制定一个备用计划,即一套步骤,用于在新模型失败、发布失败,甚至老模型在特定情况下出现奇怪行为时采取。这里有两种主要方法(如《“紧急响应必须实时完成”》中所见):
使用旧版本的模型(回滚)
这意味着保持这些实际二进制文件的正确版本化是个好主意,并且监控生产中的实际版本,因为在生产停机时为了从旧数据构建模型而加重训练基础设施的负担通常是不明智的做法的反面。
退回到更简单的算法或甚至硬编码的方法
例如,在试图为产品购买提供排名推荐时,不要显示错误的推荐,只需展示站点上最受欢迎的前 10 款产品—虽然对任何人来说都不完全正确,但大多数情况下也不会完全错误!
在回滚时要非常小心,因为许多微妙的问题等待在长草中,随时准备袭击:模式更改、格式更改或语义更改——在这些情况下,关键数据库、数据源或特征存储格式在版本发布之间的更改都是容易被忽视的例子。有时这会使得回滚变得事实上不可能或不切实际,除非整个依赖套件被重新构建,但也可能使得向前转到新版本变得困难,除非完全理解实际的错误。在这些情况下,算法备用可以拯救生命。然而,算法备用本身也可能因为分类错误而失败。
这里的一个细微之处是,即使架构保持不变,应用于模型的特征转换也可能与另一个版本中应用的不同。例如,在一个模型版本中,如何处理顺风车应用的上车位置的缺失值可能是简单地默认为乘客上次出现的位置,而在另一个版本中可能是最接近先前保存的上车位置(例如家、办公室等)。这些特征转换方式的差异可能在不同版本之间存在差异,并且还会使回滚变得复杂。更糟糕的是,如果您在系统的一侧回滚到一个特征转换,而在另一侧保留新的特征转换,则情况将变得更加复杂。
行动号召
当前在基础设施即代码(IaC)社区中使用的 CI/CD 工作流程,用于模型开发尚未普遍存在。¹⁴ 不同的公司甚至同一公司内的不同团队可能会以不同方式解决问题。这并不意味着你不能进行检查,或者不能自动执行检查——自行开发的方法当然有其用处——但如今的现实是需要手动、基于同行的代码和数据审查,并需要统计学博士的详细验证。
就其价值而言,目前的情况对机器学习开发构成了严重的摩擦。行业迫切需要努力使尽可能多的工作自动化,而这项工作太重要,不能单单依靠平台完成。因此,我们呼吁行业朝着在机器学习开发中广泛使用 IaC 方法的状态迈进,就像 CI/CD 和 IaC 在产品开发中今天所受欢迎一样。即使我们无法达到这一目标,也将手动验证后的所有训练成果安全自动地推向生产将显著改善目前整个行业的平均水平。
具体建议
用于评估机器学习模型性能的常用数值 KPI,这些内容在第五章中也有详细讨论和更深入的理论基础,并特别关注服务用例在第八章中的应用。我们在这里总结这些 KPI,以保持连贯性和易于访问性:
准确性
模型预测正确的比例。
精度
真正例与总正例的比例。
召回率
预测为正例的比例与总正例的比例。¹⁵
精度和召回(PR)曲线
在不同决策阈值下精度和召回之间的权衡空间。
对数损失
更多详细信息,请参阅第五章。
ROC 曲线和 AUC
模型质量的无阈值独立度量。
还有许多其他可能使用的数学度量标准,其中一些您可能从早期的统计课程中认识到(例如,p-值和系数效应大小),还有一些涉及的稍微复杂一些(例如,后验模拟)。总的来说,如果您能理解前面列表中关于您的模型的内容,并了解您的输出分布形状,您对正在发生的事情就有很好的把握了。
服务
在生产环境中为 ML 模型提供服务时监控它们,具有在生产中观察事物的所有困难,再加上解释 ML 特有的事物发生原因的众多挑战。尽管如此,我们可以从一组简单的问题开始:
-
哪些指标适合衡量我的模型在服务中的表现?(在某种意义上,您希望更相关的指标;任意的指标往往会不断增长,直到信号/噪音被削弱。)
-
我的模型是否如预期般执行?如果表现不佳,原因是什么,我该如何解决?
为了选择衡量模型性能的好指标,我们需要正确理解模型可能出现故障的方式。为使模型成功运行,需要三个组成部分:
模型
进行预测的模型。
数据
流入和流出模型的数据。这包括模型用于进行预测的特征及其预测结果本身。
服务
实际渲染模型的服务。 这通常涉及模型的部署和推理服务——从广义上讲,这是基础设施。
这三个组成部分中的每一个都需要按预期工作,以使模型成功。任何一个组成部分的失败都可能对模型旨在改善的整体业务关键绩效指标产生影响。因此,我们需要测量所有这些以获得完整的图片。在接下来的章节中,我们将更详细地研究它们。
模型
从模型本身开始,我们再次注意到,在服务中测量模型性能比在服务之前测量性能要困难得多。鉴于这些困难,我们更倾向于在服务中使用与训练/验证中相同的指标来评估模型,因为这将使我们更有信心,我们实际上在某种意义上“测量到了相同的东西”。当然,这样做需要能够将预测结果与相应的实际观察结果进行匹配。
例如,假设一家乘车打车公司有一个模型预测车辆到达客户的预计时间(ETA)。在验证阶段评估此模型时,你非常关心将误差(通常称为均方根误差或RMSE¹⁶) 最小化,以便模型的预测接近实际的 ETA:在这种情境下,事实证明如果你承诺过高而实际交付不足,顾客往往会更加不满意。因此,在生产环境中计算相同的度量标准,必须有一些过程可以协调预测的 ETA 与实际的 ETA(即计算误差)。
在实践中,有几种场景描述了真实结果(称为实际数据)到达的延迟及我们如何应对这些情况。¹⁷
案例 1:实时的实际数据
理想的机器学习部署场景——通常也是课堂上唯一教授的场景——是当你将模型部署到生产环境后,能够立即获取行动建议和性能信息。
许多行业非常幸运地拥有这种理想的场景。可能最著名的是数字广告:一个模型试图预测哪个广告消费者最有可能与之互动。几乎在预测完成后立即确定了真实结果——他们是否点击了广告。类似的例子是食品送货;一旦披萨送到饥饿的客户家门口,你就有了可以将模型预测与之比较的实际测量数据,而食品送货作为一个业务,有着严格的时间限制(以及其他成分)——如果时间过长,顾客通常就不再需要了。¹⁸ 最终,强有力的检测 KPI 是你想要的,如果你能够获取的话。
快速反馈环路的关键之处在于能够几乎即时(或至少非常快速地)测量模型的效果;当然,一旦你将这个潜在的真实数据与预测事件联系起来,无论获取这些数据花费多长时间,模型的性能指标都可以轻松计算和跟踪。¹⁹ 定期跟踪这些指标可以确保模型的表现没有从训练时或最初投入生产时显著降级。
然而,许多现实环境都会改变你获取真实数据的方式,以及你用来监控模型的工具。
案例 2:延迟的实际数据
在这种情况下,你无法享受之前提到的快速实时反馈的好处。事实上,这些类型的情况在业务中可能比案例 1 更常见,而且处理起来肯定更加尴尬。想象一下,你试图预测物理基础设施失败的可能性——比如桥梁倒塌——或者使用机器学习来进行房地产市场预测。这两种情况都可能需要几年甚至几十年的时间来测量。这使得确保一个旨在帮助你做出高质量决策的模型行为符合预期变得非常棘手。
这种延迟接收真实情况,而且可能是无界的。例如,一家金融科技公司试图分类哪些信用卡交易是欺诈行为。你可能要等到客户的卡片丢失报告或者交易争议之后才能知道一笔交易是否真的是欺诈。这可能发生在交易清算后的几天、几周或几个月内——或者在交易未被客户察觉的情况下,甚至永远不会发生。
最终,如果你能获得足够多的“半实时”数据,数据能够足够可靠等等,你仍然可以使第一种方法奏效,但如果你不能使该方法奏效,团队可能需要转向代理指标。代理指标是与你试图逼近的真实情况相关的替代信号,但特别选择它们的原因是它们到达得更快。
对于桥梁故障的情况,我们可能会查看桥梁检查的结果、维护计划、桥梁是否处于易受洪水影响的地区以及桥梁的年龄。对于房地产购买价格预测,一个常见的技术是查看类似房屋的价格,但尽量不改变太多组成部分:例如相同数量的卧室和浴室但在不同地区,或者不同数量的卧室但在同一地区等等。对于几个月或几年的建筑工期来说,即使是这样一个混乱的复合代理指标,也比没有要好。
最终,代理指标在面对延迟的真实情况时成为一个强大的工具,因为如果你无法在实时获取到一个强相关的度量,至少可以获取一个相关性较弱的度量;通常这已经足够了。不过,不要忘记你的代理指标需要具有统计显著性的数学要求,而且代理指标可能随时间而改变其相关性,因此需要持续重新评估。
情况 3:偏倚的实际数据
一个重要的注意事项是,并非所有的真实数据都是平等的。例如,如果我们是一家金融科技公司,在贷款情境下审视信用度,预测的核心问题是拒绝贷款意味着你将不再有关于申请人是否能够偿还贷款的任何信息。换句话说,只有你决定发放贷款给的人才会产生可以用来训练未来模型的结果,这种选择偏差可能导致其他类型的偏差潜入。因此,我们将永远不会知道模型预测的某人是否会违约,其实际是否能够完全偿还贷款。正如在第六章中更详细地描述的那样,因此至关重要的是评估我们的数据,以发现潜在的偏见、盲点和代表性不足的领域。
情况 4:没有/少量实际数据
在一些机器学习应用中,及时获取实际数据(响应)是不可能的。这可能由于各种原因,包括以下几点:
-
需要手动干预来验证模型的预测结果。
-
没有办法将响应归因于预测。
-
获取实际数据的时间窗口延迟如此之长,以至于无法有意义地通知建模者应该检查模型的性能。
例如,许多图像分类应用程序需要人为干预,以手动验证图像是否被正确分类。这可能需要抽样,以便仅对预测的有价值部分进行手动验证,以改进模型的未来训练数据集。
那么如果团队没有获取到实际数据,该怎么办呢?在这些情况下,ML 团队再次使用代理指标来提供模型性能的信号并不罕见。在这些极端情况下,较弱的相关性可能比没有更好。在测试新版本模型在生产中的同时,对模型进行 A/B 测试并比较其对产品指标的影响也很常见。监控模型的数据变得更加重要,以了解模型是否偏离了预期。
其他方法
除了模型可能如何处理与实际数据的关系之外,还可以使用模型行为的通用测量来判断事情是否真的出了问题。我们的首要选择是“无用”响应的比例,即空白、不完整或次优的回复,而另一个关键指标是我们的老朋友,数据分布。
故障排除模型性能指标
假设模型性能指标可以计算。不可避免地,你的模型在某些时候会达不到性能期望。要回答的难题是为什么。最常见的原因通常是训练数据的欠采样、漂移以及影响模型用于预测的数据质量的数据完整性问题。一个最佳实践是超越平均值,调查各种预测片段,即预测的特定子段,例如加利福尼亚州的所有人。
想象一下,你的模型正在预测欺诈的可能性。你预期误报负例(你的模型未能捕捉到真实的欺诈交易)的体积少于 0.01%。假设你突然看到误报负例跳到了 2%。继续的自然方法是查看这种行为是否局限在特定的地区或商家。通过这样做,你可以找出错过的分类发生在哪里,以及重新训练模型时需要增加哪些数据片段的样本量。当然,了解模型最差表现的片段可以为模型构建者提供反馈,以改善模型性能。
数据
ML 监控的关键组成部分是监控模型的输入和输出。随着特征的添加或删除,监控必须适应模型的架构。我们有两种常见的监控数据的方法——漂移检测和数据质量检查。漂移更适合捕捉数据分布的缓慢变化,而数据质量检查更适合捕捉数据的突然大变化。
漂移
漂移测量随时间的分布变化。模型在每种可能的输入上表现并不一样:它们高度依赖于它们训练时的数据,在看到类似的数据时表现良好,在看不到时表现较差。特别是在数据不断演变的高速增长业务中,考虑到漂移对确保模型保持相关性非常重要。因此,通过直方图风格的方法测量数据在各个维度上的分布对于理解生产过程中发生的情况至关重要。一些模型对输入分布的轻微变化具有韧性,但不存在无限的韧性;在某些时刻,数据分布将远离模型在训练中看到的情况,这将影响任务的性能。这种漂移被称为特征漂移或数据漂移。相反,当模型输出偏离已建立的基线时,这被称为模型漂移或预测漂移。
如果只有输入到您的模型的事物可以改变,那将是很好的,但不幸的是,情况并非如此。假设您的模型是确定性的,并且特征管道中没有任何变化,如果它看到相同的输入,它应该给出相同的结果。
尽管这让人感到欣慰,但如果正确答案即实际数据的分布发生变化会怎样呢?即使您的模型今天做出的预测与昨天相同,也可能出错!实际数据的这种漂移会导致模型性能的退化,通常称为概念漂移。
测量漂移
了解两个分布之间的差异很重要,但这是一个复杂的话题,我们在此不能详细展开。所以如果这些材料对您来说很陌生,不要担心。要么就直接使用它,要么去查找并学习更多。(无论如何,如果您与数据分布有任何交集,不管是主动监控还是被动使用,您都可能会遇到这些术语。)
正如我们之前讨论的,我们通过比较输入、输出和实际数据的分布来测量漂移。这两个分布通常是生产数据和基准分布。常用的基准分布包括训练数据集、测试数据集或生产中的先前时间窗口。但是如何量化这些分布之间的距离呢?
有几种流行的方法。人口稳定性指数 (PSI) 在银行和金融科技领域广泛使用,依赖于为一个度量指标进行数据桶化,计算每个分布中驻留在桶中的百分比,并比较分割百分比的对数。这可以检测到桶内或桶间的变化。Kullback-Leibler 散度 (KL 散度) 类似于 PSI,但是是非对称的,因此可以检测到分布顺序的变化。Wasserstein 距离(也称为地球移动者距离)计算将一个分布移动到另一个分布所需的工作量,这对于识别桶之间的移动量非常有用——即使从一个桶溢出到下一个,Wasserstein 分数会比从一个分布端到另一个远端进行更激烈跳跃时低。
尽管这些分布距离测量方法在计算距离的方式上有所不同,它们都在做同样的事情:提供一种量化两个分布有多不同的方式。特别是在实际数据不可用时,漂移被用于实际世界中识别模型预测、特征和实际数据的变化。
漂移故障排除
在许多机器学习用例中,当无法直接计算性能指标时,漂移通常成为监控模型预测变化的主要方法。当检查为何预测开始漂移时,我们通常从观察哪些输入也漂移了开始,并且可以将特征漂移和特征重要性结合在一起,以确定哪些特征可能与变化更强相关。反过来,这有助于我们确定哪些特征可能需要从基线重新采样,或者可能需要数据质量修复。
数据质量
虽然漂移侧重于缓慢故障,但模型数据质量监控侧重于严重故障。模型依赖于输入特征的输入来进行预测,而这些输入特征可以来自各种数据源。不同类型的数据可以监控数据质量问题——分类字段、数值字段,以及诸如嵌入等非结构化数据类型。在这里,我们将深入研究监控结构化分类和数值数据的常见策略。
分类数据
分类数据是从一个有限但更大的值集合中选择单个值的流。想想类别,比如某人拥有的宠物类型:狗、猫、鸟等等。你可能认为这里不会出什么问题,但类别分布突然变化总是可能的,可能是因为用户行为(例如,今年流行的圣诞宠物是驯鹿)或其他故障。举个例子,假设你的假设模型预测你的宠物用品店应该购买哪种宠物食品,现在的数据表明人们只拥有猫。这可能会导致你的模型只购买猫食品,而所有拥有狗的潜在客户将不得不去街对面的宠物用品店。
除了你的分类数据中突然发生的基数转移之外——即每个类别中实际计数的变化——你的数据流还可能开始返回不符合该类别的值。这很简单地是你的数据流中的一个 bug,违反了你与数据和模型之间建立的合同(语义期望)。这可能出现多种原因:你的数据源不可靠,你的数据处理代码出错,上游模式变更等等。在这一点上,你模型的输出变得未定义行为,你需要确保在分类数据流中保护自己免受类型不匹配等问题的影响。
例如可能包括以下情况:
-
你期望的功能是字符串,突然收到了浮点数。
-
对于一个特征(即状态输入),你是大小写敏感的,但期望的是小写值,现在却收到了大写值(例如,ca 和 CA)。
-
你正在从第三方供应商那里接收数据,他们的模式顺序存在一个偏移错误。现在,你看到每个特征接收到另一个特征的值。
一个不幸常见且难以处理的情况是缺失数据。这可能由于与基础设施、应用程序、存储和网络故障或简单的错误相关的任何原因引起。真正的问题是如何处理它。在训练环境中,有时只需丢弃这一行就可以使事情继续进行,而不会太糟糕;在生产环境中,你可以抛出一个错误(但不是致命错误;否则,这将把一个间歇性故障的存储服务转变为整个舰队的灾难,这是不推荐的)。虽然这些技术帮助你弥补了这个问题,但实际上并不是一个可持续的解决方案:如果你有数百、数千或数万个用于计算模型特征向量的数据流,其中一个数据流缺失的可能性就会非常高!
注意
尽管这更多与鲁棒性而非监控有关,但可以通过多种方式来补偿类别数据中的缺失值,这个过程通常称为插补。你可以选择在你的数据中历史上看到的最常见类别,²⁰或者可以使用存在的值来预测这个缺失的值可能是什么。你解决这个问题的复杂度完全取决于你的应用场景,但重要的是要知道没有一种解决方案是完美的。
数值数据
数字数据流也相当不言自明。数值数据通常由浮点数(有时是整数)表示,例如银行账户中的金额,或者华氏或摄氏温度。
在我们分析数值流可能出现的问题时,有时你会看到一个异常值,即远远超出历史值范围的值。异常值对你的模型可能是潜在危险的,因为它们可能会导致你的模型在预测中出现严重错误。
类型不匹配也会影响数字数据。可能出现你期望得到温度读数的特定数据流,而实际上得到的是类别数据点,你需要适当处理。可能的默认行为是将这个类别值转换为一个数字,虽然此时是有效的,但它完全丧失了语义意义,成为数据中极难追踪的错误。另一种可能性是类型不变但语义发生变化:也许你正在追踪一个总计计数器(具有某些任意大或小的包装),突然它被更改为一个增量。当然,根据数据的不同,这可能在相当长的时间内不被察觉!
最后,就像分类数据一样,数值数据也会遇到同样的缺失数据问题,但数值序列隐含的排序和跨度使我们在缺失值插补方面有更多选择。例如,我们可以取平均值、中位数或其他聚合分布度量来填补缺失的数值,比如纱线重量(以克为单位);参见图 9-2。

图 9-2. 处理不良生产数据的方法
测量数据质量
当今 ML 从业者对于许多模型依赖于非常大量的特征来执行其任务并不感到意外。随着训练集大小爆炸性增长至数亿甚至数十亿,特征向量长度为数十万至数百万的模型并不罕见。
这带来了今天从业者面临的一个主要挑战。为了支持这些极其庞大的特征向量,团队不断地向特征生成中注入更多更大的数据流。现实情况是,这种数据模式将不可避免地经常发生变化,因为团队在试验以改进模型。常见的做法包括添加特征、删除特征或更改特征的计算/处理方式,而诸如特征存储等平台正在广泛用于处理这种管理开销。具体而言,在所有特征上执行以下最重要的检查:
-
分类数据
-
基数:唯一值的数量是否已更改?
-
缺失值:此特征是否存在缺失数据?
-
类型不匹配:数据类型是否已更改?
-
数据量:此特征的数据量是否已更改?
-
-
数值数据
-
超出范围的违规:值是否超出了适当的范围?
-
缺失值:此特征是否存在缺失数据?
-
类型不匹配:数据类型是否已更改?
-
移动平均值:特征值是否在增加/减少?
-
服务
要使 ML 系统成功,您需要理解 ML 系统中输入和输出的数据、模型本身的性能,以及渲染或服务模型的整体服务性能——使其预测或分类结果可用。即使模型的性能改善了业务结果并保持数据完整性,但对于单个预测需要几分钟,这可能还不足以在实时服务系统中部署。与部署到生产环境的其他软件服务类似,部署模型并服务模型推理的服务需要进行监控。
有多种选项可用于将模型投入生产:部署自己的 API/微服务、使用开源模型服务框架(如 TensorFlow Serving、PyTorch Serving、Kubeflow Serving 等)、或使用第三方服务。无论使用何种模型服务方式,特别是在实时服务中,监控服务的预测延迟非常重要,因为预期的预测应该在请求发送后立即发生。有两种方法可以做到这一点:
模型层级
缩短模型进行预测所需的时间。
服务层级
减少系统接收请求后服务预测所需的时间。这不仅涉及到模型本身,还包括收集输入特征(有时预先计算或缓存它们),以及快速捕捉预测结果以提供服务。
优化模型性能
为了优化模型以降低预测延迟,最好的方法是减少模型的复杂性。减少复杂性的一些例子包括减少神经网络中的层级、减少决策树中的层级,或减少模型中的任何无关/未使用部分。架构也很重要:例如,双向编码器表示转换(BERT)比前馈方法慢,而基于树的模型比深度学习快。
在某些情况下,这可能直接影响模型的效力。例如,如果决策树中有更多层级,可以从数据中捕捉到更复杂的关系,从而提高模型的整体效果。然而,决策树中较少的层级可以减少预测延迟。在部署任何模型时,平衡模型的效力(准确度、精确度、AUC 等)与其所需的操作约束是非常重要的。这对于嵌入在移动设备或设备上的模型尤为重要。
优化服务性能
为了优化服务性能,以下是您可以监控和改进的建议区域。
首先,让我们考虑输入特征查找。在模型能够进行预测之前,必须收集所有输入特征,这通常由 ML 系统的服务层完成。一些特征将由调用者传入,而其他特征可能会从数据存储中收集或实时计算。例如,一个预测客户对广告反应可能性的模型可能会获取该客户的历史购买信息。客户在浏览页面时不会提供这些信息,但模型服务会查询特征存储或实时数据库来获取这些信息。通常将输入特征收集分为两组:
静态特征
不太可能迅速改变且可以提前存储或计算的特征。例如,可以提前计算历史购买模式或顾客的偏好。
实时计算的特征
需要在动态时间窗口内计算的特征。例如,在预测食品配送的到达时间时,可能需要知道过去一小时内下了多少其他订单。
在实践中,我们通常有用户或应用程序提供的特征、静态特征和实时计算的特征的混合。监控这些特征的查找和转换对于追踪 ML 系统中的延迟来源至关重要。
接下来,让我们考虑预先计算预测。在某些用例中,通过预先计算预测、存储并使用低延迟读取数据存储服务提供预测,可以减少预测延迟。例如,流媒体服务可以预先存储他们服务的新用户的最受欢迎推荐。这种离线批量评分作业可以大大降低服务环境中的延迟,因为大部分工作在调用模型之前已经完成。
其他需要考虑的事项
即使考虑了前述所有因素,我们还远未穷尽对监控和可观察性可能存在的潜在关注点的清单。以下是一些你在监控旅程中可能想要记住的其他领域。
机器学习监控中的 SLOs
SLOs 是一种流行且仍在增长的技术,用于明确地预先确定系统的适当可靠性水平——某种意义上决定用户体验将是什么,并决定是进行特性工作还是可靠性工作,这取决于我们在某一时刻处于哪一阈值的哪一侧。例如,如果我们已经决定客户应该有 99.9%的可用性,并且在某些时刻我们低于这个水平,这将触发修复损坏的系统,直到我们再次趋于 99.9%。这样,机器学习工程师、整体产品团队和 SRE 团队(如果有的话)协同合作,将用户体验的可靠性“弯曲”朝向优化的、预先决定的水平。
这是一个非常简单,实际上是简化的例子,事实上在多个关键领域中的现实要复杂得多。即使机器学习很复杂,你仍然可以通过 SLOs 获得一些价值。但是要注意以下微妙之处:
-
正如我们已经确定的,仅仅看模型就不能确定模型是否适合投入生产。因此,SLOs 有充分理由扩展范围以涵盖数据(以及数据分布,新鲜度等)。
-
对于请求-响应服务系统,例如yarnit.ai的前端 Web 服务器,可用性是一个相对清晰的问题——要么在一定可接受的延迟内提供正确的内容,要么不提供。当被提供的内容可能具有从 0.0 到 1.0 的分类器置信度时,以及任何单个结果或一组结果可能完全、正确地且有正当理由地低于任意质量阈值时,ML 系统的可用性意味着什么?至少,ML 的 SLO 因此必须包含质量或置信度阈值的概念。
-
或许有点令人惊讶的是,最佳方法并不是专注于 ML 系统的性能,而是专注于该 ML 系统所需交付的业务目标。换句话说,如果整体用户体验仍在定义的限制范围内,系统作为一个整体可以遭受各种各样——也许是暂时的——退化。关于这个话题的更多内容,请参见《实施服务水平目标》的第八章。
-
对于具有大量模型或大量模型变更的环境,一个有前途的方法是自助服务基础设施,使 ML 工程师可以定义和强制执行每个模型或模型类的 SLO(通常通过与黄金数据集的比较);SRE 可以开发、提供和支持这样的服务,从而帮助所有人的整体 SLO 方法扩展。 (同样的方法也可以扩展到单个模型的单独用例,只要可以以确定性方式进行标记。)
-
最后,正如从第十一章(事件响应)中清楚地看出的那样,ML 在整个业务中是交织在一起的,指定 ML 系统的 SLO 而不同时还为所有或大多数相邻系统指定它们可能是不切实际的。此外,由于检视性或可解释性通常难以获得,足以捍卫足够严格的 SLO(例如,99.5%或更高)的快速反应不会成为仅凭人工驱动的过程可以实现的事情:这将成为自动系统与人类协同行动的问题。在非 ML 情况下,自动系统单独行动通常非常有用,但在 ML 情况下我们应该谨慎行事。
如果您希望更具体地为您的 ML 基础架构建立 SLOs,我们建议您从哪里开始。如果您查看表 9-1,您将看到我们针对您关心的内容提出的 SLO 建议。行涵盖您试图衡量的内容,列涵盖范围。因此,例如,如果您担心 ML 训练系统的整体系统健康,左上角的象限是您可以找到启动点的地方。本质上,该表格概述了基于行为、指标或示例指标制定 SLO 的想法。当然,这不是一个详尽无遗的列表。
表 9-1. 每个 ML 上下文要监控的行为或指标
| 训练 | 服务 | 应用(YarnIt) |
|---|
| 整体系统健康 | 模型构建时间(不包括快照)并发训练数量
失败的构建尝试次数
资源饱和度(例如,GPU 或 I/O 吞吐量)| 延迟(响应请求的时间)流量(请求数量)
错误计数(失败请求的数量)
饱和(任何特定资源的枯竭:CPU、RAM、I/O)| 主要与用户旅程或会话购买率相关
登录率
页面子组件失败率(例如,购物车显示)
购物车弃购率 |
| 通用 ML 信号/基础模型健康 | 预训练:源数据大小(即,自上次构建以来未大幅增长或缩小)
训练:
模型类型和输入数据大小的训练时间函数
训练配置(例如,超参数)
训练后:
模型质量指标(准确率、精确度、召回率、其他模型特定指标)| 模型服务延迟(作为总体服务延迟的一部分或随时间比较)模型服务吞吐量
模型服务错误率(超时/空值)
服务资源使用(特别是 RAM)
在服务中的模型年龄/版本 | 模型特定指标(在单个页面加载时可见)每页推荐数量
每个推荐的预测点击率估计质量
搜索模型的类似指标 |
| 领域特定信号 | 构建模型通过验证测试(不仅是聚合过滤器有效,而且在黄金集和保留集测试中的结果质量相等或更好)。商店中新产品的推荐与同等或更高质量的产品相似。 | 这些指标通常会延迟。离线信号与服务预测在总体和相关片段中匹配。特定查询的推荐数量与预服务预期匹配。 | 会话或用户旅程特定指标。拜访率不下降的百分比。
每次访问的平均销售额保持不变。
保持会话持续时间。 |
实际上,具体指定一个服务级别目标最好留给其他文献,但Betsy Beyer 等编辑的《可靠性站点工作手册》(O’Reilly,2018 年)提供了一个完全具体化、详尽细致的服务级别目标文档示例;即使是像“99%的数据在两小时内更新”这样简单的描述,也能提供价值。
跨服务的监控
随着机器学习基础设施的进一步扩展,你可能会发现自己需要做的两件重要事情是分布式追踪和理解系统的延迟分布。(尽管我们在本章节中已经多次讨论分布,但在本节中我们特指监控,而非机器学习。)
分布式追踪与可观测性密切相关,它使你能够追踪请求在分布式架构中不同服务之间的完整路径。可以将其视为给请求贴上“给我一份关于路径完整报告”的标签。处理请求的每个系统在其传播过程中应该增加一定程度的额外可见性。各种商业和免费系统都实现了这一点——你可以查看OpenTelemetry来了解其工作原理。
另一个关键领域是理解分布——在这种情况下,不是机器学习数据的分布,而是延迟的分布。这并不一定直观,但在足够复杂的架构安排中,即使是一小部分运行缓慢的请求也可能显著影响客户体验。[²¹] 大多数组织没有存储或计算能力来追踪每个请求的这些情况,因此需要某种形式的请求抽样——即为某些请求跟踪详细统计信息,但默认情况下只是相对较小比例的请求。你可以根据环境的不同以各种方式实现这一点,但我们建议您尽早启用这些功能,因为对客户体验和生产行为的额外洞察通常至关重要。
最后,通常只适用于非常大型组织的一个问题是如何扩展到非常大型的监控设置。虽然我们无法在这里详细介绍这个问题,但有三个主要问题需要考虑。第一是(1)如何运行多个监控实体而不重复警报、数据等。通常这与(2)找到合理划分要监控的实体的方法相关(这通常意味着近似等分监控目标)。最后,(3)我们必须监控监控器,以确保它们自身在运行。不同的监控产品在这些功能的支持程度上有所不同——例如,Prometheus 可以监控自身并去重警报。我们的经验表明,去重可能是这里潜在最重要的能力——如果您的系统无法执行这一功能,那么下一次严重的停机事件时,您可能会收到N × <您将收到的页面数>,其中N是您拥有的监控实例数量。这可能是一个相当大的数字。
关于构建和运行复杂监控设置的进一步建议可以从多种来源获取,但特别好的一个来源是《可观测工程》(Observability Engineering)由 Charity Majors 等人提供(O'Reilly,2022 年)。
监控中的公平性
在本章中,我们已经涵盖了监控服务健康、模型有效性和模型数据完整性的重要指标。然而,监控的话题还包括其他我们无法在本章中涵盖的考虑因素。例如,我们部署的模型几乎可以说具有现实世界的影响:决定谁获得贷款,谁获得工作,或者我们将做出什么购买决策。在这种决策越来越自动化的世界中,至关重要的是我们不要通过模型将系统性偏见和歧视编码化。公平性显然是一个关键话题,在第六章中有深入探讨。从监控的角度来看,我们的主要关注点是要求能够促进对模型决策的可见性,同时不促进不适当的可见性——更多细节请参见下一节。
监控中的隐私
公平性的一个特殊案例是监控中的隐私问题。几乎默认情况下,生产监控仪表板会显示输入的信息。因此,您立即可以理解,如果您的监控堆栈暴露了个人身份信息(PII)或其他敏感信息,这些信息将直接显示在仪表板上,并且对所有能够访问该仪表板的人可见,即使他们在生产环境级别上无法访问。这显然违反了隐私期望,即使不违反某些关注隐私的法律框架(尽管我们不是律师)。
尽管每种情况都有细微差别,但一般而言,我们建议如果您无法容忍 PII 泄露的风险,要么加强仪表板访问权限(以及收集信息的每个中间点),要么控制 PII 在第一个聚合点外流时的处理方式——例如,姓名、地址等完全匿名化,并且系统已进行了彻底的隐私审查。一般而言,控制对仪表板的访问更为简单易行,但确实不是一个强有力的控制点。您几乎肯定希望(需要!)在监控系统的第一个外流点 PII-proof 数据,甚至以分阶段的方式进行,不同类型的数据可以在不同的进入点向不同的系统剥离或处理——一种多阶段过滤方法。再次见第六章,这里更详尽地讨论了这一重要问题。
业务影响
我们未涉及的另一重要类别是将模型性能指标与模型对业务影响相关联。我们用统计指标如 AUC 或对数损失来衡量模型性能,但这些指标并未包括业务在指标恶化时所经历的具体影响。指标越具代表性,就越容易建立这种关联——请谨慎选择!²²
密集数据类型(图像、视频、文本文档、音频等)
我们不会涉及的另一个重要类别是密集数据类型的监控,有时也称为非结构化数据——尽管实际上这些格式是高度结构化的,这有些误导!随着机器学习越来越多地使用图像、视频等作为模型的输入,有必要为这些非表格数据类型的数据完整性进行监控。目前普遍没有可用的方法,我们呼吁行业积极努力支持这一点。一个日益流行的方法是监控数据本身的嵌入输出。机器学习从业者使用嵌入将这些项目(如电影、图像)映射到低维向量,其中相似的项目靠得更近。监控这些低维向量提供了监控密集数据类型的代理。
高级监控策略推荐
“服务”给出了许多关于如何开始监控的详细建议,但我们想在这里概述您整体监控策略的几个高级建议:
实际情况还是?
如果您的模型能够以接近实时的方式返回实际数据,监控模型/KPI 的性能是最佳信号,因为这最接近您对模型正在执行的概念。如果没有合理的实际数据,您将不得不从一组部分来源(包括基础设施元素和模型性能)构建发生情况的图像。查看本列表末尾的“一般建议”项,了解如何做到这一点的提示。
模型性能指标
一般而言,最好公开我们在“模型”中讨论的模型性能统计数据。这在很大程度上取决于您的本地监控情况、机器学习平台使用情况等,因此我们无法详细告诉您如何做到这一点,但至少您应该追踪它们。查看模型性能如何在纯服务水平上运行也有一定的价值。将其视为简单的请求-响应服务;如果模型无法进行预测/推荐,如果模型产生的预测置信度显著降低,以及如果任何算法回退路径被调用频率超出预期,这些都是需要了解的好事情(因此您应该监控它们)。
数据关注点(漂移)
定期跟踪输入数据的分布非常重要,因此计算分布的各种度量(如 PSI、KL 散度、Wasserstein 距离等),并在监控系统中呈现它们也是至关重要的。(您的输出数据的分布—即预测本身与现实的对比—在先前已经涵盖。)
数据质量关注点
如前章节讨论过的那样,跟踪丢失数据、类型不匹配、数据语料库大小及相关属性是至关重要的。训练部分的一些建议在服务环境中也非常相关,当然不包括训练本身的持续时间,而是关于数据可用性的一切。
服务或基础设施性能
作为第一次近似,即您需要一个起点,您可以将其视为任何服务系统。从网站可靠性工程中,有四个黄金信号可用于查看您服务系统的高级状态:延迟、流量、错误和饱和度。如果您为这些建立了良好的水平,例如通过实施服务级别目标的第八章,那么在基础设施中出现严重问题并且这些问题不反映在这些数据中将非常困难。在某种意义上,您正在寻找“良好吞吐量”:问题以合理的速率到达,并且以足够快且正确地方式回答以满足应用程序的需求。
警报和服务水平目标(SLO)
在本章中,我们没有特别多地谈到警报,因为一般来说,一旦您监视了某个度量标准并建立了某种阈值,警报(应该)是一个相当机械的成就。 但是,重要的是特别注意决定要警报哪些正确的度量标准——绝对不是每个度量标准——以及什么构成一个好的阈值。 否则,每个人都会被警报淹没,吸走宝贵的认知注意力,其中几乎所有的警报对客户体验基本上都是无关紧要的。 欲了解更多信息,请参阅实施服务级目标第八章。
尽管请求/响应系统的许多概念基础适用于 ML 服务系统,但训练不同,主要是批处理或流式处理导向。 在监视训练时您经常会遇到的一个潜在问题是如何警报模型构建延迟。 这里的主要挑战在于,由于模型构建持续时间可能是大量的分钟、小时,甚至是天数,因此在训练性能每次波动时警报并不合理;否则,您将会警报太多。
因此变得重要的量是赶上时间。 如果您的模型大约需要(比如)20 小时来构建,并且您每 24 小时需要一个新模型,那么如果您在构建过程中进行了 8 小时,然后停顿了 4 小时会发生什么? 消耗了 12 个墙钟小时,还有 12 个墙钟小时要走,如果您以前的速度恢复训练,您将在完成之前学习 12 个小时。 因此,您可能已经错过了截止日期,并且提前 12 小时进行预测将是一个重要的优化。 因此,保持追赶所需时间的概念,并在当前时间+追赶时间大于阈值时发出警报,将有助于迅速引起潜在的停滞情况的注意。
通用建议
一个重要的监控和/或调试技术是将预测(ID,值)记录到表格或某种易于搜索的格式中——如果您担心速度、头部阻塞等问题,那么采样也是一个完全可行的方法(尽管您将失去保证的可解释性)。 对于额外的分数,还可以有一个实际值的列,而不是预测值,这样您可以回填和比较。 在微服务和/或分布式跟踪的世界中,让预测的客户消费者也记录预测 ID 同样很有用,这样您就有了可连接事件链。 (有时在从开发到预测的过程中删除这种脚手架是可以接受的,但在两种情况下通常都很方便。)
服务期间的可解释性
在服务过程中的可解释性的黄金标准是所谓的个体推理级解释,换句话说,为什么会批准或拒绝这笔具体交易,或者分类器在这特定背景下做出那个具体决定的原因是什么?根据前述的“通用建议”段落,成功的表现实际上是能够将模型在特定预测请求时的具体状态与特定状态联系起来。在某些行业,如贷款领域,预测是否向个人发放贷款的模型可能使用可解释性来表明为何拒绝个人。通常通过原因代码向下游用户传达这一信息。
结论
希望本章为您监控机器学习系统从诞生到投产的过程提供了有用的概述。重申一下:主要挑战在于意识到你需要尽可能高的保真度来监控——无论是为了解释性、生产调试,还是简单地了解业务的运行情况。一旦你接受了这一点,你可以选择多种实施方法,并且本章各个“具体建议”节的整合对你应该是有用的。
¹ 你不能没有监控就实现可观察性,但可以反过来——可以进行粗略级别的检测,但没有任何深入检查的能力。然而,这并非行业发展的方向。
² 注意,这里使用的“标记”一词与监督学习中“标记数据”的用法不同。在这里,标记更像是与时间序列相关的任意键值对。
³ 当然,你不会免费获得这种详细级别的信息。产品开发人员必须编写代码来维护标记的度量并正确导出它们,你还需要一个能够进行分析和展示的系统。但这是值得的。
⁴ 发现 可能不太准确。更多细节,请参阅 Farhan Khan 撰写的 Digital Realty 博文“延迟成本”,或者 Christoph Luetke Schelhowe 等人于 2018 年撰写的 Zalando 研究“加载时间的重要性”。
⁵ CI/CD 这里不便详细描述,但基本上是指以持续、可靠的方式交付软件。此外,要明确的是,仅因为我们知道在某些情况下的有效做法,并不意味着整个行业都能保持一致性——只是我们有充分的基于证据的理由去相信它。
⁶ 实际上,我们经常看到,建模的关键绩效指标难以有效与业务关键绩效指标联系起来,团队最终可能会进行一系列旨在理解在线业务指标与离线建模指标之间耦合程度的 A/B 测试。
⁷ 我们看到行业趋势朝向 SHAP 作为模型可解释性的黄金标准;LIME 也很受欢迎。详见 Ashutosh Nayak 的《关于 SHAP 和 LIME 的理念》链接。
⁸ 在可靠性文献中,向前滚动 通常被认为是相当危险的,只有在确实没有安全干净的回滚可能性时才需要认真考虑。变化就是变化,即使回到模型的旧版本也代表了一些风险,但这样做可能会通过减少未经测试的 变更来最小化风险。
⁹ 请注意,有时如果您按下重新训练按钮,情况可能会变得更糟。例如,在盎格鲁撒克逊世界中,可能会在 12 月 24 日和 12 月 26 日之间进行训练,产生的模型可能完全不同。此外,新版本并不保证更好,因此,除非您的验证过程显著自动化,否则您不仅需要支付 CPU 成本,还需要支付员工时间成本。
¹⁰ Andrej Karpathy 在ML 背景下的软件开发生命周期(SDLC)的博客和 Google Cloud 关于持续 ML的页面在这方面也非常值得阅读。
¹¹ 例如,使用周对周来避免比较(例如)星期六和星期五,它们通常具有非常不同的购物模式。总体而言,意识到这些模式对监控工作是有用的。
¹² 第五章更详细地讨论了这个主题,但有必要在这里重复一些元素,并且强调稍微不同的一组元素。
¹³ 当然,这引发了一个可能性,即,鉴于绩效可能是多维度评估,可能没有明确的赢家。在这种情况下,有充分的理由采取两种相反的做法:(1) 更倾向于当前正在运行的模型,因为它变化最少且被充分理解,以及(2) 更倾向于新模型,因为基于更近期数据构建的东西可能更能经受住变化并且过渡也不那么痛苦。只有您能判断哪种对您的情况更好。
¹⁴ IaC 是将计算机基础设施管理为代码的行为——这意味着,在文件中使用语句、版本控制、发布流程等等。
¹⁵ 对于具有搜索引擎背景的人来说,举例来说,如果搜索特定术语,精确度表示检索到包含相关术语的文档数除以总检索到的文档数,而召回率表示检索到的相关文档数除以总相关文档数。因此,高精确度意味着您不会向用户提供不相关的文档,而高召回率意味着您几乎提供了每个相关文档。相反的情况,不幸的是,两者的定义都很容易直觉理解,并且很容易生成。
¹⁶ 在许多其他地方都有关于 RMSE 的更多细节;C3 AI 术语表页可能是一个很好的起点。
¹⁷ 这里的工程挑战在于如何将这些数据集合并,通常可以使用会话 ID、用户旅程令牌或类似的东西来完成。
¹⁸ 尽管 YarnIt 一直在尝试使用直邮功能来交付其产品,但反馈循环仍然受限于物理交付周期和产品评审时间。
¹⁹ 最佳模型指标的选择主要取决于模型的类型以及预测数据的分布。这通常应与训练/验证中使用的指标相匹配。
²⁰ 这加强了应用程序保持分布状态的论点,或者至少是桶计数器。其他提高鲁棒性的技术实际上是使用丢弃数据来改善鲁棒性(这实际上是避免过拟合的同义词)。
²¹ 请参阅《规模的尾部》,作者为杰弗里·迪恩和路易斯·安德烈·巴罗索。
²² 模型的商业影响最终是其存在的唯一原因。其他所有指标都次于模型构建的目的。因此,直接监控业务影响是监控的至高无上的目标,无论其难度如何。确定可用监控指标与业务价值之间的关联几乎可以肯定是组织从其 ML 生产努力中提取最大价值的最重要事情。
第十章:连续机器学习
到目前为止,我们对机器学习系统的讨论有时集中在这样一个观点上,即模型是我们训练然后部署的东西,几乎像这是一次性的事情。稍微深入一点的看法是要区分那些训练一次然后部署的模型与那些以更连续的方式训练的模型,我们将其称为连续机器学习系统。典型的连续机器学习系统以流式或周期性批处理的方式接收新数据,并使用这些数据触发训练更新的模型版本,然后将其推送到服务环境中。
显然,从 MLOps 的角度来看,训练一次与连续更新模型之间存在重大差异。转向连续机器学习增加了自动验证的风险。它引入了围绕反馈环路和模型对外部世界变化的反应可能导致的头痛。管理连续数据流、响应模型失败和数据损坏,甚至看似琐碎的任务,如引入新特性以供模型训练,都增加了系统的复杂性。
事实上,从表面上看,创建一个连续机器学习系统可能是个糟糕的主意。毕竟,在这样做的过程中,我们将系统暴露给一组因为真实外部世界潜在变化而无法预先知晓的变化,从而可能导致意外或不希望的系统行为。如果我们记得在机器学习中,数据就是代码,那么连续机器学习的理念就是接受相当于不断涌入的新代码,这些代码可以改变我们生产系统的行为。唯一做出这种改变的理由是当不断更新的系统的好处超过成本时。在许多情况下,好处确实是相当可观的,因为拥有一个能够学习并适应世界新趋势的系统可以实现复杂的业务和产品目标。
本章的目标是审视成本可能累积和问题可能出现的领域,以期在保留好处的同时尽可能降低连续机器学习系统的总体成本。这些观察包括以下几点:
-
外部世界事件可能影响我们的系统。
-
模型可能通过反馈环路影响其未来的训练数据。
-
时间效应可以出现在几个时间尺度上。
-
危机响应必须实时进行。
-
新的启动需要分阶段的逐步推进和稳定的基线。
-
模型必须进行管理,而不是仅仅交付。
这些观点每一个都总结了一系列潜在的复杂性,我们将在本章的大部分内容中深入探讨。当然,技术挑战并不是故事的终点。除了连续机器学习在我们的机器学习开发和部署过程中引入的实际和技术挑战之外,它还创造了组织上的机会和复杂性。
小贴士
持续改进的模型需要能够管理这种持续改进的组织。
我们需要框架来生成和追踪对模型改进的想法。我们需要一种评估我们模型各个版本在长时间内表现的方法,而不是仅仅关注我们推出一个模型以替代另一个模型的时间点。我们需要将建模视为一个长期持续的、产生价值的程序,它具有成本和风险,但也有巨大的潜在好处,并在本章末讨论这些需求对组织的影响。
持续 ML 系统的解剖学
在我们详细探讨持续 ML 系统的影响之前,让我们花一些时间浏览典型的 ML 生产堆栈,并看看与非持续设置相比,事物如何变化。在高层次上,持续 ML 系统定期从世界中获取数据流,用于更新模型,然后经过适当验证,推出更新版本的模型以服务新数据。
训练示例
在持续 ML 系统中,训练数据不再是一组固定的不可变数据,而是以稳定的数据流形式存在。这可能包括来自一组可能的纱线产品的推荐产品集合,以及生成这些推荐的查询。在高容量应用中,训练示例的数据流可能类似于消防栓,每秒从全球各地收集大量数据。需要进行重要的数据工程工作,以确保这些数据流被有效和可靠地处理。
训练标签
我们示例的训练标签也是以数据流形式来自世界。有趣的是,这个数据流的来源很可能与训练示例本身的数据流不同。例如,假设我们希望使用用户是否购买了某种纱线产品作为训练标签。我们知道在查询时用户展示了哪些产品,并且可以记录它们发送给用户的情况。然而,购买行为不能在查询时知晓——我们必须等待一段时间来看他们是否选择购买——这些信息可能来自完全不同于整体服务基础设施的购买处理系统。在其他情况下,当这些标签由人类专家提供时,我们可能会看到训练标签的延迟。
将示例与其正确标签结合起来需要不可避免的延迟,并且可能涉及一些相对复杂的基础设施,以便高效可靠地进行处理。实际上,这种结合是生产关键的。试想一下,如果由于故障而导致标签信息不可用,并且未标记的示例被发送到模型进行训练,会带来多大的麻烦¹。
过滤坏数据
每当我们允许我们的模型直接从世界上的行为中学习时,我们就面临着这样的风险:世界会发送一些我们希望我们的模型不必从中学习的行为。例如,垃圾邮件发送者或欺诈者可能会试图通过发出许多虚假查询而不购买,试图使我们的羊毛产品预测模型看起来比实际上受用户欢迎度低。或者一些不良行为者可能会试图通过反复输入侮辱性文本到聊天窗口来使我们有用的yarnit.ai聊天机器人学习粗鲁的行为。必须检测并处理这些攻击。不那么恶意但同样具有破坏力的坏数据形式可能由管道中断或错误引起。在所有情况下,重要的是在训练之前从管道中去除这些坏数据形式,以确保模型训练不受影响。
有效地删除垃圾或损坏数据是一项困难的任务。这需要自动化异常检测方法以及主要目的是检测坏数据的模型。通常会出现一种类似于坏行为者试图不适当影响模型和运维团队试图检测这些尝试并过滤它们的竞争。有效的组织通常专门设有全职团队来解决从连续 ML 管道中过滤坏数据的问题。
特征存储和数据管理
在典型的生产 ML 系统中,原始数据被转换为特征,除了对学习有用外,还更紧凑以便存储。许多生产系统使用特征存储来以这种方式存储数据,它本质上是一个增强型数据库,管理输入流,知道如何将原始数据转换为特征,高效存储它们,允许在项目之间共享,并支持模型训练和服务。² 对于高容量应用程序,通常需要从整体数据流中进行一定数量的抽样,以减少存储和处理成本。在许多情况下,这种抽样不会是均匀的。例如,我们可能希望保留所有(罕见的)正例,但仅保留(非常普遍的)负例的一部分,这意味着我们需要跟踪这些抽样偏差,并将其与适当的加权合并到训练中。
尽管特征化数据更紧凑且通常更有用,但几乎总是需要保留一定数量的日志原始数据。这对于开发新特征以及测试和验证特征提取和转换代码路径的正确性非常重要。
更新模型
在持续的机器学习系统中,通常更倾向于使用允许增量更新的训练方法。基于随机梯度下降(SGD)的训练方法可以在持续环境中无需任何修改地使用。(回想一下,SGD 构成了大多数深度学习训练平台的基础。)要在持续环境中使用 SGD,我们基本上只需闭上眼睛假装模型展示的数据流是随机顺序的。如果我们的数据流实际上是相对混乱的顺序,这完全没问题。
实际上,数据流通常具有基于时间的相关性,这并不真的是随机的。因此,我们需要担心这种假设破坏我们实际应用中的影响。如果我们的数据绝对最坏的非随机方式是,我们有一个上游的批处理作业,例如,所有的正例在一个批次中出现,然后所有的负例在另一个批次中出现。在这种数据上,SGD 方法会遭遇到严重问题,我们需要对数据进行中间混洗,以帮助使 SGD 在更安全、更随机的基础上进行。
一些流水线强制执行严格的策略,只对给定示例进行一次训练,按照它在数据流中时间上的顺序。这种策略从基础设施、模型分析和可重复性的角度来看,简化了许多事情,在数据充足时并没有真正的缺点。然而,在数据匮乏的应用程序中,可能需要多次访问单个示例才能收敛到一个好的模型,因此不总是能够按顺序仅访问每个示例一次。
推送更新的模型到服务端
在大多数持续的机器学习环境中,我们将模型的重大变更称为启动。重大变更可能包括模型架构的更改、某些特征的添加或移除、超参数设置(如学习率)的更改,或其他需要在将其作为生产模型启动之前完全重新评估模型性能的变更。小的变更,例如基于新进数据的内部模型权重的微小修改,则被称为更新。
随着模型的更新,我们会定期保存当前模型状态的检查点。这些检查点会被推送到服务端,但它们在灾难恢复中也非常重要。可以将将新的模型检查点推送到服务端看作是一个小型的自动化模型启动过程。如果我们每小时推送新的检查点四次,那么我们每天几乎会进行一百次小型的自动化模型启动。
在主要模型发布时可能出现的所有问题,在推送新检查点到服务时也可能出现。模型可能某种方式被损坏——也许是由于错误,也许是由于训练在坏数据上。模型文件本身可能有缺陷,也许是由于写入错误、硬件故障,甚至(是的,真的)宇宙射线。如果模型是深度学习模型,在最近的训练步骤中可能会“爆炸”,内部模型参数包含 NaN,或者我们可能遇到消失梯度问题,有效地停止进一步学习。如果我们的检查点和推送过程是自动化的,可能会存在系统中的错误。如果我们的检查点和推送过程不是自动化的,而是依赖于手动操作,那么这个系统可能还没有准备好以连续模式运行。
当然,如果我们不定期根据新数据推送模型更新,我们的系统可能会出现很多问题,因此重点并不是避免更新模型,而是指出在将模型检查点推送到服务之前进行模型检查的重要性。典型的策略使用分阶段验证。首先,我们使用可以在离线状态下执行而不影响生产系统的测试,例如在沙盒环境中加载检查点并对一组黄金集数据进行评分。第五章 中讨论的所有离线评估方法都适用于这里。然后,我们将新的检查点加载到一个 canary——一个我们仔细观察以查看其是否出现故障的单个实例中,并允许其提供少量流量,只要监控保持稳定,我们就会逐步增加更新版本提供的流量量,直到最终提供 100% 的数据为止。
连续 ML 系统的观察
现在您对连续 ML 管道与非连续兄弟的不同之处有了一些了解,我们可以深入探讨它们的独特特征和挑战。
外部世界的事件可能会影响我们的系统
当我们查看广泛使用的类或对象的 API,比如来自 C++ 标准模板库的 vector 或 Python 的 dictionary,它们通常不包括一条醒目的文档行,例如:“警告:在世界杯期间行为未定义。” 谢天谢地它们没有,也不必有。
相比之下,连续 ML 系统有——或者应该有——确切的警告形式。它可能会写成这样:
警告
生产中模型输入分布的任何变化可能会导致系统行为异常或不可预测,因为大多数 ML 模型的理论保证实际上仅适用于 IID 设置。³
这些变化的来源可能非常多样化和意外。体育赛事、选举夜、自然灾害、夏令时调整、恶劣天气、良好天气、交通事故、网络故障、大流行病、新产品发布——所有这些都是我们数据流变化的潜在来源,因此也会影响我们的系统行为。在所有情况下,我们可能几乎没有关于事件本身的警告,尽管第九章中描述的监控策略可能帮助您考虑及时警报所需的内容。
外部事件可能引发哪些情况?以下是一个例子。对于我们的毛线店来说,让我们想象一下,一位重要政治人物在寒冷的天气里穿着手工编织的棕色羊毛手套出现在全国电视上的影响。突然间,“棕色羊毛”搜索和购买量激增。稍作延迟后,模型根据这些新的搜索和购买数据进行更新,并学会为棕色羊毛产品预测更高的价值。我们的模型使用一种 SGD 形式进行训练,导致它变得过于自信,并为这些产品制定极高的评分。由于突然的高评分,这些产品几乎展示给了所有用户,现有库存迅速售罄。一旦所有库存售罄,就不再进行购买,但几乎所有搜索仍显示棕色羊毛产品,因为它们在我们的模型中获得了高分。
下一批数据显示,没有用户购买任何产品,而模型过度补偿,但由于“棕色羊毛”产品已经在如此广泛的查询和用户中展示,模型现在学会为几乎所有产品给出较低的评分,导致所有用户查询的结果为空或垃圾结果。这加强了没有用户购买任何东西的趋势,系统陷入螺旋下降状态,直到我们的 MLOps 团队识别出问题,将模型回滚到之前良好运行的版本,并在重新启用训练之前从我们的训练数据存储中过滤异常数据。
显然,这个例子可以通过多个层次的潜在修复和监控来解决,但它说明了系统动态可能产生的难以预料的后果。
知道各种世界事件可能导致意外系统行为的一个微妙危险是,我们可能会过快地解释观察到的指标变化或监控。知道今天阿根廷和巴西要进行一场重要的足球比赛可能会让我们假设这是观察到的系统不稳定的根本原因,并错过排除管道错误或其他系统错误的可能性。
什么样的持续机器学习系统能够完全抵御分布变化的影响?基本上,我们需要一种方法来自适应地加权训练数据,使其分布不会随着世界变化而改变。一种做法是创建一个模型来进行倾向评分,显示在给定时间内某个示例在我们的训练数据中出现的可能性。然后,我们需要按照这些倾向评分的倒数来加权我们的训练数据,以便罕见的示例被赋予更大的权重。当世界事件导致某些示例突然比过去更可能发生时,倾向评分需要被迅速更新以相应地减小其权重。最重要的是,我们需要确保所有示例的倾向评分非零,以避免在进行倒数倾向评分时出现除以零的问题。
我们需要避免倾向评分过小,以免倒数倾向加权由于少数拥有巨大权重的示例而被放大。这可以通过限制权重来实现,但我们还需要这些评分在统计上是无偏的,而限制权重会引起偏差。相反,我们可以使用广泛的随机化来确保没有示例的被包括概率太低,但这可能会意味着向用户暴露随机或无关的数据,或者使我们的模型建议可能不希望的随机行动。总之,在理论上实现这样的设置是可能的,但在实践中极其困难。
提示
现实情况是,我们可能需要找到管理由于分布变化而导致的不稳定性的方法,而不是完全解决这些问题。
模型可以影响它们自己的训练数据
对于我们的持续机器学习系统,最重要的问题之一是模型和其训练数据之间是否存在反馈循环。显然,所有训练过的模型都受到用于训练的数据流的影响,但某些模型也反过来影响收集到的数据。
要帮助理解这些问题,考虑一下一些模型系统对重新训练收集的数据流没有影响。天气预测模型就是一个很好的例子。无论气象站想让我们相信什么,预测明天将是个晴天并不会真正影响大气条件。这类系统在这种意义上是干净的,因为它们没有反馈循环,我们可以对模型进行更改而不必担心我们可能会影响到明天的实际降雨概率。
其他模型确实会影响它们的训练数据的收集,特别是当这些模型向用户提供建议或决定影响它们可以学习的内容时。这些创建了隐式反馈循环,就像任何听过麦克风尖叫反馈的人知道的那样,反馈循环可能会产生意想不到的有害效果。
作为一个简单的例子,一些依赖于反馈循环来了解新趋势的系统,如果从未有机制允许它们首先尝试新事物,可能会完全错过它们。我们可以通过尝试让孩子第一次尝试新食物的经验来思考这种效应。作为一个更具体的例子,考虑一个模型,帮助推荐给用户展示羊毛产品;该模型可能会根据用户对这些选择产品的反应进行训练,例如点击、页面浏览或购买。模型将收到关于展示给用户的产品的反馈,但不会收到关于未被选择的产品的反馈。⁴ 很容易想象,例如有一种新的羊毛产品,如有机羊驼毛的新颜色,可能是用户非常喜欢购买的东西,但模型没有之前的数据。在这种情况下,模型可能会继续推荐以前的非有机产品,并对其遗漏视而不见。
不是发现新事物是坏事,但更糟糕的行为可能会发生。想象一下,有一个股市预测模型负责根据市场数据选择买入和卖出股票。如果一个外部实体错误地进行了大规模的卖出,模型可能会观察到这一点,并预测市场即将下跌,建议大多数持有也应该卖出。如果这次卖出足够大,将会导致市场下跌,这可能会使模型更加积极地想要卖出。有趣的是,其他模型——可能来自完全不同的组织——也可能在市场上看到这个信号,并决定进行卖出操作,从而形成一个反馈循环,导致整体市场崩盘。
股票预测场景虽然是一个极端案例,但事实上确实发生过。⁵ 然而,我们并不需要存在在竞争模型的广泛市场中才能体验到这些影响。例如,想象一下,在我们的yarnit.ai商店中,有一个模型负责向用户推荐产品,另一个模型负责确定何时给用户提供折扣或优惠券。如果产品推荐依赖于购买行为作为训练的信号,而折扣的存在影响购买行为,那么就存在一个反馈循环将这两个模型联系起来,而且对一个模型的更改或更新可能会影响另一个模型。
反馈回路是另一种分布变化形式,我们描述的倾向加权方法可能会有所帮助,尽管要完全正确地实现它们并不容易。通过记录模型版本信息以及其他训练数据,将这些信息作为模型的特征之一,可以在一定程度上减少反馈回路的影响。这至少让我们的模型有机会区分观察到的数据突然变化是由于现实世界的变化——比如假期结束,而在一月初没有人想购买羊毛(或者基本上任何东西)——还是模型学习状态的变化。
时间效应可以在多个时间尺度上出现
当我们关心数据随时间变化的方式时,我们创建连续的机器学习系统。其中一些变化对基础产品需求至关重要,比如引入新型合成羊毛或创建适用于家庭使用的自动编织机。尽快整合关于这些新趋势的数据对我们 yarnit.ai 商店非常重要。
其他时间效应是周期性的,周期至少会发生在三个主要时间尺度上:
季节性
许多连续的机器学习系统会经历深刻的季节性影响。对于像 yarnit.ai 这样的在线商务网站,随着冬季假期的临近,购买行为可能会出现显著的变化和增加,随后在一月初会突然下降。温暖的天气月份和凉爽的天气月份可能会有非常不同的趋势——甚至可能因地理区域或南半球与北半球的差异而显著变化。处理季节性影响的最有效方式是确保我们的模型训练了过去一整年的数据(如果我们有幸拥有),并且时间信息作为训练数据的特征信号包含在内。
每周
数据不仅会随季节变化,还会根据周周期循环,基于每周的具体日期。对某些情况来说,周末的使用量可能显著增加,比如我们 yarnit.ai 商店中面向爱好者的部分,或者在面向企业间销售的部分则可能显著减少。地域因素在这里起着重要作用,因为周末的情况可能因国家而异,而时区影响也很重要,例如在东京可能是星期一,而在旧金山仍然是星期天。
每天
当我们看到基于一天中不同时间的日常效应时,事情就开始变得复杂了。乍一看,显而易见的是,许多系统在一天中的不同时间可能会体验到不同的数据——午夜的行为可能与清晨或工作日的行为不同。显然地,地域因素在这里至关重要,因为时区效应。
日常周期的微妙之处在于,当我们考虑到大多数连续机器学习系统实际上是在现实之后持续运行时,就会出现问题,这是因为管道和数据流等待训练标签(如点击或购买行为可能需要一些时间才能确定)的固有延迟,以及过滤坏数据、更新模型、验证检查点,并将检查点推送到服务端并完全升级。事实上,这些延迟可能累计达到 6 甚至 12 小时。因此,我们的模型可能与现实相差甚远,服务的模型版本认为现在是午夜,实际上却是工作日的中心。
幸运的是,通过记录每天的时间信息以及其他训练信号,并将它们用作我们模型的输入,可以相对容易地修复这些问题。但这也突显了一个重要问题,即我们在服务中加载的模型版本可能已经过时,或者在实际情况下得到了错误信息。
紧急响应必须实时完成
到了这一点,应该清楚了,虽然连续机器学习系统可以提供巨大的价值,但它们也具有广泛的系统级脆弱性。可以说,连续机器学习系统继承了所有大型复杂软件系统的生产脆弱性,这些系统本身就存在大量的可靠性问题,并且还添加了一整套可能导致未定义或不可靠行为的额外问题。在大多数情况下,我们无法依赖于理论保证或正确性证明。
当连续机器学习系统出现此类问题时,不仅需要修复,而且需要实时修复(或减轻)。这其中有几个原因。首先,我们的模型可能是使命关键的,如果生产中出现问题,可能会影响我们组织的分钟到分钟的服务能力。其次,我们的模型可能与自身存在反馈循环,这意味着如果我们不及时解决问题,输入数据流也可能被破坏,需要小心修复。第三,我们的模型可能是更大生态系统的一部分,很难重置到已知状态。当我们的模型与其他模型存在反馈循环,或者模型的糟糕预测造成长期伤害并且难以撤销时,这种情况就会发生,比如原本有帮助的yarnit.ai聊天机器人突然对用户发出粗鲁的咒骂。
实时危机响应首先需要快速检测问题,这意味着从组织的角度来看,确定是否准备好进行连续 ML 的一个良好试金石是检查我们的监控和警报策略的彻底性和及时性。由于管道延迟和系统逐渐在新数据上学习的缓慢变化,数据缺陷产生下游有害影响的全面效果可能需要一些时间。这使得拥有简单的金丝雀指标特别重要,这些指标在输入分布发生变化时发出警报,而不是等待模型输出发生变化。
仅当有责任在警报触发时响应的人员支持时,监控或调整策略才会在实时中有所帮助。运作良好的 MLOps 组织设定了关于警报必须多快响应的具体服务水平协议,并设置了像电话值班轮换这样的机制,以确保警报在正确的时间被正确的人看到。拥有一个在多个时区拥有队友的全球团队,如果你处于这种幸运的位置,可以极大地帮助避免人们因警报在凌晨 3 点而被吵醒。
一旦收到警报,我们需要有一个良好记录的应对手册,任何 MLOps 团队成员都可以执行,并且需要一个进一步行动的升级路径。
提示
对于连续 ML 系统,我们有一组针对任何给定危机的基本立即响应措施。这些是停止训练,回退,回滚,删除坏数据和通过滚动。
并非每一次危机都需要所有这些步骤,选择哪种响应最合适取决于问题的严重性以及我们能够诊断和治愈根本原因的速度。让我们看看连续 ML 系统的每个基本危机响应步骤,然后讨论选择响应策略的因素。
停止训练
有人说,第一条挖洞的法则是这样的:当你发现自己在一个洞里时,停止挖掘。类似地,当我们发现我们的数据流以某种方式被损坏,也许是由于一个糟糕的模型,或者一个停机,或者系统中某处的代码级错误时,一个有用的反应可以是停止模型训练,并停止推送任何新的模型版本到服务中。这是一个短期的响应,至少有助于确保问题不会在我们决定采取缓解或修复措施之前变得更糟。确保 MLOps 团队有一种简单的方法来停止他们负责的任何模型的训练是有意义的。自动化系统在这里是有帮助的,但当然需要足够的警报,以免发现模型已经在三周前静默停止训练了。
提示
总是有用的有一个类似于大红按钮的东西,可以在发现紧急情况时手动停止训练。
回退
在持续的机器学习系统中,有一个备用策略非常重要,可以用来替代我们的生产模型,提供可接受的(即使是非最佳的)结果。这可以是一个远比较不连续训练的更简单的模型,或者是一个包含最常见响应的查找表,甚至只是一个返回所有查询的中位数预测的小函数。关键是,如果我们的持续机器学习系统遇到突然的大规模故障——我们可能描述为“失控状态”——我们有一个超可靠的方法可以作为临时替代品,而不至于使整个产品变得完全无法使用。备用策略通常在整体性能上比我们的主要模型不太可靠(否则,我们首先不会使用机器学习模型),因此备用策略非常适合作为短期响应,允许在系统的其他部分采取紧急响应。
回滚
如果我们的持续机器学习系统当前处于危机状态,将系统恢复到危机之前的状态并查看一切是否正常是有意义的。我们危机的根本原因可能来自两个基本领域:糟糕的代码或糟糕的数据。
如果我们相信我们问题的根本原因是糟糕的代码,由于最近引入的错误,那么将我们的生产二进制文件回滚到以前已知的良好版本可能会在短期内修复问题。当然,任何回滚到以前的生产二进制文件都必须在逐步增加的阶段进行,以防存在使旧版本二进制文件不再可用的新兼容性问题或其他缺陷。无论如何,在需要时保持一组完全编译的先前二进制文件非常重要,以便可以快速有效地进行回滚。
如果我们认为问题的根本原因是糟糕的数据导致模型训练自身进入糟糕状态,那么将模型版本回滚到以前已知的良好版本是有意义的。同样,保持我们训练的生产模型的检查点非常重要,这样我们就有一组以前的版本可以选择。例如,想象一下,美国的黑色星期五销售导致用户向我们的yarnit.ai商店发出大量购买请求,使系统的欺诈检测部分开始将所有购买标记为无效,使我们的模型看起来所有产品都极不可能被购买。回滚到一个在黑色星期五日期一周之前检查点的模型版本,至少可以让模型提供合理的预测,同时修复更大系统的其余部分。
删除糟糕的数据
当我们的系统中有不良数据时,我们需要一种简单的方法将其移除,以免模型受其污染。在前面的例子中,我们希望移除由于错误的欺诈检测系统而受损的数据。否则,当我们重新启用训练继续进行时,这些数据将被我们回滚的模型遇到,因为它在训练数据中向前移动,这些坏数据会再次对其造成污染。每当我们认为数据本身极不典型且不太可能为模型提供有用的新信息,并且坏数据的根本原因是临时的,可能是由于外部世界事件或系统中的错误而导致的时候,移除坏数据是一个有用的策略。
穿越
如果我们已经停止了连续 ML 系统的训练,在某些时候我们需要祈祷并启用它来恢复训练。通常情况下,我们会在清除了不良数据并确保修复了所有错误后进行此操作。然而,如果由于外部事件检测到了危机,有时候最好的响应策略就是祈祷并穿越,让模型在非典型数据上进行训练,然后在事件结束时自行恢复。事实上,遗憾的是,这个世界很少有没有政治事件、重大体育赛事或其他重大新闻灾难发生的日子,确保我们的模型充分接触来自不同全球地区的这类非典型数据可能是确保模型总体上健壮性的重要方式之一。
选择响应策略
我们如何选择停止、回滚和移除哪些事件,以及穿越哪些事件?要回答这个问题,我们需要观察我们的模型对类似历史事件的响应,这在我们按顺序训练模型的历史数据时最容易实现。另一个重要问题是,我们目前看到的指示危机的度量是否是由于模型错误或世界处于非典型状态造成的。换句话说,是我们的模型出了问题,还是它只是在目前被要求处理更困难的请求?判断这一点的一种方法是观察黄金数据集上的离线指标,出于这个原因,应该经常重新计算我们模型的黄金数据集结果。如果模型确实出现问题,黄金数据集的结果可能会显示性能急剧下降,这时穿越可能不是正确的方法。
组织考虑事项
当当前正发生危机时,这可能是学习新技能、在团队内确定角色或决定如何实施各种响应和缓解策略的困难时期。现实世界的消防员经常一起训练,完善最佳实践,并确保他们需要响应警报的所有基础设施都处于良好状态,并随时准备投入行动。同样,我们不知道我们的持续机器学习系统何时需要危机响应,但我们可以有信心地说,这将会发生,并且我们需要做好充分准备。创建有效的危机响应团队是创建和维护持续机器学习系统成本的一部分,在我们朝这个方向迈进时必须加以考虑。这在“持续组织”中详细讨论。
新推出需要分阶段增长和稳定基线。
当我们在持续的机器学习系统中运行模型一段时间后,最终会希望推出新版本的模型,以在各个方面实现改进。也许我们想要使用一个更大的模型版本来提高质量,现在有能力处理它,或者可能模型开发者创建了几个新特性,显著提高了预测性能,或者我们发现了一种更高效的模型架构,以重要方式降低了服务成本。在这些情况下,我们需要明确地推出新版本的模型来替换旧版本。
推出新模型往往涉及一定程度的不确定性,这是因为离线测试和验证的限制。正如我们在第十一章中描述的那样,离线测试和验证可以为我们提供关于新模型版本在生产环境中表现良好的有用指导,但通常无法给出完整的画面。当我们的持续机器学习模型是反馈环路的一部分时,情况尤其如此,因为我们先前训练的数据很可能是由先前的模型版本选择的,而离线数据的评估仅限于基于先前模型做出的行动或建议的数据。我们可以将这种情况想象成是学员驾驶员的情况,他们首先通过坐在副驾驶座位上评估,被要求对教练驾驶汽车的行为给出意见。仅仅因为他们对教练的行动完全同意,并不意味着他们在首次有机会自己驾驶汽车时不会做出一些不良决策。
因此,新模型的推出需要在生产环境中进行一定量的 测试,作为最终验证的形式。我们需要让新模型展示它有能力成为驾驶座位上的模型。但这并不意味着我们只是交给它钥匙,然后期望一切都完美无缺。相反,我们通常会使用分阶段逐步增加的策略,首先允许模型仅服务整体数据的一小部分,并且只有在观察到长期良好表现后才增加这一部分。这种策略通常被称为 A/B 测试:我们测试我们的新模型 A 与旧模型 B 的性能,以类似控制科学实验的格式,帮助验证新模型在我们的最终业务指标上是否表现得合适(这可能与离线评估指标如准确性不同)。
模型发布和理想的 A/B 测试之间的区别在于,在科学实验中,A 和 B 是独立的,彼此不会互相影响。例如,如果我们在科学环境中进行实验,以确定棉质毛衣(A)是否像天然羊毛毛衣(B)一样保暖,那么穿羊毛毛衣的人不太可能使穿棉毛衣的人报告感觉更暖或更冷。然而,如果穿羊毛毛衣的人感到非常温暖和愉快,以至于他们去为穿棉毛衣的人煮茶和热汤,那肯定会破坏我们的实验。
对于比较连续 ML 模型的 A/B 实验,事实证明当我们的模型处于反馈循环的一部分时,A 和 B 可能会互相影响。例如,想象一下,我们的新模型 A 在向 yarnit.ai 用户推荐有机羊毛产品方面做得很好,而我们之前的模型 B 从未这样做过。最初的 A/B 实验可能会显示 A 模型在这方面要好得多,但随着 A 生成的训练数据包括了许多有机羊毛的推荐和购买,B 模型(也在持续更新)可能也会学习到这些产品受用户喜欢,并开始推荐它们,使得这两个模型随着时间的推移看起来变得相似。如果这些影响更加分散,那么很难说 A 的好处是否消失了,因为它实际上从未比 B 更好,或者是因为 B 本身已经改进。
我们可以尝试通过限制 A 和 B 只在它们自己服务的数据上进行训练来解决这个问题。当每个模型提供相同数量的数据时,比如总流量的 50%,这种策略可以很好地工作,但在其他情况下可能会导致比较出现缺陷。如果 A 在早期看起来不好,是因为模型不好,还是因为它只有 1% 的训练数据,而 B 有 99%?
另一种策略是尝试创建某种稳定的基线,这可以帮助作为比较的参考点,以便我们可以弄清楚 A 和 B 之间的比较是因为 A 变得更糟还是因为 B 变得更好,或者确实,两者都在同步变得显著更糟。稳定的基线是一个不受 A 或 B 影响的模型 C,并且允许提供一定量的流量,以便我们可以将这些结果用作比较的依据。基本思想是然后观察(A-C)对(B-C)而不是直接对比 A 对 B,这将使我们能够更清楚地看到任何变化。
创建稳定基线的四种一般策略具有不同的优缺点:
作为基准的回退策略
当我们有一个合理的回退策略,不涉及持续的重新训练时,这不仅对危机响应有用,还作为一个潜在的独立数据点。如果回退策略的质量与主要生产模型的差异不太大,则这可以很好地工作。然而,如果差异非常大,统计噪声可能会压倒使用此作为参考点的 A 和 B 之间的任何比较。
停止训练器
如果我们有我们的生产模型 B 的一个副本并停止对其进行训练,那么根据定义,它将不会受到 A 或 B 的任何未来行为的影响。如果我们允许其提供少量流量服务,则可以提供一个有用的稳定基线 C,但“停止训练器”模型的整体性能会随时间缓慢下降。进行独立实验以观察可以预期的退化程度以及该策略是否有用是有益的。
延迟训练器
如果我们预计整体启动过程需要,比如说,两周时间,那么一个合理的选择可以是运行我们的生产模型的一个副本,设置为持续更新,但延迟两周。这相比于停止训练器有一个优势,即相对性能不太可能下降,但缺点是在运行时间等于其延迟的长度之后,它将开始受到 A 和 B 的影响,并且失去其效用。因此,两周延迟训练器模型将在两周后变得无用。
并行宇宙模型
一个保持与 A 和 B 严格独立但没有有限使用寿命的方法是并行宇宙模型,该模型允许为总体数据的一小部分提供服务,并且仅在其自身提供的数据上学习。A 和 B 不在这些数据上进行训练,从而使这些数据宇宙完全分离。
为什么这很有用?想象一下,将 B 投入生产的行为会以某种方式改变整体生态系统。我们可以想象股票预测市场模型是这样运作的——也许在某些特殊情况下推动整体市场的上涨或下跌。在这种情况下,A 和 B 都可能大幅增加或减少其中位预测,但 A-B 的差异可能很小且看似稳定。有了第三个观点 C,我们能够检测到模型之间的变化是由于 A 和 B 本身的差异,还是由于更广泛的影响。
平行宇宙模型在建立后通常需要时间来稳定,因为训练数据量有限且整体分布会发生变化。但经过这个初始期后,它们可以提供一个有用的独立评估点——当比较评估指标时,要考虑统计噪声的限制。
模型必须进行管理,而不是简单地投入使用。
总体而言,模型的发布需要特别注意,因为在这些时候,我们的系统最容易遇到危机。如果我们在 A 和 B 均大约占一半流量的模型发布过程中,我们刚刚增加了潜在的错误来源,并且需要处理任何可能出现的紧急情况的工作量翻倍。像危机响应一样,模型的发布在依赖于沟通良好、经过良好实践的流程时效果最佳。
有些产品就像砖墙:它们需要大量的规划和努力来完成,但一旦完成,基本上就完成了,只需要偶尔维护。默认状态是它们正常工作。连续的机器学习系统则处于相反的极端,并且需要每天关注。连续 ML 模型出现的问题可能难以以完全或永久的方式解决。例如,如果我们整体产品的一个问题是希望更好地向温暖气候的用户推荐羊毛产品,这可能需要采用多种方法,而这些方法的效用可能会随着季节和年份的变化而变化。
以这种方式,持续机器学习系统需要定期管理。有效管理模型需要每日访问报告模型预测性能的指标。这可以通过仪表板和相关工具完成,使模型管理员能够了解今天的情况、趋势可能如何变化以及可能出现的问题所在。任何仪表板的效用都取决于对其付出的关注程度,因此需要明确的负责人定期花时间关注。一个有用的比喻是,每天和我们的模型喝一杯咖啡是有益的,通过使用仪表板了解今天它的表现。就像人员经理定期进行绩效评估一样,模型所有者应定期向组织高层提交有关模型性能的报告,以分享知识和可见性。
当我们从我们的模型中学到一些有用的东西时,一个强大的最佳实践是以简短的写作形式记录下来。这样的写作,可能只是几段文字,附带有仪表板截图或类似的支持证据,可以帮助积累组织知识,当观察伴随有关于模型行为意义的简短总结时效果最佳。这样的写作历史上被证明非常有用,不仅有助于指导未来的模型发展,还有助于理解和调试危机中出现的意外行为。
最后,在我们遇到危机时,从组织角度来看,通过创建事后分析文档尽可能多地从经验中吸取教训是非常重要的。这些文档详细描述了事件的发生过程,问题的诊断方法,造成的损害,应用的缓解策略以及其成功程度,最后提出了改进建议,无论是减少问题再次发生的频率还是增强未来更有效的应对能力。在短期内,创建这些事后分析文档有助于识别修复措施,而长期来看,它们作为组织知识和经验的库存同样有用,随时可供参考。
持续的组织
到了这一点,应该清楚的是,一个致力于持续机器学习系统的组织正在承担长期的责任。像小狗一样,持续机器学习系统需要日常关注、照料、喂养和训练。为了确保我们的组织能够有效地处理持续机器学习系统的管理责任,需要建立多种有效的结构。
确定评估策略是一项关键的领导责任。评估策略使我们能够评估我们模型的健康和质量,无论是从长期的业务目标还是从短期决策来看,比如是否将某个特定特征包含或排除在模型之外。如第九章所述,把这个问题简化为确定度量指标可能是诱人的,但是一个给定的度量指标(如收入、点击、精度、召回率甚至延迟)如果没有参照点、基准或分布,就毫无意义。在持续的机器学习环境中做决策常常需要进行某种反事实推理,思考反馈环路的影响,或是应对噪声和不确定性,这些都使有效的决策变得具有挑战性。通过制定清晰定义并记录评估标准和流程,我们可以在一定程度上帮助减少这些挑战的难度。
在组织层面,做出投资决策同样具有挑战性。我们应该投入多少资源来创建更大、潜力更强的模型,这种投资是否能够通过改善产品结果来回本,相对于机会成本来说?我们如何在投资模型质量改进和机器学习系统级可靠性之间进行权衡?在组织层面,如何有效地引导有限的人力专家的时间和精力,以最大程度地使整体使命受益?这些都是根本性难题,其中一部分原因是我们组织的不同部分可能具有不同甚至是不兼容的优先事项。
我们有两种主要策略来处理这些问题。第一种是确保我们有足够广泛的组织领导能够有效权衡改善模型监控和危机响应处理的不同需求,与提高模型准确性的需求。确保每个组织部分的经验教训能够在整个组织内充分传播,可以帮助不同部门理解彼此的挑战和痛点。最好的方式是定期分享事故事后总结,并通过主动的“事前分析”讨论识别潜在的弱点和故障模式来实现。第二种策略是投资于基础设施,确保警报和其他警告在生产者和消费者的完整链条中得到有效传播。这可能需要组织的认真承诺,但长期来看可以在减少复杂系统内部验证的人力负担方面收益。
在组织上,理解持续机器学习系统依赖于持续的数据流来确定系统行为,显然表明数据管道本身需要严肃、专注的监督和管理。除了简单地确保数据流畅和管道功能良好外,关键问题还包括应收集哪些类型的数据、数据存储多长时间以及我们的数据管道应如何与上游生产者和下游消费者进行交互,这些都是组织领导者必须解决的关键战略问题。隐私、伦理、数据包容性和公平性等更深层次的问题同样起着重要作用,并且必须成为整体组织战略的一部分。
正如我们所指出的,机器学习系统的启动过程及进一步改进在持续机器学习设置中必然需要一个分阶段的逐步启动过程。领导层的关键角色是对每个阶段的结果进行监督和评审,并作出是否进入下一个阶段的批准决定,或者确定我们尚未准备好继续前进,甚至需要降低规模,如果事情的发展不如预期。这些决策需要高层监督,因为后果可能影响深远,并且可能与多个生产者或消费者系统发生交互,特别是在存在反馈循环或其他复杂的系统对系统交互点时。在进行各个启动阶段的广泛影响评估并确保稳定之前,必须确立并严格遵循一套流程,这对于长期有效的持续机器学习组织至关重要。
最后,当事件或危机时刻发生时,我们需要建立一个有效的响应流程。对于持续的机器学习系统,我们在处理事件时有优势和劣势。优势在于,我们几乎总是有一个稍微旧一些的当前模型版本,可以在我们检查出错原因的同时回滚到服务中,这在我们需要迅速应对当前模型出现严重问题时非常有帮助。劣势在于整个系统不断演化,难以隔离根本原因或变更中的断裂点。我们模型的变更可能是由系统中的其他并发变更(如添加新数据或使用模型的新集成)驱动或需要的。在这种情况下,要精确地排查问题变得更加困难,尤其是在持续的机器学习环境中。关于这一点的具体例子,请参阅第十一章。
运行连续 ML 系统的组织最重要的前期工作是预先协商停机的后果和处理方式。这不仅仅是提前确定谁将担任哪些角色的问题 — 虽然这也是必须做的。ML 生产工程师不应在处理中确定解决特定事件的紧急程度,模型开发者也不应在停机事件发生时猜测成本和后果。每个人都应清楚自己的角色、权限以及向他人升级决策的途径,因为这些应该事先制定好。但是在可能的情况下,整个组织还应就一些一般的服务可靠性标准达成共识。例如:
-
即使我们通常希望其基于不超过大约 1 小时的数据,此模型可以达到 12 小时的老化而没有严重后果。
-
如果此模型的质量指标低于已知特定阈值,批准的回退方法是回滚到旧模型。
-
如果模型低于预定的额外阈值,唤醒以下业务领导是适当的…
依此类推。总体思路是预先确定各种类型的停机参数,以便事件响应者能够最大程度地采取行动,并尽量减少对如何应对的决策延迟。许多组织通常不会在事先做出这些决策,直到经历了一些停机事件后,才会认为预先决定在遇到严重 ML 问题时应采取何种措施是非常合理的。
重新思考非连续 ML 系统
本章节我们讨论了连续 ML 系统的一系列问题。除了提供希望能为面对困难时创建健壮可靠系统的有用缓解策略之外,我们还想提出一个更广泛的建议:
所有生产 ML 系统都应被视为连续 ML 系统。
我们应该把每个作为生产系统关键部分的模型都视为连续训练的模型,即使它实际上并非每分钟、每小时,甚至每天或每周都会基于新数据进行更新。
为什么我们要做出这样的建议?毕竟,连续 ML 系统充满了复杂性和故障向量。一个原因是,如果我们将连续 ML 系统的标准和最佳实践应用于所有生产级 ML 系统,我们将确保我们的技术基础设施、模型开发以及 MLOps 或危机响应团队都能够应对挑战。如果我们假设我们的 ML 系统是一个连续 ML 系统并相应地进行规划,我们将处于一个良好的位置。
这是否过度?如果一个模型只被训练一次,那么应用连续机器学习的标准和最佳实践可能会被视为资源浪费。但实际上,没有任何生产模型只会被训练一次。根据我们的经验,我们发现每个生产级机器学习模型最终都会重新训练或推出新版本——可能在几个月后,或明年,随着新数据的出现或模型的发展。这可以通过不定期的方式进行,每隔几周或几个月一次,但这种不规律的方法很可能导致失败和疏忽。我们强烈建议,有效的 MLOps 团队确保他们的模型按照规定的时间表进行更新,无论是每天、每周还是每月,以便验证程序和检查表能够成为组织文化的一部分。从这个角度来看,连续机器学习系统的建议适用于每一个机器学习系统。
结论
在本章中,我们提出了一套程序和实践方法,可作为组织管理连续机器学习系统时的基础手册。这些系统提供了广泛的好处,能够使模型随时间适应新数据,并允许响应式学习系统与用户、市场、环境和世界进行交互。
很明显,任何既具有高影响力又容易受影响的系统都需要进行深入监督。根据我们的经验,在这些情况下,监督需求远远超出个人能力范围,不能依赖直觉或即兴处理。任何管理连续机器学习系统的组织都需要把这视为一项持续的高优先级任务,特别是在系统发布或重大更新时,但也需要进行持续的监控,并制定应急预案,以便对新出现的危机能够快速响应。
我们总结了关于连续机器学习系统的六个基本观点,希望您能从中受益:
-
外部世界事件可能会影响我们的系统。
-
模型可能通过反馈循环影响其未来的训练数据。
-
时间效应可能在多个时间尺度上出现。
-
危机响应必须实时进行。
-
新发布需要分阶段的推进和稳定的基线。
-
模型必须进行管理而非简单部署。
最后,我们认为所有机器学习系统最好都被视为连续机器学习系统,因为所有模型最终都会重新训练,建立强大的标准将使任何组织长期受益。
¹ 详见“5. 广告点击预测:数据库与现实”,这里有一个相关案例。
² 详见“特征存储”以深入了解特征存储。
³ 在统计学和机器学习术语中,IID 假设是数据是从相同分布独立抽取的,也就是说,我们的测试集和训练集以相同的方式随机抽取自同一来源。这在第五章中有更详细的介绍。
⁴ 熟悉机器学习不同子领域的人士会注意到,这在技术上是一个情境感知的强化学习设置,因此存在探索与利用的权衡。在这种情境下的主要思想是,当我们的系统只学习它有意选择的内容时,有时随机改变选择以更多地探索世界,并确保我们不会将系统锁定在自我永续信念的循环中是至关重要的。探索过少会导致错失最佳机会;过多则是时间和资源的浪费。当然,这与我们自己生活中的任何选择有什么相似之处,完全是巧合。
⁵ 参见闪崩:一场全新的解构,详细讨论导致闪崩事件的事件,包括触发事件及促成市场条件的考量。从这次讨论中可以得出一个结论,即在涉及多个模型相互作用的系统中进行根本原因分析是多么困难。
第十一章:事故响应
在这个世界上,有时候坏事情会发生,即使是对良好的数据和系统也是如此。磁盘故障。文件损坏。机器损坏。网络中断。API 调用返回错误。数据卡住或轻微变化。曾经准确代表模型的模型变得不那么准确。世界也可能在我们周围改变:以前几乎从未发生的事情可能变得司空见惯;这本身对我们的模型产生影响。
本书的大部分内容涉及构建能够预防这些问题发生的机器学习系统,或者在这些问题发生时——而它们确实会发生——正确识别情况并加以缓解。具体而言,本章讨论了在机器学习系统遇到坏事情并需要紧急响应时的应对方法。你可能已经熟悉团队如何处理系统宕机或出现问题的情况:这被称为事故管理,并且有关管理这些事故的最佳实践在许多计算机系统中都是通用的¹。
我们介绍了这些通用的实践方法,但我们的重点是如何管理机器学习系统的故障,并特别关注这些故障及其管理与其他分布式计算系统的不同之处。
最重要的一点是,机器学习系统具有使其故障处理可能与非机器学习生产系统的故障处理截然不同的特性。在这种情况下最重要的特性是它们与真实世界情况和用户行为的紧密联系。这意味着我们可能会看到不直观的效果,例如 ML 系统、世界或我们试图建模的用户行为之间的不一致。我们稍后会详细讨论这一点,但现在需要理解的主要事情是,解决机器学习事故可能需要组织的更多参与,远超标准生产事故的工程部门,包括财务、供应商和供应商管理、公关、法律等。ML 事故的解决不一定只是工程部门的事情。
最后一个严肃的观点是,在此开篇,我们想要表明的是,和机器学习系统的其他方面一样,事故管理对伦理有着严重的影响,并且很常见地涉及到隐私问题。将重点放在先让系统工作,然后担心隐私,这是一个错误。在本节中,不要忽视我们工作的这一关键部分。隐私和伦理问题会在本章的几个部分中显现,并且朝着章节结束直接讨论,因为到那时我们将能够更清晰地得出一些关于机器学习伦理原则如何与事故管理互动的结论。
事故管理基础知识
成功的事故管理的三个基本概念是了解事故所处的状态,确定角色,以及记录信息以便后续跟进。许多事故因未能识别事故所处状态和谁负责管理其各个方面而拖延。如果这种情况持续足够长的时间,你就会有一个未管理的事故,这是最糟糕的事故类型。²
的确,如果你处理事故的时间足够长,你可能已经见过这样的事故,并且它可能是这样开始的:一个工程师意识到有问题;他们独自排除问题,希望找出原因;他们未能评估问题对最终用户的影响;他们也未向团队其他成员或组织其余部分沟通问题的状态。排除问题本身通常是杂乱无章的,并且在行动之间存在延迟,以及在行动后评估发生的情况。一旦初始排查者意识到事故的范围,他们可能会遇到更多延迟,因为他们试图弄清楚需要协助的其他团队,并发送页面或警报以跟踪它们。如果问题无限期持续下去,组织的其他部门可能会注意到问题存在,并独立(有时是适得其反地)采取不协调的步骤来解决问题。
关键思想在于实际上有一个过程——一个经过充分演练的过程——在发生值得称为事故的不良事件时可靠而系统地应用它。当然,创建一个管理良好的事故是有成本的,正式化沟通、行为和后续行动会增加开销。所以我们并不是每一个在日志中的WARNING都需要几个小时的会议或电话。成为一名有效的值班工程师需要发展出对什么是严重问题和什么不是的感觉,并在需要时平稳地启动事故处理机制。提前明确定义关于何时宣布事故、如何管理它以及事后如何跟进的指南是极其有帮助的。
事故的生命周期
事故在其存在中有明显的各个阶段。尽管有良好意愿的人可能在具体细节上有分歧,但事故可能包括以下状态:
事前事故
导致中断的架构和结构决策。
触发
发生某些事情导致用户端影响。
中断开始
我们的服务受到至少一些用户在至少一些功能上的显著影响。
检测
服务的所有者通过自动化监控通知我们或外部用户投诉而意识到问题的存在。
故障排除
我们试图找出问题的原因并设计修复问题的方法。
缓解
我们确定最快和最少风险的步骤,以至少防止问题中最严重的情况发生。这可能从发布一则通知表明某些事情不正常工作,一直到完全禁用我们的服务。
解决方案
我们解决了根本问题,服务恢复正常。
后续
我们进行回顾,了解关于中断的所有信息,确定我们希望修复的一系列问题或其他要采取的行动,然后实施这些行动。
计算机系统的中断大致可由以下阶段描述。我们将简要介绍典型事件中的角色,然后尝试理解处理 ML 事件的不同之处。
事件响应角色
一些公司有成千上万的工程师从事系统基础设施工作,而其他公司可能只有一名幸运儿。但无论您的组织规模是大还是小,本节描述的角色都需要填补。
需要注意的是,并非所有角色必须由不同的人填补,因为并非所有责任同等紧急,也不是所有事件都需要孤立的关注。此外,您的组织和团队有特定的规模,不是每个团队都能直接填补每个职位。此外,某些问题只在规模上产生:尤其是与管理的基础设施复杂性相关的沟通成本往往会在较大的组织中增加。相反,较小的工程团队可能会受到狭隘视野和经验多样性不足的困扰。我们的指导并不意味着您无需适应情况,以及做出正确选择——通常是首先做出错误选择。但有一个关键事实是,您必须提前计划好组织能力,以妥善支持事件管理职责。如果它们是人员招募不足的事后想法,或者您假设任何人都可以在没有结构、培训或空闲时间的情况下参与事件处理,结果可能会很糟糕。
我们最熟悉的事件管理框架源自美国联邦应急管理局(FEMA)国家事件管理系统。在此框架中,典型的最小可行角色集通常如下:
事件指挥官
一位具有整体高层次了解事件的协调员,负责分配和监控其他角色。
通讯负责人
负责出站和入站通讯。根据系统不同,此角色的实际职责差异显著,可能包括更新面向最终用户的公共文档,联系其他内部服务团队寻求帮助,或回答面向客户支持人员的查询。
运维负责人
批准、安排并记录与中断相关的所有生产变更(包括停止先前计划的与中断无关的同一系统的生产变更)。
计划负责人
记录那些不应丢失但不影响即时故障解决的长期项目。这包括记录待修复的工作项目、存储待分析的日志以及安排未来审查事故的时间。(如适用,规划负责人还应为团队订晚餐。)
这些角色是不变的,无论您是否处理机器学习事故。以下是变化的内容:
检测
与非机器学习系统相比,机器学习系统的确定性较低。因此,编写监控规则以在人类用户之前捕捉所有事故变得更加困难。
参与解决方案的角色和系统
机器学习事故通常在故障排除和解决过程中涉及更广泛的员工,包括业务/产品和管理/领导层。机器学习系统对多个系统产生广泛影响,并且通常建立在多个复杂系统之上并由其供给。这导致任何事故都可能涉及多样化的利益相关者。由于其在集成和修改基础设施的角色,机器学习故障通常会影响多个系统。
时间轴/解决方案不清晰
许多机器学习事故会影响到已经随时间变化的质量指标。这使得事故和解决方案的时间轴更难以精确指定。
为了对为何在这种情境中出现这些差异有更直观和具体的理解,让我们考虑一些机器学习系统中的实际故障案例。
机器学习中心故障的解剖
这些示例是作者根据真实经验绘制的,但并不对应于我们参与过的具体案例。尽管如此,我们希望许多有经验运行机器学习系统的人能在至少一个这些示例中看到熟悉的特征。
当您阅读它们时,请特别注意以下一些可能与其他类型的故障大不相同的特征:
架构和基础条件
在此之前我们对系统做出了哪些决定,这些决定可能在事故中发挥了作用?
影响开始
我们如何确定事故的开始?
检测
检测事故有多容易?我们如何做到?
故障排除和调查
谁参与其中?他们在我们组织中扮演什么角色?
影响
对我们的用户来说,故障的“成本”是多少?我们如何衡量它?
解决方案
我们对解决方案的信心有多大?
后续处理
我们能区分修复和改进吗?我们如何知道从事故的后续处理结束并进行前瞻性工程?
在您考虑本章后面呈现的故事时,请牢记以下问题。
术语提醒:模型
在第三章中,我们介绍了以下几点的区别:
模型架构
学习的一般方法
模型(或配置模型)
一个特定模型的具体配置,以及我们将在其上进行训练的学习环境和数据结构
训练模型
在某个时间点上,针对一个配置的模型训练的特定实例
特别是这种区别很重要,因为我们经常关心哪些因素发生了变化,可能涉及到事故。在以下各节中,我们将尽量明确我们所指的是哪一个。
讲述时间
我们在我们虚构的公司 YarnIt 框架内讲述以下故事,以便让它们与您产生共鸣。但它们都是基于或至少受到我们在生产中观察到的真实事件的启发。在某些情况下,它们基于某个特定时间的单个故障,而在其他情况下,它们则是组合的。
故事 1:搜索但未找到
YarnIt 使用的主要 ML 模型之一是搜索排名模型。像大多数网络商店一样,顾客会访问网站并点击首页提供的链接,但他们也直接搜索他们正在寻找的产品。为了生成这些搜索结果,我们首先过滤我们的产品数据库,以找到粗略匹配顾客搜索词的所有产品,然后使用 ML 模型对这些结果进行排序,试图预测如何在搜索时根据我们了解的一切对它们进行排序。
Ariel,一位从事搜索系统可靠性工作的生产工程师,正在处理监控想法的积压。搜索团队希望监控和趋势化的一项指标是用户在搜索结果的前五个链接中点击的速率。团队成员假设这可能是查看排名系统是否运行最佳的好方法之一。
Ariel 查看了可用的日志,并确定了公开生成指标的方法。在对过去 12 周进行了逐周报告以确保数字看起来合理后,Ariel 发现了一些最初令人鼓舞的结果。从 12 周前到 3 周前,Ariel 看到顾客大约 62%的时间内会点击前五个链接。当然,这可以更好,但我们在大多数时间内仍然在前几个结果中找到某些用户感兴趣的内容。
然而,三周前,前五个链接的点击率开始下降。事实上,本周只有 54%,而 Ariel 注意到它似乎仍在下降。这在很短的时间内是一个巨大的下降。Ariel 怀疑新仪表盘存在缺陷,并要求搜索可靠性团队进行查看。然而,团队确认:数据看起来正确,这些数字确实令人担忧!
注意
检测已发生。
Ariel 宣布了一次紧急事件,并通知了搜索模型团队,因为可能是模型出了问题。Ariel 也通知了零售团队,只是为了确认我们并非突然在从搜索产品的顾客那里少赚钱(而不是简单地浏览产品),并要求团队检查网站最近是否有更改,这些更改可能会影响搜索结果的呈现方式。然后,Ariel 探究了搜索可靠性团队自身的基础设施:他们那边有什么变动?Ariel 发现——并且搜索模型团队确认——在过去两个月内,并没有对模型配置进行任何更改。数据或模型使用的相关元数据也没有发生大的变动——只是正常地将顾客活动添加到日志中。
相反,搜索模型团队的一位成员注意到了一些有趣的事情:他们每天使用一个黄金查询集来测试新模型,并注意到在过去三周里,这个黄金查询集产生了极其一致的结果——足够引起怀疑。搜索模型通常通过重新训练前一天搜索和点击结果的模型来每日更新。这有助于保持模型对新偏好和新产品的更新。这也倾向于在黄金查询集的结果中产生一些不稳定性,尽管这种不稳定性通常在合理范围内。但是从三周前开始,这些结果变得异常稳定起来。
Ariel 前往查看已部署到生产环境的训练模型。这个模型已经三周没有更新过,自那时以来一直如此。 这解释了黄金查询的稳定性。它也解释了用户点击行为的下降:我们可能在新偏好和新产品上显示较少的良好结果。当然,如果我们继续使用同样陈旧的模型,最终将无法正确推荐任何新内容。因此,Ariel 查看了搜索模型训练系统,该系统每晚都安排搜索模型的训练。在过去三周内没有完成过一次训练运行,这肯定可以解释为何生产环境中没有新的训练模型。
注意
我们已经找到了故障的近因,但目前我们还不知道根本原因,并且没有明显的简单缓解措施:没有新的训练模型投入使用,我们就无法改善情况。这也是影响起始相当严重的一次近因。
训练系统是分布式的。一个调度程序加载一组处理过程来存储模型的状态,另一组处理过程则读取昨天的搜索日志,并使用用户新表达的偏好来更新模型。Ariel 注意到,所有试图从搜索系统读取日志的处理过程,大部分时间都在等待这些日志从日志系统返回。
日志系统通过一组称为日志供应者的进程访问原始客户日志,这些进程有权限读取日志的相关部分。在查看这些日志供应进程时,Ariel 注意到其中有 10 个进程每隔几分钟就会崩溃并退出。深入研究进程崩溃日志时,Ariel 发现日志供应者因为内存不足而崩溃。当它们无法分配更多内存时,它们会崩溃。崩溃后,新的日志供应进程会在新的机器上启动,训练过程会重新尝试连接,读取几个字节,然后该进程再次因为内存耗尽而崩溃。这种情况已经持续了三周。
Ariel 建议将日志供应进程数量从 10 增加到 20。在训练作业中分散负载可能会防止作业崩溃。如果需要,他们也可以考虑为作业分配更多内存。团队同意了这个建议,Ariel 进行了更改,日志供应作业不再崩溃,并且搜索训练运行几小时后完成。
注意
训练运行完成并将新训练的模型投入生产后,中断得到了缓解。
Ariel 与团队合作,再次确认新训练的模型是否能自动加载到服务系统中。查询黄金集的表现与三周前的不同,但表现仍然可接受。然后,他们等待几个小时以积累足够的日志来生成所需的数据,以确保更新的训练模型对客户的表现良好。随后,他们分析日志,发现前五个结果的点击率现在已经恢复到应有的水平。
注意
在此时,中断得到了解决。有时候没有明显的缓解阶段,缓解和解决同时进行。
Ariel 和团队对事件进行了回顾,并积累了一些事后工作,包括以下内容:
-
监控服务中模型的年龄,并在超过某个小时阈值时发出警报。“年龄”可以是墙上钟的年龄(字面上是文件的时间戳)或数据的年龄(模型基于的数据有多老)。这两者都可以通过机械手段进行测量。
-
确定我们对于必须有一个新鲜模型的需求,并将可用时间分配给训练过程的各个子组件。例如,如果我们最多每 48 小时需要在生产环境中更新一个模型,我们可能会给自己大约 12 小时来解决问题并训练一个新模型,然后我们可以将剩余的 36 小时分配给日志处理、日志供应、训练、评估和复制到服务流水线的部分。
-
监控黄金查询测试,并在它没有变化或变化太多时发出警报。
-
监控训练系统的训练速率,并在其低于合理阈值时发出警报,以便我们预测基于分配的时间量我们将无法按时完成训练。选择监控内容是困难的,为这些变量设置阈值甚至更难。这在“ML 事件管理原则”中简要涉及,并且在第九章中已经涵盖。
-
最后,也是最重要的一点:监控前五个结果的点击率,并在其低于某个阈值时发出警报。这应该能够捕捉到任何影响用户感知质量但未被其他原因捕捉到的问题。理想情况下,这个指标应该至少每小时可用,这样即使只在每天基础上稳定也可以在未来解决问题时使用它。
随着这些后续项目的安排,艾瑞尔准备休息一下。
ML 事件响应故事 1 的阶段
尽管这次停机的原因相当简单,但它可以帮助我们开始看到机器学习事件在某些阶段的响应生命周期中表现出略有不同的方式:
事前事件
培训和服务系统是一个相当典型的结构,一个系统生成训练模型并定期更新,另一个系统使用该模型来回答查询。这种架构非常具有弹性,因为面向客户的实时系统与学习系统隔离开来。当它出现故障时,通常是因为服务中的模型没有更新。底层日志数据也以一种保护日志但仍允许训练系统从中学习的干净方式进行了抽象处理。但这种与日志的接口正是我们系统中弱点所在。
触发器
分布式系统在超过特定扩展阈值时通常会失败,从而显著降低性能,有时称为瓶颈。在这种情况下,我们超过了日志馈送部署性能的阈值,却没有注意到。触发器是数据的简单增长,对应于训练系统需求的增长,以及消费该数据的业务需求。
停机开始
停机开始三周后我们才注意到。这很不幸,这也是为什么良好的监控如此重要的原因。
检测
未充分工具化的机器学习系统通常将系统问题表现为仅有质量问题——它们仅仅开始表现得不太好,并且随着时间的推移逐渐恶化。模型质量变化通常是系统基础设施出现问题的唯一端到端信号。
故障排除
机器学习故障排除通常涉及比其他类型的故障更广泛的团队,这正是因为它们通常表现为公开可见的质量问题。在问题被缩小之前,最好不要对我们正在经历的故障类型进行假设——这可能是系统问题、模型问题,或者只是我们正确预测世界能力的漂移。³ 有时候,问题是世界变化速度超过我们能跟上的速度——关于这一点,后续故事将详细介绍。并非所有的质量下降都是故障。未来的故事将展示更广泛的参与故障排除的人员阵容。
缓解/解决方案
在这种情况下,缓解问题的最快、最低风险的步骤涉及训练一个新模型,并成功部署到我们的生产搜索服务系统中。对于机器学习系统,特别是那些在大量数据上进行训练或生成大型模型的系统来说,可能没有这样的快速解决方案。
后续
我们可以在这里添加丰富的监控内容,其中许多内容并不容易实施,但在未来的事件中将对我们有益。
这个第一个故事展示了一个相当简单的与机器学习相关的故障。我们可以看到,故障可能表现为模型质量问题,未能完全符合我们的预期或需求。我们还可以开始看到,在许多情况下需要广泛的组织协调来解决问题的模式。最后,我们可以看到,对后续工作的规范是非常诱人的。在记住这三个主题的情况下,让我们考虑另一个故障。
故事 2:突然无用的合作伙伴
在 YarnIt,我们有两种业务类型。我们的第一部分是直营店,销售针织和编织产品。但我们还有一个市场,推荐其他合作伙伴通过我们的商店销售的产品。这是一种可以向我们的客户提供更多种类产品的方式,而无需增加库存或营销投入。
何时以及如何推荐这些市场产品有点棘手。我们需要将它们作为基准纳入到我们网站上的搜索结果和发现工具中,但我们应该如何进行推荐呢?最简单的方法是列出我们产品数据库中的每个产品,包括所有涉及它们的操作在我们的日志中,然后将它们添加到我们的主预测模型中。一个显著的限制是,这些合作伙伴中的每一个都要求我们将他们的数据与其他合作伙伴的数据分开;否则,他们将不允许我们列出他们的产品。⁴ 因此,我们将不得不为每个合作伙伴训练一个单独的模型,并将合作伙伴特定的数据提取到隔离的存储库中,尽管我们仍然可以为共享数据维护一个通用的特征存储。
YarnIt 雄心勃勃,计划为潜在的非常大量合作伙伴之间——大约在五千到五百万之间——设计一个设置,而不是为少数大型模型进行优化。因此,我们建立了一个系统,从每个合作伙伴中提取历史数据并将其放入单独的目录或小型特征存储中。然后,每天结束前,我们分离出前一天的增量并将其添加到我们的存储中,然后开始训练。现在,我们的主要模型训练速度很快,我们的较小合作伙伴模型也训练速度很快。最重要的是,我们符合合作伙伴要求的访问保护标准。
注意
到这一点,预事故已经完成。舞台已经搭建好,停机的条件也已经设置好。到这时,可能已经很明显存在许多问题的机会。
Sam 是 YarnIt 的一名生产工程师,负责合作伙伴培训系统。在即将进行的业务会议前,Sam 被要求为合作伙伴 CrochetStuff 制作报告。在准备报告时,Sam 注意到所讨论的合作伙伴在机器学习训练数据中没有最近的转化记录,但会计系统报告称其每天都在销售产品。Sam 制作了一份报告并转发给负责数据提取和连接工作的同事以寻求建议。与此同时,Sam 在向合作伙伴团队的数据报告中没有提到这个事实,只包括了销售数据。
注意
检测发生在这里。没有计算机系统检测到停机情况,这意味着它可能已经持续了不确定的时间。
像这样的计数数据不一致问题经常发生,因此数据提取团队不将 Sam 的报告视为高优先级。Sam 报告了一个合作伙伴的单一差异,团队提交了一个 bug,并计划在未来一周左右解决。
注意
事故未经管理,继续混乱进行。它可能很小,也可能不是。尚无人确定数据问题的影响程度,并且没有人负责协调快速和有针对性的应对措施。
在业务会议上,CrochetStuff 指出其销售环比下降了 40%,并且每天都在继续下降。尽管用户找到产品的速率依然很高,但他们的页面浏览量、推荐和用户查询量都在下降。CrochetStuff 要求知道为什么 YarnIt 突然停止推荐其所有产品!
注意
到目前为止,我们进行了内部检测、内部合作伙伴倡导、客户报告,并可能发现了正在发生的事情的线索。这些都是很多噪音,但有时我们直到多人独立注意到它之后才宣布事故。
Sam 宣布了一个事件,并开始解决问题。合作模型训练系统的日志清楚地报告说,合作模型每天都在成功训练,并且最近没有对执行训练的二进制文件或模型结构和特性进行任何更改。通过模型生成的指标来看,Sam 可以看到 CrochetStuff 目录中每个产品的预测值在过去两周内每天都显著下降。Sam 查看其他合作伙伴的结果时,看到了完全相同的下降趋势。
Sam 找来建模的机器学习工程师们来排查发生了什么。他们再次确认没有任何改变,然后对底层数据进行了一些聚合检查。他们注意到的一件事与 Sam 最初注意到的一样:在过去两周内,机器学习训练数据中没有任何合作伙伴的销售数据。所有数据都来自我们的主日志系统,并且每天提取以与每个合作伙伴的历史数据进行连接。数据提取团队从几天前 Sam 的错误中恢复,并开始调查。
Sam,需要快速缓解问题的人员,注意到团队保存了长达几个月的旧版本训练模型。Sam 询问机器学习工程师只加载旧模型到服务中目前可能带来的后果。团队确认,虽然旧的训练模型版本不包含任何关于新产品或消费者行为大变化的信息,但它们对所有现有产品的推荐行为仍具有预期效果。由于故障的范围如此之大,合作团队决定冒这个风险回滚模型。在与合作团队磋商后,Sam 将所有合作训练模型回滚到两周前创建的版本,因为这似乎是故障影响开始之前的时间点。机器学习工程师快速检查了旧模型的聚合指标,并确认推荐应该恢复到两周前的状态。⁵
注意
此时,故障虽然得到了缓解,但并没有真正解决。情况非常不稳定,尤其是我们无法使用我们习惯的流程构建新模型,并使其良好运行。我们仍然需要找出最佳的完整解决方案,以及如何避免再次陷入这种情况。
当 Sam 在减轻问题时,数据提取团队一直在进行调查。它发现,虽然提取工作正常,但将提取的数据合并到现有数据中的过程始终无法为任何合作伙伴找到可合并的内容。这一问题似乎始于大约两周前。进一步的调查揭示,两周前,为了促进其他数据分析项目,数据管理团队更改了用于在其日志条目中识别每个合作伙伴的唯一合作伙伴键。这个新的唯一键被包含在提取的数据中,因为它与以前的合作伙伴标识符不同,所以新提取的日志无法与添加键之前提取的任何数据合并。
注意
现在这是停机的一个合理的根本原因。
Sam 请求重新提取单个合作伙伴的数据,并在新数据上训练一个模型,以快速验证系统是否正确端到端地工作。一旦完成,Sam 和团队能够验证新提取的数据包含预期数量的转化,并且模型现在再次预测这些产品是许多客户的好推荐。Sam 和数据提取工程师对重新提取所有数据需要多长时间进行了一些快速估算,然后 Sam 与机器学习工程师商议重新训练所有模型需要多长时间。他们得出一个共同的估计为 72 小时,在此期间,他们将继续提供来自两周前恢复的陈旧模型版本的推荐。在与零售产品和业务团队商议后,他们决定执行这种方法。合作伙伴团队起草了一些邮件通知合作伙伴有关问题及解决时间表。
Sam 请求重新提取所有合作伙伴数据,并尽可能从头开始重新训练所有合作伙伴模型。他们监控这个过程三天,一旦完成,验证新模型不仅推荐旧产品,还推荐了在两周前不存在的新产品。经过仔细检查,机器学习工程师认为新模型是好的,并投入生产。服务结果经过仔细检查,许多人进行实时搜索和浏览以验证合作伙伴列表是否按预期显示。最终,停机宣布解决,合作伙伴团队起草了一份更新,通知合作伙伴们。
注意
在这一点上,停机已经解决。
Sam 召集团队一起讨论停机事件,并提出一些后续错误报告,以便他们能够避免类似的停机事件,并比这次更快速地检测到它。团队考虑重新架构整个系统,以消除所有数据两次拷贝的问题,具有稍有不同的用途和约束,但他们决定,如果统一,仍然没有很好地了解如何达到两个系统的性能目标。
他们确实提出了一组与监控数据提取成功、数据复制和数据合并相关的错误报告。最大的问题在于,他们没有一个关于“应该合并多少行数据”的可靠真实来源。这种失败发生在整个日志类别中,团队很快就能为“必须大于零的日志行合并”添加警报。但在调查过程中,还发现了一系列不太严重的失败,为了捕捉这些失败,我们需要知道每个合作伙伴预期合并的日志数量,以及实际合并的数量。
数据提取团队决定采用一种策略,按合作伙伴每天合并的日志行数进行存储,并将今天的成功与过去 n 天的滞后平均值进行比较。当合作伙伴稳定时,这种方法效果相对不错,但当他们的流行度发生较大变化时会产生噪音。
两年后,这种警报策略仍未实施,因为在实施过程中遇到了不必要的噪音挑战。这种策略可能是一个好主意,但考虑到动态的零售环境,已被证明行不通,而且团队仍然缺乏良好的端到端快速检测这类日志提取和合并故障的能力,除了在灾难性情况下。然而,他们在几个月前实施的一种启发式方法——通过触发任何合作伙伴配置变更并通知工程师潜在的故障——至少增加了对这种变化作为潜在触发器的持续意识。
ML 事故响应故事 2 阶段
这次事故经历的许多特征阶段与任何分布式系统事故的相似之处很多。但是它有明显的不同之处,要看到这些特点,最好的方法是通过合作伙伴培训中断的过程,并查看在每个部分发生的与机器学习相关的特征:
事前事件
大多数问题在我们系统结构中已经潜在存在。我们的系统有两个数据的权威来源,其中一个是另一个的提取版本,定期应用增量提取。机器学习系统最常见的失败是由于数据和元数据的问题。我们将深入研究观察和诊断系统中耦合数据和机器学习中断的策略,参见“机器学习事故管理原则”。
触发器
数据架构已更改。这次更改距离我们观察到问题的地方很远,显然这使得识别变得困难。重要的是要将这次中断视为识别我们在整个处理堆栈中对数据所做的假设的一种方式。如果我们能够识别这些假设及其实施位置,我们就能避免创建会因为这些假设变化而受损的数据处理系统。在这种情况下,我们的主要特征存储架构不应该更改,除非也修改或至少通知所有下游用户这个特征存储的情况。显式的数据架构版本控制是实现这一结果的一种方式。
中断开始
中断始于一个内部系统处理数据的过程使用另一个内部系统处理数据的方式,而这种方式已不再与其结构一致。这是任何大型分布式管道系统的常见危险。
检测
机器学习系统很常见地以终端用户首先检测到的方式失败。其中一个挑战是,机器学习系统通常被指责失败,或者至少在正常运行时表现不佳,因此忽视用户和客户的投诉似乎是合理的。注意到这种特定中断的主要方法是一个常见的方法:推荐系统不再提供与以往相同质量的推荐。通过机器学习系统的监控,牢记高级别、端到端、粗粒度的整体情况特别有用——核心问题是,我们在过去的短时间内是否显著改变了模型的预测?这类端到端的质量指标完全独立于实现,将检测到任何严重损害模型的中断。挑战在于过滤该信号,以避免出现太多误报。
故障排除
Sam 需要与多个团队合作,以理解中断的范围和潜在原因。我们有商业和产品人员(合作伙伴团队)、构建模型的机器学习工程师、从特征存储和日志存储中提取数据并将其送至我们的合作伙伴模型训练环境的数据提取工程师,以及像 Sam 这样协调整个工作的生产工程师。解决机器学习中断问题确实必须从外部世界开始,而不是从数据开始:我们的模型说了什么,为什么是错误的?有如此多的数据,仅仅“浏览数据”甚至“对数据进行聚合分析”可能会是一个漫长而毫无成果的搜索。从模型的变化或有问题的行为开始,倒推出现在模型为什么会这样做会更容易些。
缓解
对于某些服务来说,可以在准备修复方案的同时简单地恢复软件的旧版本。虽然这可能会给依赖新功能的用户带来不便,但其他人可以继续不受影响。
机器学习停机通常只能通过恢复模型的旧版本来部分缓解,因为它们的任务是帮助计算机系统适应世界,而没有办法恢复世界过去的快照。
此外,快速培训新模型通常需要比我们现有的计算能力更多。正如我们合作伙伴模型停机的情况一样,没有无成本的快速缓解措施。确定最佳缓解选项需要最熟悉我们合作伙伴、用户和业务的产品和业务人员最终做出决定。对于非机器学习服务,这种升级到业务领导层的情况有时会发生,但对于机器学习服务则更为频繁。大多数依赖机器学习来运行业务重要部分的组织将需要培养既懂业务又懂技术的技术领导者。
解决方案
Sam 确保合作伙伴培训系统中的数据是正确的(至少在总体上,抽查似乎确认它看起来不错)。新模型已经训练完成。当我们准备部署它们时,实际上没有简单的方法来确定新模型是否“修复”了问题。在我们努力解决这个问题的同时,世界继续变化。因此,一些先前受欢迎的产品现在可能不那么流行了。一些被忽视的产品可能被我们的用户发现了。我们可以查看总体指标,看看我们是否推荐合作伙伴产品的速率接近之前的水平,但这不会完全相同。有时人们会在这里使用一组黄金查询,以查看是否能生成一组“正确”的预置结果。这可能在一定程度上增加我们的信心,但也带来了一个新问题,即我们将希望不断地维护这组黄金查询,以代表我们用户搜索的内容。一旦我们做到了这一点,我们不一定会在非常长的时间段内得到稳定的结果。⁶
后续处理
事后工作总是困难的。首先,有直接知识的人已经很累了,到这个时候可能已经忽略了他们的其他工作。我们已经为停机付出了代价,所以我们最好从中获得价值。尽管监控错误通常包含在事后跟进中,但对于基于机器学习的系统来说,这种错误往往会懒散下来(有时长达数年)。原因相对简单:以高信号低噪声方式监控真实数据和真实模型非常困难。任何过于敏感的东西都会一直警报——数据不同了!但是过于宽泛的东西会错过我们服务的子集的完全停机。这些问题存在于大多数分布式系统中,但对于机器学习系统来说是特征性的。
尽管这次停机在技术上复杂,并且在表现上有些微妙,但许多机器学习停机都有非常简单的原因,但仍然以难以关联的方式显示出来。
故事 3: 推荐您寻找新供应商
在 YarnIt,我们有几个业务方面的模型。特别是推荐模型具有重要的信号:购买。简单来说,我们在用户倾向于购买产品时,在每一个浏览上下文中推荐产品给他们。这对我们的用户来说是好事,因为他们更快地找到想购买的产品;对于 YarnIt 来说,这意味着更快地销售更多产品。
Gabi 是一名工作在发现建模系统上的生产工程师。一个异常愉快的夏日,Gabi 在处理已经悬而未决的配置清理工作,并处理其他部门的请求。客户支持人员发送了一封通知,他们在过去几周内一直在网站上追踪到一个反馈主题,称推荐内容“奇怪”。一些客户的这种主观印象通常很难采取任何具体行动,但是 Gabi 将该请求归档到“待跟进”部分,以便稍后跟进。
注意
不要透露剧透!我们绝对不能说到目前为止是否已经发生了事件检测。
在后续的请求中,Gabi 发现了一个异常的问题报告。网站支付团队告诉 Gabi,财务部门报告收入大幅下降。网站上过去一个月的收入下降了 3%。这可能看起来不是很大的下降,但经过进一步的调查,团队发现相比四周前,上周的下降接近 15%!支付团队已经检查了支付处理基础设施,并发现客户支付购物车的成功率与历史上相同。他们指出,尽管如此,购物车的平均产品数少于以往,并且特别是购买推荐产品的人数少于预期。这就是为什么支付团队联系了 Gabi。看到如此大的数字,Gabi 宣布了一个事件。
注意
检测到并宣布了事件。
Gaby 要求财务团队再次核实过去几周的本周与四周前的比较,并要求提供过去几周收入的更详细的时间表。最后,Gaby 要求提供任何可用的产品、类别或合作伙伴的分解情况。然后,Gaby 要求支付团队验证关于添加到购物车的推荐的数字,并提供他们能提供的任何分解信息。特别是:团队是否看到某种特定类型的购物车比其他购物车少推荐或者最近发生了变化?
与此同时,Gaby 开始查看应用程序的聚合指标,试图弄清楚一些基本问题。我们是否在显示推荐?我们是否像过去一样频繁地显示推荐,以及对于所有的查询、用户和产品,我们是否以过去的同样比例跨用户子群体生成销售?我们是否像通常一样从推荐中生成销售?推荐中是否有明显不同的显著之处?
Gaby 还开始进行常规的生产调查,特别关注最近推荐堆栈中发生了什么变化。结果并不令人鼓舞,找不到明显的罪魁祸首:推荐模型和用于训练模型的二进制文件在过去六周内都没有改变。当然,模型的数据每天更新,这也是需要关注的一点。但是特征存储中的数据架构几个月来都没有变化。
Gaby 需要继续故障排除,但却花时间撰写一条快速消息给财务和支付团队,请求帮助解决这个问题。Gaby 确认了到目前为止所知的情况:推荐系统正在运行并产生结果,但尚未验证结果的质量。考虑到公司似乎正在损失大量资金,Gaby 提醒他们如果尚未通知部门负责人则需要通知他们,这似乎是明智的做法。
没有明显的软件、建模或数据更新与停机时间相关,因此 Gaby 决定深入研究推荐模型本身。Gaby 发送了一条快速消息给建模者 Imani,请求帮助。当 Gaby 向 Imani 解释他们到目前为止所知道的情况(购买产品减少,每次结账购买的推荐减少,没有系统变更)时,客户支持的便签也跃入脑海。如果时间线符合,客户抱怨有关“奇怪”推荐的确显得相关。
客户支持人员确认他们在刚过去的三周左右开始收到第一批零星投诉,但最近一周情况变得尤为尖锐。Imani 认为这可能值得调查,并请求 Gabi 收集足够的数据以追踪推荐系统的一些基本指标:每个浏览页面的推荐数量,预期的所有推荐产品的平均每小时差异(客户购买推荐产品的概率乘以购买价格的预期“价值”),以及观察到的价值(最终购买的所有推荐产品的总价值)。Imani 获取了最近客户查询和产品结果的副本,以便将它们用作推荐系统的可重复测试。推荐系统使用用户的查询、所在页面以及他们的购买历史(如果我们知道的话)来进行推荐,因此这是 Imani 将需要直接查询推荐模型的信息。
注意
没有更多信息的情况下,我们必须担心 Imani 可能侵犯了 YarnIt 客户的隐私。搜索查询可能包含受保护的信息,如用户 IP 地址,而任何搜索查询的收集还有另一个问题,即在给定用户的情况下,它们相互关联时会透露更多私人信息。(参见第 7 页,第十一章,第 128 页脚注)Imani 肯定应该在 YarnIt 咨询隐私和数据保护专家之后,或者更好的做法是根本不应该直接无监控地访问这些查询,以避免这种错误。
Imani 提取了大约 100,000 个查询和页面浏览数据,并建立了一个测试环境,可以对推荐模型进行测试。在系统的测试运行结束后,Imani 得到了所有结果的推荐,并存储了整个运行的副本,以便将来需要修改或修复模型时进行比较。
Gabi 回来报告了一些有趣的事情。三周多前,每页推荐的数量开始缓慢下降。一周内,每个推荐的预期值和观察到的值之间的差距只略有下降。两周前,推荐数量停留在比过去少了将近 50%的水平。但是随后推荐的价值开始显著下降,相比预期值。这种下降持续到上周。两周前,推荐的观察值达到了预期值的 40%的低点。更奇怪的是,推荐的预期值和观察到的值之间的差距在一周前开始缩小,但同时推荐显示的数量再次下降,现在我们似乎根本没有显示多少推荐,但显示的推荐似乎相对准确地被价值化了。显然出现了问题,看起来是模型的问题,但目前还没有清晰的诊断结果。图 11-1 展示了这些变化随时间的图形表示。

图 11-1. 期望和显示推荐的数量以及它们随事件期间变化的平均期望值
Imani 继续构建 QA 环境来测试假设。基于直觉,Gabi 和 Imani 又拿出了一个月前(在出现问题之前)的另外 100,000 个查询和页面视图,以及过去六周每周的一个模型快照。虽然模型每天都进行重新训练,但即使模型的配置每天完全相同,模型每天都会根据用户前一天的行为进行学习。Imani 计划运行旧和新的查询与每个模型进行对比,看看可以学到什么。
Gabi 主张先进行快速测试:今天的查询与一个月前的模型进行对比。思路是:如果这个方法有效,可以快速减轻问题(恢复旧模型提供服务),同时继续进行故障排除。Gabi 的焦点是尽快解决收入损失问题。Imani 运行了测试,结果并不太令人满意,也很难评估。旧模型与新模型做出了不同的推荐,而且似乎稍微多一些。但是,与一个月前的查询相比,旧模型对今天的查询仍然做出了更少的推荐。
没有更具体的依据,Gabi 不确定将模型改为旧模型是否有帮助。这甚至可能比当前模型对我们的收入造成更大的损害。Gabi 决定将推荐系统保持当前状态。现在是向财务和支付部门发送另一封关于故障排除当前状态的通知。支付和财务联系人都报告说,他们的老板想要更多关于发生情况的信息。Gabi 的同事 Yao 一直跟踪调查,并熟悉推荐系统,被选中负责沟通。Yao 迅速建立了一个包含到目前为止已知状态的共享文档,并链接到特定的仪表板和报告以获取更多信息。Yao 还向公司高级管理人员广发通知,告知他们停机情况及调查的当前状态。
Imani 和 Gabi 对旧模型和新模型运行了所有新旧查询的完整检查。每对的结果都不同,但没有明显的广泛系统性问题可以解释这些差异,而且总体指标与之前描述的奇怪模式相匹配。Imani 决定暂时放下模型,转而专注于查询和页面访问本身。Imani 想弄清楚他们在过去一个月里如何改变,也许问题在于模型处理用户行为转变的能力,而不是模型本身有问题。
Imani 抽查了这些查询,但每批有 10 万条,两批都有,而它们之间可能存在的显著差异并不明显。与此同时,Gabi 制作了两份报告。第一份报告专门研究了客户用于访问最终产品页面的搜索查询。Gabi 对搜索查询进行了标记,并简单统计了每个单词出现的次数。在此期间,Gabi 将客户最终访问的产品页面分配到大类(纱线、图案、针、配件、装备)中,并根据产品本体论(由另一个团队建立)将其进一步分到子类中。Gabi 对比了四周前和今天用户行为的最大差异。
结果显而易见:与四周前相比,用户越来越多地寻找完全不同的产品。特别是,他们现在寻找轻量级纱线、背心和小件物品的图案,以及较小规格的针。Imani 和 Gabi 盯着结果看,问题突然变得如此明显。四周前发生了什么?北半球的热浪来得比往常早,并显著减少了大多数 YarnIt 客户对用粗毛线编织的兴趣。
然而,Imani 指出,这并不能解释推荐减少,只是推荐内容的变化。这仍然让人困惑,为什么我们不推荐优质的大麻和丝绸纱线,而是推荐羊毛呢?Gabi 手动执行了几个查询到推荐引擎,使用了一个专为这样的故障排除而构建的命令行工具,并注意到了一些情况。推荐引擎的测试实例设置为记录比生产实例更多的细节。其中一个高频记录的情况是,许多推荐候选产品因为缺货而被取消显示给用户。
Yao 从 Imani 和 Gabi 那里得到了最新的消息,更新了一些共享文档,并向越来越多等待公司解决问题的人群发布了一些信息。来自零售团队的某人看到了关于许多推荐产品缺货的说明,并提到 YarnIt 最近确实失去了几个重要的供应商。其中最大的一个,KnitPicking,是一家流行的时尚纱线供应商,其中许多产品恰好是轻巧的纱线。事实上,KnitPicking 是这些重量级和价格点的主要供应商之一。Yao 获取了关于供应问题时间安排的更多细节,将其添加到文档中,并向 Gabi 汇报了情况。
注意
这是一个有趣的问题状态。我们有一个可能的根本原因,但没有明显的解决或减轻它的方法。
Imani 和 Gabi 对异常推荐有了一个坚实的假设。推荐系统配置了对每个推荐产品显示的最低预期值阈值,这样在没有好的推荐产品时就不会显示糟糕的推荐。但是,一个推荐产品的预期值调整需要一段时间,特别是当最近它没有经常被显示时。Imani 得出结论,系统很快学到了很少人想要重量级羊毛纱线。但一旦这些产品被认定为不良推荐,系统在最终确认我们当前客户真正想购买的产品库存非常有限之前,需要很长时间循环检查许多其他产品。
Gabi、Imani 和 Yao 安排了一次与零售和财务负责人的会议,讨论他们所学到的内容,并寻求如何继续前进的指导。奇怪的是,目前的情况似乎是推荐系统现在在当前情况下表现得相当不错。由于我们目前没有大多数客户想要的产品,它对大多数客户的大多数页面浏览推荐很少产品。收入损失不仅是由于供应问题,也是由于推荐系统。在以已知的事实为基础的情况下,零售负责人要求团队核实其发现以确保准确,但同意解决供应问题是最优先的任务。财务主管点头同意,然后立即大幅减少本季度的盈利预期。鉴于我们的供应短缺以及天气对客户偏好的影响方式,很明显推荐模型没有明显的改变能够改善情况。
注意
此时,停机很可能已经结束,因为我们决定不改变系统或模型。
第二天,团队齐聚一堂,回顾所发生的事情,并从中学习。以下是一些提议的后续行动:
-
监控并绘制每页浏览的推荐数量、每个推荐的收入以及预期所有推荐每小时的预期价值与实际销售价值之间的百分比差距。
-
对于候选产品推荐高失效率(无论出于何种原因:缺货、法律限制等),应进行监控和警报。如果可以找到高信号方式,我们还可以考虑直接监控库存水平,尽管最理想的情况是由供应链或库存管理团队负责。在这里,我们应当小心,避免对其他团队的工作进行过度监控,以免未来过多的警报负担我们自己。我们应该考虑直接监控用户查询行为的总体情况,这样我们可能能够检测到查询主题和分布的显著变化。这种监控通常适合绘图,但不适合警报,因为它很难实现正确。最后,我们可以更密切地与客户支持团队合作,为他们提供调查此类用户报告的工具。如果支持团队有一个查询复制器/分析器/记录器,可能会生成比“客户说他们得到奇怪推荐”更详细的报告。这种“增强另一个团队效率”的努力通常比纯自动化产生更大回报。
-
检查如何使模型更快地调整。花费如此多的时间才能收敛于正确的推荐行为是不合理的。总体上,模型的稳定性被认为具有价值,但在这种情况下,它最终向用户显示了糟糕的推荐,使生产团队更难以解决与其相关的问题。伊曼尼希望找到一种方法,在不使模型过于不稳定的情况下提高对新情况的响应能力。
-
我们应该把这视为一个思考模型在没有任何好的推荐时应该怎么做的机会。这从根本上来说是一个产品和业务问题,而不是 ML 工程问题:我们需要弄清楚我们希望模型展示的行为以及在这种情况下我们认为应该向用户展示的推荐类型。在高层次上,我们希望以合理的利润率继续赚钱,即使我们没有客户最想要的产品。弄清楚是否有一种方法来确定产品推荐策略来解决这个难题是一个棘手的问题。
-
最后,显然 ML 系统需要一些外生数据始终可用,以便更轻松地进行类似的故障排除。特别是,生产工程师应该在产品目录中按产品类别、地理位置和用户查看产品的原始来源(搜索结果、推荐或主页)的汇总和分解中始终有收入结果。
许多这些后续措施非常雄心勃勃,不太可能在任何合理的时间内完成。其中一些,但可以相对较快地完成,并且应该使我们的系统在未来更具抗干扰能力。正如往常一样,找到正确的平衡并理解实施这些措施的权衡是良好后续措施的本质,尽管我们应该偏爱那些使问题更容易排查的措施。
ML 事件响应阶段 3
尽管此次事件与前两个案例的轨迹略有不同,但我们可以看到许多相同的主题出现。与其重复它们,让我们试着集中精力从这次中断中学到的任何额外教训:
事前准备
在我们系统的架构或实施中没有明显的重大故障导致这次中断,这很有趣。我们确实可以做出不同选择,使中断进展不同,并且更顺利地为我们的用户服务,但最终我们不能推荐我们没有的产品,销售肯定会下降。在这种情况下可能会有一个模型能够在这些情况下产生更好的推荐(需求快速变化与库存问题结合),但这更多地属于持续模型改进而不是事故避免的范畴。
触发器
天气变化,并且我们失去了一个供应商。这是一种难以直接检测到的事件组合,但我们可以尝试使用一些选择的监控方法来进行检测。
停机开始
从某些方面来看,这并不是停机。这是此次事件最有趣的地方。停机可以被理解为系统的失效,导致其产生错误结果。适当地描述“奇怪推荐”期间的时期可以作为停机的描述,但成本仅为最小,因为主要影响可能只是稍微让我们的用户感到恼火。但是收入损失并非由推荐模型造成,也无法通过它来预防。同样,直到天气改变或我们获取新的轻量级纱线供应之前,停机都不会结束。
检测
此次停机的最早迹象是关于奇怪推荐的客户投诉。这是一种可能不能依赖的嘈杂信号,但正如所指出的,我们可以为支持团队提供更好的工具,以便能够更详细地报告问题。其他不那么明显的信号可能具有更高的准确性,我们可以用于检测,但即使弄清楚它们也是一个数据科学问题。
故障排除
调查此次停机的过程包括许多以机器学习为中心的停机调查的特征:在特定模型(或一组模型或建模基础设施)上进行详细探索,同时广泛调查我们周围环境的变化。如果 Sam 对财务团队的详细收入时间表进行了跟进,调查可能会更快地进行下去。通过按产品、类别或合作伙伴细分的收入变化的详细数据,我们本应该能够看到消费者行为的急剧变化,以及 KnitPicking 销售的急剧上升和下降(因为我们的产品库存短缺)。有时候很难记住,关于停机的清晰度可能来自于更广泛地观察整个情况,而不是更仔细地观察其单个部分。
缓解/解决
有些停机没有明显的缓解措施。这非常令人失望,但偶尔没有快速恢复系统到先前状态的方法。而且,实际解决核心停机并让我们的收入恢复正轨的唯一方法是改变我们的用户需求或修复我们可供销售的产品。团队没有考虑的一件事,可能部分原因是因为它专注于排除模型和解决停机的机器学习部分,那就是可能有其他非机器学习方式来缓解停机:如果我们的系统显示缺货推荐并邀请客户在我们有这些(或类似)产品时通知他们呢?在这种情况下,我们可能通过将损失的收入向前移动并减少向客户提供的奇怪推荐,从而避免了一些损失。有时候,缓解措施可以在我们的系统之外找到。
后续处理
在许多情况下,从以机器学习为中心的事故的后续发展成为一个阶段,这个阶段不再像“修复问题”那样,而更像是“改善模型性能”。事故后的跟进往往演变成长期项目,即使对于非机器学习相关的系统和故障也是如此。但对于机器学习系统来说,“修复”和“持续改进模型”之间的界限特别模糊。一个建议是:首先清晰定义您的模型改进流程。跟踪正在进行的工作,并定义计划用于指导模型质量改进的指标。一旦发生事故,从事故中获取输入以添加、更新或重新排列现有的模型改进工作。有关更多信息,请参见第五章。
然而,这三个故事在细节上有所不同,展示了机器学习事故在检测、故障排除、缓解、解决以及最终事故后跟进行动中的共同模式。记住这些对于理解这些事件如何在某种程度上与分布式计算系统中的其他故障有所不同是有用的。
机器学习事故管理原则
尽管这些故事各具特定性,但它们的许多教训在各种事件中仍然有用。在本节中,我们将远离这些故事的紧迫性,并概括它们以及我们在机器学习系统故障中的其余经验可以教给我们的东西。我们还为您提供了一份具体的建议清单,供您准备和应对事故使用。
指导原则
三个贯穿机器学习事故的主题如此常见,我们将它们列为指导原则:
公共
机器学习的故障通常首先由最终用户检测到,或者至少在流水线的最末端,在服务中或集成到应用程序中。这在一定程度上是因为机器学习模型性能(质量)监控很困难。某些类型的质量故障对最终用户是明显的,但对开发人员、决策者或 SREs 并不明显。典型的例子包括任何影响小部分用户百分之百时间的情况。这些用户始终从我们的系统中获得糟糕的性能,但除非我们碰巧查看到这些用户的一小部分,否则聚合指标可能不会显示任何问题。
模糊
机器学习(ML)中断在两个方面不太明确:在影响和时间上。关于时间,确定 ML 事件的确切开始和结束通常很困难。虽然可能有可追溯的起始事件,但建立起明确的因果链可能是不切实际的。ML 中断在影响上也不明确:很难看出 ML 系统的特定条件是重大中断,还是仅仅是模型尚未像我们希望的那样复杂或有效。一个思考方式是,每个模型最初都非常基础,只能完成我们希望它有朝一日能完成的部分工作。如果我们的工作有效,随着我们改进对建模世界的理解和改进模型使用的数据,模型会随着时间而变得更好。但是,模型之间可能没有“糟糕”和“好”的明显过渡。通常只有“更好”和“不太好”。“损坏”和“可以改进”的界限并不总是容易看到。
无限制。
ML 中断的故障排除和解决涉及广泛的系统和组织部分。这是 ML 系统跨越组织内技术、产品和业务领域的方式的结果,比非 ML 系统更广泛地涉及组织范围。这并不是说 ML 中断一定比其他中断更昂贵或更重要——只是理解和修复它们通常涉及更广泛的组织范围。
在考虑这三大原则的基础上,本节的其余部分按角色组织。正如我们所述,许多在 ML 系统上工作的人扮演多种角色。无论你是否期望做这项工作,阅读每个角色的原则都是值得的。通过按角色结构化课程,我们可以突出特定于该角色的特定视角和组织安置。
模型开发者或数据科学家。
在 ML 系统管道的早期工作的人有时不喜欢考虑事故。对一些人来说,这似乎是他们宁愿避免的困难的“运维”工作。然而,如果 ML 最终在应用或组织中很重要,数据和建模人员绝对会参与最终的事故管理。他们可以采取某些措施来为此做好准备。
准备工作。
提前采取几个具体步骤可以显著提高组织应对事故的能力。其中包括以下几点:
组织和版本化所有模型和数据。
这是数据和建模人员为准备未来事件所能采取的最重要步骤。如果可能的话,将所有训练数据放入一个版本化的特征存储中,并清楚地记录元数据,说明数据的来源以及负责其创建和管理的代码或团队。通常会忽略到最后这部分内容:我们最终会对放入特征存储的数据执行转换操作,因此跟踪和版本化执行这些转换的代码至关重要。此外,如果可能的话,我们还应该在元数据系统中存储所有训练运行的中间产物。最后,将模型的历史版本存储为可即时服务的格式是很有用的。正如你所见,这些可以在模型质量迅速且无法解释地下降时,对快速缓解非常有用。
指定可接受的备用方案
当我们开始时,可接受的备用方案可能是“我们现在正在做的任何事情”,如果我们已经有一个足够好用的启发式方法。在推荐案例中,这可能是“只推荐最流行的产品”,几乎没有个性化。挑战在于,随着我们的模型变得更好,原有的启发式方法与我们所做的可能会有很大差距,以至于旧的启发式方法不再适用。例如,如果我们的个性化推荐足够好,我们可能会吸引多个(潜在上非常不同的)用户群体来使用我们的应用和网站。⁸ 如果我们的备用推荐是“流行的任何东西”,那么对于使用网站的每个不同子群体,这可能会产生真正糟糕的推荐。如果我们依赖于我们的建模系统,下一步是保存多个模型副本,并定期测试是否可以回退到它们。通过在任何时候使用几个版本的模型(例如主要、新旧模型),可以将此过程集成到我们的实验过程中。
决定有用的度量标准
最有用的最后一部分准备工作是仔细考虑模型质量和性能指标。我们需要知道模型是否有效,而模型开发人员会使用一组客观函数来确定这一点。最终,我们希望有一组能够检测模型停止有效运行的指标,而这些指标与其实现方式无关。这实际上比看起来更具挑战性,但我们越接近这个目标,效果就越好。第九章稍微详细地讨论了选择这些指标的主题。
事故处理
在事件发生期间,模型开发人员和数据科学家扮演着重要角色:他们解释当前构建的模型。他们还产生并验证关于可能导致我们所见问题的假设。
为了发挥这种作用,模型和数据的人员需要保持可接触性;他们应该按照值班轮换或等价的有组织时间表在非工作时间内可用。他们不应频繁被唤醒,但如果必要的话,他们可能是不可或缺的。
最后,在事件处理和分析期间,可能需要模型和数据人员进行定制数据分析,甚至生成当前模型的变体来测试假设。他们应该准备好这样做,但也应准备好拒绝任何违反用户隐私或其他伦理原则的请求。详见“伦理值班工程师宣言”以获取更多关于这个想法的详细信息。
持续改进
模型和数据的工作人员应致力于缩短模型质量评估循环,作为一个重要但不主导的优先事项。第五章 提供了更多细节,但这里的想法类似于任何故障排除:改变与评估之间的延迟越短,我们就能更快地解决问题。这种方法也将显著促进模型的持续发展,即使我们没有故障期间也是如此。为了做到这一点,我们必须为获取训练迭代、工具和所需的指标来证明人员配备和机器资源做好准备。这不会便宜,但如果我们投资于机器学习以创造价值,这是我们团队的这一部分提供该价值的最佳方式之一,风险最小的方式。
软件工程师
一些组织有软件工程师负责实现系统软件以使机器学习工作,将各部分粘合在一起,并移动数据。扮演这一角色的人可以显著提高事故处理的成功率。
准备工作
数据处理应该干净利落,具有清晰的来源和尽可能少的数据版本。特别是,在存在多个“当前”副本的情况下,这可能导致仅在模型质量下降或意外错误中才能检测到的微妙错误。数据版本应明确,数据来源应清晰标记和可发现。
如果模型和二进制部署分开且可分离,这将非常有帮助。例如,在服务中执行推理的二进制文件和它们所读取的模型应该独立地推送到生产环境中,并且每次都进行质量评估。这是因为二进制文件和模型都可能在微妙地影响质量。如果部署是耦合的,故障排除将会变得更加困难。
在服务和训练中的特征处理和使用应尽可能一致。一些最常见和最基本的错误之一是训练和服务之间特征使用的差异(称为训练-服务偏差)。这些包括特征量化的简单差异,甚至某些特征内容的改变(例如曾经是收入的特征变成了邮政编码,这会立即导致混乱)。
尽可能地实现或开发工具(有时测试开发由专门的测试工程师完成,但这取决于组织)。我们将需要用于模型部署和回滚、二进制部署和回滚的工具。我们应该有工具显示每个环境中数据版本(从元数据中读取),以及为客户支持人员或生产工程师(SRE)直接读取数据以进行故障排除的工具(带有适当的日志记录和审计追踪以尊重隐私和数据完整性保证)。在可能的情况下,找到已存在于您的框架和环境中的工具,但计划至少实施一些。存在有效运行的工具越多,软件工程师在事故发生时的负担就越低。
事故处理
软件工程师在事故期间应作为升级点,但如果他们的工作做得好,他们应该很少接到警报。软件失败会发生在模型服务器、数据同步器、数据版本控制器、模型学习者、模型训练编排软件和特征存储中。但随着我们的系统变得更加成熟,我们将能够将其视为几个可以有效管理的大系统:一个数据系统(特征存储)、一个数据流水线(训练)、一个分析系统(模型质量)和一个服务系统(服务)。对于 ML 而言,每一个问题都只比非 ML 问题稍微难一点,因此做得好的软件工程师在生产方面的责任可能非常低。
持续改进
软件工程师应定期与模型开发人员、SRE/生产工程师以及客户支持合作,以了解缺失的内容以及软件应该如何改进。最常见的改进将涉及对数据大变动的弹性和对软件状态的精心导出,以实现更有效的监控。
ML SRE 或生产工程师
ML 系统由某人运行。较大的组织可能会有专门的生产工程师或 SRE 团队负责管理这些系统的生产环境。
准备工作
生产团队在处理突发事件时应有足够的空闲时间。许多生产团队的工作任务从自动化到仪表化项目不等。像这样的项目工作既令人愉快,又常常在系统中带来持久的改进,但如果它们被高优先级和截止日期驱动,那么在和之后的事件中它们总是会受到影响。如果我们希望有效地执行项目工作,我们需要有备用容量。
我们还需要培训和实践。一旦系统成熟,大型事件可能不经常发生。我们值班人员熟悉处理事件管理过程本身以及我们的故障排除工具和技术的唯一方法是实践。良好的文档和工具可以帮助,但如果值班人员无法理解文档或找到仪表板,则没有用处。有些系统足够动态,以至于提供自己的定期实践机会(这是指出某些系统经常出现故障的委婉方式)。在这种情况下,团队应确保在机会出现时定期分享事件管理主导角色。对于那些情况不是这样的系统,安排在工作时间定期意图中断是一个不错的方法。⁹
生产团队应定期进行系统架构审查,以思考最可能的弱点并加以解决。这些可能是不必要的数据副本、手动过程、单点故障或不能轻易回滚的有状态系统。
设置监控和仪表板是一个独立的话题,将在第九章更详细地讨论《监控和模型可观察性》。目前我们应注意,监控分布式吞吐量管道非常困难。由于进展不能简化为单一值(我们仍在读取的最旧数据、我们已经读取的最新数据、我们的训练速度、剩余要读取的数据量),我们需要根据管道数据分布的变化来做出决策。
我们需要设置 SLO(服务水平目标)并捍卫它们。如前所述,我们的系统将以多维度、变化的表现方式行为复杂。要选择阈值,我们首先需要定义我们想要跟踪的 SLI(服务水平指标)。在机器学习中,这些通常是数据或模型的切片(子集)。然后我们会选择一个指标来衡量它们的表现。由于这些指标会随时间变化,如果我们的数据呈正态分布,我们可以通过它们与中位数的距离来选择阈值。¹⁰ 如果我们定期更新它们但不频繁,我们将继续对大的变化保持敏感,同时忽略较长期的趋势。这可能会错过在几周或几个月内慢慢发生的停机事件,但不会过于敏感。
生产工程团队应当深入了解所处的业务环境。这看似次要,但却并非如此。工作正常的 ML 系统对于部署它们的组织至关重要。要成功处理事故,SRE 或生产工程师应当了解业务的关键点以及 ML 如何与其互动。ML 系统是否进行预测、避免欺诈、连接客户、推荐书籍或降低成本?它如何以及为何这么做,以及这对我们组织有何重要性?我们的组织正在尝试实现哪些具体目标,并如何进行衡量?甚至更基本的是,我们的组织是如何构建的?对这些问题的提前回答将为生产工程师在优先级确定、故障排查和减轻 ML 中断所需工作方面做好准备。
最后,我们需要尽可能多的客观标准来触发事故。事故宣布前的最困难阶段往往涉及许多人的关注。存在广泛而不连贯的证据表明事情进展不顺。但在有人宣布事故并启动正式的事故管理机制之前,我们无法直接管理事故。我们提前确定的指导方针越清晰,混乱期间就越,混乱期间就越短。
事故处理
站在整个系统的角度回望。ML 中断很少由其显现的系统或度量标准引起。收入下降可能是由于数据缺失(在整个系统的另一侧!)。在服务中的崩溃可能是由于训练中模型配置的变更或连接训练与服务之间同步系统中的错误引起的。正如我们所见,周围环境的变化本身也可能是影响源泉。这与生产工程师通常采用的实践有所不同,但对 ML 系统中断却是必要的。
准备好与产品 与产品负责人和业务决策者打交道需有充分准备。机器学习(ML)中断很少仅限于技术团队的边缘。如果出现问题,通常会影响销售或客户满意度——即业务。对客户或业务领导进行广泛交流的经验并非生产工程师的典型要求。ML 生产工程师往往会迅速克服这种偏好。
其余的事故处理与正常的 SRE/生产事故处理相同,大多数生产工程师都擅长处理此类情况。
持续改进
ML 生产工程师将收集许多关于事件可能如何更好处理的想法。这些想法从监控到快速检测问题的方式到系统重新架构,以避免整个中断。生产工程师的角色是优先处理这些想法。
事故后的跟进项目有两个优先级维度:价值和实施成本/可行性。我们应优先处理既有价值又易于实施的项目。许多跟进项目属于“可能有价值但极难实施”的类别。这些项目应定期与高级负责人审查,但不应与其他战术工作并列优先,因为在那种情况下处理它们永远没有意义。
产品经理或业务领导人
业务和产品领导人经常认为跟踪和追踪事故不是他们的问题,而是技术团队的问题。一旦你在几乎所有方面都将机器学习引入你的环境中,你对它的意识可能就变得至关重要了。业务和产品领导人可以报告机器学习问题的真实影响,并建议哪些原因最有可能以及哪些减轻措施成本最低。如果机器学习系统很重要,业务和产品领导人应该并且将会关心它们。
准备工作
在可能的情况下,业务和产品领导人应该了解在他们的组织和产品中部署的机器学习技术,特别是负责任地使用这些技术的需求。正如生产工程师应该了解业务一样,业务领导人应该了解技术。
我们应该了解两个关键事项:首先,我们的系统如何工作(它使用什么数据来做出什么预测或分类),其次,它的局限性是什么?机器学习系统可以做许多事情,但也有许多事情它们(或许还)做不到。了解我们做不到的事情和我们试图做什么一样重要。
了解机器学习工作方式的业务和产品领导人,在严重事故中将比不了解的人更有用。他们还能直接参与挑选值得投资的机器学习项目的过程。
最后,业务领导人应确保其组织有能力处理事故。这在很大程度上意味着组织的人员配置到位,能够管理这些事件,接受过事故管理的培训,并投入必要的空闲时间来处理事故。如果没有这样做,业务领导人的工作就是为这些投资腾出空间。其他任何做法都会导致更长时间、更大规模的停机。
事件处理
业务领导人很少有值班轮班或其他系统化的方式紧急联系他们,但替代方案是“几乎每个人大部分时间都值班”。从文化上讲,业务领导人应考虑正式化这些值班轮班,即使只是为了让自己能自由地度假。另一种选择是授权另一组值班人员做出独立决策,这些决策可能会对收入产生重大影响。
在实际事故中,业务领导最常面临的问题是想要主导。这一次,他们不是最有价值或最有知识的人。他们有两项权利:首先,得到通知;其次,提供事件对业务影响的背景信息。他们通常无法直接有效参与事故处理;他们与技术系统的距离太远。许多业务领导应考虑通过其他人代理他们的问题,并避免直接参与事故通讯(聊天、电话、Slack 等),以避免他们天生的接管欲望。
持续改进
事故后,业务领导应确定工作优先级,并设定完成这些任务的标准。他们可以在不对如何确切改进提出特定意见的情况下进行这些操作。相反,他们可以倡导通用的标准和方法。例如,如果我们按优先顺序排列后续工作项目(从最高优先级到优先但不急需),我们可以优先处理最高优先级的错误,然后是高优先级的错误,依此类推。我们可以制定指南,如果在特定时间段内未完成所有最高优先级项目,则进行审查,以查明是否有任何阻碍因素及我们能否采取措施加快实施。
同样,产品团队在指定、维护和开发服务水平目标(SLO)方面发挥重要作用。SLO 应该代表满足客户需求并使客户满意的条件。如果不能满足,我们应该修改它们,直到达到目标。主要负责定义和演化这些价值的人是产品管理团队。
特别主题
我们还未解决在处理机器学习事故过程中出现的两个重要话题。本节深入探讨这些主题。
生产工程师与机器学习工程师对比建模
鉴于许多机器学习系统问题表现为模型质量问题,机器学习生产工程师似乎需要一定程度的机器学习建模技能和经验。如果这些工程师对模型的结构和功能一无所知,他们可能难以有效和独立地解决问题并评估潜在解决方案。反过来的问题也出现了:如果没有强大的生产工程团队,我们可能最终由建模人员负责永久的生产服务系统。尽管这两种结果可能是不可避免的,但并非理想情况。
这并不完全错误,但完全取决于具体情况。特别是在较小的组织中,模型开发人员、系统开发人员和生产工程师往往是同一人或同一个小团队。这与开发人员负责服务的生产部署、可靠性和事件响应的模型类似。在这些情况下,显然对模型的专业知识是工作的必要部分。
然而,随着组织和服务的扩大,要求生产工程师成为模型开发人员的要求完全消失了。事实上,在大型雇主的 ML 系统上进行生产工程的大多数 SRE 从未或很少独自训练模型。那不是他们的专长,也不是他们工作良好所需的或甚至有用的专长。
ML SRE(机器学习可靠性工程师)或 ML 生产工程师确实需要一定的与机器学习相关的技能和知识才能发挥效力。他们需要基本了解什么是 ML 模型,它们如何构建,以及构建它们的相互连接系统的特点和结构。系统组件之间的关系以及数据在系统中的流动比学习算法的细节更为重要。
例如,假设我们有一个监督学习系统,使用 TensorFlow 作业在特定时间执行,从特定特征存储或存储桶中读取所有数据,并生成一个保存的模型。这是构建 ML 训练系统的一个完全合理的方式。在这种情况下,ML 生产工程师需要了解 TensorFlow 是什么以及它的工作原理,数据如何在特征存储中更新,模型训练过程如何调度,如何读取数据,保存的模型文件的外观如何,大小如何,以及如何验证它。该工程师不需要知道模型有多少层或者它们如何更新,尽管了解这些也无妨。他们也不需要知道原始标签是如何生成的(除非我们计划重新生成它们)。
另一方面,假设我们已经确定了一个交付管道,其中机器学习建模工程师将他们的模型打包到一个 Docker 容器中,用适当的配置系统注释一些配置细节,并将模型提交为在 Kubernetes 中运行的微服务。机器学习建模工程师可能需要理解 Docker 容器的构建方式及其大小,配置选择将如何影响容器(特别是如果存在配置错误),以及如何跟踪容器到其部署位置并进行一些简要的日志检查或系统检查以验证基本健康检查。然而,机器学习建模工程师可能并不需要了解像 Pod 中断预算设置、容器 Pod 的 DNS 解析或 Docker 容器注册表与 Kubernetes 之间的网络连接细节等低级 Kubernetes 选择。尽管这些细节很重要,特别是在基础设施组件是故障的一部分的情况下,但机器学习建模工程师可能不适合解决它们,可能需要依赖熟悉基础设施该部分的 SRE 专家来处理这些类型的错误。
对模型构建的详细知识确实非常有帮助。但是,大多数组织遇到的最大可靠性问题并不是缺乏关于机器学习的知识,而是缺乏构建和产品化分布式系统的知识和经验。机器学习知识是一个很好的补充,而不是最重要的技能集。
《伦理值班工程师宣言》
在本章中,我们已经讨论了当涉及到机器学习时,如何执行事件响应不同且更加困难。机器学习事件响应变得困难的另一方面是在解决问题并处于待命状态时如何处理客户数据,我们称之为隐私保护事件管理的约束。对一些人来说,这是一个难以适应的改变,因为今天(以及几十年前),值班工程师习惯于及时且不受限地访问系统、配置和数据以解决问题。但遗憾的是,对于大多数组织和大多数情况,这种访问是绝对必要的。我们无法轻易移除它,同时又允许快速修复问题。
在值班工程师响应、故障排除、缓解和解决服务中断的过程中,他们需要特别注意确保他们的行动是道德的。特别是,他们必须尊重用户的隐私权利,监视并识别不公平的系统,并防止机器学习的不道德使用。这意味着需要仔细考虑他们行动的影响——在紧张的值班期间并不容易做到,并且需要与大量和多样化的熟练同事咨询,以帮助做出周到的决策。
为了帮助我们理解为什么这样做是必要的,让我们考虑机器学习伦理考虑的四个事件维度:影响(严重性和类型)、原因(或促成因素)、故障排除过程本身以及行动呼吁。
影响
涉及公平性的模型事件可能对我们的用户造成巨大且即时的伤害,当然也会给我们的组织声誉造成损害。无论效果是否显而易见于跟踪高级别关键绩效指标的生产仪表板,这都无关紧要。想象一下一个银行贷款批准程序出现意外偏见。尽管申请中提供的数据可能省略了申请者种族的详细信息,但模型可能会从提供的数据以及其他标签数据中学习到种族类别。¹¹ 如果模型然后在批准贷款时系统性地对某些种族进行歧视,我们可能会批准同样数量的贷款,并在高级别仪表板上显示大致相同的收入数字,但结果是极不公平的。这样一个存在于用户面向生产系统中的模型对我们的客户和组织都可能是有害的。
在理想情况下,没有任何组织会在不经过至少粗略的负责人工智能评估的情况下使用机器学习作为系统和模型设计的一部分。¹² 这种评估将为在模型中可能出现的偏见的识别和缓解提供清晰的指导方针、指标和工具。
原因
对于任何事件,导致或促成停机的原因可能对在岗的工程师产生伦理上的影响。如果原因竟然是一项难以逆转的刻意设计决策呢?或者模型在开发过程中根本没有或没有足够地关注伦理和公平性问题呢?如果系统会因为昂贵的重构而继续以这种不公平的方式失败呢?内部威胁是真实存在的¹³,不要忘记,但我们并不需要想象有预谋的恶意才会发生这些事情:一个同质化团队,强烈专注于产品上线而排斥其他一切,可以纯粹因偶然而使其成为可能。当然,目前大多数机器学习系统缺乏可解释性,这一切都进一步加剧了问题。
故障排除
在故障排除阶段经常会出现伦理问题(通常是隐私问题)。正如您在故事 3 中看到的那样,查看原始用户数据可能是诱人的——有时甚至是必要的——用于解决建模问题。但这样做直接暴露了私人客户数据。根据数据的性质,它可能还会涉及其他伦理问题——例如,一个包含客户投资决策的金融系统的原始数据。如果员工可以访问这些私人信息并将其用于自己的个人投资,显然是不道德的,并且在多个司法管辖区可能严重违法。
解决方案和行动号召
好消息是这些问题大多数都有解决方案,并且开始解决问题成本合理。一方面,我们已经谈论过多样化团队在确保组织免受不良后果方面扮演的普遍低估角色。解决这些问题通常涉及修复产生问题的过程,而不是仅仅减轻一次性的伤害。
但是,仅仅拥有多样化的团队成员并不能解决问题。团队需要在模型和系统设计阶段采用负责任的人工智能实践,以便创建对公平性指标进行一致监控并为事件响应者提供评估框架。在事件管理期间故意或无意地访问客户数据时,默认情况下限制访问,并通过理由、日志记录和多人负责来行使伦理检查,是风险与回报的合理平衡。其他有助于避免构建有缺陷模型的机制已在第六章中概述。
最后,尽管我们无权单方面宣布它——也不愿意这样做——但我们坚信有理由正式化这样的宣言,并在整个行业推广。时间将会来临——如果它还没有到来的话——当一名值班工程师发现某些重要且值得公开披露的事情时,可能会对如何处理产生冲突。在机器学习领域没有一个普遍理解的告密者定义的情况下,社会将受到影响。
结论
机器学习模型在某种程度上是世界现状及其变化与计算机系统之间的接口。该模型旨在将世界的状态表示给计算机系统,并通过其使用允许计算机系统预测并最终修改世界。在某种意义上,这适用于所有计算机系统,但对于机器学习系统而言,在语义上更高更广泛地适用。
想象一下诸如预测或分类等任务,其中 ML 模型试图学习世界上一组元素,以便正确预测或分类未来的这些元素实例。预测或分类的目的始终是并且必须是,根据预测或分类改变计算系统或组织的行为。例如,如果一个 ML 模型确定一笔支付是欺诈行为,基于交易的特征和我们的模型从先前交易中学到的信息,这个事实不仅仅会悄悄地记录在某个账本上 —— 相反,在做出这样的分类后,模型通常会拒绝该交易。
ML 失败特别在于三个元素之间的不匹配:世界本身及其关键事实、ML 系统表示世界的能力,以及系统作为整体适当地改变世界的能力。这些元素的每一个或者通常是它们之间或交叉点处可能出现失败。
ML 事件就像其他分布式系统的事件一样,除了它们不同的方面。这里的故事分享了几个共同的主题,将帮助 ML 生产工程师准备好在 ML 系统中识别、排查、减轻和解决问题。
在本章中关于 ML 系统的所有观察中,最重要的是 ML 模型在工作时对整个组织都具有重要意义。因此,模型和数据质量必须成为组织的使命。当 ML 模型出现问题时,修复它有时也需要整个组织的参与。希望让他们的组织准备好管理这类中断的 ML 生产工程师们应确保工程师理解业务,业务和产品领导者理解技术。
¹ 如果您正在寻找关于一般事故管理的详细覆盖,您可以考虑查阅Site Reliability Engineering和PagerDuty 事故响应手册。
² 更多详细信息,请参阅Site Reliability Engineering的第十四章。
³ 这种漂移,以及黄金集的内容,也是我们系统中不公平偏见可能成为因素的关键地方。详见第六章,更详细地讨论这些主题。
⁴ 对数据混合的这种限制在某种程度上很常见。公司对他们的商业数据(例如谁在搜索了Y之后购买了X)被用于使他们的竞争对手受益非常敏感。在这种情况下,这些公司甚至可能把 YarnIt 视为竞争对手(尽管后者为他们带来了他们重视的大量业务)。
⁵ 这是测试这一假设的一种冒险方式。最好先推出一个单一模型来验证旧模型的表现更好,并且没有其他灾难性问题。但在高风险的故障期间,这是人们可以辩护的选择。
⁶ 事件响应有一对有用的概念。恢复点目标(RPO)是我们能够在恢复故障后将系统恢复到全功能状态的时间点,理想情况下是故障前的即时。恢复时间目标(RTO)是从故障中恢复系统功能需要的时间。ML 系统当然有一个 RTO;重新训练模型、复制旧版本等需要时间。但问题在于,大多数 ML 系统没有一个有意义的 RPO 概念。偶尔,一个系统完全在“过去”上运行,基于预先存在的输入,但大多数时候 ML 系统存在是为了调整我们对世界当前变化的响应。因此,唯一重要的 RPO 是“现在”,对于不断变化的“现在”值。一个“几分钟前”训练的模型可能对“现在”来说足够好,但也可能不够。这显著复杂化了对解决方案的思考。
⁷ 在许多司法管辖区中,IP 地址可能被视为个人信息或 PII,因此必须谨慎行事。这并不总是系统工程师或运营商广泛理解的,特别是在法律监管框架较为松散的国家工作的人。此外,可以与同一用户相关联的搜索查询通过组合查询表明展示私人信息。著名的例子,请参阅维基百科的"AOL 搜索日志发布"页面了解背景。
⁸ 当然,这些不同的建议可能意味着模型正在捕捉到不公平偏见的代理,模型设计师和操作者应使用公平性评估工具定期查找这种偏见。
⁹ 关于这个主题的更多信息,请参阅凯西·罗森塔尔和诺拉·琼斯的《混沌工程》(O'Reilly,2020)。
¹⁰ 关于此及设置阈值技术的统计信息在迈克·朱利安的《实用监控》(O'Reilly,2017)中有很好的涵盖,特别是第四章。
¹¹ 在那些有种族隔离住房的地区,模型可以从地理因素中学习种族信息,从那些与种族相关的家庭或名字中学习,还可以从有种族隔离教育的地方的教育历史中学习,甚至可以从职位名称或职业行业中学习。在一个种族偏见的社会中,许多信号与种族相关,模型可以轻松学习这些信号,即使模型中没有种族标签。
¹² 这个主题在第六章中有更详尽的探讨。
¹³ 例如,参见“著名的 Twitter 账户被黑客入侵:内部威胁还是社会工程攻击?” 的 Clare O’Gara,尽管出现在报纸上的事件几乎可以被定义为实际发生事件的一个小子集。
第十二章:产品与机器学习的互动方式
随着公司急于利用机器学习能力来满足客户需求,它们渴望利用前沿研究来解决各种业务应用问题。许多产品团队和业务经理,仍然坚守传统软件产品开发方法论,发现自己处于一个新而陌生的领域:构建机器学习产品。
构建你的第一个机器学习产品可能会令人不知所措。这不仅仅是关于如何正确运用机器学习,这本身就已经够难了;更重要的是,将机器学习整合到产品的其余部分(以及企业的其余部分)需要许多需要共同运作的事物。在这些事物中,数据收集实践与治理、数据质量、产品行为的定义、UI/UX 以及业务目标都对基于机器学习的产品或特性的成功起到了贡献作用。
不同类型的产品
机器学习的一个重要且有用的特点之一是它可以应用于许多类型的产品中。它可以用于分析应用程序,以推断业务趋势和指标。它可以集成到家电或设备中,以便发货给消费者。复杂的机器学习系统被内置到自动驾驶汽车中,用于检测其他对象并做出驾驶决策。机器学习应用的广泛程度是巨大且不断增长的。由于这些广泛多样的用例,专注于将机器学习整合到现有或新产品中的组织面临着极其陡峭的学习曲线和关于其实施的众多选择。
这一章节不涵盖大多数不同类型的机器学习。特别是,本章无法认真考虑存在的许多常见类型的机器学习产品集成。相反,我们将专注于本书中一直讨论的用例:yarnit.ai(我们的电子商务网店)希望集成机器学习。
特别考虑这个用例具有一些良好的方面,并不仅仅因为它延伸了本书中每章都触及的一个例子。yarnit.ai的用例集合包括一些后端的(例如,使用浏览和购买日志来预测产品的兴趣),以及许多前端的集成(例如,查找这位客户可能现在对哪些产品感兴趣)。它具有一定的复杂性,但对大多数读者来说并不难以理解。当然,显然它无法成为每个可能系统的合适类比。尽管如此,我们仍希望这里的内容对您有所帮助。
敏捷机器学习?
除了某些明确定义的环境外,许多当代软件工程团队已经转向以迭代、专注和短周期循环(称为sprints,依据敏捷宣言)开发。然而,将敏捷方法应用到机器学习系统远非易事。作为一种方法论,敏捷具有几个基本特征:短反馈循环、以客户为导向的故事或故事点,以及旨在小团队上工作这些故事点的估算。
将机器学习集成到产品中违反了这些假设。反馈循环较长(有时长达数月或数年),并且间接来源于数据而非直接来源于客户。小团队执行效果较差,因为集成通常涉及公司各部门的人员(详见第十三章)。模型开发可能会有任意长的延迟,因为我们需要将模型集成到产品中,并等待结果显示在数据中。此外,我们不能先构建再验证,因为即使是构建阶段也需要基于数据。还有一个最后的、可能是最重要的观点:机器学习模型既不是完全可重现的,也不是随时间稳定的。正如已指出的那样,我们可以多次训练相同的模型但结果不同,或者我们可以保留相同的模型,但世界已经发生了足够的变化,以致我们的价值不再相同。机器学习模型永远不会“完成”,因此机器学习产品集成具有有限的确定性。
尽管敏捷方法可能不太适合机器学习,但采用本章讨论的标准机器学习开发生命周期可以促进您的组织利用机器学习系统来提升客户体验并增加收入。
机器学习产品开发阶段
为了在产品开发生命周期中管理不确定性,机器学习项目从一开始就需要高度迭代。机器学习产品开发项目的最重要阶段包括发现与定义、业务目标设定、MVP 构建和验证、模型与产品开发、部署以及支持与维护(参见图 12-1)。

图 12-1. 机器学习产品开发阶段
发现与定义
机器学习产品的开发始终应从发现和定义开始。跳过这一步是诱人的,特别是如果你来自先构建后验证的背景,但在机器学习环境中,这一步至关重要,有助于产品团队早期处理不确定性。首先要定义问题空间,并理解和框定业务问题及预期结果。这一过程以将问题映射到解决方案空间结束,这并非总是易事。技术团队寻求量化基准以衡量可行性。另一方面,业务部门在结果不明确的时候,努力实现清晰度,并寻求明确的成本效益分析。在满足利益相关者需求、业务问题框架、定义目标与结果以及与业务建立关系方面,将是关键。
考虑到我们的产品最终设计用于向人类显示结果,没有捷径可以替代传统的用户研究。进行彻底的用户研究,以识别用户的痛点并根据其需求进行优先排序。这有助于建立用户旅程地图,识别关键工作流程和潜在障碍。此外,路线图对于定义需要修改的流程以使机器学习解决方案首次运行非常有用。您可以进行市场规模评估以估算业务潜力。接下来的问题是,我们如何知道机器学习是否能帮助解决我们的用户问题?虽然有许多机器学习应用存在,但在其核心,机器学习最适合做出决策或预测。通常情况下,我们面向人类的机器学习系统在生产中部署时将具有以下一个或多个特征:
复杂的逻辑,难以通过人定义的规则解决
例如,搜索引擎通常有多个排名阶段依次发生,如从文本索引的初始检索,使用文本相似性的主要排名,上下文排名和个性化排名。
大规模个性化
如果问题预计会扩展到数千用户或更多,则可能是机器学习的一个良好应用案例。在yarnit.ai网店的例子中,我们预计在三到六个月内将有成千上万的客户利用新的优惠/折扣,这意味着需要支持大量用户群体的个性化。
规则会随时间快速变化
如果规则一般在多年间保持静态不变,启发式解决方案更可取。但是,如果业务的成功依赖于快速适应和规则变更,则机器学习是一个不错的选择。例如,如果网店用户不断撰写产品评论,推荐相关产品的算法需要实时调整,适合机器学习解决方案。
明确的评估指标
例如,我们希望模型提供能够促成销售的推荐。在搜索中,键入“儿童帽子”应该返回与儿童颜色或编织规格针相关的图案和纱线列表,这与帽子相关。
不需要百分之百的准确性
如果可以通过高准确率而不是完美来实现业务成功,机器学习是一个不错的选择。例如,如果用户并不总是想要所提供的内容,推荐系统也不会被认为是有故障的。用户仍然可以有很好的体验,并且机器学习模型可以从销量不佳中学习,在未来提供改进的推荐。
业务目标设定
机器学习需求的选择需要仔细结合设计和业务目标。产品经理(PMs)需要理解最终用户和长期的业务目标以推动价值。例如,我们希望改进网店,鼓励客户找到并购买更多他们想要的产品,但我们也真正希望这种情况每次客户返回时都会重复发生。最终,我们通过专注于最终用户并深入理解产品可以解决的特定问题来实现这一点。否则,可能会出现开发一个极其强大的系统,但只解决了一个小(或可能不存在的)问题的风险。
机器学习很少是无错误的,没有防护措施的开发可能会产生严重后果。我们需要承认,出现错误可能会带来巨大的成本,了解犯错的成本是构建机器学习产品的重要部分。例如,假设我们试图在客户因订单错误和/或计费问题而联系支持团队时预测并取消订单。在这种情况下,模型中的错误可能会错误地解释用户的意图为取消订单,从而对用户和公司产生财务后果。另一方面,对于推荐系统来说,在产品详细页面上建议类似产品给没有购买历史的用户,错误推荐的影响可能仅仅是低转化率,也许是对我们的网店不太信任或不太有用的模糊感觉。然后我们必须考虑如何改进模型,但在我们的用例中犯错的后果并不是灾难性的(尽管在许多其他机器学习产品中显然是这样)。
机器学习在很大程度上依赖于概率。因此,模型给出错误输出的可能性总是存在的。产品经理负责预见并认识到错误预测的后果。预见此类后果的一个很好的方法是进行测试,测试,再测试一些。了解模型计算的概率组成部分。我们需要根据机器学习的业务目的来考虑模型的期望精度(和召回率)。
一旦确定了预测错误的所有后果,PM 需要确保定义并构建相关的安全网以减轻风险。此外,PM 可能会考虑改变基础产品(更改交互流程、修改输入和输出数据路径等)的方法,以减少不正确预测的可能性。因此,安全网可以是内在的和外在的,它们融入到所有产品中。ML 也不例外。在将 ML 引入产品之前,定义与正在构建的产品相关的安全网和业务绩效指标是至关重要的一步。
内在的安全网
这些指标体现了产品本质上的不可能性。例如,在我们的网店中,如果用户根本没有下订单,就不能取消订单。收到这类用户的电子邮件,没有订单号,主题是“取消订单”,可以被试图学习订单取消原因的模型忽略。但是,建议让客服人员调查这种情况是个好主意。为产品绘制用户旅程图,并确定用户可能经历的状态,是一项有用的活动。这有助于排除不可能的预测。内在的安全网对用户是不可见的。
外在的安全网
外在的安全网对用户是可见的。它们可以采取确认用户意图或双重检查潜在结果的形式。某些消息系统有一个模型,试图检测消息的意图并为其用户建议回复。然而,在大多数情况下,这些系统不会自动假定回复是正确的,并在未经人类确认的情况下发送。更常见的情况是,这些系统要求用户从潜在回复列表中选择。
业务绩效目标
除了我们在第八章中讨论过的一般 ML 模型性能指标之外,对于 PM 来说,清楚地定义业务绩效指标以衡量 ML 系统在生产中的成功非常重要。为了评估业务绩效,必须从产品或功能目标开始。例如,增加收入可能是我们yarnit.ai网店的一个很好的业务目标。一旦定义了这个目标,就应指定一个产品指标来评估成功。最好的指标具体可测。具体的指标减少了歧义,增加了关注度。此外,成功衡量起来越容易,我们就越有把握实现最初设定的结果。
这些指标因产品而异。例如,在像yarnit.ai这样的电子商务店铺上,跟踪基于 ML 的推荐的一些重要业务指标包括:
点击率(CTR)
从推荐列表中产品页面的浏览次数除以推荐列表上显示的产品总数。例如,在购物车页面上,此指标将有助于确定支持“常一起购买”的 ML 模型的成功程度。
转化率
从推荐列表中添加到购物车事件的数量除以推荐列表上显示的产品总数。例如,在产品详细信息页面上,此指标将有助于确定支持“与类似商品比较”列表的 ML 模型的成功程度。
平均订单价值(AOV)
所有购买事件的订单的平均价值。AOV 等于总收入除以订单数。
推荐者参与的 AOV
包括至少从推荐列表中选择的一个商品的订单的平均价值。这是从推荐者参与的收入除以至少包含一个从推荐列表中选择的商品的订单数量计算出来的。
总收入
所有记录的购买事件的总收入。此值包括运费和税费。
推荐者参与的收入
包括至少从推荐列表中选择的一个目录商品的购买事件的收入。此值包括运费、税费和任何折扣。
此外,电子商务企业通常会追踪更多的业务指标,包括客户获取成本(CAC)、客户生命周期价值(CLV)、客户保留率(CRR)、退款和退货率(RrR),以及虚荣指标,如社交媒体参与度、网站流量和页面浏览量。¹
MVP 构建与验证
为了确定我们是否可以将 ML 模型整合到我们的产品中,投资 ML 模型可能会很昂贵。我们需要回答两个问题:(1)我们能否制作一个有效(或足够有效)的模型?(2)我们能否以引人注目且有用的方式将该模型整合到我们的产品中?建立具有正确特征和标签的数据集,训练模型,并将其投入生产,这可能需要几周到几个月的时间。我们希望尽早获取有用性的信号,以验证模型是否有效。可以通过仔细的离线评估我们构建的模型来实现这一点,分析我们预期从应用程序中获得的各种常见用例的响应。
为了评估用户交互的效用,最好先模拟该交互,针对一小部分用户。有时,这被称为使用一组固定规则或启发式方法(而没有真实的 ML 模型)来推动“最小可行产品”(MVP),以证明该功能确实能解决客户需求的点。
例如,考虑个性化使用情况,准备好一系列物品让用户根据他们上次选择的内容进行选择。简单的基于规则的引擎通常是进化为更复杂机器学习模型的第一步。以下是一些基于规则的推荐系统的例子:
-
如果用户购买了编织图案,他们可能还需要用于该图案的毛线以及针和其他编织相关用品。
-
如果用户每到秋天天气变冷就购买新的毛线,我们应该在他们所在地的每个秋天向他们推荐。
-
如果用户总是使用信用卡支付,我们将其作为下次的默认支付选项显示出来。
显然不可能编写覆盖每种情况的规则,这时候机器学习可以发挥最好的作用,但是一些简单的基于规则的代理可以在很大程度上验证机器学习方法的结果。关键是测试用户是否积极响应机器学习。尽管这些技术可能不会提供最佳结果,但对于获取信号而言至关重要。早期获取信号可以节省时间和精力,并帮助修正产品的视野和方向。这是确保投入建立机器学习系统的投资回报的最佳机会。
模型和产品开发
通过之前阶段制定的明确目标和目标,下一步是构建模型并将其集成到面向客户的特性中。关于此的一般介绍,请参阅第三章和第七章。但总体而言,这是一个与设计、工程、机器学习研究员、业务所有者和产品经理共同努力的过程,产品经理可以通过持续的利益相关者管理带来很大价值。从简单到复杂的构建过程将推动产品通过训练、测试和验证周期;管理与科学家们的站立会议,无论是否取得进展;以及导航设计、科学和工程团队之间的迭代依赖关系。我们在第十三章中讨论了各种团队的角色和责任。
部署
在生产部署阶段,机器学习系统被引入基础架构,用于服务实时客户流量,并收集反馈数据,这些数据被馈送到机器学习训练管道以改进模型。反馈循环有助于衡量模型的影响,并能增加对可用性的整体理解。在机器学习系统的背景下,反馈对于模型学习和变得更好也非常重要。我们在第八章中讨论了各种模型服务架构和最佳实践。
反馈循环是重要的数据收集机制,产生可直接插入学习机制的标记数据集。在我们的 yarnit.ai 网店示例中,反馈循环可能会相当简单——客人是否点击了推荐,并且是否购买了这个推荐?
将产品推向生产环境应该与在控制范围内观察业务指标(本章前面讨论过)紧密联系,以了解影响并做出增加推广或关闭推广并调查意外结果的决策。特别是,一个挑战是,大公司中的具体倡议或项目最终包含了建立机器学习模型的日常工作,这些倡议与更高层次的业务目标可能存在许多层次的分离。个性化是一个很好的例子:在高层次上,个性化可能涉及增加像每用户平均收入或增加新用户获取增长这样的指标。但是当一个模型被开发时,它很可能会被优化以改善各种低级用户体验指标,比如参与度分数。
产品经理在这两个领域之间充当翻译者的关键角色,并不断努力改进用户可观察性方法,这些方法可以帮助将低级别改进与高层次影响假设相连接。因此,对产品团队而言,有一个逐步部署机器学习系统的计划非常重要。我们在第五章中讨论了各种模型评估方法。
支持与维护
设计用于整合到产品中的机器学习系统在其首个发布版本上并不完整。可以说,它们永远不会完整,因为它们试图对世界的状态建模,并在产品中提供关于世界状态的有用价值。虽然开发和部署机器学习系统可能相对廉价,但随着时间的推移,维护它们可能比通常假定的更难以及更昂贵。²
组织如果真的认真将机器学习整合到其产品中,就需要认真对待维护这些机器学习模型及产生它们的基础设施。这至少部分解释了为什么敏捷方法不太适合机器学习产品的整合:它们从未真正完成,或者说它们永远不会完成。随着我们产品的变化、客户需求的变化、我们对业务的理解以及世界的变化,我们将需要不断开发和发布模型。
机器学习系统的一个特点是,通常不清楚团队正在进行的工作是“维护”还是“开发”,因此依赖于它们之间清晰分离的发展工作概念很难应用。
自建与购买
在这一部分中,我们需要仔细界定是否建立或购买的问题。模型是归数据和基础设施拥有的组织所属的。一般来说,模型必须来自于您自己数据的学习。[³] 但是,我们用来创建模型的工具和基础设施则是另一回事。ML 领域提供了大量的工具,包括开源和商业工具。建造与购买的决定通常是在成本、风险、定制、长期资源可用性、知识产权(IP)和供应商锁定等方面进行权衡。然而,在 ML 时代,我们有更多维度来考虑这个传统问题,包括制造或购买模型、数据处理基础设施/工具以及将所有这些内容保持在一体的端到端平台。在决定什么对企业最好时,这里有一些要考虑的因素。
模型
正如我们所述,模型通常是本地的,不容易在我们自己的组织之外获取。尽管如此,许多行业特定的 ML 模型和应用程序是可用的。供应商提供的解决方案可能会带来显著的节省时间和精力的潜力,但下面讨论的评估模型建造与购买的关键方面。
通用用例
购买预构建解决方案需要我们的组织目前使用的数据和流程与预期的输入/输出和行为高度兼容。如果一个用例的细节、数据或流程相对于组织而言是相当特定的,那么调整内部系统和流程以匹配供应商提供的解决方案的规格可能会抵消购买现成产品的好处。如果打包解决方案真正通用,它可以提供巨大的好处。简单阅读本段可能会听起来好像这种情况比较少见:是否存在一个通用模型,它能够在不需要在我们的数据上重新训练或扩展的情况下做到我们需要的功能?
随着 ML 服务提供商的增加,这里的机会正在变得越来越好。考虑一些非常有用但真正通用的用例:
图像中的物体识别
告诉我图片里有什么。
多语言文本转语音和语音转文本
与用户进行口头交互。
情感分析
告诉我一组文本对其主题的积极或消极程度。
在所有这些例子中,预训练模型可以在大量用例中表现良好,包括我们在 YarnIt 的用例。在这些情况下,我们可能完全可以跳过训练模型的步骤。
公司的数据倡议
在部署特定 ML 用例方面所做的工作的好处远远超出了该用例本身。通常情况下,第一个用例是全面数据倡议的开始。因此,ML 模型和/或应用程序的建设或购买决策也应考虑公司的数据策略:有时获取专业知识和技术本身就是真正的目标。
数据处理基础设施
数据处理和基础设施工具与技术已经发展,并且仍在以极快的速度不断发展。传统供应商、开源和基于云的解决方案在数据基础设施、处理和存储堆栈的每个环节上都在竞争。建立或购买的含义略有不同,并且通常更侧重于如下责任的委派:
支持和/或维护
通常是全开源的,与独立第三方软件供应商相对比
运营
云与本地
可访问性
打包的云工具与原生云工具
在数据处理基础设施方面,主要的决策因素不再是关于使用案例,而是关于内部可用的技能和供应商锁定风险因素。商业和开源平台各有其利弊。
在 ML 领域,许多商业平台是新的,并来自新提供商,缺乏任何长期的记录或历史。因此,它们可能提供了重大的机会,但也存在重大的风险。
另一方面,无论是用于 ML 还是通用软件的开源解决方案,可能被广泛采纳,在许多情况下比某些商业解决方案有更长的历史记录。但它们也有缺点。特别是它们可能具有较慢的发布周期,但更重要的是,它们很少为问题提供完整的解决方案。开源 ML 解决方案通常是更广泛背景下的优秀点解决方案,但仍然需要我们做必要的工作来将它们集成到我们的环境中,并组装一个完整的解决方案。
End-to-End 平台
在当前成熟度状态下,基本上没有提供从数据开始到在服务系统中可用模型的相对完整集成解决方案的 ML 平台。这并不一定是一个巨大的问题。模型、数据处理基础设施、人力资源和业务价值在不同的方式和速度下都在发展。将所有东西协调在一起,以确保 ML 的可持续成功,需要大量的努力。但同样,在这里,决策因素是不同的,现在基于组织数据方法的基本原则:
长期或一次性数据倡议
ML 工具和技术正在不断发展,创新的速度没有减缓的迹象。这带来了一个严重的问题,类似于我们在其他情境中看到的问题:技术投资必须有时间去回报。如果一个平台的效用在我们完成实施成本之前就消失了,我们可能会意识到我们犯了一个错误。虽然在分布式计算或数据存储平台中有时会有这种显著关注,但在 ML 领域尤为困难,因为工具和技术可能在适当实施它们的时间内就已经过时了。⁴ 如果该倡议意图是长期的,那么获得一个能够适应快速发展的数据技术的完整平台可能是相关的,而对于短期倡议,可能可以基于今天的组件进行组装。
数据倡议的预期规模
在小规模 ML 项目中,不需要过多的整体连贯性或一致性,这导致更自然的“构建”场景。如果更广泛的愿景是扩展数据以增强组织活动的重要部分,那么需要包含许多技能和公司流程来成功执行该愿景。在这种情况下,购买方法可能更相关。
例如,商业 ML 平台不仅允许团队完成一次完整的数据项目,还在各个方面引入效率来实现规模化。其中包括以下功能:
-
节省清洗数据和执行数据处理流程中不提供直接业务价值的其他部分的时间
-
在每天部署模型时,平滑生产问题并避免重复发明轮子
-
改善文档和可再现性,以便更轻松地符合一些监管要求
决策制定的评分方法
一旦我们明确了要解决的问题,并且我们需要 ML 来解决这个问题,至少我们需要考虑以下每个因素来评估构建或购买 ML 是否是正确选择:
对齐
产品或技术是否很好地满足我们的需求?我们的目标是否实现了?是否需要定制?是否满足数据隐私和安全要求?
投资
是否必须实现特定的净现值(NPV)或投资回报率(ROI)?总体拥有成本包括人力资本、软件和硬件是多少?
时间
我们能多快开发并部署解决方案到生产环境中?
竞争优势
技术是否提供了专有的资产或 IP?这个 IP 是否为客户、员工和投资者提供了增加的价值?
维护和支持
人力资源、硬件和软件支持的工作量和成本是多少?
我们可以根据这些因素的权重来决定我们的平台的哪些部分是应该构建还是购买的。
做出决策
无论是自建还是购买,将 ML 技术作为关键业务工具的决策是一个战略性决定,不应轻率或在所有支持因素未就位的情况下做出。重要的是仔细评估决策将如何影响公司的长期目标和路线图。
此外,不要忘记与主要利益相关者会面,审查决策标准并确定利弊。我们在第十三章和第十四章详细讨论了各个团队和关键利益相关者的角色和责任。包括领导层、产品和销售团队以获取有效变更管理的共识和反馈至关重要。最后,与各种供应商交谈,权衡各种选择。与他们坦诚相待,获取他们对您选择和情况的诚实意见。我们可以通过任何一条路径实现结果,但需要利用先前发现步骤的结果来帮助为组织的独特需求做出正确的解决方案。
由 ML 提供支持的样例 YarnIt 商店特性
机器学习(ML)可以在像yarnit.ai这样的网络商店中用来实现各种业务目标。 ML 可以通过提高转化率和平均订单价值来增加收入,可以提高利润率,甚至可以提高客户忠诚度。今天的消费者不想被视为众多顾客中的一个。他们更喜欢高度个性化的体验。产品推荐是一个许多特性可以由 ML 模型驱动的领域。就像人类了解某人然后能够选择最适合他们的生日礼物一样,ML 模型可以利用包括产品目录、搜索查询、浏览历史、过去的购买、放入购物车的商品、社交媒体上推荐的产品、位置、客户段/买家人物等数据。以下是一些示例推荐用例。
展示总销量最高的毛线
这种非个性化的技术不是基于用户的个人选择,而是基于集体偏好。推荐可能根据以下标准在主页上显示:
-
购买的毛线或图案数量(例如,在假期季节发布新图案时,所有人都赶去购买)。
-
顾客在查看特定类型的毛线或图案上花费的时间。
-
用户所在国家或地区的浏览次数和购买次数。在多个国家或地区运营网络商店时,通常需要考虑文化或季节因素。
在这个例子中,虽然我们可能并没有真正个性化客户的体验,但是展示每个类别(线的类型、图案、品牌等)的热门商品可以定位首次使用者,这些使用者尚无账户历史记录(即所谓的冷启动问题)。这显然有利于仅依赖经过时间验证的数据库技术,这些技术比机器学习更为普遍和可靠。
基于浏览历史的推荐
正如其名称所示,用户将根据他们已经查看过的产品获取新的产品建议。例如,如果用户正在搜索和浏览“羊毛线”,我们可以展示由专门生产羊毛线和图案的热门品牌制作的产品。
交叉销售和提升销售
大多数现代网店都有一些基础设施设计用于交叉销售和提升销售。这两者都旨在帮助用户选择可能的最佳商品,同时即使我们正在向新客户销售,也可以增加收入。例如,当客户在产品页面搜索“婴儿线”时,展示交叉销售建议,如“使用这种线的图案”和/或“流行的婴儿服装”,不仅有助于提高平均订单价值,还可以为客户节省时间。类似地,展示大尺寸或捆绑销售的特别折扣可能有助于客户节省费用,同时增加我们业务的收入。
基于内容的过滤
利用产品的元数据来推动推荐。元数据的准确性将对这类推荐的质量产生更大的影响。
例如,如图 12-2 所示,许多网店在产品详细页面或结账前后都有“类似产品”功能。在我们的yarnit.ai网店中,如果我们的用户总是购买来自品牌“xyz”的“红色”和“蓝色”棉线,我们可以考虑在推荐的商品中,推荐来自另一个品牌“abc”的相同颜色和类型的棉线,前提是这些推荐的商品也具有相似的质量评级,并且“abc”正在举行特卖活动。

图 12-2. 带有“类似产品”功能的基于内容的推荐
协同过滤
协同过滤可能被认为是所有产品推荐方法中最流行的。这种技术仅依赖其他用户如何积极与产品互动(查看、购买或对购买的积极评价)。这种方法源于这样一个想法,即过去喜欢相似事物的人们未来可能也会喜欢同样的东西。此外,它信任真实的人们所做出的选择,而不仅仅是简单的评级,后者可能只是估算的猜测。
例如,如图 12-3 所示,用户 A 和用户 B 在其浏览和购买历史以及网店产品反馈方面具有相似的用户画像。利用这些相似性,当用户 B 在“毯子纱线”产品详情页面时,我们可以展示用户 A 购买的“标记”和“针织针”等工具和配件,这些配件与同款“毯子纱线”产品一同展示。因为两位用户具有相似的喜好/用户画像,向他们展示上下文相关的推荐内容不仅可以提升用户体验,还可以增加升级销售的机会,直接影响业务的整体收入。
大多数主要的网店都同时使用协同过滤和基于内容的过滤技术来提高个性化推荐的准确性。为了评估推荐模型是否有效,我们可以通过进行简单的A/B 测试,从几个预测和假设开始,比如“这种算法将提高x%的参与度和/或转化率”(多变量测试也是一种选择)。每种替代方案都将基于不同的推荐技术。

图 12-3. 使用协同过滤的产品推荐
结论
要使机器学习项目产生巨大的业务影响,产品经理和业务所有者需要在每个阶段都专注于提出正确的问题。团队不应直接深入技术细节和机器学习实施,而是必须确保他们尽可能具体地理解业务问题和目标。这需要与利益相关者进行沟通,并将需求转化为技术需求。一旦明确了业务目标,我们必须首先评估是否真正需要机器学习来实现这些目标。如果机器学习是解决方案,接下来需要回答的下一个问题是,我们是否应该与外部服务提供商提供的现有解决方案集成(购买),还是投资于自建机器学习系统(构建)。无论哪种情况,都需要大量的计划和协调来将机器学习解决方案整合到面向客户的产品中。
明确定义业务目标和可衡量的产品指标,选择适当的成功衡量标准,以及迭代部署解决方案,是构建优秀机器学习产品的重要步骤之一。但是,机器学习还有许多其他要求,其中许多与传统软件应用开发的要求不同。成功在于高度意识到机器学习给您带来的新情况,同时清楚地了解哪些是真正对业务有利的,并朝着这个目标努力——尽管可能会经历坎坷的道路。
¹ 了解更多关于电子商务业务指标的信息,请参阅 Anastasia Stefanuk 的“7 个电子商务指标帮助您衡量业务成功”。
² 为了突出强调,这段话可能有些言过其实。尽管功能完整的机器学习产品需要持续维护,而且需要比类似的非机器学习项目更多的维护工作,但仍然可以肯定大部分工作发生在项目的前半段。随着模型的成熟(也许是所模拟的行为或情况也稳定下来),一些组织会达到稳态,因为进一步投资于模型改进的回报递减。
³ 一个例外是迁移学习,通过这种方式我们可以从外部提供者那里获得一个通用模型(比如用于图像识别的模型),然后在我们自己的数据上进行训练。但即使如此,最终的模型仍然属于我们自己。
⁴ 这里有些微妙的差别。算法确实变化很快(通常每年一次),因为新的方法被尝试并被发现在某些类型的问题上更成功。一些机器学习平台,如 TensorFlow 和 PyTorch 尤为突出,已经维护了相当长的时间(分别从 2015 年和 2016 年起)。然而,即使在这段时间内,它们也发生了显著变化,并且出现了其他可能更有效解决相同问题的机器学习平台。因此,即使是最稳定的机器学习平台和工具也只能在适度的时间内保持稳定。
第十三章:将机器学习整合到您的组织中
将任何重要的新学科整合到组织中,往往看起来更像是一种不规则园艺的练习:你随意撒播种子,不管土壤是否肥沃,然后定期回来看看哪些得以茁壮生长。你可能会幸运地在春天看到五颜六色的景象,但如果缺乏更多结构和纪律,你更可能会面对一片贫瘠。
由于各种普遍原因,正确进行组织变革是如此困难。首先,关于如何改变组织和文化的材料几乎是无穷无尽的。甚至从这些众多选择中做出决策都是一件令人望而生畏的事情,更不用说如何最好地实施所选择的方案了。
然而,在机器学习的情况下,我们有一些领域特定的理由证明这一点是真实的,并且可以说这些理由更为相关。正如迅速变成陈词滥调的是,机器学习在根本上与数据的性质和表达紧密耦合。因此,在您的组织中任何存在数据的地方,都可能与机器学习相关。即使试图列举出业务中所有涉及或处理数据的领域也有助于证明这一点——数据无处不在,而机器学习也是如此。因此,机器学习不仅仅是一种神秘的、孤立的事物,可以与其他开发活动分离开来。要使机器学习成功,领导者需要全面了解正在发生的事情,并有影响其各个层面做法的方式。
关于这种情况特别令人沮丧和反直觉的是,几乎每种变革管理方法都建议从小处开始,以管理一次性做太多的风险。尽管在大多数情况下这是非常明智的,而且您的第一个临时实验通常可以在没有太多开销的情况下完成,但小型试点的成功并不能保证在更大规模上机器学习的实施会顺利进行。在大多数组织中避免孤立化已经足够困难,但对于机器学习来说尤为重要。
然而,还有一个好消息:从实际上讲,从小处开始,发展一个成功的试点,并确保正确处理机器学习的机遇和风险是完全可行的。但你必须有意识地去做,这就是为什么我们应该首先讨论我们的框架和假设。
章节假设
我们在起草本章时,有几个假设前提需要在开始前明确。每个假设都在本节中有详细说明。
基于领导者的观点
我们的第一个假设——可能已经很明显了——是本章和第十四章均直接面向组织领导者撰写。虽然对数据科学家、机器学习工程师、SRE(可靠性工程师)等也有相关性,但本章主要针对负责其组织健康、结构和结果的人员,从团队(两个或更多人)到业务单元或公司(数百或数千人)的规模。
细节至关重要
一般来说,组织领导者不会深入参与任何 变革项目的详细实施和管理,除非在有强烈需求的情况下。机器学习需要有所不同。根据前述假设,由于良好的机器学习实施涉及理解其工作原理、数据的使用方式、什么被视为数据等原则,领导者在做出决策前需要了解这些内容才能做出明智的决策。
我们的主要观察是,默认情况下,领导者不会在他们的日常管理活动中获取与机器学习相关的知识,因此需要有一个明确的机制来实现这一点。这与大部分传统管理理论相反,后者认为大多数团队可以通过少量代表性关键绩效指标和对团队动态的深刻理解来有效管理。目前我们认为机器学习足够复杂、新颖且具有潜在影响力,因此了解其细节至关重要——尽管随着时间的推移我们预计这种情况会发生改变。(1)然而,目前领导者需要了解机器学习的基础知识,并能接触从业者,这反过来将帮助他们评估成功的可能性,并使结果更好。
除了培训项目之外,我们建议要实现这种理解水平的主要方法是,机器学习不应被孤立,无论是作为独立的技术驱动型努力,还是以其他方式。考虑到它可以触及一切,强大的孤立化将颠倒信息和控制的流向,并可能引入重大的风险管理问题。机器学习本质上是一种横向活动。
机器学习需要了解业务
我们的第三个假设是,业务 的复杂性直接影响了机器学习的构思和实施方式。这不仅仅是将机器学习从业者纳入关于目标和绩效的部门通报中——它要比这更广泛和全面。机器学习从业者需要比普通产品开发人员更加关注广泛的业务层面的问题和状态。
通过几个例子可以更清楚地说明这一点:
例子 1
YarnIt 的一位机器学习开发人员希望在业务销售部分产生业务影响。他们致力于建立一个模型,识别在销售方面表现不佳的产品。该模型在特定情境中推荐这些产品,以增加它们的销售。这样的模型可能会以多种方式取得成功。它可能会为这些产品识别新的购买者,或者只是提醒曾经购买这些产品的人可能再次购买它们。
但是在我们的情况下,现在出现了一个问题:它设法找到了羊绒纱线,这是 YarnIt 库存非常低的高档商品。由于这种模型没有(不能有效地表示或理解)利润或库存的功能,它设法全部售出。羊绒纱线在行业内供应短缺,更换将需要数周,甚至数月的时间。虽然很少有顾客大量购买这种纱线,但他们中的许多人偶尔会在较大的订单中购买少量。电子商务中有时会出现的另一种影响是,当网店没有特定商品库存时,顾客有时会将他们的整个订单转移到其他地方——YarnIt 也遇到了这种情况。因此,现在 YarnIt 因为缺货而在其他产品上失去了销售额。
示例 2
另一个案例揭示了跨组织的隐私和合规问题。推荐和发现团队训练模型,以帮助顾客充分利用yarnit.ai网站并帮助 YarnIt 从顾客那里赚取更多的钱。模型使用的特性包括顾客访问网站时使用的浏览器信息,因此团队只使用浏览器提供的User-Agent字符串的有限信息——足以确定浏览器和平台。
与此同时,网页设计团队一直在研究新的互动方式,并希望更好地了解顾客使用的浏览器配置。为了获取所需的所有信息,团队决定,未经与机器学习专家讨论,只是记录和跟踪完整的浏览器信息。结果,建模团队开始在模型中使用完整的浏览器User-Agent,却不知情。
问题在于User-Agent的完整内容加上位置信息(模型也有)通常能唯一识别一个人。因此,我们现在有了一个能够针对个人进行定位的模型。这违反了 YarnIt 的某些隐私治理政策以及其所运营国家的合规要求,对整个组织构成了严重的风险。
在这两种情况下,个别团队在他们的上下文中并没有做错什么。但是,基于对其选择对其他团队影响的不完全信息的行动导致了不良结果。因此,领导者需要意识到机器学习在他们的组织中的功能,这样他们就能提供关键的协调和广泛的监督,否则这些都会缺失。真正的问题是如何最好地提供这些支持。
这里有一种结构化的思考方式:你需要能够集中机器学习工作中最重要的监督和控制部分,解放出那些领域特定关注点最重要的部分,并提供一个整合点,在这个点上,工作流可以汇聚。正是在这个整合点上,监督、引导和沟通应该发生。
大多数组织已经有一些地方可以进行跨部门对话是一个好消息。如果你很幸运的话,这些对话会在(例如)产品管理中自然而然地进行,那里的客户生命周期管理是一种正常的关注事项。如果无法融入现有的会议、工作流或某种场所,你就必须创建一个新的。但是,无论如何实施,你都需要进行这种类型的对话。
你做出的最重要的假设
我们的材料是基于所有前述的假设。然而,你的组织变革努力也有假设——甚至,或者尤其是,如果你认为没有的话——这些假设与你非常接近,因此最终可能决定你的机器学习努力的成功。
最重要的问题之一,在你开始机器学习之旅之前深入研究的,是与你的机器学习项目目标密切相关的问题。这是你假设机器学习可以为你做些什么。
机器学习的价值
机器学习对你的业务能做的不仅仅是让你赚更多钱²。实施机器学习可以意味着你可以改善公民参与、为灾难救援筹集更多资金,或找出哪些桥梁最急需维护³。但对于业务领导者来说,通常意味着通过自动化降低成本,使顾客更加满意(而满意的顾客通常会为企业带来更多收益),或者增加收入。
例如,让我们回顾一下 YarnIt。几年前,CEO 开始听说机器学习。最初关于如何利用机器学习的想法包括以下内容:
-
根据一个模型,网站的搜索结果能够根据一个给定客户(或者如果他们没有登录的话,是一个网站会话所有者)的先前行为和兴趣,预测他们可能购买的产品。
-
帮助客户发现新产品,包括将首页的大部分空间用于那些由专门设计用途的模型选出的产品。
-
管理库存。ML 可以对供应链约束和库存水平进行建模,并为产品提出最佳的重新订购建议,以确保 YarnIt 拥有适当混合的产品库存,考虑财务、销售、存储和供应约束。
-
通过将产品和订单利润作为其他模型的特征,来提升盈利能力。
请注意,这些想法有不同的时间尺度和不同级别的组织侵入性。其中一些可以轻松添加到已有的工作和方式中。改变搜索结果的排名可能会对客户满意度和销售产生可测量的影响,但可以相对较快地完成(几周或几个月,而不是几个季度或几年),并且不需要广泛的组织参与来实施。改变库存和供应链工作的方式将需要更长的时间,并且需要其他部门的广泛参与。如果做得好,它有可能真正改变 YarnIt 作为公司的整体效率,也许类似于即时供应链。但这不是一项可以由 ML 工程师主导的变革。
即使面对这些实施挑战,组织领导者通常对 ML 的价值都有广泛的认同。事实上,ML 有潜力根据组织已经收集的数据实现额外的价值。这是一种真正可以改变组织功能方式的一代技术变革——因此,有必要仔细审视 ML 对你能做什么,找出你想实现的那部分,然后在开始之前把这些都写下来。
重要的组织风险
假设你已经评估了 ML 对你有什么作用,决定了它将采取的具体形式,写下了你的假设,并且迫不及待地盼望着这些美好变化会带来你名利双收。显而易见的问题是,“接下来怎么办?”不幸的是,在我们开始之前,理解风险和价值同样重要。否则,你将无法做出一个基于权衡的决策。
ML 不是魔法
尽管大多数业务领导对 ML 的价值和潜力有所认识,但他们不一定同样了解风险。因此,有时会出现一种领导层的视角,几乎将 ML 从业者视为可以实现奇迹般成就的人。然而,至少在领导层,没有人理解 ML 的作用方式和原理。通过误解 ML 的范围和机制,领导层也忽视了这些项目对整个组织影响的范围。在这种情况下,最大的危险是风险变得看不见,或者有效地变成外部性问题——换句话说,成为了别人的问题。这是导致不可避免的,尽管可能是任意延迟的灾难的配方。
心理(思维方式)模型的惯性
改变组织工作方式从未是一个简单的建议,关于这个话题已经写了成千上万页。在这里,我们限于说,实施机器学习就像任何其他变化一样,需要干系人管理和获得那些受影响者的支持,但与其他变化不同的是,涉及的干系人总数可能要大得多。
因此,问题的某些组成部分,如涉及干系人数量(例如,确定需要参与的人的纯物流问题)的部分显然会变得更大。然而,更重要的是,涉及说服、沟通,特别是理解人们模型化变化方式的任何组成部分,在重要性上也显著增加。
在推动重大变革时,仅仅出现在所有会议上,并携带涉及高级领导的谈话要点,很少能奏效。你不会仅基于高级领导的视角对情况进行表征来说服人们改变他们的行为。特别是,关键问题是心态,以及整个组织中领导者和从业者所使用的心理模型,用来表征发生的事情及如何对其做出反应。如果计划假设每个人都会转向理解事物的方式,就像你(或某个特定个体)那样,那么这个计划可能会很短命。
但有时,新的做事方式确实是对特定情况做出反应的正确方式。如果是继续进行的正确方式,但心理模型没有改变,你作为变革者必须承担说服的负担。为了最有效,这种说服必须伴随着一种或一组动机,并且这些动机必须与听众的心理模型相契合。例如,也许听众认为通过花费精力使他们团队的数据对他人可读没有真正获益;或者他们害怕被显示比其他团队更差;或者他们深信唯一重要的事情是尽快将产品功能推向公众,而花费精力在其他任何事情上都不重要。无论哪种方式,你的变革建议都需要征求、理解和解决你听众的心理模型。
最终,对于大多数实际问题来说,实施机器学习需要认真的干系人管理和大规模的努力来转变心理(思维方式)模型。
在不同文化中正确表达风险
显然,如果领导层明确了收益,但风险却看不见,这将导致风险管理以临时的、资金不足的方式进行,甚至可能故意不进行。这些风险甚至可能被误传,特别是在负面取向的文化中。在软件工程组织的背景下,可能有必要审查 Ron Westrum 博士建议的组织类型学,以更详细地了解这种情况的影响。⁴
如果我们稍微简化一下,Westrum 建议可以广泛将组织分为以权力为导向、以规则为导向或以绩效为导向。其中,唯一一种在实施机器学习时会遇到结构性问题的组织文化是以规则为导向、官僚化的文化。为什么?一方面,以权力为导向 的组织倾向于压制新颖性,因此在任何严肃的方式上很少会自行实施机器学习。另一方面,以绩效为导向 的文化对新颖性、合作、沟通和风险共享持开放态度。这些环境很可能容忍成功实施机器学习所需的开放协调方式。
相反,以规则为导向 的组织容忍新颖性,但对出错的人进行惩罚。失败会对那些被视为失败者的人产生负面后果,组织的责任范围狭窄(并且得到充分的保护),协调性很小。在这些组织中,我们预计机器学习可能会找到立足之地,但一旦出现问题或变得困难,责任在于的人将受到惩罚,创新很快就会停止。不幸的是,这种行为使得充分建模和响应伴随机器学习而来的横切风险变得非常困难;可能会造成重大损失。
孤立团队无法解决所有问题
另一个常见的风险是将机器学习团队和项目等同于对待其他新工作类型的方式,一种常见的本能反应是成立一个新的孤立团队来完成这项工作,从而导致其在组织中的分离。这是减少启动摩擦以便构建并展示结果的常见方法。然而,这对机器学习来说却带来问题,因为要实施它通常需要多个部门或部门的帮助。更重要的是,由于机器学习项目可能产生广泛的影响范围,成功部署机器学习需要组织变革来支持结构、流程和保持可靠所需的人员。肯定有可能将范围过于狭窄以致失败。
实施模型
讨论了将机器学习引入组织中可能涉及的一些风险后,让我们集中于实际操作的要点——如何真正完成这项工作。
一个小的实施项目可能从将机器学习应用于对您组织成功至关重要的内容开始。这涉及创建和整理数据源,组建具有问题空间和机器学习方面正确专业知识的团队,并制定您需要跟踪进展并引导项目的水平调控机制。在整个过程中,保持幸福的乐观主义可能是有利的,当您知道麻烦迟早会找上门时——尽管您不知道具体是何时或是什么形式。
首先选择一种度量指标:理想情况下,它将是系统中有用但不是关键的内容。这样,您可以从实施中获得宝贵的经验,工作将涉及组装您未来扩展所需的团队之间的交叉连接,但如果事情搞砸了,重大灾难的可能性将降低。
让我们以 YarnIt 为例。实施团队可能会考虑几种选择。使用机器学习来帮助搜索排名是一个有吸引力的起点。但团队注意到,直接来自搜索结果页面的销售额代表了显著的收入。这使得这个地方最终应用机器学习变得有吸引力,但开始时风险较大。在寻找站点的其他部分并看到它们都与收入敏感或收入关键相关后,团队采取了不同的方法:如果我们在目前没有任何内容的地方添加由机器学习生成的结果会怎么样?团队成员查看yarnit.ai网站,注意到有几个页面没有向最终用户显示推荐内容,但却可以这样做。他们决定在用户将商品添加到购物车时看到的确认页面上添加推荐产品——或者换句话说,我们利用用户展示对某个产品感兴趣的那一刻,来推荐其他产品。
这是一个很好的开始地方:纯粹的增加,风险低,并且至少有合理回报的可能性。购买意图已经存在,并且这种改变对现有客户工作流程的影响不是太大。因此,团队采用“购买X的人也购买Y”模型,并决定通过收集推荐产品的点击率并将其与搜索结果的点击率进行比较来衡量它。当然,一旦团队了解更多如何做到这一点的方法,另一个可能的选择是采用结合可实现性和预期收益的更传统方法,而不是专注于最小化干预风险。
记住目标
虽然保持灵活性很重要,尤其是在执行过程中,我们也必须记住目标——通过实验机器学习来建立组织的能力。希望你能达到所选的业务度量改进,但即使不成功,项目仍然可以总体成功:你仍然可以学到很多,并尝试另一种方法,如果事情不顺利的话。
但重要的是要在不被途中遇到的事物分散注意力和不过于坚持先前决定的细微界限之间行走。
小贴士
记下你的战略目标及其背景,在解决战术问题或处理事故时可以帮助你回顾。
绿地与褐地
当你在组织中启动一套新的活动时,经常出现的一个基本问题是你是从零开始做(也称为绿地),还是有一个现有的系统、团队或业务流程来处理(也称为褐地)。在实践中,几乎所有的实施都是褐地,因为大多数组织通过改进他们已经拥有的系统获得最大的价值。总体而言,尽管极大地简化,转型项目在绿地情况下进行得更顺利,或者可以尽可能地使其成为绿地情况,这一点非常重要。
一种常见的直觉是,在已经存在并(在某种程度上)运行良好的基础上构建东西更容易。但事实上,新倡议成功的关键指标是它引起多少反对。反对通常更常见于褐地情况下,在这种情况下,别人的职业成功往往取决于什么都不改变。
正因如此,大多数预期会遇到重大反对的实施项目通常会尝试启动一个涵盖以前未涵盖职责的新团队或职能。我们的观点是,由于机器学习的强大相互连接性,期望相对孤立地继续进行是不现实的。最终——而且可能比你想象的更早——你将会与其他需要征求许可的人交谈。
我们在此提供的最佳指导意见,正如以往所述,是从一个有意义的度量开始,因为这是最容易讲述的故事——成功的转变几乎总是需要一个好的故事。然后利用这一点来确定你的项目需要多少是“绿地”还是“褐地”,同时要承认大多数事情都是褐地。
机器学习角色与责任
做好机器学习工作涉及到一系列技能、关注领域和业务问题。我们发现一个有用的知识结构方式是始终考虑组织内数据的流动。例如:
业务分析师或业务经理
这些角色负责特定业务线的运营及其财务结果。他们拥有使机器学习成功所需的数据和愿望,但如果情况不好,他们的工作能力将因错误信息而受到影响。
产品经理
这些角色为产品设定方向,并决定如何将机器学习整合到现有产品中。他们帮助我们决定数据的用途。还可能有专门的机器学习产品经理指导我们要实现的内容。
数据工程师或数据科学家
这些人了解如何提取、策划、管理和追踪数据,以及如何从中提取价值。
机器学习工程师
他们构建和管理模型及其生成系统。
产品工程师
他们开发我们试图通过机器学习改进的产品。他们帮助我们理解如何将机器学习应用到产品中。
用于机器学习的 SRE 或 MLOps 工作人员
他们主导部署机器学习模型的整体可靠性和安全性。他们改进现有的构建和部署模型流程,提出和管理跟踪我们随时间推移表现的指标,并开发新的软件基础设施来确保模型的可靠性。这些角色围绕整个过程,是少数几个从端到端看待流程的工程师之一。
在较小的组织中,每个角色可能与其他角色结合起来。它们是需要考虑填补的功能。
如何招聘机器学习人才
目前招聘有才华的机器学习员工很困难,并且在可预见的未来可能会继续困难。机器学习技能需求的增长远远超过了受过教育和有经验的员工的供应。这影响到所有雇主,但是最负盛名的机器学习公司(通常是大型科技组织)继续雇佣大部分新毕业生和有经验的员工。这使其他组织处境困难。
在这种情况下通常的建议包括尝试在周期的早期找到潜在的合格候选人,确保招聘过程的运作一般上是良好的,定期与候选人沟通,向候选人推销该公司的优势等等。虽然所有这些都是正确的、有用的、需要努力的,并且可能对你有用,但它们都是标准的方法。如果市场特别火爆,即使做所有这些也可能不奏效。
我们建议另一种方法。将问题重新框架化为在那些确实需要立即具备机器学习知识和经验的员工之间分配人员,以及那些可以在工作中学习的员工之间分配人员。大多数情况,特别是初创企业项目,只需要一两位经验丰富的机器学习研究人员或实践者。这些经验丰富的员工可以帮助设计模型以满足组织的目标,并且还可以指定需要构建和部署这些模型的系统。但是需要管理数据、将机器学习整合到产品中并维护生产中的模型的员工,可以是在其他方面有才能但在工作中深入学习机器学习的人员。(您甚至可以购买类似的书籍来帮助这些员工更快地提升水平!)
因此,分割了问题之后,我们仍然需要问,大多数组织如何能够雇佣那些最初的有经验的机器学习研究人员和工程师来启动这个过程。标准的做法包括雇佣有经验的公司的承包商或顾问,支付愿意教授的真正有经验和证书的超级明星,以及押注于初出茅庐的新星,同时要理解这条路会很不平坦。当您的组织希望进行机器学习但没有声望或资金与更大公司竞争时,这些都是实际的选择。
现在,我们已经考虑了组织在专门适应机器学习方面面临的一些具体挑战,让我们退后一步,从传统组织设计的角度来考虑这个问题。
组织设计与激励
使组织有效运作,根据其应该完成的任务——通常称为组织设计——是一门艰难的艺术,涉及战略、结构和流程的混合。对领导者来说,关键点在于报告结构通常是成功的组织设计中最不重要的部分。其他更为强大的方面和决定因素影响行为。
在我们进一步深入之前,值得注意的是,组织设计是一个技术性和常常充斥术语的主题。对于一些领导者,特别是在较小的组织中,可能难以从整个过程中看到全局。战略、流程和结构的讨论可能难以与主要的实际任务:雇佣合适的人员并将机器学习应用到您的应用程序中进行匹配。然而,最终的主要教训是,思考您的组织目前的运作方式,以及这将如何改变,极大地提高了您成功进行机器学习的机会。
我们可以选择多种模型来理解如何改变一个组织以实现特定目标。本节不旨在提供对所有这些模型的完整审查。相反,我们将选择一种常见的思考组织方式,Jay R. Galbraith 的星型模型,并将其特别应用于在组织中实施 ML 的挑战(图 13-1)。

图 13-1. 星型模型(© Jay R. Galbraith. 获得许可后重印。)
在这个模型中,策略、结构、流程、奖励和人员都是管理可以设定的设计政策或选择,这些政策或选择影响组织中员工的行为。
这个模型很有用,因为它超越了报告结构或组织图表,大多数领导人往往只关注并结束他们的变革努力。Galbraith 指出,“大多数设计努力在绘制组织图表上投入了太多时间,而在过程和奖励方面投入的时间远远不够。”该模型允许您考虑这一观察结果,然后思考所有相互关联的方面是否受到影响或可以改变以更好地支持需求。政策、流程、人员和奖励政策可以随后进行调整,以支持你的结构和策略。
让我们在试图实施 ML 的组织背景下审视每一个。
策略
策略是你的组织试图前进的方向。它推动你的业务或组织成功模型。它影响哪些部分得到关注或资助,以及如何衡量或认为组织成功。
“羊毛分销行业的一流机器学习”可能是一个策略,将 ML 视为 YarnIt 的主要关注点,但如果我们坚持只使用“一流”的 ML,则可能会限制 ML 的部署位置。⁵ 另一种“产品所有方面的机器学习”的策略可能意味着组织资助新的和创新的 ML 使用方式,对于起始阶段的低质量结果更具包容性。另一方面,如果我们设定“通过多样化方法增加销售,包括使用 ML”的策略,我们可能会认为它比其他更传统的增加销售的方法更具实验性或不太重要。
结构
结构描述了谁在组织中拥有权力。你也可以将其视为组织图表或报告结构,因为它确定了正式的监督权威。(当然,它可能完全不同;在其他地方,权威可能在团队内,某些技术领导必须在实施决策之前支持。)
一种思考组织结构选择的方法,Galbraith 指出,包括功能、产品、市场、地理和过程结构:
功能
这种结构围绕特定的功能或专业(例如,在一个团队中集中 ML 实施)组织公司。
产品
这种结构将员工分为不同的产品线。在这种情况下,ML 团队将分布到各个单独的产品团队中。
市场
公司根据他们销售给的客户市场段或行业组织。对于 YarnIt 来说,可能会根据手艺人的类型(编织者、织布者或钩针者)进行组织。
地理
这种结构按地域划分:产品与地区、位置或甚至分布经济(比如食物来源)有依赖关系。考虑采用这种结构方法来管理 ML 的唯一明显理由可能是治理和遵守当地法律。这可能不是我们组织 ML 实施的方式。
过程
有时也称为水平组织,这种结构将权力集中在组织中开发和部署流程的所有人员身上。对于需要跨产品线工作但需要为组织创建标准和流程的 ML 团队而言,这可能是一个良好的模型。
领导者通常会对组织的运作方式和影响变革的方法有一种心理模型。例如,想象一种心理模型,即要启动一个新的功能,必须首先聘请高级领导。有了这种心理模型,领导者往往会围绕特定的高级领导者集中 ML 功能——如果找不到合适的领导者,或者集中化与(比如)现有的工程文化不太匹配,这显然会有明显的缺点。类似地,隔离的 ML 功能可能对于高级领导者更容易控制,但会阻碍其他工程团队在 ML 上的进展。最终,领导者可能需要根据选择的 ML 策略调整他们的工作方式的心理模型。(没有适合所有情况的结构存在,尽管对于那些希望采用某种大小适合某些情况的方法的人,我们在第十四章中详细介绍了结构实施选择。)
过程
过程约束信息和决策在组织中的流动,因此对 ML 的工作方式至关重要。它们可以用来根据需要解决结构中的问题。Galbraith 框架定义了两种类型的过程:垂直过程分配稀缺资源(例如预算),水平过程管理工作流程(例如客户订单录入和完整的履行)。
将机器学习引入组织的一种潜在方式是将引入过程视为一个垂直过程,由中央做出决策,但在整个组织中实施。如果领导者已经掌握了他们的依赖性和联系,这种方法会很好地运行。如果情况并非如此,那么会出现脱节的决策。例如,如果我们资助一个机器学习培训和服务团队来为我们的应用程序添加一个新的机器学习功能,那么我们是否也要资助团队来筛选所有数据,或者在一段时间内处理模型质量测量或公平性?如果是这样的话,可能会在我们的本地范围内复制中央功能,这是低效的,可能会增加摩擦。
一旦组织实施了几个机器学习项目,将这些项目的基础设施集中到一起,以满足特定的工作流程,这样可以增加鲁棒性和可靠性。例如,许多模型团队最初会提供他们自己的端到端基础设施,但最终我们可能会有许多建模团队提供能够集成到我们应用程序中的模型。在那时,我们可以为一些模型实现中央化的服务,考虑构建一个中央特征存储,从而开始建立与模型团队无关的机器学习组织基础设施的共同方面。
奖励
奖励既有金融性的,也有非金融性的。尽管大多数组织很难仅凭金融基础竞争机器学习人才,但对于组织来说更有意义的可能是基于使命、文化或增长而进行竞争。大多数员工都重视认可、地位或职业机会。他们还重视自主运用他们的技能,创造出有价值的东西。自主部分是棘手的,因为机器学习人员需要独立,但同样重要的是他们要受到组织需要确保所部署的机器学习是公平、合乎道德、有效且符合相关法律的治理。将奖励与不仅是业务目标的原始执行对齐,而且可靠性、公平性和鲁棒性将有助于创造正确的激励措施,以避免忽视这些领域。
还有一个让人惊讶的奖励 ML 技能和知识的要点需要注意。请记住,机器学习可能会影响我们组织的大部分部分。应该考虑的一件事是奖励全组织范围内的员工学习更多关于机器学习的知识。如果销售人员、会计人员、采购人员和产品经理都具备了基本的机器学习教育,那么长期来看,组织可能会更加有效。
我们预计机器学习专业知识将持续稀缺,对薪酬、招聘难度等方面会产生影响—请参阅“如何招聘机器学习人员”以获取主动方法的建议。
人员
最后,我们需要考虑影响组织中的人类的因素的集合。这包括这些人需要的心态和技能。它还包括人力资源政策,例如招聘、选择、轮岗、培训和人员发展。例如,灵活的组织需要灵活的人。跨职能团队需要能够彼此合作并了解组织多个方面的“通才”。
鉴于目前机器学习教育和技能的稀缺性,大多数组织应考虑招聘能够在工作中学习的员工,而不仅仅是那些已经具备资格的人。虽然这适用于机器学习人员的招聘整体图景,但在 SRE 领域尤其如此。机器学习生产工程师更多地受益于稳定可靠和分布式系统技能,而不是机器学习技能。在这些角色中,机器学习是工作发生的背景,但并非总是工作的内容。
最后,组织将需要那些能够解决由机器学习引起的问题模糊性的人才,而不仅仅停留在“机器学习模型如此说”的根本原因。这是一个很好的起点,但人们需要能够创造性地思考机器学习模型的构建方式,以及世界和数据变化如何影响它们,以及这些模型如何影响其组织的其他部分。这种视角和方法的一部分来自机器学习的教育和技能,但一些来自于对问题解决的好奇和坚持不懈的方法,而这并非每个人都具备的起点。
关于顺序的注释
为了清晰解释和便于说明,前述主题被分开。虽然关注点分离是计算机科学中常用的强大技术,但在现实世界的组织工作中,一切都纠缠在一起,这通常使单纯通过对单一维度的控制来改变事物几乎不可能。好消息是,最终常常发现这正是你想要的。
改变星型模型前述元素的单一维度本身不太可能带来成功。单独进行战略变更而不改变过程几乎肯定会导致同样的结果。引入一群将学习旧文化的新人很可能会培养出一批表现如同老员工的新员工。在财务上奖励新行为,同时仍然让旧行为易于实现(因为所有流程都优化为这样)本身不会改变任何事情。依此类推;严酷的现实是,成功的变革通常需要在多个方面同时推进。
然而,你并不需要在所有这些方面以相同的速度或强度前进。这是第二个好消息——你可以顺序进行这些。宣布你正在改变战略,然后是流程,然后是奖励。逐一处理它们,但至少涉及到那些对你的组织至关重要的部分。告诉每个人你正在遵循的时间表和评估成功的标准。传达你的意图,但承认并非所有事情会一次性改变——不会——但要大声并公开承诺总体目标。这样增加了变革的信誉并得到了组织内的支持者。
结论
我们无法为你推荐具体的变革维度,因为这很大程度上取决于你的当地情况。然而,我们建议至少考虑以下几点:
-
组织关心什么?试图完成组织不关心的事情来推动变革,很可能会被忽视,并且更不太可能获得资源。如果你与这些关注点一致,你的工作总体上更有可能成功。
-
今天人们在做什么,以及它需要如何改变?许多变革计划源自高级别员工,他们与其他员工日常经验脱节。如果你退后一步,看看他们做什么以及为什么这样做,你的变革计划成功的机会会更大。
-
做新事情相比旧事情容易吗?如果新事情比旧事情更难做,每个人可能都会认为做这件事非常重要,但改变会更慢,更困难,甚至可能根本不会发生。让正确的事情变得更容易做,而错误的事情变得更难做。
-
最后,要承认变革需要时间。正如我们所说,展示组织上的脆弱性不仅会让你得到更多支持来自那些欣赏现实主义的人,还可以让人们更好地管理自己对变革的反应。只是不要忘记保持定期的沟通节奏:一个大新闻公告之后长时间的沉默通常会让人们怀疑动力是否已经停滞。
如果你想看前面几点的实例,请参阅第十四章。
¹ 话虽如此,我们并不崇拜那些经常涉足细节的领导者——有时候这样做会更好,有时则会更糟——但我们确实认为,在机器学习发展的当前阶段,领导者有必要理解其中的权衡。至少,组织领导者需要了解正在优化的业务指标,并且需要有一种方法来衡量机器学习系统是否有效地优化了这些指标。理解一些实施细节以及衡量有效性的过程将使领导者能够充满信心地做出这些决策。
² 这一观察并不局限于盈利企业。寻求实施机器学习的领导者们往往希望它改善他们已经做的事情:赚更多的钱,提供更多的食物,支付更多的住房费用。机器学习确实可以做到这些事情,但它也可以改变您对整个组织运营方式的看法。
³ 在撰写本书期间,美国宾夕法尼亚州匹兹堡市发生了一起重大的桥梁坍塌事故,我们中的一些人就居住在这里。尽管美国基础设施的主要问题在于国家未能投入足够的资金,但事实上,优先考虑在哪里使用有限资源可能适合机器学习的应用。
⁴ Westrum 的原始论文是 “组织文化的分类”。Google 云架构中心 在 DevOps 的背景下审视了这一点,但大多数观点同样适用于机器学习生产工程。
⁵ “大多数情况下是合理的” 机器学习实际上可以改善各种情况下现有算法的部署。
第十四章:实用的 ML 组织实施示例
组织是复杂的实体,它们的各个不同方面都是相互连接的。组织领导者将面临新的挑战和变化,这是由于采用 ML 所带来的。为了在实践中考虑这些问题,让我们看看三种常见的组织采用结构以及它们如何适用于我们一直在考虑的组织设计问题。
对于每种情况,我们将描述组织领导者选择如何将 ML 集成到组织中以及该选择的影响。总体而言,我们将考虑每种选择的优势和可能的缺陷,但特别地,我们将考虑每种选择如何影响过程、奖励和人员方面(来自第十三章中介绍的星型模型)。组织领导者应该能够在这些实施场景中看到足够的细节,以识别自己组织的方面,并能将其映射到他们自己的组织环境和战略中。
情景 1:新的集中式 ML 团队
假设 YarnIt 决定通过雇佣一个单一的 ML 专家将 ML 纳入其堆栈中,并开发一个模型来生成购物推荐。试点成功,并由于发布而增加了销售。现在公司需要就如何在这一成功基础上扩展以及如何(以及多少!)投资于 ML 做出一些决定。YarnIt 的 CEO 决定雇佣一个新的副总裁来建立和运行 ML 卓越中心团队,作为组织的一种新的集中能力。
背景和组织描述
这种组织选择有显著的优势。团队可以专注,有充分的合作机会和共同工作的机会,并且领导层可以明确地优先考虑公司内 ML 工作。如果他们的范围限于 ML 系统,可靠性专家可以在同一组织中。集中还创建了一个重要的影响中心:ML 组织的领导者在整个 YarnIt 公司中更有权利为他们的优先事项辩护。
随着团队的壮大和项目的多样化,YarnIt 的更多部门将需要与 ML 组织互动。这就是集中化成为劣势的地方。ML 团队不能与业务其余部分距离太远,否则团队将需要更长的时间来发现机会,深入了解原始数据,并构建良好的模型。如果 ML 团队与个别产品团队隔离开来,那么它成功的可能性就不大,如果没有这些产品团队的支持。更糟糕的是,将这两个功能(ML 和产品开发)完全分开放在组织结构图中可能会促使团队竞争而不是合作。
最后,集中化的组织可能对请求帮助将机器学习整合到其产品中的业务部门的需求没有实质性的响应。当涉及到机器学习的产品化时,业务部门可能不了解机器学习团队的可靠性需求,也不理解为什么要遵循可靠性流程(从而导致交付速度变慢)。
尽管集中化机器学习团队存在这些缺陷,但组织始终可以进化。该场景经历了星形模型,好像它只使用了一个集中化团队,但我们还将在第三种情况下说明一个集中化团队在基础设施中的演变。另一种可能的演变是,集中化团队教育和使其他人增加组织内的机器学习素养。
过程
正如我们所提到的,引入机器学习在组织中的影响往往是广泛的。为了解决集中化组织的一些缺点,引入流程可以帮助分散(或分权)决策或知识。这些流程包括以下内容:
主要利益相关者的审查
机器学习团队定期提交的这些审查应确保当前建模结果的批准,以及业务领导对系统适应业务方式的理解。确切地确定这些审查中应包括哪些指标的科学是必要的,但这些指标应是全面的,需要包括任何给定模型实施的改进及其成本。关键的业务利益相关者还可以审查各种机器学习团队工作的优先级以及投资回报率和使用案例。
对变更的独立评估
集中化机器学习团队可能面临的一个问题是,所有变更都变得彼此依赖,并可能被其他变更所阻碍。如果团队改为独立评估变更,确保每个模型在改变其自身的生产中的准确性,那么变更可以更快地可用。通常,一个模型可能会在平均性能上改进,但可能会损害特定子组的性能。判断这些权衡是否值得往往需要进行重要的分析和挖掘,并可能需要基于不易通过简单指标如预测准确性反映的业务目标的判断。
降低变更组合测试的风险
在大型模型开发团队中,通常会并行开发多个改进措施,然后可能一同推出。问题是这些更新是否能良好地配合。这就需要同时测试候选变更的组合效果,而不仅仅是单独地测试。¹ 重要的是建立一个流程来审查候选变更,并确定哪些组合测试是有用的。这可能会通过进行走/不走的会议来讨论模型推出及团队如何进行组合测试来进一步促成测试或决策是否推出。
虽然在集中式机器学习团队中更容易实现,但是引入流程使得来自各业务单位的人员也能够评估变更。对于集中式机器学习团队而言,可能是请求变更或特性的产品/业务团队,或者可能会受到变更影响的支持团队。
奖励
为了确保机器学习项目的成功实施,我们需要奖励业务与模型构建者之间的互动。员工需要根据他们跨组织合作的有效性和对业务结果的对齐进行评估,而不仅仅是评估他们所在部门、部门或团队完成狭窄任务的有效性。寻求其他组织的意见和正式审查、提供反馈以及沟通计划,这些行为都应该得到奖励。如何奖励这些行为在文化上依赖于每个组织,但它们应该得到认可。
奖励可以是金钱(奖金、休假)但也可以包括晋升和职业机会。在 YarnIt,我们可能会添加“有效影响者”等评价特征作为我们寻找成功员工的标准之一。
人员
产品领导者需要实验心态,既要欣赏机器学习所创造的价值,也要容忍一些风险。产品领导者需要理解,调整机器学习模型以符合组织目标可能需要一些实验,并且在这个过程中几乎肯定会出现负面影响。
YarnIt 及所有实施机器学习的组织,需要聘请具有细微差别心态的人才以确保成功。领导者需要容忍复杂性,并且在超出自身职权范围的组织边界内工作时感到舒适。特别是,领导者还必须有信心向上级层传达这些影响的复杂性,而不是过于简化或粉饰。YarnIt 的 CEO 不需要听到机器学习是魔法并将解决所有问题,而是需要了解如何利用机器学习作为工具实现业务目标。目标不是做机器学习,而是推动业务变革。虽然机器学习很强大,但细微之处在于通过最小化负面影响来创造价值。
如果这些中心团队的人员在这些领域没有专业知识,他们需要接受有关质量、公平、道德和隐私问题的培训。
默认实现
一个过于简化的集中模型的默认实现如下:
-
雇佣一位具有机器学习建模和生产技能的新领导。
-
雇佣机器学习工程人员来构建模型。
-
雇佣软件工程人员来建立机器学习基础设施。
-
雇佣机器学习生产工程人员来运行基础设施。
-
-
与产品团队制定实施计划(数据来源和新模型的集成点)。
-
设立整个计划的常规执行审查。
-
根据成功的实施计划进行补偿,并对机器学习人员和产品领域人员进行补偿。
-
启动隐私、质量、公平和道德计划,建立标准和对这些标准的遵守监控。
情景 2:分散的机器学习基础设施和专业知识
YarnIt 可能决定在整个组织中投资几位专家,而不是一个单一的高级领导者。每个部门将必须自行雇佣其自己的数据科学家,包括购物推荐和库存管理团队。基本上,YarnIt 将允许数据科学和机器学习的简单实现出现在任何有足够需求和愿意支付的部门。
背景和组织描述
这种方法更快,或者至少更容易开始。每个团队可以根据自己的优先事项雇佣和安排项目人员。随着机器学习专家的雇佣,他们将更接近业务和产品,因此能更好地理解每个组的需求、目标甚至政治因素。
存在风险。缺乏集中的机器学习专业知识,尤其是在管理方面,将使深入理解 YarnIt 需要在机器学习成功方面做的更多工作变得更加困难。管理层将不了解需要什么专门工具和基础设施。很可能会倾向于尝试用现有工具解决机器学习问题。很难理解当机器学习团队主张真正需要的东西(如特定于模型的质量跟踪工具如 TensorBoard),与可能很好但可能并非必需的东西(某些模型类型和大小的 GPU 或提供大规模但成本也很高的云训练服务)之间的区别。此外,每个团队将会重复执行一些相同的工作:创建一个稳健且易于使用的服务系统,可以跨多个模型共享资源,并监控系统以跟踪模型的训练进度并确保完成训练。如果可以避免,所有这些重复可能都是昂贵的。
如果这些团队中有些团队在处理涉及其他产品的工作,而他们很可能会这样做,故障排除和调试就会变得更加困难。当产品或生产问题出现时,YarnIt 需要找出哪个团队的模型出了问题,或者更糟的情况是,让多个团队一起调试彼此模型之间的交互。大量的仪表盘和监控会使这一切变得指数级更加困难。对于任何给定模型变化的影响不确定性将会增加。
最后,YarnIt 将努力确保其采用一致的方法。在 ML 公平性、道德和隐私方面,只要一个糟糕的模型就可能损害他们的用户,并且在公众中损害我们的声誉。YarnIt 还可能会通过这种组织结构复制认证、集成到 IT、日志记录和其他 DevOps 任务。
虽然存在真正的权衡,但对于许多组织来说,这种分散的方法确实是正确的选择。它可以减少启动成本,同时确保组织立即从 ML 中获得有针对性的价值。
过程
为了使这种结构有效,组织应专注于能够引入一致性而不会引入过多开销的流程。这些流程包括以下几点:
高级利益相关者的评审
模型开发者仍应该参与高级利益相关者的评审。对于模型开发者来说,创建每个提议的模型开发目标及其发现的写作是一种非常有用的做法。这些内部报告或白皮书,尽管篇幅较短,却能比较详细地记录尝试过的想法以及组织从中学到的东西。随着时间的推移,这些会形成组织的记忆,并强化评估的严谨性,类似于软件工程师代码评审中的严谨性。YarnIt 应该为这些报告创建一个模板,可能由一些最早开始使用 ML 的团队共同合作生成,并为参与人员超出仅仅实施 ML 的组织的小组定期评审制定标准时间表。
分类或 ML 生产会议
ML 模型开发者应每周与生产工程人员及产品开发组的利益相关者会面,以审查 ML 部署的任何变化或意外效果。像所有事情一样,这可以做得好也可以做得不好。一个糟糕的会议版本可能没有所有相关的观点,可能基于偶发性问题而不是被深入理解的系统性问题,可能深入解决问题解决得太多,或者简单地可能持续时间过长。良好的生产会议应该是简短的,专注于分类和优先级确定,分配问题的所有权,并审查过去的任务更新和进展。
技术基础设施的最低标准
YarnIt 应建立这些最低标准,以确保所有模型在投入生产之前都通过了某些测试。这些测试应包括基线测试,例如“模型能否提供单个查询的服务?”以及涉及模型质量的更复杂的测试。即使是像标准化的 URL 这样的简单变化也可以帮助推动内部的一致性(在机器学习快速变化且复杂的世界中,任何有助于记住和行为一致的东西都是有用的)。
奖励
为了平衡这种方法的分散效果,YarnIt 高级管理层需要奖励一致性和公布的质量标准。例如,领导应奖励及时的撰写和在广泛可用的语料库中进行仔细审查的员工。每个团队都有其本地优先事项,因此有必要奖励平衡增加速度与一致性、技术严谨性和沟通的行为。
在这种情况下需要注意的一个具体因素是,YarnIt 不太可能拥有具有显著机器学习经验的员工。一个有用的奖励是鼓励员工参加(并在)与他们工作相关的会议上发表演讲。
人员
在这种部署中,YarnIt 应寻找那些能够既能本地思考又能全局思考的人才,平衡本地利益与公司可能的不利因素(或反之)。影响力和跨组织线合作等技能可能是需要明确表达和奖励的。
组织仍然需要关心质量、公平性、道德和隐私问题的人员,并能够影响组织——这在每种部署方案中都是如此。不同之处在于,在这种情况下,这些员工将不得不开发本地实施方案,以实现质量、公平性、道德和隐私,同时还要制定广泛的标准并推动它们在公司内的实施。
默认实施
这里是分散结构方案的一个过度简化的默认实施:
-
每个团队在其业务单元内聘请专家:
-
雇佣机器学习工程人员直接与产品团队一起构建模型。
-
雇佣或转移软件工程人员来构建机器学习基础设施。
-
雇佣机器学习人员或转移生产工程人员来运行基础设施。
-
-
发展内部发现报告的实践,供高级利益相关者审查。
-
建立公司范围内的技术基础设施标准。
-
每周进行分类或机器学习生产会议以审查变更。
-
启动一个关于隐私、质量、公平性和道德的计划,为这些标准建立标准和合规监控。
情景 3:混合中心化基础设施/分散建模
YarnIt 开始通过集中模型实施,但随着组织的成熟和机器学习的普及,公司决定重新审视该模型并考虑采用混合结构。在这种情况下,组织将保持一些集中的基础设施团队和一些中央组织的机器学习模型咨询团队,但各个业务单元也可以自由聘请和培养他们自己的机器学习建模专家。
这些分布式机器学习工作人员可能起初会严重依赖中央建模顾问,但随着时间的推移,他们会变得更加独立。然而,所有团队都应该使用并为中央的机器学习生产实施做出贡献。
通过集中投资和基础设施的使用,YarnIt 将继续从效率和一致性中受益。但至少在一定程度上分散机器学习专业知识将增加采用速度,并改善机器学习模型与业务需求之间的对齐。
注意,许多组织都会演变成这种混合模型。作为领导者,计划这种演变可能是明智的选择。
背景和组织描述
这种混合实施的缺点源于集中和分散的机器学习组织结构。在分散人员配置和在整个组织中实施机器学习方面可能存在效率低下的问题。业务单元可能对机器学习了解不足,并可能存在特别糟糕的实施。如果失败与隐私或道德有关,这尤其成问题。同时,集中的基础设施可能会对分散建模团队产生摩擦。而且,集中的基础设施可能感觉更复杂和更昂贵。然而,公司存在的时间越长,集中的基础设施模型带来的回报就越多。
过程
有一种思考这种混合实施影响的方法是重新考虑在 “大不一定是好的” 中的购物车放弃示例。在这种情况下,如果建模团队居住在网店产品团队中,这些团队成员更有可能快速注意到问题,并重新调整模型的指标,而不仅仅是最大化购物车的大小。他们还会考虑可能的 新功能,比如“现在购买一半的毛线,一个月后保留另一半”。在所有这些情况下,机器学习已经引发了关于如何更加顾客友好的讨论。
但假设问题发生在组织部门之间:网店模型给购买带来问题。在这些情况下,解决问题可能会慢得多,因为采购团队试图说服网站团队模型造成了问题。在这些情况下,组织文化必须支持跨团队模型故障排除甚至开发。
考虑推荐给场景 1 和 2 的流程,看看它们是否可以帮助减轻这种实施可能的缺点:
-
对变更组合的无风险测试
-
对变更的独立评估
-
评审:
-
机器学习团队的发现文档和审查
-
模型结果的业务评审
-
ML 生产会议的分类
-
-
技术基础设施的最低标准
-
质量、公平性、伦理和隐私问题的培训或团队
奖励
在混合场景中,YarnIt 的高级管理层应该奖励那些利用集中基础设施的业务单元,以防止它们开发自己的重复基础设施。集中基础设施团队应该因满足其他业务单元的需求而获得奖励。在几乎所有情况下,衡量和奖励采用,同时鼓励使用中央基础设施,都是有意义的。
中央基础设施团队应该有计划识别业务单元中开发的关键技术,并将其扩展到公司的其他部门。从职业发展的角度来看,业务单元的 ML 建模师应该能够在一段时间内轮换到中央基础设施团队,以了解可用的服务及其限制,并为这些团队提供最终用户的视角。
人员
要在整个 YarnIt 公司有效运作,所有这些团队都需要有全公司视角的工作。基础设施团队需要建立能够真正有用和受其他公司部门欢迎的基础设施。与业务部门紧密结合的 ML 团队需要有合作是最好的心态,因此他们应该寻找跨部门合作的机会。
默认实现
这是集中基础设施/分散建模模型的一个过度简化的默认实现:
-
雇佣一个具备 ML 基础设施和生产技能的集中团队(领导者):
-
雇佣软件工程人员建立 ML 基础设施。
-
雇佣 ML 生产工程人员来运行基础设施。
-
-
每个产品团队都会雇佣他们业务单元的专家:
- 雇佣 ML 工程人员直接与产品团队建立模型。
-
开发一种内部发现报告的实践,供高级利益相关者审查。
-
建立全公司技术基础设施标准。
-
根据成功实施计划补偿,并且不仅补偿达到业务目标,还要衡量利用中央基础设施的效率。
-
选择那些有助于跨组织协作的流程,如跨团队 ML 发现审查。
-
启动隐私、质量、公平和伦理计划,建立标准并监督这些标准的合规性。
结论
首次将机器学习技术引入组织是困难的,最佳路径必然因组织而异。成功将需要提前考虑确保成功所需的组织变化,包括诚实面对缺失的技能和角色、流程变化,甚至整个缺失的子组织。有时可以通过招聘或提拔合适的新高级领导者并委以实施任务来解决这些问题。但通常所需的组织变化将涵盖整个公司。
表格 14-1 总结了各种组织结构,以及它们在人员、流程和奖励方面的影响和要求。
一些团队,如生产工程或软件工程团队,开始并不需要大量的机器学习技能来变得有效。但他们将受益于学习小组、参加会议及其他专业发展活动。我们还需要在业务领导者中建立机器学习技能。确定一些能理解将机器学习加入基础设施的好处和复杂性的关键领导者。
然而,成功的最大障碍通常是组织领导层对风险、变革和细节的容忍度,以及坚持机器学习可能需要一段时间才能显现回报的态度。为了推动机器学习进展,我们必须愿意承担风险并改变我们的做法。确保团队专注于业务结果将有助于推广。这涉及改变工作良好的流程并改变成功团队和领导者的行为。这通常也意味着冒险损失成功的业务线。为了理解正在承担的风险,领导者必须关心实施的一些细节。领导者需要容忍风险,但明确关心其机器学习实施的最终可靠性。
表格 14-1. 各种结构和要求的总结
| 中心化的机器学习基础设施和专业知识 | 分散化的机器学习基础设施和专业知识 | 中心化基础设施与分散化建模的混合体 |
|---|
| 人员 | 具有明确专注的专业团队,对机器学习优先事项和投资具有影响力的核心。
需要有实验心态。
领导者/高级成员需要成为其组织外有效的合作者和影响者。
团队需要成为公司内跨团队的机器学习质量、公平性、道德和隐私的倡导者。| 机器学习专业知识分布在各个团队中,通常既重复又稀缺。
领导者/高级成员需要鼓励和执行内部社区。
孤立的决策将导致不良/不一致的客户体验,从而产生显著的业务影响。
所有产品领域的团队需要在机器学习质量、公平性、伦理和隐私方面获得专业知识。 | 集中机器学习基础设施和建模,用于通用/核心业务用例,但鼓励根据具体需求开发个体模型。
避免重复,提高团队效率和一致性,尤其是在大规模情况下。
机器学习质量、公平性、伦理和隐私需要在所有部门的基因中。 |
| 流程 | 需要进行跨职能的协作来做出决策和分享知识。
业务单元的关键利益相关者需要共同审查提案和结果,以及启动计划。
需要去中心化/独立的模型评估,以确保和衡量业务目标和影响。
确保对组合变更进行验证,以避免意外退步,并建立进行/不进行审查会议。 | 需要大量关于最佳实践、知识、评估和启动标准的文档,以保持一致性,或者在本地团队范围之外决定不维护任何文档(这对机器学习来说是有问题的)。
业务单元的关键利益相关者需要共同审查提案和结果,以及启动计划。
需要良好结构化和适度主持的进行/不进行会议,以避免延迟。
为机器学习流水线的技术基础设施建立标准。 | 需要跨职能协作和基础设施与个体产品团队在项目/程序基础上的适度文档化。
建立具有明确责任的跨职能团队。
需要在项目/程序级别定期进行跨职能同步。
业务单元的关键利益相关者需要共同审查提案和结果,以及启动计划。
| 奖励 | 除了总体质量和达到业务目标外,个人/团队绩效还应根据跨职能协作的有效性进行评估。
建立机制,共同补偿成功的 AI 功能发布的机器学习和产品团队。 | 除了总体质量和达到业务目标外,个人/团队绩效还应根据一致性、已发布的质量标准以及运营内部机器学习社区进行评估。 | 除了总体质量和达到业务目标外,个人/团队绩效还应根据可重复使用性、共同基础设施演化以及执行速度进行评估。
¹ 在大多数文献中,这被描述为算法或技术问题。当然,它确实是这些问题,但也很大程度上是组织问题。如果我们没有决策和管理框架来分开评估变更并制定部署策略,我们将无法正确优先考虑这项工作。
第十五章:案例研究:MLOps 实践
本书阐述了 MLOps 的原则和最佳实践,并且我们已经尽力在整个过程中提供了示例。但是,没有什么比听到从事这一领域工作的人的故事更能帮助我们看到这些原则在现实世界中是如何发挥作用的。
本章提供了来自不同实践者团体的一系列案例研究,每一个都详细描述了他们从 MLOps 角度经历的特定问题、挑战或危机。每个故事都是由实践者们自己撰写的,因此我们可以听到他们亲自经历了什么。我们可以看到他们面对的问题,他们是如何处理的,他们学到了什么,以及下次他们可能会有何不同的做法。确实,看到像负载测试这样貌似简单,或者像完全不相关的移动应用程序更新一样,如何给那些负责日常管理和维护 ML 模型和系统的人带来头疼,这是非常引人注目的。(请注意,为了保护商业机密,某些细节可能已被省略或省略。)
1. 在 ML 管道中考虑隐私和数据保留政策
作者:Riqiang Wang,Dialpad
背景
在 Dialpad,自动语音识别(ASR)团队负责为全球客户生成各种 AI 功能的端到端语音转录系统(统称为Dialpad AI)的实时转录。我们 AI 系统的各个子组件都严重依赖于 ASR 输出,以进行进一步的预测,因此转录中的任何错误都会传播到其他下游自然语言处理(NLP)任务,如实时辅助或命名实体识别(NER)。因此,我们不断努力改进 ML 管道中的 ASR 模型。
问题和解决方案
到 2020 年,我们的系统在典型的北美方言中达到了很高的准确率,但我们的基准测试和轶事证据显示其他方言经常被误转录。随着我们将业务扩展到英国、澳大利亚和新西兰等其他主要英语国家,我们需要至少达到为北美方言设定的同一标准。因此,我们开始研究如何提高特定方言的 ASR 准确率,甚至是北美内众多方言的 ASR 准确率。这包括转移学习实验和使用专门的词汇表,但单独使用它们是不够的。隐私在 Dialpad 所做的一切中都是核心问题,这也是现代大多数 ML 生态系统面临的主要挑战。在本案例研究中,我们讨论了我们遇到的几个挑战及其解决方案,以及在尊重用户隐私的同时努力部署多方言模型的工作。
注
与相关文献不同,我们主要使用“方言”这个术语,而不是“口音”,因为我们意识到除了口音(即语音的声音)外,还存在其他变化。例如,纽约和新西兰的方言在词汇、短语表达甚至语法上也有所不同。我们希望在使 ASR 更具包容性的过程中能够理想地解决所有这些方面。
挑战 1:哪些方言?
在 Dialpad,我们重视用户隐私,并且为了支持各种 AI 功能,我们需要大量数据来进行模型训练。因此,我们需要在我们的方言处理管道中进行适当的调整。具体来说,我们尽可能保留与通话相关的少量元数据,并且基于隐私原因在需要时移除通话记录。
但是为了训练一个优秀的方言模型,我们想知道我们的用户中谁使用某种方言,无论是英式、澳式还是其他方言。因此,我们需要尽可能多的元数据,以便我们可以相应地为每种方言进行采样。
我们最初考虑了让人类转录员注释每个通话中所讲的口音的想法,但后来意识到,要准确识别口音是非常困难的,尤其是对于非母语者,他们更可能有个人语言特征而非方言(即每个说话者都有自己的说话方式)。然后,我们考虑让用户自行报告方言,但这种分类显然会引起数据隐私问题,与我们促进包容性的目标相矛盾。
解决方案:摒弃方言的概念!
最终,我们意识到,无论用户使用何种方言,我们只是希望我们的模型在处理它当前遇到困难的语音时能做得更好。ASR 模型在处理北美方言时表现良好,是因为我们一直在提供北美的语音数据,因此我们也可以通过添加被欠采样数据来改进现有模型,建立一个不受方言限制的模型。我们最终通过模型自身的置信度量筛选了更多模型表现不佳的数据。我们手动转录了这些低频数据,并用这些数据集加上原始训练数据训练了一个新模型。
在几轮模型调优和评估后,ASR 模型在我们手动策划的低频方言测试集上表现得更好,而不需要改变训练技术或模型架构。更重要的是,这些额外的方言数据集只是更大原始训练数据的一小部分,但在性能上有了显著的提升。这显示了数据收集中意图和多样性的重要性。它还表明,当真正的多样性难以衡量时,我们可以依赖信心/不确定性测量作为数据收集的伪多样性指标。
挑战 2:与时间赛跑
将 Dialpad 的无成本、可定制的数据保留政策作为所有客户的标准可用性,意味着客户可以随时请求删除他们的数据,或安排新的数据仅在特定时间段内可用。然而,这些重大的隐私胜利需要整个 ASR 系统在模型测试和实验方面同样巨大的智慧,尤其是对于由多个步骤组成的方言 ML 流水线:音频收集、转录、数据准备、实验和最终投入生产。这些步骤可以跨越多个季度,长于某些收集数据的生命周期。这意味着训练数据和测试集并非恒定不变,这使得复现实验结果变得困难,有时会导致训练模型和推出客户期望改进的延迟。
在推广新的方言模型的过程中,我们发现它在多个测试集上表现良好,但在多次内部试验中,与生产中发布的模型(六个月前发布)相比,对一个单一测试集的表现明显较差。这导致我们暂停了模型的部署,以便进一步调查原因。我们采用了多种方法,包括从头开始训练新的方言模型和检查数据分区(在之前的一次不愉快的事件中,数据分区无意中在训练数据和测试数据之间发生了错误划分)。
我们还希望通过使用相同的过程训练模型来复现生产模型的结果,但是在 11 个月后,受数据保留政策约束的数据已经开始过期,我们再也没有完全相同的训练数据集了。这使得复现过去模型构建的结果变得困难,我们只得到了不确定的结果。最终,解决这一差异的关键洞察是,在测试集的参考文本中,先前表现良好的模型实际上是在生产数据被用来制作测试集时正在使用。由于我们的人工转录员通过编辑生产模型的转录来创建测试集的转录,这意味着这个测试集的参考转录偏向于旧模型的输出。然而,我们永远无法确定,因为数据受任意数据保留制度的瞬时性质使得为不足数据建立和维护足够的语料库问题变得更加复杂。
解决方案(以及新的挑战!)
我们认为,这种经验是朝着将我们对数据隐私目标的尊重与可再现研发的严谨性相结合迈出的一大步。在项目结束时,我们已经创建了一个专门的数据团队,负责处理 ASR 或 NLP 团队的数据任务,重新定义了我们整个数据收集和标注准备流程。数据团队的任务是标准化我们的测试集创建过程,创建动态测试集,即使由于数据保留政策需要移除一些测试数据,也能保证高度的可再现性。例如,具有基于时间的保留政策的数据在创建测试集时不再考虑,数据团队还通过补充处理手动数据删除,同时监控我们的测试集上的性能指标随时间变化的情况。
团队还统一了训练数据收集:不再让每个 ASR 工程师自行编写数据库查询来获取数据,现在我们可以向数据团队提交请求,根据需要提供结构化数据,包括考虑(甚至避免)标记为删除的数据。随着对人工标注流水线准确性和完整性的信心提高,我们还在探索在大规模情况下识别个人数据元素的可能性,以便在完全删除转录本之前删除或标记它们。虽然具有挑战性,但这一挑战提出了一种促进隐私、数据最小化技术的方式,从而更加安全地访问 ML 训练数据。
收获
无疑,与隐私和数据保留政策的整合在 ML 流水线中引入了挑战,特别是那些支持面向客户产品/服务的主要用例的 ML 流水线。在我们的用例中,为方言的更具包容性的 ASR 模型进行工作,我们首先了解到,即使在我们的训练数据中稍微增加多样性,也能使模型更加鲁棒。在传统的 ML 实践中,我们倾向于强调训练数据的数量,但我们的结果表明,质量——特别是多样性——是不可替代的。更重要的是,我们可以通过使用模型置信度测量来获得多样性,而无需深入用户的隐私。
其次,尽管在多样性方面的努力受到了我们尊重客户在数据使用上的选择的复杂性的影响,但我们发现通过精心策划,我们可以通过专门团队标准化数据集的创建,将鲁棒性和可再现性引入我们的 ML 流水线中,并实现效率收益。我们相信,通过放弃“权衡”叙事,最终可以通过展示我们愿意付出努力来成为良好的管理员,从而改善我们对所需客户数据的访问。像我们的多样性和方言倡议这样的努力同样向客户展示了广泛参与和 ML 训练集的代表性的价值。
2. 持续影响流量的 ML 模型
作者:Todd Phillips,Google
背景
这是一个来自几年前谷歌内部的事件故事。为了保密,我们隐藏了一些细节,不直接说受影响的系统是哪一个,但这个故事的大概情节仍值得重述。
该系统包含一个连续的机器学习模型,帮助预测在搜索引擎设置中某些类型结果的点击可能性,不断根据新数据进行更新。数据来自多个来源,包括网络浏览器和移动设备上的专业应用程序。(有关连续机器学习模型的更多背景,请参阅第十章。)
有一天,一个特定应用程序做出了改进,向系统贡献了大量流量。作为改进的一部分,包含了一段代码,要求应用程序在更新后再次发出最近的查询,以确保服务的结果处于最新状态。这项改进作为一个瞬间更新推送到了所有应用程序的安装中。为了预示不祥,我们称这次大规模瞬时更新为问题 A。
问题和解决方案
接下来的一天半时间发生了有趣的事情。全球每台设备接收到更新的瞬间,它就重新发出了最近的查询。这导致流量急剧增加,但由于查询是自动发出的,没有额外的用户结果点击。这些具有更多查询但没有额外点击的数据被用来重新训练连续的机器学习模型。
由于一个与此无关的问题,我们将其称为问题 B,原始推送被撤销了。每个收到原始更新的设备现在都更新回了先前的版本。这当然导致每个设备都按照重新发出最近的查询的协议,再次发出最新的查询,造成第三轮重复查询,甚至更多没有相关点击的数据。
此时,连续的机器学习模型正在愉快地训练所有损坏的数据。由于这些损坏的数据中包含很多没有相关点击的流量,模型得到的信号表明,全球的整体点击率现在比仅几小时前低了约一半。模型内的学习结果很快导致了服务模型的变化,而且毫不奇怪地,服务的预测比正常情况下要低。这很快引发了大量警报,模型运维人员开始注意到一个问题,而且没有明显的根本原因,因为应用程序的所有者和模型的所有者对彼此的系统一无所知——实际上,他们处于同一组织的完全不同领域之中。
与此同时,导致回滚的与此无关的问题 B 被修复了,应用程序相关人员再次推送了更新。你猜对了!这导致每个手机设备上的应用程序都再次更新,并且还有一轮重复查询。
到这个时候,运维人员已经按下了连续 ML 模型训练的停止按钮,所有模型训练都已停止。因此,最新版本的模型受到了损坏数据的影响。
到这个时候,组织中已经传开了这件事情,根本原因已经追溯到最近的应用推送,但由于应用更新导致模型预测变化的具体原因并不明显。应用更新导致重复查询的行为并不广为人知,知情者也没有将其与连续 ML 模型中的训练数据影响联系起来。因此,假设更新可能包含另一个错误,并决定重新回滚应用更新,并在此之后观察几个小时。当然,这次再次回滚导致了更多的重复查询和损坏的数据。
当回滚完成并观察了几个小时的系统后,就有足够的信息来确保问题仅仅是推送方式的问题。最终的缓解措施变得很简单:停止在回滚和重新更新方面对应用进行更新,然后让连续 ML 系统向前发展,以迎合世界新状态。ML 模型最终看到了具有适当点击率的干净数据。
亮点
这个研究给我们带来的一个教训是,许多尝试的缓解措施实际上造成了与好处一样多的伤害,并在某些方面延长了影响期。回想起来,如果我们只是允许模型自行运行,系统可能会比我们试图修复问题后更顺利和优雅地恢复。有时候,坚持下去是明智的选择。
3. 钢材检查
作者:Ivan Zhou,Landing AI
背景
许多行业的制造商依赖视觉检测来在生产钢卷过程中检测关键缺陷。我是 Landing AI 的一名机器学习工程师,并撰写了这个案例研究,展示了我们用来开发深度学习模型进行视觉检测任务的一些数据中心技术。
最近,我和我的团队在一个钢材检查项目上进行了工作(图 15-1)。客户多年来一直在开发视觉检测模型,并将其投入生产。但他们的模型只能达到 70%到 80%的准确率。我能够快速原型化一个新的深度学习模型,在项目中检测缺陷的准确率达到了 93%。

图 15-1. 本案例研究重点关注于检测可能在生产中发生的钢卷缺陷
该项目的目标是准确分类客户热轧数据集中的缺陷;热轧 是钢轧制生产管道中的关键阶段。这些缺陷分布在 38 个类别中,许多缺陷类别只有几百个样本。
客户们已经在解决这个问题上工作了近 10 年,他们的模型能够达到的最佳性能只有 80%的准确率,这并不符合客户的需求。多年来,客户尝试引入几个其他 AI 团队来提高模型的准确性。他们尝试通过设计几种最先进的模型来提高性能,但最终都未能取得任何改进。
问题与解决方案
我现场前往参与这个项目。我雇了三名当地实习生帮助我标记这些图像。在第一周,我几乎所有的时间都花在学习缺陷类别、管理标记工作和审核他们的标签上。我按批次向实习生提供数据。每次他们完成后,我会审核他们的标签,并在出现标注错误时给予反馈。
我们没有一次性标记所有数据。在第一次迭代中,每个类别的数据我们只标记了 30%,找出了所有的模棱两可之处,加以解决,然后再标记下一个 30%。所以我们在两周内进行了三次标记。我们专注于可能在制造管道的“轧制”阶段引入的缺陷,即在金属浇铸完成之后但还未完成之前。这些缺陷可能是由于热处理过程中的各种物理条件引起的,并按类别分组。最终,我们标记了 18,000 张图像,丢弃了超过 3,000 张我们认为混淆的图像(图 15-2 和 15-3)。

图 15-2. 热轧设定的细节

图 15-3. 数据标记、标签审核和模型训练的时间轴
一个耗费大量时间的挑战是管理和更新缺陷共识。在 38 个缺陷类别中,许多类别一开始看起来非常相似,因此很容易让标注者混淆。当出现分歧时,我们不得不不断讨论模棱两可的案例,并更新我们的缺陷定义,以维持三名标注者和机器学习工程师之间的缺陷共识。例如,你能从图 Figure 15-4 的九张图像中区分出三个明显的缺陷类别吗?

图 15-4. 从九张图像中视觉识别三类别(黑线、黑条纹和划痕)的区别绝非易事
所以这些就是答案。在我们看到更多这三类样本后,我们能够持续纠正这三种缺陷类型之间的界限,并更新它们的缺陷定义(图 15-5)。我们花了大量精力来保持标注人员对缺陷的一致性。对于确实难以识别的样本,我们不得不从训练数据集中移除它们。

Figure 15-5. 三种更新定义的缺陷类型
除了缺陷定义外,建立标注一致性也非常关键。标注人员不仅要准确地判断缺陷类别,而且由于我们正在进行目标检测,我们还希望他们的边界框标注紧凑而一致。
例如,显示在图 15-6 中的样本来自一个称为辊压铁皮的缺陷类别,其特征是非常密集的孔或黑点。当标注人员标注这些图像时,他们应该在所有具有明显缺陷模式的区域周围绘制紧凑的边界框。如果出现不连续性,他们需要用单独的框进行注释,就像第三张图片(图 15-6)那样。然而,第四张图片在标注审查时被拒绝,因为框太宽松,覆盖了一个缺陷区域。如果我们允许此标注添加到我们的训练集中,将会误导模型在计算损失时,我们应该避免这种情况。

Figure 15-6. 第三张图片展示了一个有详细注释的不连续性,而第四张图片在标注审查期间被拒绝,因为框覆盖的缺陷区域太宽松。
收获
我们花了不到 10%的时间进行模型迭代。每次训练完模型后,我大部分时间都用来回顾错误预测的例子,并找出错误的根本原因。然后,我将这些见解用于进一步清洗数据集。经过两次这样的迭代,我们在测试集上达到了 93%的准确率,错误率降低了 65%。这远远超过了基线和当时客户的预期,满足了他们的需求。
4. NLP MLOps:配置文件和分阶段负载测试
作者:Cheng Chen,Dialpad
背景
Dialpad 的 AI 团队开发了 NLP 应用程序,帮助用户更好地利用他们的通话,包括实时转录格式化、情绪检测、行动项提取等。开发和部署大型 NLP 模型系统是一个挑战。将它们适应实时、成本效益高的性能限制,使这一挑战变得更加复杂。
2019 年,大型语言模型 BERT 实现了最先进的自然语言处理性能。¹ 我们计划利用它提供更准确的 NLP 能力,包括标点恢复、日期、时间和货币检测。然而,为了降低云成本,我们的实时生产环境资源非常有限(GPU 不是选项,多个模型最多只有一个 CPU)。此外,我们对模型推理的硬限制是每个话语 50 毫秒。与此同时,BERT 基础模型具有 12 层变压器块和 1.1 亿个参数。我们知道将其优化以适应我们的实时环境将是一项挑战,但我们仍然忽视了一个关键问题:估算模型需要多快才能满足我们的实时需求是多么困难。
问题与解决方案
我们的团队需要进行本地分析,以便对各种自然语言处理(NLP)模型进行基准测试,这些模型对大量随机抽样的话语进行模型推理,并计算每个话语的平均推理时间。
一旦平均推理速度达到固定阈值,打包的模型将交给我们的数据工程(DE)团队,在我们的 Google Kubernetes Engine(GKE)集群中进行金丝雀部署,并监控各种实时指标的仪表板(图 15-7),能够深入分析特定指标(图 15-8)。
这就是我们如何逐步将基于 BERT 的新标点模型(其目标是恢复标点符号)部署到生产环境中的过程,也是混乱开始的地方。对于基于 BERT 的大型语言模型,DE 团队经常发现延迟或队列时间显著增加,他们不得不回滚部署。显然,本地分析配置与生产系统中实际发生的模式不一致。这种差异可能来自两个方面:集群计算资源分配和/或流量模式。然而,事实是科学家们没有正确的工具来正确评估模型推理。这导致部署和回滚非常耗时,需要大量重复的手动工作。加上对部署潜在表现不佳模型的焦虑,导致系统拥塞和服务中断。作为一种权宜之计,应用科学家和工程师们同意增加计算资源,例如增加一个额外的 CPU 用于推理,但我们显然需要更好的基准测试方法。

图 15-7. 监控实时指标的仪表板

图 15-8. 针对特定模型进行详细分析
一个改进的基准测试过程
我们需要一种方法,允许 NLP 应用科学家高效获取接近生产指标的基准测试结果。(请注意,生产部署仍然需要金丝雀部署。)
除了生产系统外,DE 团队还维护了一个演示环境,用于部署 NLP 模型并与产品界面(参考)集成,以便在生产部署之前进行测试。我们的 QA 团队对各种调用功能进行测试调用,而应用科学家则利用该环境确保模型能够与产品界面正常运行。然而,他们尚未将其用于全面测试大型模型。
DE 团队提出了一个全面且自助的负载测试工具,以帮助应用科学家在演示环境中对模型推理进行基准测试。在设计负载测试工具时,我们牢记以下几个高级要点:
-
负载测试数据应包含触发模型的短语。
-
负载测试数据应包含健康混合的话语长度。最好使用较长的话语长度,以更好地近似系统在压力下的表现。
-
负载测试数据应触发模型推理,而不会被优化/缓存所绕过,从而导致误导性的低运行时延迟。
-
我们使用 CircleCI 工作流来控制自动部署到演示环境。
-
(可选)负载测试数据应具有与预期在生产中使用的数据类似的特征。
开发完成后,应用科学家在演示环境中执行负载测试时有两个选择:
-
基于音频的(端到端)负载测试
-
这是一个完整的端到端测试。
-
这模拟了对系统的调用。
-
数据自动从演示环境中的调用(例如 QA 调用)中采样,并尝试在某些特定功能上提供良好的覆盖范围。
-
如果需要,可以根据需要定制此音频,因此我们可以放置特定于 NLP 的音频数据集。
-
-
基于文本的(特定于模型的)负载测试
-
这仅针对单个微服务(例如,标点符号或情感模型)。
-
这使我们能够选择最具挑战性的输入来对我们的模型进行压力测试。
-
科学家们确定负载测试的类型并准备好所有必要的数据后,将更改部署到演示环境并开始负载测试。
一旦负载测试开始,科学家们可以监控实时仪表板,查看诸如运行时 95 百分位数之类的重要指标,如图 15-9 所示。这是在评估推理速度时最重要的值。作为一个经验法则,低于 1 秒的任何时间都能满足要求。目前,大多数模型倾向于聚集在或低于 0.5 秒。

图 15-9. 运行时 95 百分位数
有了这个工具,科学家们可以自行启动分段测试,无需向 DE 团队寻求帮助。Datadog 仪表板还提供了每个模型运行时性能的全面分析,以便应用科学家能更密切地监控指标数字。因此,在我们快速开发周期中,负载测试工具显著减少了通信开销。
要点
将最先进的自然语言处理性能融入资源受限的实时生产环境中,需要非常高的信心,即测试期间的基准将在生产中得到验证。当我们的测试方法开始在资源密集型的 BERT 模型上失效时,我们利用我们的分段环境为科学家提供更具代表性的测试环境,并使其自助化,以便他们能够快速迭代。自动化分段基准测试步骤已成为模型开发过程中的标准流程。现在,两个团队都感到放心,因为应用科学家能够非常自信地获得接近生产的模型推断估计。
5. 广告点击预测:数据库与现实之间的挑战
由 Google 的 Daniel Papasian 提供
背景
谷歌的广告定位系统旨在帮助最大化显示广告的长期价值,其中包括尽量减少向用户展示不想看的广告的频率。他们部分地通过使用模型来预测某个广告被点击的概率来实现这一目标。当有机会展示广告时,会进行拍卖,拍卖的一部分是服务器使用模型来预测某些广告被点击的概率。这些概率是拍卖的几个输入之一,如果模型表现不佳,用户和广告主的体验都会受到影响。显示广告的行为导致我们向数据库插入一行。数据库中的行对应于向用户展示广告,其列与用于模型训练的特征相关联。此外,一个布尔列表示广告是否导致点击。当插入行时,此列默认为false。
如果广告被点击,将在点击日志中生成一条记录。点击日志团队运行一个过程来移除欺诈点击,并发布一份“干净”点击的反馈,供其他内部用户使用。这个反馈用于更新已经创建的数据库行,标记广告展示已经导致点击。
模型是通过查看此数据库中的行作为示例进行训练的,并使用点击位作为标签。 数据中的行是模型的原始输入,并且每个事件的标签记录为“导致点击”或“未被点击”。 如果我们从不更新模型,它们将在一段时间内表现良好,但最终由于用户行为和广告库存的变化而精度下降。 为了改善整体行为,我们自动化了点击预测模型的重新训练和部署。
在推送重新训练到生产之前,我们验证了我们是否提高了模型的准确性。 我们从训练集中留出一部分数据集,并将其用作测试集。 我们的训练过程通过伯努利抽样处理:在训练之前的 48 小时内展示的每个广告,我们将有 99%的机会对其进行训练,以及 1%的机会将其保留为测试集。 这是通过在我们将test_set位设置为true的行上实施的。 当训练系统读取事件表时,它将过滤出所有这些位为 true 的行。 新训练的模型将发送到此验证系统,该系统对具有test_set位的最近事件生成推断。 它将这些推断与观察到的标签进行比较,以生成有关模型准确性的统计数据。 只有新模型在最近的测试集事件上表现优于旧模型时,才会将模型推送到生产环境。
问题与解决方案
有一个星期一,我们进来时被自动警报所迎接:我们的广告显示率远低于正常水平。 我们很快意识到,我们平均预测的点击概率只有通常水平的十分之一。 我们是否展示广告部分取决于我们认为广告会被点击的可能性。 因此,广泛的点击概率低估解释了广告显示率警报。 但问题仍然存在:我们的用户行为是否发生了变化? 或者我们的模型更新是否在某种程度上对我们造成了伤害,尽管我们有验证措施?
我们查询了训练截止前 48 小时内的所有行的数据库。 无论我们如何聚合它,我们看到的点击率都是惊人地典型。 模型表现得好像点击远不及我们数据库中的数据。 但是为什么我们的验证系统没有阻止模型进入生产? 我们委托我们的数据科学和生产工程团队调查这种情况,以了解发生了什么。
数据科学团队首先查看了验证系统:这个系统原本旨在防止我们发布比替换版本表现更差的模型。验证系统通过在测试集上生成推断来计算损失指标。更低的损失意味着更好的模型。周日的验证运行日志显示,我们按预期处理了测试事件,并且新模型的损失统计低于旧模型。有人有预感,决定再次使用相同的模型对测试集进行验证。测试集从数据库重新读取,并且生成了预期的推断。这一次,损失指标表明新模型比旧模型更差——与周日相反的结果。到底发生了什么?
生产工程团队检查了大量系统的数据范围,试图查看相关系统中是否存在任何未解释的异常。耐人寻味的是,一个图表显示周三到周日的收入为 0,然后在周一凌晨出现了非常大的收入额。这个图表是由一个监视验证点击流的系统生成的。
当生产工程师和数据科学家团队相互商议并分享他们的发现时,他们意识到由于负责处理原始点击日志和向消费者分发干净点击流的基础设施失败,模型出现了欠预测的情况。干净的点击数据直到周一早上模型最后一次训练后才到达 ML 训练系统。没有证据表明相反情况,模型认为这段时间内显示的每个广告都没有被点击。每个事件都是真负或假负,这也是我们的测试集所包含的。我们训练的模型得出的结论是广告很糟糕,没有人会点击任何一个广告,这在我们训练模型时的数据是准确的。当点击处理流赶上时,验证数据被重新标记,使得产生点击的广告被相应标记。这解释了为什么对已训练模型的后续验证尝试仍然失败。问题通过在修正后的数据上重新训练得到解决。
收获
回顾起来,重要的是要注意,我们的模型从未直接预测点击的概率。相反,它预测了在训练时段内被标记为“被点击”的广告展示的概率。确实,虽然我们期望我们的数据库能够准确反映现实,但是错误或故障可能导致差异。在这种情况下,上游系统的生产故障导致了此标签的含义与我们希望反映的不同。我们使用监督学习技术构建的模型在我们的训练集中预测标签,我们的标签反映现实是至关重要的。
团队合作撰写了一份事后分析报告,分析发生了什么以及如何防止。这对我们的组织来说是一次重要的学习经验。我们整理了时间线:从点击预测模型工作人员的角度来看,问题直到周一才被发现。我们后来得知,点击日志团队在周三的软件发布时注意到他们的管道出现故障,并在当天通过他们的警报系统意识到了问题未被处理。他们采取了措施确保点击最终仍将被计费,并计划在周一第一时间修复其余的数据处理问题。他们没有意识到他们的系统是下游机器学习流程的数据依赖,以及该系统如何对数据的完整性作出假设。我们认为许多机器学习流水线对输入数据的完整性和提供标签的正确性做出了假设,而没有验证这些假设,因此可能面临类似问题的风险。
我们列出了我们能够想到的每一个停机的潜在原因;我们知道我们会根据改进的工作量和预期改进的价值来优先考虑这些原因。这些原因包括缺乏集成测试导致点击日志中断、训练系统依赖点击日志处理的可靠性高于约定的服务可用性目标,以及我们假设最近的事件会代表所有事件。
我们的后续工作包括为点击日志处理系统建立可用性目标,扩展我们的验证系统以检查测试集的正样本比例是否异常偏低或偏高,并建立一个流程,用于当模型健康出现严重问题时,点击日志团队可以通报故障并暂停训练。
6. 在机器学习工作流中进行测试和测量依赖关系
作者:Harsh Saini,Dialpad
背景
在 Dialpad,我们有一个语音识别和处理引擎,它具有几个机器学习依赖项。音频从我们的电话后端输入,并通过我们的专有 ASR 模型实时转录,在这过程中还进行格式化和可读性改进。然后输出被馈送到我们的语言特定的自然语言处理模型中,如 NER 和情感分析。这个管道可以简化为一个流程图(见图 15-10)。

图 15-10. Dialpad 语音识别和处理管道流程图
然而,实际情况并不像这个简化的图表所显示的那样直接。根据用户的位置和/或他们在 Dialpad 内使用的产品线,可能会使用多个语音识别模型。例如,使用呼叫中心产品线的英国用户将使用在英国英语方言上进行了微调,并针对呼叫中心领域特定知识的语音识别模型。同样地,使用销售产品线的美国用户将使用在美国英语方言上进行了训练,并针对销售电话领域特定知识的语音识别模型来转录他们的通话。
此外,针对 NLP,多个任务特定模型并行运行,执行情感分析、问题检测和行动项识别等任务。考虑到这一点,简化的流程图可以扩展以突显 Dialpad 生产 ML 管道中模型的多样性。
问题与解决方案
图 15-11 强调了关于上游语音识别模型的 NLP 任务特定模型的一些 ML 依赖项。NLP 模型性能对 ASR 模型输出产物非常敏感。尽管大多数 NLP 模型对 ASR 模型输出的微小变化并不过敏感,但随着时间的推移,数据发生显著变化,NLP 模型由于回归和数据漂移而性能下降。导致 ASR 的一些常见更新导致 NLP 模型输入数据分布发生变化的几个更新如下:
-
ASR 系统词汇的修改(例如,添加了冠状病毒这个词)
-
ASR 系统输出的变化(例如,人们说着相同的话,但我们在准确转录它们方面变得更好)
-
主题漂移,即人们实际上在谈论不同的事物(例如,突然间所有人都开始谈论美国的选举)。

图 15-11. 一些针对 NLP 任务特定模型的 ML 依赖项
为了应对这种现象,Dialpad 的 DE 团队与数据科学团队合作,建立了一个离线测试管道,可以测量给定 ASR 模型的 NLP 模型性能。
建立回归测试沙盒
我们的回归测试和监控系统的一些关键需求如下:
-
确保在发布新的 ASR 模型时,NLP 模型性能的监控将自动进行。
-
模拟观察到的生产模型行为。
-
收集并报告通过评估提交的指标,供利益相关者查看。
-
收集模型推断产物和日志,以帮助科学家进行故障排除。
-
允许数据科学团队在希望评估先行发布模型时进行临时评估。
-
确保我们能够建立可比较的基线,因为评估数据集可能会在带外进行修改。
-
要成为一个可扩展的系统,以便可以同时进行多次评估,并且在增加数据集大小或测试模型数量时也不会成为瓶颈。
鉴于这些要求,做出了以下设计决策:
-
Kubeflow Pipelines(KFP)被选为托管沙箱的平台:
-
KFP 允许用户编写称为pipelines的自定义有向无环图(DAGs)。
-
每个管道都是隔离的,整个平台可以独立扩展到所有运行中管道的需求。
-
Dialpad 的工程团队对Kubernetes和Argo Workflows投入了大量资源,这些技术是支持 KFP 的基础技术,因此使用这个平台似乎是明智的选择。
-
-
KFP 中的管道将通过选择正确的模型部署工件来建立评估所需的正确基础设施,考虑到评估标准。
-
这将在运行时进行,不会持久化,以降低成本。
-
测试平台将与模型版本解耦,并仅了解正确编排的依赖顺序。
-
-
每个模型的输出将会为了调试目的持久化 30 天。
-
每个任务特定 NLP 模型的数据集都将进行版本管理,以跟踪评估数据的变化。
-
将为每个 ASR 模型版本、NLP 模型版本和数据集版本的每个组合收集度量标准。
-
这确保了我们能够正确地消除不同依赖项之间的歧义。
-
这些度量标准将在仪表盘上进行可视化以进行观察。
-
-
测试管道的输入是对话的原始音频记录,因为想法是捕捉 ASR 模型是否发生了足以改变输出的变化,从而影响下游 NLP 模型的性能。
-
一旦收集了音频样本,它们将被注释以说明它们是否包含特定的 NLP 时刻。例如,给定的音频片段将由人类注释,以验证其在情感分析任务中是否包含正面、负面或中性情感。
-
正如你所看到的,这是一项艰巨的任务,仍然是该项目最大的瓶颈之一。正确地切片、注释和存储这些样本对每个 NLP 任务来说都是极其耗时的(图 15-12)。
-

图 15-12. 高级别的回归测试环境
而在 KFP 内部,一个管道将模拟评估一个 ASR 模型版本、NLP 模型版本和数据集版本的单个组合。由于 KFP 允许我们并行运行多个管道,这将使我们能够扩展到我们想要执行的所有评估组合(图 15-13)。

图 15-13. KFP 管道的 DAG 架构
用于回归监控
一旦在 KFP 上建立了管道,项目的下一步是在 NLP 模型的依赖关系发生变化时自动执行回归测试。在 Dialpad,我们有由工程团队管理的成熟的 CI/CD 工作流,并已更新为在转录服务中更新 ASR 模型时触发 KFP 管道。CI/CD 工作流会向 KFP 发送有关 ASR 模型、NLP 模型等的信息,然后在 KFP 上进行评估。度量数据将被存储,并将发出 Slack 消息,包含评估摘要。
一旦投入运行,这个过程将为平台上所有具有测试数据的 NLP 任务特定模型捕获性能评估数据。例如,NLP 情感分析模型的 F1 分数在一年内下降了约 25%,如图 15-14 所示;该图突出显示了与基准线的绝对差异。这一观察引起了 NLP 团队的注意,他们调查发现积累的数据漂移是导致性能下降的原因。新的情感模型使用最新的 ASR 模型输出进行了重新训练,并在短短几个月内发布到生产环境中。
这个过程的另一个间接好处是,在生产发布之前,它允许针对不同语音识别(ASR)模型对自然语言处理(NLP)模型进行临时评估。例如,可以测量情感分析模型在发布之前针对新的英语方言(如澳大利亚或新西兰英语)的 ASR 模型的准确性。

图 15-14. NLP 情感分析模型的 F1 分数
要点
这在 Dialpad 开发的 ML 回归测试平台大大提升了数据科学家和工程师对新模型发布对我们生产堆栈中所有依赖组件影响的可见性。即使对所有部署的生产模型了解不完全,人们也能够了解建议的发布是否会影响生产流水线中其他模型的稳定性和性能。这减少了回滚的可能性,并且可以提前指示是否需要进一步改进与现有组件的兼容性。
测试平台正在积极开发中。正在处理其他移动组件,其中之一是保持沙箱编排与生产同步,并允许仅在生产调用期间短暂存在的其他“实时数据”,这在回归测试平台中很难模拟。另一个正在考虑的功能是如何在建议的发布对下游模型有重大影响时提供自动警报,而不是当前的人工参与方法。
¹ 查看 Jacob Devlin 等人于 2019 年发表的论文 “BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding”。


浙公网安备 33010602011771号