meta QuickUpdate介绍

Reading time ~4 minutes

meta Ins在《QuickUpdate: a Real-Time Personalization System for Large-Scale Recommendation Models》给出了它们的系统实现:

摘要

深度学习推荐模型在在线公司中扮演着重要角色,并且占据了用于训练和推理的AI基础设施的主要部分。这些模型的准确性高度依赖于它们在服务端的发布速度。提高模型更新延迟和频率的主要挑战之一是模型的大小,这些模型的大小已经达到了TB级别,并且预计未来还会进一步增加。大模型大小导致了在分布式服务器中更新模型时的高延迟(和写入带宽)。我们提出了QuickUpdate,一个用于大规模推荐模型实时个性化的系统,它能够作为在线训练的一部分高频发布模型,提供与完全新鲜模型相当的服务准确性。该系统采用了新技术来最小化所需的写入带宽,包括:优先参数更新、间歇性全模型更新、模型转换和宽松一致性。我们使用真实世界的数据在Meta的一个最大生产模型上评估了QuickUpdate。结果表明,QuickUpdate提供了与完全新鲜模型相当的服务准确性,同时将平均发布的更新大小和所需带宽减少了超过13倍。它为实时服务生产模型提供了一个可扩展的解决方案,这在网络和存储带宽有限的情况下,否则是不可能大规模实现的。

1 引言

深度学习推荐模型(DLRM)在许多在线公司中被广泛使用。这些模型通过大规模数据进行训练,以学习用户和产品特征,从而在各种场景中提供个性化推荐。例如,Netflix [7] 和 YouTube [4] 为用户提供电影列表;Amazon [19] 和 Alibaba [20] 根据用户的搜索查询推荐相关产品;Google [3] 和 Meta [23] 则根据用户兴趣展示广告和内容。DLRM 在这些公司中占据了 AI 基础设施的主要部分。以 Meta 为例,DLRM 消耗了超过 80% 的机器学习推理周期 [8] 和超过 50% 的训练周期。

推荐模型有助于业务增长。例如,它们贡献了 Amazon 总购买量的 35% [8, 14]。由于这种广泛的业务影响,准确性成为大规模推荐模型的重要性能指标。特别是在 Meta 的业务中,设计检查点(checkpoint)和量化算法时要求准确性损失小于 0.01%[5]。这是一个非常狭窄的容差范围,表明了推荐模型及其准确性的重要性。

模型新鲜度 是个性化推荐模型准确性的关键因素 [4, 6, 9, 22, 25]。由于模型在高度动态的环境中运行推理,准确性可能会迅速下降。例如,每天都有新用户和物品注册到系统中,用户的兴趣可能会受到近期事件的影响。如果模型没有频繁更新,它将无法反映用户和产品的变化,从而导致准确性逐渐下降。为了进一步强调新鲜度的影响,图 3 展示了模型在数小时未刷新时的显著准确性损失。因此,为了将准确性保持在可接受的水平,推荐模型需要使用最新数据进行重新训练,并使用更新后的模型来服务实时推理。

图 3

保持推理模型新鲜的一种常见技术是在线训练。与每次从头开始重新训练模型不同,它使用实时流数据不断训练和优化模型。定期创建模型的快照并将其发布到位于不同地理区域的数百台服务器中。这些服务器随后利用该模型对在线查询进行实时预测。然而,更新服务模型会带来训练集群与分布式服务主机之间的延迟,导致模型刷新延迟,这主要是由于现代模型的规模庞大。

多年来,模型规模迅速增长,达到了 TB 级别,并包含数万亿个参数 [5, 10, 15],以捕获数百万个稀疏特征并提高模型准确性。有限的写入带宽在将如此大的模型传输到分布式服务器和存储时构成了挑战。因此,更新延迟可能会延长到数小时。如第 3 节详细讨论的那样,这种长时间的延迟可能会对准确性产生不利影响。

为了解决上述由大模型规模及其导致的更新延迟带来的挑战,我们提出了 QuickUpdate。QuickUpdate 采用以下设计元素来实现大规模 DLRM 的实时个性化:

  1. 优先参数更新:在数百个地理分布的节点中完全更新所有服务模型的参数需要大量的网络和存储带宽,这构成了瓶颈。
    QuickUpdate 通过优先参数选择来最小化更新规模。它对服务模型中的特定参数进行排序和选择,同时从更新中修剪其余参数。这种方法显著减少了总体更新规模并缓解了带宽需求。
    参数排序算法在最小化更新规模时避免准确性下降至关重要。

  2. 间歇性全模型更新:间歇性全模型更新是指在一系列连续的部分更新之后进行一次完整的模型更新。这些完整更新的主要目的是保持服务模型的长期准确性。每次部分更新后,服务模型会偏离训练模型,因为前者仍然使用过时的参数值。随着更多部分更新的进行,这种偏差会变得更大,从而导致潜在的准确性影响。为了提高准确性,间歇性地发布完整模型更新以限制服务模型与训练模型之间的差距。

  3. 实时更新的模型转换:QuickUpdate 采用了几种模型转换技术来减少发布的模型规模,包括推理剪枝和量化。
    量化已在一些研究中成功实施 [11, 24, 27],以在不牺牲准确性的情况下降低浮点精度。它有助于减少推理集群中的存储需求和通信成本。推理剪枝则应用于非常大的查找表。在 DLRM 中,实体(如用户或视频)及其对应的向量以查找嵌入表的形式存储。实际不活动的实体索引(或 ID)从服务平台中修剪,以显著减少服务模型的规模。

  4. 简化的服务设计和宽松的一致性要求:在传统的服务设计中,模型在开始服务查询之前会完全加载到服务平台中,以保持强一致性。在这种设计中,每个推理请求都基于特定版本的模型权重执行,确保一致且可靠的结果。然而,这种方法由于使用额外的缓冲节点而带来了相当大的基础设施开销。
    在 QuickUpdate 中,我们通过放宽一致性要求引入了一种更高效的服务设计。权重直接在服务节点中更新,而不是使用缓冲节点。这消除了对额外基础设施的需求并减少了开销。然而,这种宽松的设计可能会导致嵌入表中的一些不一致性,因为它们可能包含新鲜和过时权重的混合。
    尽管嵌入表中可能存在不一致性,但我们的评估表明,服务模型的准确性并未受到影响,反而带来了准确性的提升。

