文章目录


第 8 章中,我们讨论了 ML 系统在生产中可能出现故障的各种方式。我们专注于一个特别棘手的问题,该问题在两位研究人员中引起了很多讨论和从业者:数据分布的变化。我们还讨论了检测数据分布变化的多种监控技术和工具。

本章是这个讨论的延续:我们如何使我们的模型适应数据分布的变化?答案是不断更新我们的机器学习模型。我们将首先讨论什么是持续学习及其挑战——剧透:持续学习在很大程度上是一个基础设施问题。然后我们将制定一个四个阶段的计划,以使持续学习成为现实。

在您设置好基础架构以允许您根据需要频繁更新模型之后,您可能需要考虑一下我遇到的几乎每个 ML 工程师都问过我的问题:“我应该多久重新训练我的模型?” 这个问题是本书下一部分的重点。

如果模型经过重新训练以适应不断变化的环境,仅在静态测试集上对其进行评估是不够的。我们将介绍一个看似可怕但必要的概念:生产测试。此过程是一种使用生产中的实时数据测试您的系统的方法,以确保您更新的模型确实可以正常工作而不会造成灾难性后果。

本章和前一章的主题紧密结合。生产中的测试是对监控的补充。如果监控意味着被动地跟踪正在使用的任何模型的输出,那么在生产中测试意味着主动选择生成输出的模型,以便我们可以对其进行评估。生产中监控和测试的目标是了解模型的性能并确定何时更新它。持续学习的目标是安全有效地自动更新。所有这些概念使我们能够设计一个可维护且可适应不断变化的环境的 ML 系统。

这是我最兴奋的一章,我希望我也能让你兴奋!

持续学习

当听到“持续学习”时,许多人会想到训练范式,其中模型会根据生产中的每个传入样本进行自我更新。很少有公司真正做到这一点。首先,如果你的模型是一个神经网络,学习每个传入的样本使其容易发生灾难性遗忘。灾难性遗忘是指神经网络在学习新信息时完全而突然地忘记先前学习的信息的趋势。1

其次,它会使训练变得更加昂贵——今天的大多数硬件后端都是为批处理而设计的,因此一次只处理一个样本会导致计算能力的巨大浪费,并且无法利用数据并行性。

在生产中采用持续学习的公司会以微批量的方式更新他们的模型。例如,他们可能会在每 512 或 1,024 个示例之后更新现有模型——每个微批次中的最佳示例数量取决于任务。

在评估之前不应部署更新的模型。这意味着您不应直接更改现有模型。相反,您创建现有模型的副本并在新数据上更新此副本,并且仅在更新的副本证明更好时才用更新的副本替换现有模型。现有模型是称为冠军模型,而更新的副本称为挑战者。这个过程如图 9-1所示。为了便于理解,这是对过程的过度简化。实际上,一家公司可能同时有多个挑战者,处理失败的挑战者比简单地丢弃它要复杂得多。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-1。持续学习如何在生产中发挥作用的简化。实际上,处理失败的挑战者的过程比简单地丢弃它要复杂得多。

尽管如此,“持续学习”这个词还是让人们想象更新模型非常频繁,比如每 5 或 10 分钟一次。许多人认为,大多数公司不需要频繁更新他们的模型,原因有两个。首先,他们没有足够的流量(即足够的新数据)来使该再培训计划有意义。其次,他们的模型不会衰减得那么快。我同意他们。如果将再培训计划从一周改为一天没有回报并导致更多开销,则没有必要这样做。

无状态再培训与有状态培训

然而,持续学习不是关于再训练的频率,而是模型的方式再培训。大多数公司都进行无状态再训练——模型每次都是从头开始训练的。持续学习也意味着允许有状态的训练——模型继续训练新数据。2有状态训练也称为微调或增量学习。无状态再训练和有状态训练之间的区别如图 9-2 所示

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-2。无状态再培训与有状态培训

有状态的训练允许你用更少的数据更新你的模型。从头开始训练模型往往需要比微调相同模型更多的数据。例如,如果您从头开始重新训练模型,您可能需要使用过去三个月的所有数据。但是,如果你从昨天的检查点微调你的模型,你只需要使用最后一天的数据。

Grubhub 发现有状态训练可以让他们的模型更快地收敛,并且需要更少的计算能力。从每日无状态再培训到每日有状态培训,他们的培训计算成本降低了 45 倍,购买率提高了 20%。3

一个经常被忽视的美丽特性是,通过有状态的训练,有可能完全避免存储数据。在传统的无状态再训练中,一个数据样本可能会在模型的多次训练迭代中重复使用,这意味着需要存储数据。这并不总是可行的,尤其是对于具有严格隐私要求的数据。在有状态的训练范式中,每次模型更新只使用新鲜数据进行训练,因此一个数据样本仅用于训练一次,如图 9-2所示. 这意味着可以训练您的模型,而无需将数据存储在永久存储中,这有助于消除对数据隐私的许多担忧。然而,这一点被忽视了,因为今天让我们跟踪一切的做法仍然让许多公司不愿意丢弃数据。

有状态的培训并不意味着没有从头开始培训。最成功地使用有状态训练的公司偶尔也会在大量数据上从头开始训练他们的模型来校准它。或者,他们也可以从头开始训练他们的模型与状态训练并行,然后使用参数服务器等技术将两个更新的模型结合起来。4

一旦您的基础设施设置为允许无状态再培训和有状态培训,培训频率只是一个旋钮。您可以每小时更新一次模型,每天更新一次,或者在检测到分布变化时更新。如何找到最佳的再训练计划将在“多久更新一次模型”一节中讨论。

持续学习是关于以某种方式设置基础架构,使您(数据科学家或 ML 工程师)能够在需要时更新您的模型,无论是从头开始还是微调,并快速部署此更新。

您可能想知道:有状态训练听起来很酷,但是如果我想在模型中添加新功能或其他层,这将如何工作?要回答这个问题,我们必须区分两种类型的模型更新:

模型迭代

将新功能添加到现有功能模型架构或模型架构已更改。

数据迭代

模型架构和功能保持不变,但您使用新数据刷新此模型。