我们使用真实世界的数据和 Meta 生产中部署的最大模型之一对 QuickUpdate 进行了评估。总体而言,我们的结果表明,QuickUpdate 能够提供与完全新鲜模型相当的服务准确性,同时将所需的写入带宽减少了超过 13 倍。它为实时服务生产 DLRM 提供了一个可扩展的解决方案,而这在网络和存储带宽有限的情况下是无法大规模实现的。QuickUpdate 通过利用新颖的技术实现了这一点,包括选择性发布每次更新的最重要部分,同时仍然结合低频的间歇性全模型更新以确保长期准确性。

2 背景

2.1 深度学习推荐模型(DLRM)

通常,深度学习推荐模型由稀疏层和稠密层组成,如图 1 所示 [5, 10, 26]。稀疏层实际上是嵌入表,其中每个嵌入表表示一个分类特征,表的每一行表示一个特定的 ID(例如用户 ID 或视频 ID)。嵌入表将每个 ID 转换为一个固定大小的浮点值向量,这些向量是可训练的。模型中其余可训练的部分称为稠密层。

图片名称

图 1

图 1 展示了数据在 DLRM 中的流动方式。稀疏特征通过嵌入表进行转换;稠密特征通过底部的稠密层进行转换。转换后的特征随后被连接起来,并在顶部的稠密层中进一步转换,以计算输入数据的可能性。

2.1.1 训练 DLRM

并行化是规模化训练推荐模型的主要方法 [5, 8]。稀疏层和稠密层可以采用不同的并行化逻辑。稀疏层占整个模型大小的 99% 以上,可能达到数 TB 的规模。由于将所有稀疏层存储在单个节点中是不可行的,因此采用模型并行化的方法将表分片到多个节点上。另一方面,稠密层的规模足够小,可以容纳在每个节点中,因此它们被复制到各个节点上以利用数据并行化。

在 Meta,一个典型的训练集群包括 16 个节点,每个节点包含一个多插槽 CPU 和 8 个 GPU。稀疏层在所有 GPU 上分片,在正向和反向计算期间进行“all-to-all”通信。稠密层在所有 GPU 上复制,在反向传播期间使用“all-reduce”通信来聚合多个 GPU 中计算的梯度 [16]。在训练期间,稀疏层和稠密层的新权重被同步计算和更新,以避免准确性下降。

2.1.2 服务 DLRM

为了以高吞吐量的方式高效地服务批量请求,通常使用 GPU 进行模型服务。在 Meta,服务节点位于专用的服务集群中。一个服务节点由主机 CPU 和附加的 GPU 组成。服务模型在服务节点之间复制,并使用数据并行化进行规模化模型服务。广告嵌入表存储在单个 GPU 中,因为它们需要更高的读取吞吐量。其他嵌入表存储在 CPU 中,CPU 通常具有更大的内存容量(例如 1.5 TB DRAM)。为了存储嵌入表,使用紧凑的数据结构来最小化大小并以 GPU 友好的方式存储。特别是,嵌入表是连续存储的,每个嵌入表以行优先顺序存储在数组数据结构中。

为了刷新服务模型,使用额外的缓冲节点来避免暂停当前的服务节点。在新发布的模型加载到缓冲节点后,请求流量会切换到缓冲节点。

2.2 在线训练与离线训练

当服务模型需要使用实时数据流不断训练和更新时,会实施在线训练。在在线训练中,服务模型在提供预测的同时,会定期(以分钟到小时为单位)更新。训练在后台(通常在单独的集群中)继续运行以微调模型。训练模型发布到服务平台的速率对其生成的预测准确性有显著影响。

相比之下,离线训练不使用实时数据流进行训练,也没有严格的时间限制来训练模型并将其发布到服务平台。相反,它通常使用已经存储在数据存储中的大量数据。模型使用所有可用数据进行训练,当满足某些最优条件时训练停止,之后将其发布到服务平台。

选择在线训练还是离线训练取决于具体的使用场景。当模型需要及时更新时,会实施在线训练系统。典型的用例可能是广告、搜索和视频的 DLRM(例如 [13, 18, 21]),当环境高度动态且需要模型几乎实时更新(以分钟为单位)时。在线训练帮助这些模型整合最新数据并避免准确性下降。当业务需求不需要实时模型更新时,可以使用离线训练方法来更新模型。

2.3 优化器状态作为特征重要性度量

通常,大型 DLRM 可以使用数十万个特征进行训练;然而,其中一些特征及其对应的权重对准确性没有影响。这些特征可能属于不活跃的用户或内容 ID,或者某些其他特征可能无法提供训练信号。在模型发布时,维护所有这些参数会消耗额外的带宽,或者在服务平台中运行推理时会消耗额外的计算和 GPU 存储。

为了减轻这些不利影响,我们可以计算特征重要性,并相应地修剪那些实际上不影响准确性的特征和权重。

QuickUpdate 使用优化器状态(或梯度动量)来计算特征重要性。它属于基于梯度的特征重要性度量家族(例如 [2, 12, 18])。优化器状态是梯度值的历史平均值,比梯度值更稳定,因为梯度值有时会在正值和负值之间振荡。优化器状态可以为我们提供以下指示:

  1. 对准确性的影响:它实际上显示了在训练过程中某个特定参数被更新的频率和幅度。较高的梯度值表明对提高准确性有较大影响;如果这种影响在历史上持续存在,我们可以更有信心地推断该参数对准确性很重要;因此,优化器状态是特征对准确性影响的稳定指示。

  2. 访问率:优化器状态为零(或接近零)表明该参数在训练过程中实际上没有被更新。这有两层含义。首先,这可能意味着该参数没有被访问过。这可能发生在一些不活跃的用户 ID 或过时的视频上。其次,如果实体是活跃的,接近零的值可能意味着从相关数据中可能没有重要的信号可以学习。例如,某个特定用户 ID 可能没有使用平台点击广告。

基于上述信息,QuickUpdate 使用优化器状态来完成两项不同的任务:

  1. 推理剪枝:当发布完整模型时,QuickUpdate 使用优化器状态来减少完整模型更新的规模。在此阶段,QuickUpdate 关注优化器状态值的低尾部分,并修剪那些对准确性没有影响的参数。

  2. 优先参数选择:当发布部分更新时,QuickUpdate 使用优化器状态来选择更重要的参数进行更新。在此阶段,QuickUpdate 关注优化器状态值的高尾部分,以更新更重要的参数。

2.4 推理剪枝

推理剪枝是为了在将完整模型快照发布到服务平台时减少模型的大小。剪枝特别针对查找嵌入表实施,并显著减少其大小(例如减少 50%)。由于查找表占 DLRM 大小的 99% 以上,剪枝可以在不影响准确性的情况下显著减少模型的大小。减少模型大小有助于消耗更少的带宽来发布模型更新;因此,更新可以以更短的延迟发布到数百个地理分布的集群中。此外,它还有助于更快地执行推理,因为计算中涉及的行数更少。

图片名称

图 2

图 2 展示了一个查找表的示例,其中包含索引和对应的行。每个索引代表分配给用户、视频等的唯一 ID。每一行可以被视为一个由可训练的浮点值组成的向量,模型使用这些向量为用户生成个性化推荐。

直观上,推理剪枝算法识别出代表不活跃实体或无法提供训练信号以提高准确性的行。从数学上讲,这是通过使用优化器状态向量来实现的。具体来说,训练器可以为每一行提供一个优化器状态向量。优化器状态向量中的每个元素表示该行中对应元素的梯度动量。优化器状态向量中元素的平均值用于量化行的重要性值。如果行的重要性值接近零,则意味着该行的元素在训练过程中实际上没有被更新;因此,该行可以被剪枝。

图 2 还展示了剪枝前后查找表的变化。使用行重要性值,推理剪枝算法确定最不重要的索引,并在将完整更新发布到服务器之前将其剪枝。出于操作目的,原始索引值会被重新映射到新的索引。新索引会简单地按照它们在原始表中的出现顺序递增。

需要注意的是,在本文中,完整模型更新指的是执行推理剪枝后的模型快照。

3 动机

在本节中,我们通过真实世界的数据来展示开发 QuickUpdate 的动机。首先,我们展示了当模型一小时或更长时间未更新时,准确性如何显著下降。接着,我们讨论了模型规模扩大带来的影响。如果不修改模型发布方法,我们只能选择接受更长的更新延迟和逐渐下降的准确性,或者大量投资基础设施以保持更新延迟的一致性。最后,我们强调了无损模型更新的局限性,强调了优先更新的必要性。

准确性增益

更新完整的服务模型是一个耗时的过程,可能需要数小时。因此,用户的最新行为和兴趣(例如发布新动态或与特定内容互动)在几小时内不会反映在服务模型中,这可能会降低模型的准确性。

图片名称

图 3 展示了在 Meta 的一个大规模模型中,随着模型更新延迟(1 到 7 小时),准确性如何下降。它将陈旧服务模型的准确性损失与完全新鲜模型进行了比较。结果显示,当模型更新延迟时,准确性损失显著增加,7 小时后损失超过 0.6%。

减少更新规模有助于加速模型更新并提高服务模型的准确性。

模型规模

近年来,DLRM 的规模显著增加。这些模型利用大量数据和参数来更好地理解用户兴趣和产品特征,从而提高准确性。这一进展催生了具有数万亿参数 [15] 和数 TB 模型大小 [5] 的复杂模型。此外,这一趋势预计在未来仍将持续。