时至今日,状态训练主要应用于数据迭代,因为更改模型架构或添加新功能仍然需要从头开始训练生成的模型。有研究表明,通过使用知识转移(Google,2015)和模型手术(OpenAI,2019)等技术,可以绕过从头开始的模型迭代训练。根据 OpenAI 的说法,“Surgery 在选择过程后将经过训练的权重从一个网络转移到另一个网络,以确定模型的哪些部分未更改,哪些部分必须重新初始化。” 5几个大型研究实验室已经对此进行了试验;但是,我不知道该行业有任何明确的结果。

术语歧义

我使用术语“持续学习”而不是“在线学习”,因为当我说“在线学习”时,人们通常会想到在线教育。如果您在 Google 上输入“在线学习”,排名靠前的结果可能是关于在线课程的。

有些人使用“在线学习”来指代模型从每个传入的新样本中学习的特定设置。在这种情况下,持续学习是在线学习的概括。

我也使用术语“持续学习”而不是“持续学习”。持续学习是指您的模型对每个传入样本持续学习的机制,而在持续学习中,学习是在一系列批次或微批次中完成的。

持续学习有时被用来指代 ML 的持续交付,这与持续学习密切相关,因为两者都有助于公司加快其 ML 模型的迭代周期。然而,不同之处在于,在这种意义上使用“持续学习”时,是从 DevOps 的角度来建立持续交付的管道,而“持续学习”是从 ML 的角度来看的。

由于“持续学习”一词的含糊不清,我希望社区可以完全远离这个词。

为什么要持续学习?

我们讨论了持续学习是关于设置基础设施,以便您可以更新模型并尽可能快地部署这些更改。但是,为什么您需要尽可能快地更新模型的能力呢?

持续学习的第一个用例是对抗数据分布的变化,尤其是当变化突然发生时。想象一下,您正在构建一个模型来确定 Lyft 等拼车服务的价格。6从历史上看,这个特定社区周四晚上的乘车需求很慢,因此该模型预测乘车价格较低,这使得司机上路的吸引力降低。然而,在这个星期四晚上,附近发生了一件大事,突然乘车需求激增。如果您的模型无法通过提高其价格预测和调动更多司机到该社区来足够快地响应这一变化,那么乘客将不得不等待很长时间才能乘车,这会导致负面的用户体验。他们甚至可能转向竞争对手,这会导致您失去收入。

持续学习的另一个用例是适应罕见事件。想象一下,你为亚马逊这样的电子商务网站工作。黑色星期五是一年仅举行一次的重要购物活动。您无法为您的模型收集足够的历史数据,从而能够准确预测您的客户在今年黑色星期五期间的行为方式。为了提高性能,您的模型应该全天学习新鲜数据。2019 年,阿里巴巴以 1.03 亿美元收购了领导流处理框架 Apache Flink 开发的团队 Data Artisans,以便该团队可以帮助他们将 Flink 用于 ML 用例。7他们的旗舰用例是在光棍节提出更好的建议,光棍节是中国的购物场合,类似于美国的黑色星期五。

持续学习可以帮助克服的当今 ML 生产面临的一个巨大挑战是持续冷启动问题。当您的模型必须在没有任何历史数据的情况下对新用户进行预测时,就会出现冷启动问题。例如,为了向用户推荐他们接下来可能想看的电影,推荐系统通常需要知道该用户之前看过什么。但是,如果该用户是新用户,您将没有他们的观看历史记录,并且必须为他们生成一些通用的东西,例如,您网站上目前最流行的电影。8

持续冷启动是冷启动问题的一种概括,9因为它不仅可能发生在新用户身上,也可能发生在现有用户身上。例如,可能会发生这种情况,因为现有用户从笔记本电脑切换到手机,并且他们在手机上的行为与在笔记本电脑上的行为不同。这可能是因为用户没有登录——大多数新闻网站不需要读者登录才能阅读。

当用户访问服务太少以至于该服务拥有的关于该用户的任何历史数据都已过时时,也会发生这种情况。例如,大多数人一年只预订几次酒店和航班。Coveo 是一家为电子商务网站提供搜索引擎和推荐系统的公司,该公司发现,电子商务网站 70% 以上的购物者每年访问其网站的次数少于 3 次是很常见的。10

如果您的模型没有足够快地适应,那么在下次更新模型之前,它将无法提出与这些用户相关的建议。到那时,这些用户可能已经离开了服务,因为他们找不到任何与他们相关的东西。

如果我们可以让我们的模型适应访问会话中的每个用户,那么即使在用户第一次访问时,模型也能够对用户做出准确、相关的预测。例如,TikTok 成功地应用了持续学习,在几分钟内将他们的推荐系统适应每个用户。您下载该应用程序,观看几个视频后,TikTok 的算法能够高精度地预测您接下来想观看的内容。11我不认为每个人都应该尝试构建像 TikTok 这样令人上瘾的东西,但这证明了持续学习可以释放强大的预测潜力。

“为什么要持续学习?” 应该改写为“为什么不继续学习?” 持续学习是批处理学习的超集,因为它允许您完成传统批处理学习可以做的所有事情。但是持续学习还允许您解锁批量学习无法解锁的用例。

如果持续学习与批量学习花费相同的精力和成本进行设置,那么没有理由不进行持续学习。在撰写本书时,在建立持续学习方面仍然存在很多挑战,我们将在下一节中深入探讨。但是,用于持续学习的 MLOps 工具正在成熟,这意味着,在不久的将来,它可能会变得很容易设置持续学习作为批量学习。

持续学习挑战

尽管持续学习有很多用例,并且许多公司已经成功应用它,但持续学习仍然面临许多挑战。在本节中,我们将讨论三个主要挑战:新数据访问、评估和算法。

新数据访问挑战

第一个挑战是获取新数据的挑战。如果你想每小时更新一次模型,你每小时都需要新数据。目前,许多公司从他们的数据仓库中提取新的训练数据。从数据仓库中提取数据的速度取决于这些数据存入数据仓库的速度。速度可能很慢,尤其是当数据来自多个来源时。另一种方法是允许在数据存入数据仓库之前提取数据,例如,直接从实时传输(如 Kafka 和 Kinesis)将数据从应用程序传输到数据仓库12 ,如图 9-3所示。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-3。在将数据存入数据仓库之前,直接从实时传输中提取数据,可以让您访问更新鲜的数据

能够提取新数据是不够的。如果您的模型需要更新标记数据,就像今天的大多数模型一样,这些数据也需要标记。在许多应用程序中,模型更新的速度受到数据标记速度的限制。