随着模型规模的增加,由于传输所需的带宽增加,模型更新延迟也随之延长。如果不加以解决,预计这将导致未来模型新鲜度的下降。鉴于模型规模的持续扩大,单纯增加基础设施并不是一个可行的长期解决方案。因此,对大规模 DLRM 进行部分更新似乎是一个有前景的策略,旨在减少更新延迟,而无需增加更多基础设施。

无损模型更新

为了更好地理解模型随时间变化的比例,我们监控了更新的嵌入行,并据此计算了模型中被修改的平均比例。图 4 显示了模型随时间更新的百分比。很明显,模型的大部分在短时间内被更新。例如,在短短 10 分钟的时间间隔内,58% 的模型被更新。更新 58% 的模型是资源密集型的,需要比每小时更新完整模型更多的基础设施。这促使我们探索一种优先更新的方法,以显著减少更新规模。

图片名称

图 4

4 系统概述

图 5 提供了 QuickUpdate 架构的概览。DLRM 系统由训练节点、服务节点和用于保存模型快照的远程存储组成。QuickUpdate 的发布逻辑主要在 UpdateSelectorUpdatePatcher 代理中实现,这两个代理分别部署在训练节点和服务节点中。UpdateSelector 负责决定模型的哪一部分应该更新,并在保存到远程存储之前对其进行量化。UpdatePatcher 根据执行的更新类型实现不同的修补策略。以下部分提供了更多详细信息。

图片名称

图 5

4.1 更新什么

QuickUpdate 专注于对嵌入表执行部分更新,这些表通常占深度学习推荐模型的绝大部分(在我们的工作负载中超过 99%)。在这些模型中,每个表表示一个分类特征(例如用户、视频),表中的每一行对应于与该特征相关的特定 ID。

在我们的探索中,我们考虑了两种更新嵌入表的选项:

  1. 更新选定表的所有行。
  2. 更新所有表中的选定行(不同表的选定行索引可能不同)。

我们发现,以行级粒度进行更新可以在最小化整体更新规模的同时提高准确性。因此,QuickUpdate 决定服务端需要更新表中的哪些特定行。这种方法使 QuickUpdate 能够优先更新更有可能提高准确性的内容或用户 ID,从而确保更新策略的高效性和有效性。对于模型中的稠密层,QuickUpdate 执行完整更新。这是因为这些层的更新规模相对较小,针对这些层的任何优化对整体更新过程的影响不大。

4.2 UpdateSelector

QuickUpdate 的 UpdateSelector 组件在训练集群中实现。这是因为它需要从训练器中获取某些模型信息(例如参数值)以准备模型更新。

在在线训练期间,训练器以批次间隔运行。在每个训练间隔结束时,训练器将模型状态和优化器状态共享给 UpdateSelector。模型状态包括分片的嵌入表和稠密参数值,而优化器状态包括梯度值及其动量。这些状态从 GPU 内存复制到主机 CPU 内存中。

UpdateSelector 使用优化器状态对 CPU 中的模型副本执行以下两项任务:

  1. 优先参数选择:此任务的主要目标是仅更新模型参数的一小部分,同时最小化准确性的下降(与完整更新相比)。在此阶段,QuickUpdate 根据优化器状态值选择嵌入行,优先选择那些可能对准确性提升较大的行。
  2. 推理剪枝:此任务在发布完整模型时执行。推理剪枝专注于稀疏嵌入表,旨在减少完整模型更新的规模。在此阶段,QuickUpdate 识别低尾优化器状态值,并剪枝值接近零的嵌入行。这些行对模型准确性的影响可以忽略不计。

一旦更新(无论是完整还是部分)准备就绪,它们会经过量化以减少其大小。量化作为一种压缩方法,对模型准确性的影响可以忽略不计。量化后的更新随后存储在远程存储中,准备用于更新过程。

4.3 UpdatePatcher

UpdatePatcher 负责加载发布的快照并更新服务模型。它对部分和完整模型更新都采用了一种高效的非原子更新方法。在非原子更新过程中,多个线程可以访问模型参数,并逐步将参数修补到服务器中。这种方法允许多个线程并发修补参数,而无需锁定服务器或模型。因此,服务器可以在应用更新的同时继续对传入流量进行推理。这种方法确保了在更新过程中实时流量的高效且不间断的服务。

4.4 工作流程

图 6 展示了 QuickUpdate 的工作流程。为简化说明,我们仅展示了训练器、UpdateSelector 和一个服务节点中的时间尺度。模型的演化是一个可重复的模式,因此我们专注于一个周期,该周期进一步分为多个间隔。在周期 ( c ) 的每个间隔 ( i ) 开始时,UpdateSelector 可以访问完整模型 ( F_{c,i} ) 以确定模型的哪一部分应该更新。具体来说,首先会发布一个完整快照(即 ( F_{c,1} ))并加载到服务器中,然后连续的部分更新(( P_{c,i} ) 其中 ( i > 1 ))会被发布并修补到完整快照中,以创建服务快照 ( S_{c,i} )。

图片名称

图 6

将更多部分更新与服务模型合并可能会导致服务模型 ( S_{c,i} ) 与当前训练器状态 ( F_{c,i} ) 之间的偏差增大。这种偏差可能会导致准确性下降。因此,另一个完整的新鲜快照(即 ( F_{c+1,1} ))将被发布到服务集群,标志着当前周期的结束。服务端的模型演化可以表示如下:

[ S_{c,1} = F_{c,1} ] [ S_{c,i} = M(S_{c,i-1}, P_{c,i}) \quad \text{对于} \quad 1 < i \leq I ]

其中,( I ) 是一个周期中的间隔数,( M ) 是合并操作符。合并操作符简单地复制 ( P_{c,i} ) 的参数值并将其更新到 ( S_{c,i-1} ) 中。

5 设计

在本节中,我们讨论了设计选项及其对准确性指标的影响。我们首先定义了指导设计和评估的具体准确性指标。通过在整个设计过程中优先考虑准确性,我们的目标是创建一个有效的系统,在解决网络和存储带宽瓶颈的同时,提供高服务准确性。需要注意的是,QuickUpdate 是可配置的,并在生产环境中进行监控,以应对罕见的准确性下降情况。

5.1 准确性指标

二元交叉熵(Binary Cross Entropy)或熵(Entropy)[17] 是评估广告模型准确性的一个众所周知的综合指标。在本研究中,我们使用归一化熵(Normalized Entropy, NE),其定义为二元交叉熵除以一个常数。为了理解部分更新相对于完全新鲜快照和过时模型的表现,我们计算了 NE 的以下变体。为简化说明,我们从符号中省略了周期下标 ( c )。

  1. NE 损失:它表示使用模型 ( S_i ) 而不是相应的完全新鲜模型 ( F_i ) 运行推理时的准确性下降。 [ \text{NE}{\text{loss}}(S_i) = \frac{\text{NE}{S_i} - \text{NE}{F_i}}{\text{NE}{F_i}} \times 100 \quad (1) ] 其中,( \text{NE}{S_i} ) 和 ( \text{NE}{F_i} ) 分别表示模型 ( S_i ) 和 ( F_i ) 的归一化熵。

  2. NE 增益:它表示如果使用 ( S_i ) 进行推理而不是过时模型,可以预期的准确性提升: [ \text{NE}{\text{gain}}(S_i) = \frac{\text{NE}{S_i} - \text{NE}{\text{stale}}}{\text{NE}{\text{stale}}} \times 100 \quad (2) ] 过时模型被认为是最近发布的完整模型 ( F_1 )。

  3. NE 恢复:它表示模型 ( S_i ) 已达到的最大 NE 增益的百分比。我们假设如果可以使用完全训练的模型 ( F_i ) 进行推理,则可以实现最大 NE 增益。因此,NE 恢复定义为: [ \text{NE}{\text{recovery}}(S_i) = \frac{\text{NE}{\text{gain}}(S_i)}{\text{NE}_{\text{gain}}(F_i)} \times 100 \quad (3) ]

5.2 选择标准

为了优先更新能够带来更大准确性增益的行,我们需要一个在训练过程中保持稳定的可靠指标。虽然梯度向量可以作为标准,但其在正值和负值之间的振荡引入了数值不稳定性。相反,我们可以使用优化器状态向量(也称为动量),它提供了更稳定的度量。优化器状态向量表示特定行的历史梯度的平均平方和。通过将 ( \text{OS}^r_{c,i} ) 表示为模型在间隔 ( i ) 时行 ( r ) 的优化器状态向量,并将 ( \overline{\text{OS}^r_{c,i}} ) 表示为其元素的平均值,我们可以利用该度量作为行重要性的指示。

直观上,具有较大 ( \overline{\text{OS}^r_{c,i}} ) 值的行更有可能提高准确性。例如,这些行可能代表频繁使用平台点击广告的特定用户,或者代表具有高访问率的特定视频。除了给定间隔的 ( \overline{\text{OS}^r_{c,i}} ) 的大小外,跟踪其随时间的变化也可能很重要。这对于我们更倾向于优先选择相对于旧版本发生变化的参数的情况可能具有潜在的信息价值。基于这些直觉,我们评估以下选择标准:

  1. 绝对优化器状态: [ \text{abs}(\overline{\text{OS}^r_{c,i}}) \quad \text{对于} \quad i > 1 \quad (4) ]

  2. 增量优化器状态: [ \text{abs}(\overline{\text{OS}^r_{c,i}} - \overline{\text{OS}^r_{c,i-1}}) \quad \text{对于} \quad i > 1 \quad (5) ]

选择使用绝对优化器状态还是增量优化器状态作为选择标准取决于它们各自的优势和权衡。虽然绝对优化器状态提供了行对准确性影响的稳定和综合度量,但增量优化器状态捕捉了与前一个间隔相比影响的变化。然而,使用增量优化器状态需要额外的内存来存储前一个间隔的优化器状态。为了评估这些标准的影响,我们进行了实验,间隔长度为 30 分钟,更新规模为 10%。在发布完整快照并再训练一小时后,我们根据这两个标准发布了更新规模为 10% 的部分快照。然后,我们评估了与完全新鲜模型相比的服务准确性。表 1 中的结果(在多次此类实验中一致)表明,增量优化器状态实现了 100% 的 NE 恢复,而绝对优化器状态实现了 70% 的 NE 恢复。这意味着基于增量优化器状态选择行可以减少服务模型与相应完整快照之间的差异。

5.3 增量选择的基线