持续学习的最佳候选者是可以通过短反馈循环获得自然标签的任务。这些任务的示例是动态定价(基于估计的需求和可用性)、估计到达时间、股票价格预测、广告点击率预测以及在线内容(如推文、歌曲、短视频、文章等)的推荐系统。

但是,这些自然标签通常不是作为标签生成的,而是作为需要提取到标签中的行为活动来生成的。让我们通过一个例子来说明这一点。如果您运行一个电子商务网站,您的应用程序可能会在晚上 10:33 注册,用户 A 单击 ID 为 32345 的产品。您的系统需要查看日志以查看此产品 ID 是否曾被推荐给此用户,如果是,那么是什么查询提示了此推荐,以便您的系统可以将此查询与此推荐匹配,并将此推荐标记为好推荐,如图 9-4所示。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-4。简化从用户反馈中提取标签的过程

回顾日志的过程提取标签称为标签计算。如果日志的数量很大,这可能会非常昂贵。标签计算可以通过批处理来完成:例如,等待日志首先存入数据仓库,然后再运行批处理作业以一次从日志中提取所有标签。然而,如前所述,这意味着我们需要先等待数据被存入,然后等待下一个批处理作业运行。一种更快的方法是利用流处理直接从实时传输中提取标签。13

如果您的模型的速度迭代受到标记速度的限制,还可以通过利用 Snorkel 等程序化标记工具以最少的人工干预生成快速标记,从而加快标记过程。也可以利用众包标签来快速注释新数据。

鉴于围绕流媒体的工具仍处于初期阶段,构建一个高效的流媒体优先基础设施以访问新数据并从实时传输中提取快速标签可能是工程密集型且成本高昂的。好消息是围绕流媒体的工具正在快速增长。Confluent 是建立在 Kafka 之上的平台,截至 2021 年 10 月,它是一家价值 160 亿美元的公司。2020 年底,Snowflake 成立了一个专注于流媒体的团队。14截至 2021 年 9 月,Materialise 已筹集 1 亿美元用于开发流式 SQL 数据库。15随着围绕流媒体的工具日趋成熟,它将变得越来越多公司更容易、更便宜地为 ML 开发流优先的基础设施。

评估挑战

持续的最大挑战学习不是写一个函数来不断更新你的模型——你可以通过写一个脚本来做到这一点!最大的挑战是确保此更新足以部署。在本书中,我们讨论了 ML 系统如何在生产中造成灾难性故障,从数百万少数族裔被不公正地拒绝贷款,到过度信任自动驾驶仪的司机卷入致命车祸。16

灾难性失败的风险会随着不断学习而放大。首先,更新模型的频率越高,更新失败的可能性就越大。

其次,持续学习让你的模型更容易受到协同操纵和对抗性攻击。因为您的模型从现实世界的数据中在线学习,所以用户可以更轻松地输入恶意数据来欺骗模型学习错误的东西。2016 年,微软发布了 Tay,这是一款能够通过 Twitter 上“随意而有趣的对话”进行学习的聊天机器人。Tay 一推出,巨魔就开始在推特上发布机器人种族主义和厌恶女性的言论。该机器人很快开始发布具有煽动性和攻击性的推文,导致微软在其发布 16 小时后关闭了该机器人。17

为避免发生类似或更严重的事件,在将更新部署到更广泛的受众之前,彻底测试每个模型更新以确保其性能和安全性至关重要。我们已经在第 6 章讨论过模型离线评估,本章将讨论在线评估(生产测试)。

在为持续学习设计评估管道时,请记住评估需要时间,这可能是模型更新频率的另一个瓶颈。例如,与我合作的一家大型在线支付公司有一个机器学习系统来检测欺诈交易。18欺诈模式变化很快,因此他们希望快速更新系统以适应不断变化的模式。在针对当前模型进行 A/B 测试之前,他们无法部署新模型。但是,由于任务的不平衡性(大多数交易不是欺诈),他们大约需要两周时间才能看到足够多的欺诈交易,从而能够准确评估哪种模型更好。19因此,他们只能更新系统每两周一次。

算法挑战

与新数据挑战相比和评估,这是一个“更软”的挑战,因为它只影响某些算法和某些训练频率。准确地说,它只影响希望非常快速(例如,每小时)更新的基于矩阵和基于树的模型。

为了说明这一点,请考虑两种不同的模型:神经网络和基于矩阵的模型,例如协同过滤模型。协同过滤模型使用用户项目矩阵和降维技术。

您可以使用任意大小的数据批次更新神经网络模型。您甚至可以仅使用一个数据样本执行更新步骤。但是,如果要更新协同过滤模型,首先需要使用整个数据集构建用户-项目矩阵,然后再对其进行降维。当然,您可以在每次使用新数据样本更新矩阵时对矩阵应用降维,但如果您的矩阵很大,那么降维步骤会太慢且成本太高而无法频繁执行。因此,与前面的神经网络模型相比,该模型不太适合使用部分数据集进行学习。20

使神经网络等模型比基于矩阵和基于树的模型更容易适应持续学习范式。然而,已经有一些算法可以创建可以从增量数据中学习的基于树的模型,最著名的是 Hoeffding Tree 及其变体 Hoeffding Window Tree 和 Hoeffding Adaptive Tree,21但它们的用途尚未广泛。

不仅学习算法需要处理部分数据集,特征提取代码也必须如此。我们在“缩放”一节中讨论过,通常需要使用最小值、最大值、中值和方差等统计数据来缩放特征。要计算数据集的这些统计数据,您通常需要遍历整个数据集。当您的模型一次只能看到一小部分数据时,理论上,您可以为每个数据子集计算这些统计信息。然而,这意味着这些统计数据将在不同子集之间波动很大。从一个子集计算的统计数据可能与下一个子集有很大不同,这使得在一个子集上训练的模型难以泛化到下一个子集。

为了使这些统计数据在不同子集中保持稳定,您可能希望在线计算这些统计数据。您可以在看到新数据时逐步计算或近似这些统计数据,而不是一次使用所有数据的均值或方差,例如“流中的最佳分位数近似”中概述的算法。22当今流行的框架提供了一些计算运行统计数据的能力——例如,sklearn 的 StandardScaler 有一个partial_fit允许将特征缩放器与运行统计数据一起使用的能力——但是内置方法速度很慢,不支持广泛的运行统计信息。