增量优化器状态是基于基线计算的。在计算增量优化器状态时,我们考虑了两种选择基线的方法:

  1. 上一次更新时的模型状态:此选项将上一次更新时的模型状态作为基线。这与上一节中增量优化器状态的定义相同。

  2. 上一次完整更新时的模型状态:如第 5.6 节所述,QuickUpdate 还利用间歇性完整更新。在此基线选项中,将上一次间歇性完整更新时的模型状态用作增量。在这种情况下,增量优化器状态定义为: [ \text{abs}(\overline{\text{OS}^r_{c,i}} - \overline{\text{OS}^r_{c,1}}) \quad \text{对于} \quad i > 1 \quad (6) ]

对于第一种选项,需要在每个训练间隔结束时保存基线,而对于第二种选项,只需在周期的第一个间隔中保存一个基线。因此,第一种选项提供了更新鲜的基线,但需要额外的计算资源将其保存在内存中。

我们通过实验检查了不同基线对服务准确性的影响,每个间歇性完整更新后跟随四个部分更新。我们评估了与完全新鲜模型相比的服务准确性(NE 恢复)。表 2 中的结果显示,使用上一次间隔的基线可以实现 3.11%(95.94% 对比 99.05%)更高的 NE 恢复。这表明,使用上一次更新的模型状态作为基线可以更好地反映最近的用户兴趣,因为它在每个更新间隔中都会刷新。此外,使用完整更新作为基线可能会优先选择在前一个间隔中重要但不再对准确性有贡献的参数。随着时间的推移,这些参数的优化器状态可能达到平稳状态,但由于其较大的增量优化器状态值,完整更新基线可能仍然会考虑它们。更频繁地刷新基线有助于消除对此类参数的优先选择,转而优先选择最近变化的参数,这些参数更有可能对准确性提升有贡献。

5.4 实时推理剪枝

如第 2.4 节所述,推理剪枝有助于减少服务模型的大小和所需的 GPU 数量。它实际上会剪枝那些不再活跃或对准确性影响可以忽略的行(或 ID),以减少嵌入表的大小。然后,剪枝后的表以 GPU 访问友好的方式紧凑地存储,以进一步减少服务集群中的大小。

剪枝仅在完整模型发布到服务集群时实施。对于后续的间隔,我们希望部分更新能够与完整模型更新中的剪枝表兼容。理想情况下,部分更新中的行 ID 应存在于剪枝表中。这有助于我们简单地更新现有行的值,而无需重新构建 GPU 中的表。然而,情况并非总是如此。由于部分更新的训练数据与完整模型更新不同,可能会出现某些行 ID 在部分更新中变得重要,而这些 ID 在服务端的剪枝表中不存在的情况。当发生这种情况时,一种简单的实现方法是将缺失的行插入服务端的剪枝表中,但这可能是资源密集型的,并且可能需要重新调整所有 GPU 上的嵌入表以确保可访问性和效率(例如,避免内存碎片)。

为了避免嵌入表的密集重新调整,我们探索了两种与部分更新兼容的推理剪枝策略:

  1. 固定索引剪枝(见图 7a):在此策略中,QuickUpdate 执行优先参数选择以选择要更新的候选行索引。然而,仅更新嵌入表中已存在的行,而剪枝的行保持不变。

  2. 固定剪枝比例(见图 7b):在此策略中,每次完整更新时从嵌入表中剪枝固定比例的行。当 QuickUpdate 执行优先参数选择时,它最多选择 ( X ) 个索引进行更新,其中 ( X ) 是服务平台上给定表中的总行数。这确保了表中的行数保持一致。

图片名称

图 7

第一种策略避免了重新调整,因为只会进行行更新操作,而不会向嵌入表中插入新行。第二种策略通过使用行更新和索引重映射操作来避免重新调整。由于嵌入表的大小在第二种策略中不会改变,因此也避免了在 GPU 之间重新分片嵌入表的需要。

为了评估这两种剪枝策略,我们考虑了三种训练场景:1-无剪枝,2-固定剪枝索引,3-每个表固定剪枝比例。

我们的实验表明,剪枝导致的 NE 损失实际上可以忽略不计(<0.001%),且两种剪枝策略之间没有准确性差异。考虑到实现需求,我们选择了固定剪枝索引策略,因为其实现更简单。与固定剪枝比例策略不同,它不需要在每次新更新时更新索引映射。

6 评估

我们在 Meta 部署的最大推荐模型之一上评估了 QuickUpdate,使用真实世界的数据,并在类似于 [15] 的生产训练集群上进行训练。该模型是 [16] 中提出的 DLRM 模型的扩展,但其规模显著更大,达到 TB 级别。我们在所有实验中使用相同的预记录数据流,使实验可重复且可比较,并消除了由于时间数据变化导致的潜在结果偏差。模型最初使用几周的真实世界数据进行训练作为预热期,以达到稳定状态。对于准确性评估,我们评估了在训练数据之后的时间段内数据流的服务预测(即推理期间评估的数据未在之前的训练中使用)。

6.1 准确性

在本节中,我们比较了不同更新粒度对准确性的影响,并推导出最小完整快照频率,以确保 NE 损失不超过 0.01%。在这些实验中,我们在开始时发布一个完整快照,并继续发布具有不同粒度的部分更新。这些部分更新应用于完整服务快照之上,并使用相同的记录数据集进行准确性评估。