持续学习的四个阶段

我们已经讨论了持续学习是什么,为什么持续学习很重要,以及持续学习的挑战。接下来,我们将讨论如何克服这些挑战并实现持续学习。在撰写本书时,持续学习并不是公司开始的事情。朝着持续学习的转变分为四个阶段,如下所述。我们将回顾每个阶段发生的事情以及从前一个阶段转移到这个阶段所需的要求。

第 1 阶段:手动、无状态再培训

一开始,ML 团队通常专注于开发 ML 模型以解决尽可能多的业务问题。例如,如果您的公司是一个电子商务网站,您可能会依次开发四种模型:

  1. 检测欺诈交易的模型

  2. 向用户推荐相关产品的模型

  3. 预测卖家是否滥用系统的模型

  4. 用于预测运送订单需要多长时间的模型

因为您的团队专注于开发新模型,所以更新现有模型处于次要地位。仅当满足以下两个条件时才更新现有模型:模型的性能已经下降到弊大于利的程度,并且您的团队有时间更新它。您的某些模型每六个月更新一次。有些每季度更新一次。有些已经在野外使用了一年,根本没有更新。

更新模型的过程是手动和临时的。某人,通常是数据工程师,必须查询数据仓库以获取新数据。其他人清理这些新数据,从中提取特征,在新旧数据上从头开始重新训练该模型,然后将更新后的模型导出为二进制格式。然后其他人采用该二进制格式并部署更新的模型。通常,封装数据、特征和模型逻辑的代码在重新训练过程中发生了更改,但这些更改未能复制到生产中,导致难以追踪的错误。

如果这个过程对您来说听起来很熟悉,那么您并不孤单。科技行业以外的绝大多数公司——例如,不到三年前采用 ML 并且没有 ML 平台团队的任何公司——都处于这个阶段。23

第 2 阶段:自动再培训

几年后,您的团队成功地部署模型来解决大多数明显的问题。您有 5 到 10 个模型在生产中。您的首要任务不再是开发新模型,而是维护和改进现有模型。上一阶段提到的临时手动更新模型的过程已经发展成为一个无法忽视的痛点。您的团队决定编写一个脚本来自动执行所有再培训步骤。然后使用 Spark 等批处理程序定期运行此脚本。

大多数机器学习基础设施比较成熟的公司都处于这个阶段。一些成熟的公司进行实验以确定最佳的再培训频率。然而,对于这个阶段的大多数公司来说,重新训练的频率是根据直觉来设定的——例如,“一天一次似乎是对的”或“让我们每天晚上有空闲计算时开始重新训练过程”。

在创建脚本以自动执行系统的再培训过程时,您需要考虑到系统中的不同模型可能需要不同的再培训计划。例如,考虑一个由两个模型组成的推荐系统:一个模型为所有产品生成嵌入,另一个模型对给定查询的每个产品的相关性进行排名。与排名模型相比,嵌入模型可能需要重新训练的频率要低得多。因为产品的特征不会经常改变,你可能可以每周重新训练一次嵌入,24而你的排名模型可能需要每天重新训练一次。

如果模型之间存在依赖关系,自动化脚本可能会变得更加复杂。例如,因为排名模型依赖于嵌入,当嵌入改变时,排名模型也应该更新。

要求

如果您的公司在生产中拥有 ML 模型,那么您的公司很可能已经拥有自动化再培训所需的大部分基础设施。此阶段的可行性围绕着编写脚本以自动化您的工作流程并将您的基础架构配置为自动的可行性:

  1. 拉取数据。

  2. 如有必要,对这些数据进行下采样或上采样。

  3. 提取特征。

  4. 处理和/或注释标签以创建训练数据。

  5. 开始训练过程。

  6. 评估新训练的模型。

  7. 部署它。

编写此脚本需要多长时间取决于许多因素,包括脚本编写者的能力。但是,总的来说,会影响这个脚本可行性的三个主要因素是:调度器、数据和模型存储。

调度程序基本上是一种处理任务调度的工具,我们将在“Cron、调度程序和编排程序”一节中介绍。如果您还没有调度程序,则需要时间来设置一个。但是,如果您已经有了 Airflow 或 Argo 之类的调度程序,那么将脚本连接在一起应该不会那么难。

第二个因素是数据的可用性和可访问性。您是否需要自己将数据收集到数据仓库中?您是否必须加入来自多个组织的数据?您是否需要从头开始提取大量特征?您还需要标记数据吗?您回答“是”的问题越多,设置此脚本所需的时间就越多。Stitch Fix 的机器学习/数据平台经理 Stefan Krawczyk 评论说,他怀疑大多数人的时间可能都花在了这里。

您需要的第三个因素是模型存储,用于自动版本化和存储重现模型所需的所有工件。最简单的模型存储可能只是一个 S3 存储桶,它以某种结构化方式存储模型的序列化 blob。但是,像 S3 这样的 Blob 存储在版本控制工件方面既不擅长也不易于人类阅读。你可能需要更成熟的模型存储,例如 Amazon SageMaker(托管服务)和 Databricks 的 MLflow(开源)。我们将详细介绍模型商店是什么,并在“模型商店”部分评估不同的模型商店。

功能重用(记录和等待)

从新数据创建训练数据以更新模型时,请记住新数据已经通过预测服务。该预测服务已经从这些新数据中提取了特征以输入到模型中进行预测。一些公司将这些提取的特征重新用于模型再训练,既节省了计算量,又允许预测和训练之间的一致性。这种方法被称为“记录并等待”。这是减少第 8 章中讨论的训练服务偏差的经典方法(参见“生产数据不同于训练数据”一节)。

记录并等待还不是一种流行的方法,但它越来越流行。Faire 有一篇很棒的博客文章讨论了他们的“登录并等待”方法的优缺点。

第 3 阶段:自动化、有状态的训练

在第 2 阶段,每次重新训练模型时,您从头开始训练(无状态再训练)。它使您的再培训成本高昂,尤其是对于更高频率的再培训。您阅读了“无状态再训练与有状态训练”部分并决定要进行有状态训练——当您可以仅使用最后一天的数据继续训练时,为什么要每天训练最近三个月的数据?