6.1.1 与过时模型相比的 NE 增益

我们首先比较 QuickUpdate 与过时模型的准确性,以量化准确性增益并验证在完整快照之上应用部分更新不会对准确性产生负面影响。这里的过时模型指的是最初发布的完整快照。图 8 显示了不同更新粒度(且无间歇性完整模型更新)相对于过时模型的 NE 增益。所有更新规模的 NE 增益均高于过时模型,并且 NE 增益随时间增加。5% 和 10% 的更新提供了非常相似的 NE 增益,但 1% 的更新返回的 NE 增益较少,表明一些重要的行未包含在 1% 的更新中。总体而言,这些趋势表明,即使在应用部分更新超过 10 小时后,也没有负面影响,并且与过时模型相比,准确性提高了 0.7%。

图片名称

图 8

6.1.2 与完全新鲜模型相比的 NE 损失

在本节中,我们研究了使用部分更新发布的 QuickUpdate 模型的 NE 损失,与理想的完全新鲜服务模式进行比较。图 9 中的结果显示,使用 10% 更新时,NE 损失在整个 10 小时内低于 0.005%。使用 5% 更新时,NE 损失始终高于 10% 更新,但在超过 6 小时内仍低于 0.01%。随着训练周期的增加,NE 损失增加,因为服务模型与相应训练模型之间的差异增加。结果还展示了采用不同更新粒度对完整模型发布延迟的影响,同时确保 NE 损失保持在可接受的 0.01% 阈值以下。通过采用 10% 的粒度,我们可以有效地将完整模型发布的需求延迟超过 10 小时。同样,当使用 5% 的粒度时,我们可以将完整模型发布延迟 6 小时,同时仍将 NE 损失保持在可接受范围内。这突显了 5% 粒度下部分更新在捕获重要更新并在相当长的时间内保持模型准确性和新鲜度方面的有效性。

图片名称

图 9

6.1.3 短期内的 NE 损失

为了分析短期内的 NE 损失,我们进行了一项评估,涉及四个连续的 10 分钟更新。检查的更新粒度为 5%、3% 和 1%。每次更新后,使用未见过的数据测量与完全新鲜模型相比的 NE 损失。图 10 显示了不同 10 分钟间隔内的变化,强调了流数据的波动性。然而,当在多个短时间间隔内平均时,NE 损失趋于稳定。正如预期的那样,结果显示,随着粒度的增加,NE 损失减少。最后一列显示的平均 NE 损失证实,5% 的粒度在我们的工作负载中会返回可接受的 NE 损失(平均而言)。

图片名称

图 10

6.1.4 结论

准确性结果证明了 QuickUpdate 在采用 5% 更新粒度长达 6 小时的有效性,同时保持与完全新鲜模型相当的准确性水平,并确保 NE 损失低于 0.01% 的阈值。

此外,使用 QuickUpdate 的 5% 更新粒度允许在需要发布完整模型之前延迟 6 小时。这种延迟之所以可能,是因为部分更新成功捕获并整合了重要变化,从而生成了准确且最新的模型。

基于这些发现,QuickUpdate 默认每 6 小时触发一次间歇性完整模型发布,从而优化了准确性与更新频率之间的平衡。

6.2 分析长期行收敛性

在之前的分析中,我们的重点是基于准确性指标最小化部分更新粒度,并确定间歇性完整更新的适当频率。结果表明,使用 5% 粒度的部分更新持续 6 小时可以达到令人满意的准确性。

在本实验中,我们的目标是探索部分更新更新了模型中多少百分比的重要行。

为了确定重要行的代理,我们训练模型 6 小时(即与满意准确性相同的持续时间)。我们将重要行定义为训练模型中排名前百分之几的行,使得在 6 小时结束时发布这些行(而不是整个模型)将返回令人满意的准确性(即与完全新鲜模型相比差异低于 0.01%)。

图 11 显示了在 6 小时训练后,不同大小的单次更新与完全新鲜模型相比的 NE 损失。可以看出,单次 5% 的部分更新不足以将 NE 损失降低到可接受的 0.01% 阈值以下。然而,10% 的部分更新证明足以将 NE 损失降低到可接受的水平。这表明排名前 10% 的嵌入行是此时间窗口内重要行的良好代理。

图片名称

图 11

为了了解这些重要行中有多少百分比被多个较小的 5% 更新覆盖,我们运行了 QuickUpdate 6 小时,并使用多个 5% 粒度的部分更新。在将所有这些更新合并为一个联合集后,我们观察到该集合涵盖了上述重要行的 70%,并总体覆盖了模型中所有行的 7.3%。因此,大部分重要行被连续的较小部分更新所覆盖。

6.3 带宽使用

在 QuickUpdate 中,更新大小是带宽使用的代理。带宽使用量取决于粒度、更新间隔和间歇性完整模型更新的频率。通常,这些参数是可配置的,并可能根据 DLRM 的类型和所需的准确性而变化。在本节中,我们评估了基于发布模型百分比的不同策略的带宽使用情况。详细信息如下并在图 12 中展示:

图片名称

图 12

  1. 基线 1:每小时发布一次完整模型。
  2. 基线 2:每 10 分钟发布一次完整模型(未在图中显示)。
  3. 5% 更新(默认策略):每 10 分钟发布一次部分更新,粒度为 5%,每 6 小时发布一次间歇性完整更新(如 6.1 节所述)。
  4. 10% 更新:与之前的策略类似,每 10 分钟发布一次部分更新,但粒度为 10%。每 6 小时发布一次间歇性完整更新。