所以在这个阶段,你重新配置你的自动更新脚本,这样当模型更新开始时,它首先找到前一个检查点并将其加载到内存中,然后继续在这个检查点上进行训练。

要求

在这个阶段你需要做的主要事情是改变思维方式:从头开始再培训是一种常态——许多公司已经习惯于数据科学家每次都将模型交给工程师从头开始部署——以至于许多公司不这样做考虑建立他们的基础设施以实现有状态的培训。

一旦你致力于有状态的训练,重新配置更新脚本就很简单了。在此阶段,您需要的主要是一种跟踪数据和模型沿袭的方法。假设您首先上传模型版本 1.0。此模型使用新数据更新以创建模型版本 1.1,依此类推以创建模型 1.2。然后上传另一个模型并称为模型版本 2.0。此模型使用新数据更新以创建模型版本 2.1。一段时间后,您可能会拥有模型版本 3.32、模型版本 2.11、模型版本 1.64。您可能想知道这些模型如何随着时间的推移而演变,使用哪个模型作为其基本模型,以及使用哪些数据来更新它,以便您可以重现和调试它。据我所知,没有现有的模型商店具有这种模型沿袭能力,因此您可能必须在内部构建解决方案。

如果您想从实时传输而不是从数据仓库中提取新数据,如“新数据访问挑战”一节中所述,并且您的流式基础架构还不够成熟,您可能需要改造您的流媒体管道。

第 4 阶段:持续学习

在第 3 阶段,您的模型仍会根据开发人员制定的固定时间表进行更新。找到最佳时间表并不简单,而且可能取决于具体情况。例如,上周市场上没有发生什么太大的变化,所以你的模型并没有那么快衰减。但是,本周发生了很多事件,因此您的模型衰减得更快,需要更快的再训练计划。

您可能希望在数据分布发生变化和模型性能下降时自动更新模型,而不是依赖固定的时间表。

圣杯是将持续学习与边缘部署相结合。想象一下,您可以使用新设备(手机、手表、无人机等)发布基本模型,并且该设备上的模型将根据需要不断更新并适应其环境,而无需与中央服务器同步。不需要集中式服务器,这意味着没有集中式服务器成本。也无需在设备和云端之间来回传输数据,这意味着更好的数据安全性和隐私性!

要求

从第 3 阶段到第 4 阶段的转变非常陡峭。您首先需要一种机制来触发模型更新。该触发器可以是:

基于时间

例如,每五分钟

基于性能

例如,每当模型性能下降时

基于体积

例如,每当标记数据的总量增加 5%

基于漂移

例如,每当检测到主要的数据分布变化时

要使这种触发机制起作用,您需要一个可靠的监控解决方案。我们在“监控和可观察性”一节中讨论过,困难的部分不是检测变化,而是确定这些变化中的哪些重要。如果您的监控解决方案提供了很多错误警报,那么您的模型最终会比它需要的更新频率更高。

您还需要一个可靠的管道来持续评估您的模型更新。编写一个函数来更新你的模型与你在第 3 阶段所做的没有太大区别。困难的部分是确保更新的模型正常工作。我们将在“生产测试”一节中介绍您可以使用的各种测试技术。

多久更新一次模型

既然您的基础架构已经设置为可以快速更新模型,您就开始问一直以来的问题困扰着各种规模和规模公司的 ML 工程师:“我应该多久更新一次我的模型?” 在尝试回答这个问题之前,我们首先需要弄清楚你的模型会从更新新数据中获得多少收益。您的模型从更新的数据中获得的收益越多,重新训练的频率就越高。

数据新鲜度的价值

如果我们知道模型性能会提高多少,那么多久更新一次模型的问题就会变得容易得多与更新。例如,如果我们从每月重新训练模型切换到每周重新训练,我们可以获得多少性能提升?如果我们改用日常再培训呢?人们一直在说数据分布发生了变化,所以更新鲜的数据更好,但更新鲜的数据有多好?

计算增益的一种方法是根据过去不同时间窗口的数据训练模型,并根据今天的数据对其进行评估,以了解性能如何变化。例如,假设您有 2020 年的数据。要衡量数据新鲜度的值,您可以在 2020 年 1 月至 2020 年 6 月的数据上试验模型版本 A,在 4 月至 9 月的数据上试验模型版本 B,然后以 6 月至 11 月的数据为模型版本 C,然后在 12 月的数据上分别测试这些模型版本,如图 9-5所示. 这些版本的性能差异将使您了解模型可以从更新的数据中获得的性能提升。如果使用一个季度前的数据训练的模型比使用一个月前的数据训练的模型差得多,那么您知道您不应该等待一个季度来重新训练您的模型。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-5。要了解您可以从较新的数据中获得的性能提升,请使用过去不同时间窗口的数据训练您的模型,并测试今天的数据以查看性能如何变化

 这是一个简单的例子来说明数据新鲜度实验是如何工作的。在实践中,您可能希望您的实验更加细粒度,而不是几个月,而是几周、几天,甚至几小时或几分钟。2014 年,Facebook 做了一个类似的广告点击率预测实验,发现他们可以将模型的损失降低 1%,从每周再训练到每天再训练,这种性能提升足以让他们改变他们的从每周到每天的再培训管道。25鉴于当今的网络内容更加多样化,用户在线关注度变化更快,我们可以想象数据新鲜度对于广告点击的价值率甚至更高。一些拥有复杂 ML 基础设施的公司已经发现足够的性能提升,可以将他们的再培训管道切换到每隔几分钟。26

模型迭代与数据迭代

我们在本章前面讨论过,并非所有模型更新都是相同的。我们区分了模型迭代(向现有模型架构添加新功能或更改模型架构)和数据迭代(相同的模型架构和功能,但您使用新数据刷新此模型)。您可能不仅想知道多久更新一次模型,还想知道要执行什么样的模型更新。

理论上,您可以同时进行这两种类型的更新,而在实践中,您应该不时同时进行这两种更新。但是,您在一种方法中花费的资源越多,您可以在另一种方法中花费的资源就越少。

一方面,如果您发现迭代数据并没有给您带来太多性能提升,那么您应该将资源用于寻找更好的模型。另一方面,如果找到一个更好的模型架构需要 100 倍的计算来进行训练并为您提供 1% 的性能,而在过去三个小时的数据上更新相同的模型只需要 1 倍的计算并且还提供 1% 的性能提升,那么您将更好地迭代数据。

也许在不久的将来,我们会获得更多的理论理解,以了解一种方法在什么情况下效果更好(提示“呼吁研究”),但截至今天,没有一本书可以回答你哪种方法效果更好为您的特定任务的特定模型。你必须做实验才能找到答案。

关于多久更新一次模型的问题很难回答,我希望本节已经充分解释了它的细微差别。一开始,当您的基础设施处于初期阶段并且更新模型的过程是手动且缓慢时,答案是:尽可能多地进行

但是,随着您的基础设施成熟并且更新模型的过程部分自动化并且可以在几小时甚至几分钟内完成,这个问题的答案取决于对以下问题的回答:“多少性能提升我会从更新鲜的数据中获取信息吗?” 运行实验以量化数据新鲜度对模型的价值非常重要。

生产测试

在整本书中,包括本章,我们都谈到了部署模型的危险性评估。为了充分评估您的模型,您首先需要混合第 6 章中讨论的离线评估和本节中讨论的在线评估。要了解为什么离线评估还不够,让我们回顾一下离线评估的两种主要测试类型:测试拆分和回测。

您可能会考虑的第一种模型评估类型是可以用来离线评估模型的旧测试拆分,如第 6 章所述。这些测试拆分通常是静态的,并且必须是静态的,以便您有一个值得信赖的基准来比较多个模型。如果两个模型在不同的测试集上进行测试,将很难比较它们的测试结果。

但是,如果您更新模型以适应新的数据分布,则仅在旧分布的测试拆分上评估此新模型是不够的。假设数据越新鲜,来自当前分布的可能性就越大,一个想法是在您可以访问的最新数据上测试您的模型。因此,在您根据前一天的数据更新模型后,您可能希望根据前一小时的数据测试此模型(假设最后一小时的数据未包含在用于更新您的数据的数据中)模型)。根据过去特定时间段的数据测试预测模型的方法称为回

问题是回测是否足以取代静态测试拆分。不完全的。如果您的数据管道出现问题并且上一小时的某些数据已损坏,仅根据这些最近的数据评估您的模型是不够的。

通过回溯测试,您仍然应该在已广泛研究并(大部分)信任作为健全性检查形式的静态测试集上评估您的模型。

由于数据分布发生变化,模型在过去一小时的数据上表现良好的事实并不意味着它将在未来继续在数据上表现良好。了解模型在生产中是否会表现良好的唯一方法是部署它。这种洞察力导致了一个看似可怕但必要的概念:生产中的测试。但是,生产中的测试并不一定很可怕。有一些技术可以帮助您(大部分)安全地评估生产中的模型。在本节中,我们将介绍以下技术:影子部署、A/B 测试、金丝雀分析、交错实验和老虎机。

影子部署

影子部署可能是部署模型或任何软件更新的最安全方法。影子部署的工作原理如下:

  1. 与现有模型并行部署候选模型。

  2. 对于每个传入请求,将其路由到两个模型以进行预测,但仅将现有模型的预测提供给用户。

  3. 记录新模型的预测以进行分析。

只有当您发现新模型的预测令人满意时,您才会用新模型替换现有模型。

因为在确保模型的预测令人满意之前,您不会向用户提供新模型的预测,所以这个新模型做一些时髦的事情的风险很低,至少不高于现有模型。然而,这种技术并不总是有利的,因为它很昂贵。它使您的系统必须生成的预测数量增加一倍,这通常意味着您的推理计算成本增加一倍。

A/B 测试

A/B 测试是一种比较对象的两个变体的方法,通常通过测试对这两个变体的响应,以及确定两种变体中的哪一种更有效。在我们的例子中,我们将现有模型作为一个变体,将候选模型(最近更新的模型)作为另一个变体。我们将使用 A/B 测试根据一些预定义的指标来确定哪个模型更好。

A/B 测试变得如此普遍,以至于截至 2017 年,微软和谷歌等公司每年都会进行超过 10,000 次 A/B 测试。27这是许多 ML 工程师对如何在生产中评估 ML 模型的第一反应。A/B 测试的工作原理如下:

  1. 将候选模型与现有模型一起部署。

  2. 一定比例的流量被路由到新模型进行预测;其余的被路由到现有模型进行预测。两种变体同时提供预测流量是很常见的。然而,在某些情况下,一个模型的预测可能会影响另一个模型的预测——例如,在拼车的动态定价中,一个模型的预测价格可能会影响可用司机和乘客的数量,进而影响另一个模型的预测。在这些情况下,您可能必须交替运行您的变体,例如,在一天提供模型 A,然后在第二天提供模型 B。

  3. 监控和分析来自两个模型的预测和用户反馈(如果有),以确定两个模型的性能差异是否具有统计显着性。

要以正确的方式进行 A/B 测试,需要正确地做很多事情。在本书中,我们将讨论两件重要的事情。首先,A/B 测试由一个随机实验组成:路由到每个模型的流量必须是真正随机的。否则,测试结果无效。例如,如果流量路由到两个模型的方式存在选择偏差,例如接触模型 A 的用户通常在他们的手机上,而接触模型 B 的用户通常在他们的桌面上,那么如果模型 A 有比模型 B 更准确,我们无法判断是因为 A 比 B 好还是“正在打电话”影响预测质量。

其次,您的 A/B 测试应该在足够数量的样本上运行,以获得对结果的足够信心。如何计算 A/B 测试所需的样本数量是一个简单的问题,答案却非常复杂,我建议读者参考 A/B 测试方面的书籍来了解更多信息。

这里的要点是,如果你的 A/B 测试结果显示一个模型比另一个模型更好,具有统计显着性,你可以确定哪个模型确实更好。为了测量统计显着性,A/B 测试使用统计假设测试,例如两样本测试。我们在第 8 章中看到了两个样本测试当我们使用它们来检测分布变化时。提醒一下,双样本检验是用于确定这两个总体之间的差异是否具有统计显着性的检验。在分布偏移用例中,如果统计差异表明两个总体来自不同的分布,这意味着原始分布发生了偏移。在 A/B 测试用例中,统计差异意味着我们已经收集到足够的证据表明一个变体比另一个变体更好。