为了比较这些策略,我们平均了消耗的带宽。结果显示,默认策略(5% 更新粒度,6 小时间歇性完整更新间隔)平均每小时写入模型大小的 43.6%,而策略 3(10% 更新)为 68.2%,基线 1 为 100%。基线 2 提供了与策略 2 和 3 相当的准确性,但需要每小时发布模型大小的 600%。

总体而言,使用默认策略,QuickUpdate 能够将消耗的带宽比基线 1 减少 2.3 倍,同时提供与完全新鲜模型相当的更好准确性。与基线 2 相比(由于网络和存储带宽限制,无法大规模实施),QuickUpdate 能够将所需带宽减少超过 13 倍,同时仍提供相当的准确性。

6.4 宽松一致性

传统上,服务模型以原子方式更新以保持一致的推理。这涉及将所有模型权重加载到缓冲节点中,这些节点随后成为计算推理的服务节点。然而,这种方法由于使用缓冲节点而资源密集。为了解决这个问题,QuickUpdate 放宽了一致性要求,并在执行推理查询的同时直接在服务节点中更新参数。

我们评估了在 QuickUpdate 中间歇性完整模型更新期间的 NE 恢复(与完全新鲜模型相比),作为已更新权重百分比的函数。如图 13 所示,放宽一致性可以在加载期间提高生产中的准确性。随着更多参数的加载,NE 恢复增加。我们的数据显示,通过修补 30% 的参数,我们可以捕获约 54% 的 NE 恢复。在修补仅 70% 的参数后,NE 恢复达到约 94%。

图片名称

图 13

宽松一致性允许早期服务新鲜行(而不是等待整个模型更新),从而整体提高准确性。尽管在加载期间表的视图不一致(意味着不同的行可能属于不同的状态),服务一部分新鲜行已经导致准确性增加。NE 恢复随着时间的推移继续增长,直到整个模型更新完毕。

7 相关工作

异步或部分更新策略已在少数实时 DLRM 中实施 [13,18,21]。在 Kraken [21] 中,稠密参数每隔几秒批量更新一次,而稀疏参数在训练器中值发生变化时更新。这是一种无损参数更新,对于具有 1000-10000 亿参数 [15] 和地理分布式服务器的大型模型,可能会产生大量流量。Monolith [13] 主要专注于开发具有无冲突嵌入表的稀疏特征系统。稀疏参数可以在训练时以分钟级粒度更新,其值自上次同步以来发生变化。与 Kraken 类似,这是一种无损更新,可能会产生巨大的流量。总体而言,无损模型更新可能非常资源密集,如第 3 节所述。为了克服这个问题,QuickUpdate 可以执行优先参数选择,从而减少约 78% − 92% 的带宽,并且准确性损失可以忽略不计(< 0.01%)。在另一项研究中,Ekko [18] 被设计为一个高效的系统,用于将更新从训练模型广播到所有服务推理节点。为了快速更新服务模型中的较大嵌入表,他们使用了嵌入表更新中的稀疏性和时间局部性。Ekko 系统与 QuickUpdate 正交,两者可以一起实施。在 QuickUpdate 中,我们优化了设计元素,如发布间隔、更新粒度和参数选择标准,以实现所需的准确性并最小化完整模型的发布。优先参数选择是我们在本文中使用的技术之一。在以往的研究中(例如 [1,2,12]),基于梯度的参数选择已在分布式训练系统中探索。Ekko [18] 进一步扩展了这一标准,并额外考虑了每个参数的请求频率和参数新鲜度作为选择标准。在 QuickUpdate 中,我们决定选择梯度动量的增量,这是一个比梯度本身更稳定的度量,并且它发布的参数能够返回与基线快照相比的最高准确性。

8 结论

QuickUpdate 是一个支持在线训练执行低延迟部分更新的系统,同时提供与完全新鲜模型相当的服务准确性。它为实时服务生产规模的 DLRM 提供了一个可扩展的解决方案。这一点尤其有价值,因为由于网络和存储带宽的限制,大规模实时服务此类模型具有挑战性。

QuickUpdate 通过利用创新技术实现了其可扩展性和准确性目标。其中一项技术是选择性发布每次更新的最重要部分,从而在保持准确性的同时减少整体更新规模。此外,QuickUpdate 以低频率结合间歇性完整模型更新,以确保长期准确性。这种选择性部分更新和间歇性完整更新的结合使 QuickUpdate 能够在低延迟服务和长期保持准确性之间取得平衡。

我们使用大规模个性化广告模型的真实世界数据对 QuickUpdate 进行了评估,结果表明 QuickUpdate 能够提供与完全新鲜模型相当的服务准确性,同时将所需的写入带宽减少超过 13 倍。

附录

google Titans介绍

google在《Titans: Learning to Memorize at Test Time》提出了区别于Transformer的的一种新架构:Titans。我们来看一下它的实现,是否有前景:# 摘要在过去的十多年里,关于如何有效利用循环模型(recurrent mo...… Continue reading

kuaishou CREAD介绍

Published on August 05, 2024

Meta推荐系统-scaling laws介绍

Published on August 02, 2024