统计意义虽然有用,但并非万无一失。假设我们运行一个双样本测试并得到模型 A 优于模型 B 的结果,p值为p = 0.05 或 5%,我们将统计显着性定义为p ≤ 0.5。这意味着如果我们多次运行相同的 A/B 测试实验,(100 – 5 =) 95% 的时间,我们会得到 A 优于 B 的结果,而另外 5% 的时间, B 比 A 好。所以即使结果在统计上显着,如果我们再次运行实验,我们可能会选择另一个模型。

即使您的 A/B 测试结果在统计上不显着,也不意味着此 A/B 测试失败。如果您使用大量样本运行 A/B 测试,并且两个测试模型之间的差异在统计上不显着,那么这两个模型之间可能没有太大差异,您可以使用其中任何一个。

对于有兴趣了解更多关于 A/B 测试和其他在 ML 中重要的统计概念的读者,我推荐 Ron Kohav 的书Trustworthy Online Controlled Experiments (A Practical Guide to A/B Testing)(剑桥大学出版社)和 Michael Barber 的统计学入门对于数据科学(短得多)。

通常,在生产中,您不会只有一个候选但有多个候选模型。可以使用两个以上的变体进行 A/B 测试,这意味着我们可以进行 A/B/C 测试甚至 A/B/C/D 测试。

Canary Release(金丝雀发布)

Canary Release是一种减少通过在将更改推广到整个基础架构并使其可供所有人使用之前,将更改缓慢推广到一小部分用户,从而在生产中引入新软件版本的风险。28在 ML 部署的上下文中,金丝雀发布的工作方式如下:

  1. 将候选模型与现有模型一起部署。候选模型称为金丝雀。

  2. 一部分流量被路由到候选模型。

  3. 如果其性能令人满意,则增加候选模型的流量。如果不是,则中止金丝雀并将所有流量路由回现有模型。

  4. 当金丝雀服务于所有流量(候选模型已替换现有模型)或金丝雀中止时停止。

根据您关心的指标,根据现有模型的性能衡量候选模型的性能。如果候选模型的关键指标显着下降,金丝雀将被中止,所有流量将被路由到现有模型。

由于其设置的相似性,Canary 版本可用于实施 A/B 测试。但是,您可以在没有 A/B 测试的情况下进行金丝雀分析。例如,您不必随机分配流量以路由到每个模型。一个合理的情况是,您首先将候选模型推广到不太重要的市场,然后再推广到所有人。

对于对金丝雀发布在行业中的运作方式感兴趣的读者,Netflix 和谷歌有一篇很棒的共享博客文章,介绍了他们公司如何使用自动化金丝雀分析。

交错实验

假设您有两个推荐系统,A 和 B,并且您想评估哪个更好。每次,模型都会推荐 10 个用户可能喜欢的商品。通过 A/B 测试,您可以将用户分为两组:一组暴露给 A,另一组暴露给 B。每个用户都将看到一个模型提出的建议。

如果我们不让用户看到来自模型的推荐,而是让用户看到来自两个模型的推荐,然后看看他们会点击哪个模型的推荐,那会怎样?这就是交错实验背后的想法,最初是由 Thorsten Joachims 在 2002 年针对搜索排名问题提出的。29在实验中,Netflix 发现交错“与传统的 A/B 测试相比,能够可靠地识别出样本量小得多的最佳算法”。30

图 9-6显示了交错与 A/B 测试的不同之处。在 A/B 测试中,保留和流式传输等核心指标在两组之间进行测量和比较。在交织中,可以通过测量用户偏好来比较两种算法。因为交错可以由用户偏好决定,所以不能保证用户偏好会带来更好的核心指标。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-6。交错与 A/B 测试的图示。资料来源:改编自 Parks 等人的图片。

当我们向用户展示来自多个模型的推荐时,重要的是要注意推荐的位置会影响用户点击它的可能性。例如,与底部推荐相比,用户更有可能点击顶部推荐。为了交错产生有效的结果,我们必须确保在任何给定位置,推荐由 A 或 B 生成的可能性相同。为了确保这一点,我们可以使用的一种方法是团队草案交错,它模仿起草过程运动的。对于每个推荐位置,我们以相等的概率随机选择 A 或 B,并且选择的模型选择没有推荐的最佳推荐已经被选中了。31这种团队起草方法如何工作的可视化如图 9-7所示。

【Designing ML Systems】第 9 章 :生产中的持续学习和测试-LMLPHP

图 9-7。使用团队草稿将来自两种排名算法的视频推荐交错。资料来源:Parks 等人。32

Bandits(土匪)

对于那些不熟悉的人来说,强盗算法起源于赌博。一个赌场有多台老虎机支出。老虎机也被称为单臂强盗,因此得名。您不知道哪台老虎机的派彩最高。您可以随着时间的推移进行试验,以找出哪种老虎机是最好的,同时最大限度地提高您的支出。多臂老虎机算法允许您在利用(选择过去支付最多的老虎机)和探索(选择可能获得更多回报的其他老虎机)之间取得平衡。

到今天为止,标准方法在生产中测试模型是 A/B 测试。通过 A/B 测试,您可以将流量随机路由到每个模型以进行预测,并在试验结束时测量哪个模型效果更好。A/B 测试是无状态的:您可以将流量路由到每个模型,而无需了解它们当前的性能。即使使用批量预测,您也可以进行 A/B 测试。

当您有多个模型要评估时,每个模型都可以被视为您不知道其支出(即预测准确性)的老虎机。Bandits 允许您确定如何将流量路由到每个模型进行预测,以确定最佳模型,同时最大限度地提高用户的预测准确性。Bandit 是有状态的:在将请求路由到模型之前,您需要计算所有模型的当前性能。这需要三件事:

  • 您的模型必须能够进行在线预测。

  • 最好是短反馈循环:您需要获得有关预测是否良好的反馈。这通常是真的对于可以根据用户反馈确定标签的任务,例如在推荐中——如果用户点击推荐,则推断它是好的。如果反馈循环很短,您可以快速更新每个模型的收益。

  • 一种收集反馈、计算和跟踪每个模型的性能并根据其当前性能将预测请求路由到不同模型的机制。

Bandits 在学术界得到了充分的研究,并且已被证明比 A/B 测试更高效(在许多情况下,bandits 甚至是最佳的)。Bandits 需要更少的数据来确定哪个模型是最好的,同时,他们可以更快地将流量路由到更好的模型,从而降低机会成本。请参阅LinkedIn、Netflix、Facebook 和 DropboxZillowStitch Fix上关于强盗的讨论。有关更理论的观点,请参阅强化学习的第 2 章(Sutton 和 Barto 2020)。

在 Google 的 Greg Rafferty 进行的一项实验中,A/B 测试需要超过 630,000 个样本才能获得 95% 的置信区间,而简单的强盗算法(Thompson Sampling)确定一个模型在少于 12,000 个样本的情况下比另一个模型好 5% . 33

然而,bandits 比 A/B 测试更难实现,因为它需要计算和跟踪模型的收益。因此,除了少数大型科技公司外,强盗算法并未在该行业广泛使用。

强盗算法

多臂老虎机问题的许多解决方案都可以在这里使用。最简单的探索算法是ε -greedy。对于一定百分比的时间,比如 90% 的时间或ε = 0.9,您将流量路由到当前性能最佳的模型,而在另外 10% 的时间,您将流量路由到随机模型。这意味着对于您的系统生成的每个预测,其中 90% 来自最佳时间点模型。

两种最流行的探索算法是 Thompson Sampling 和 Upper Confidence Bound (UCB)。Thompson Sampling 选择一个模型,在给定当前知识的情况下,该模型是最优的。34在我们的例子中,这意味着算法根据其比所有其他模型具有更高值(更好的性能)的概率来选择模型。另一方面,UCB 选择置信上限最高的项目。35我们说UCB在不确定性面前实行乐观主义,它对不确定的项目给予“不确定性红利”,也称为“探索红利”。

上下文强盗作为一种探索策略

如果用于模型评估的老虎机要确定每个模型的支出(即预测精度),上下文匪徒将确定每个动作的支出。在推荐/广告的情况下,操作是向用户展示的项目/广告,支出是用户点击它的可能性。与其他老虎机一样,上下文老虎机是一种提高模型数据效率的惊人技术。

想象一下,您正在构建一个包含 1,000 个要推荐的项目的推荐系统,这使其成为 1,000 臂老虎机问题。每次,您只能向用户推荐前 10 个最相关的项目。用老虎机的术语来说,你必须选择最好的 10 个武器。显示的项目获得用户反馈,通过用户是否点击它们来推断。但是您不会收到有关其他 990 项的反馈。这称为部分反馈问题,也称为强盗反馈。您还可以将上下文老虎机视为带有老虎机反馈的分类问题。

假设每次用户点击一个项目,该项目获得 1 个价值点。当一个项目的价值点为 0 时,可能是因为该项目从未向用户显示过,也可能是因为它已显示但未点击。您想向用户展示对他们来说价值最高的商品,但如果您一直只向用户展示价值最高的商品,您将继续推荐相同的热门商品,而从未展示过的商品将继续有0个价值点。

上下文强盗是一种算法,可帮助您在向用户显示他们喜欢的项目和显示您想要反馈的项目之间取得平衡。36这与许多读者在强化学习中可能遇到的探索-利用权衡相同。上下文强盗也称为“一次性”强化学习问题。37在强化学习中,您可能需要采取一系列行动才能看到回报。在上下文强盗中,您可以在操作后立即获得强盗反馈 - 例如,在推荐广告之后,您会获得有关用户是否点击了该推荐的反馈。

上下文老虎机经过充分研究,并已被证明可以显着提高模型的性能(参见TwitterGoogle的报告)。然而,上下文老虎机比模型老虎机更难实现,因为探索策略取决于 ML 模型的架构(例如,它是决策树还是神经网络),这使得它在用例中的泛化性降低。有兴趣将上下文强盗与深度学习相结合的读者应该查看 Twitter 团队撰写的一篇精彩论文:“Deep Bayesian Bandits: Exploring in Online Personalized Recommendations”(Guo 等人,2020 年)。

在结束本节之前,我想强调一点。我们已经对 ML 模型进行了多种类型的测试。但是,重要的是要注意,一个好的评估管道不仅关乎要运行什么测试,还关乎谁应该运行这些测试。在 ML 中,评估过程通常由数据科学家负责——开发模型的人负责评估它。数据科学家倾向于使用他们喜欢的测试集来评估他们的新模型。首先,这个过程充满了偏见——数据科学家对他们的模型有大多数用户没有的上下文,这意味着他们可能不会像大多数用户那样使用这个模型。其次,过程的特殊性意味着结果可能是可变的。

缺乏确保模型在生产中的质量的方法导致许多模型在部署后失败,这反过来又加剧了数据科学家在部署模型时的焦虑。为了缓解这个问题,每个团队都必须概述关于如何评估模型的清晰管道:例如,要运行的测试、它们应该运行的顺序、它们必须通过的阈值才能提升到下一阶段. 更好的是,只要有新模型更新,这些管道就应该自动化并启动。应该报告和审查结果,类似于传统软件工程的持续集成/持续部署 (CI/CD) 过程。了解良好的评估过程至关重要不仅涉及要运行什么测试,还包括谁应该运行这些测试。

概括

本章涉及一个我认为最令人兴奋但尚未充分探索的主题:如何在生产中不断更新模型以使其适应不断变化的数据分布。我们讨论了公司在对其基础设施进行现代化改造以进行持续学习的过程中可能经历的四个阶段:从手动、从头开始的培训阶段到自动化、无状态的持续学习。

然后,我们研究了困扰各种公司的 ML 工程师的问题:“我应该多久更新一次模型?” 通过敦促他们考虑数据新鲜度对其模型的价值以及模型迭代和数据迭代之间的权衡。

与第 7 章讨论的在线预测类似,持续学习需要成熟的流式基础设施。持续学习的训练部分可以批量进行,但在线评估部分需要流式处理。许多工程师担心流媒体既困难又昂贵。三年前确实如此,但从那时起,流媒体技术已经显着成熟。越来越多的公司正在提供解决方案以使公司更容易迁移到流媒体,包括 Spark Streaming、Snowflake Streaming、Materialize、Decodable、Vectorize 等。

持续学习是 ML 特有的问题,但它在很大程度上需要基础设施解决方案。为了能够加快迭代周期并快速检测新模型更新中的故障,我们需要以正确的方式设置我们的基础设施。这需要数据科学/ML 团队和平台团队一起工作。我们将在下一章讨论机器学习的基础设施。

11-15 09:09