使用 ClickHouse 推动特征存储

图片

本文字数:7833;估计阅读时间:20 分钟

作者:Dale McDiarmid

审校:庄晓东(魏庄)

本文在公众号【ClickHouseInc】首发

介绍

在本文中,我们将深入探讨 MLOps 领域,并探讨特征存储:不同类型、为什么需要特征存储、以及特征存储的主要组件。我们将介绍如何使用 ClickHouse 来推动特征存储,从而推动模型的生命周期,并提供性能和灵活性。

这篇博客主要是关于此主题的入门内容,旨在作为一个前导,后续我们介绍:使用存储在 ClickHouse 中的特征训练 ML 模型的示例。作为这一ML潜在能力的证明,我们展示了与 Featureform 的最新集成 - 一个开源的“虚拟”特征存储,我们将在以后的示例中使用到它。

什么是特征?

在解释特征存储是什么之前,先搞清楚什么是特征可能会有帮助。

简而言之,在机器学习模型中,特征是对具有预测能力的实体的某些属性。在这种情况下,实体是特征的集合,还包括代表现实世界概念的类别或标签。如果特征具有足够的质量。并且存在这样的关系,它们在预测实体的类别时,应该是有用的。例如,银行交易可以被视为一个实体。这可以包含诸如交易金额和涉及的购买者/卖家等特征,类别描述交易是否是欺诈行为。

图片

开发特征通常需要一些先前的数据工程步骤和数据转换逻辑,然后它们才能用于训练模型或从中推断结果(进行预测)。在前一种情况下,许多特征(和实体)将被组合并公开为训练数据(通常是相当大的规模),并用于训练模型。在后一种推理情况下,模型将使用包含仅在预测时可用的数据的特征调用,例如欺诈预测案例中的交易详细信息。其他特征可能源自与训练数据相同的来源,但包含最新值,例如用户账户余额。

图片

图片

以上假设特征始终可以在推断时按需构建,使用在训练时使用的相似转换。由于延迟要求,有时无法做到这一点,因此某些特征的最新版本通常需要在“在线”存储中缓存和预处理。

要让模型准确预测,几乎总是需要数据科学家仔细选择与正在预测的类别相关的特征,除非是深度学习(有时也有例外)。

什么是特征存储?

在其最简单的形式中,特征存储是用于存储和管理特征数据,并充当事实源的集中式存储库。

通过提供可存储、版本控制和检索特征的 API,特征存储旨在为从开发到生产环境的训练和推理提供一致的特征视图。无论是自定义的内部解决方案还是现成的产品,特征存储提供的实际产品级特征会有所不同,有些提供完整的数据平台,能够将数据聚合成特征,甚至提供用于训练模型的计算引擎 - 请参阅下面的“特征存储的类型”。其他提供较轻量的抽象,管理元数据和版本控制,但将训练和数据/特征存储推迟到与其集成的其他平台和数据库。

无论特征存储具备多少功能,它们都提供对数据的抽象,数据科学家和工程师熟悉这些抽象。除了将数据提供为版本化的实体、特征和类别之外,大多数还公开了特征组、训练集、批处理、流处理和时间点查询(例如能够识别特定时间点的特征值,如最新值)的概念。

图片

为什么要使用特征存储?

理论上,特征存储将不同的系统和能力联系在一起,形成一个完整的 ML 数据层,既可以作为训练数据的事实源,也可以在进行预测时提供上下文。

虽然它们提供的确切功能各不相同,但目标保持不变:

  • 通过集中特征及其转换逻辑,提高数据科学家和数据工程师之间的协作和可重用性

  • 通过允许在训练和推断时重复使用特征,减少实验和部署过程中的模型迭代时间

  • 通过规则和版本控制实现治理和合规性,可以限制模型对敏感数据(和特征)的访问

  • 通过从数据科学家那里抽象出数据工程的复杂性,确保他们只使用通过 API 交付的质量一致的特征,从而提高模型性能和可靠性。

虽然,这是特征存储解决的一些问题的非常高级的概述,但这里的主要好处是:能够在团队之间共享特征,并在训练和推理时利用相同的数据。

特征存储还解决了 MLOps 中存在的一些其他挑战,比如:如何回填特征数据、处理对源数据的增量更新(以更新特征)或监控数据漂移。最近,它们还集成了矢量数据库,充当 RAG 流水线的编排层或使用嵌入来帮助查找相似特征 - 这是在某些模型训练过程中非常有用的功能。

那么,你真的需要吗?

在决定是使用现成的特征存储,还是构建自己的方案时,决策可能会参考下面的因素(据我们看来):

  • 现有工具 - 如果你使用了一个完整的 ML 平台,那么你可能不需要特征存储。这些功能大多是这种平台的子集。然而,这些平台通常最不灵活,成本和复杂性最高。相反,如果你使用一组不同的系统和工具来完成 ML 训练和推理过程的不同部分,也许这是有意义的。

  • 复杂性和规模 - 尽管 ML 模型训练不需要成为业务的基本部分,但你可能需要足够多的数据集、模型和数据科学家,以证明额外的复杂性是合理的。虽然在较小的用例中,也可能用临时的替代方式工作,但将更大、更关键的模型迁移到生产环境时,你将需要更大的治理和更强大的流水线。

  • 抽象的好处 - 特征存储提供的抽象对某些团队更有益。如果你有非常明确的数据科学家和数据工程师的角色,那么特征存储可以实现关注点的分离,工程师可以通过一个简单的 API(他们理解的术语)向数据科学家提供特征,后者从特征准备过程中抽象出来。

    相反,如果你的数据科学家熟悉特征工程,提供的抽象可能带来较少的好处。例如,假设你的数据存储在一个兼容 SQL 的数据库或数据湖中(可通过查询引擎访问),那么转换可能通过诸如 dbt 的工具来管理。这将需要你的数据科学家直接在 SQL 中查询表,但可能已经足够了,因为 dbt 提供了转换的版本控制和文档。然而,这确实需要你通过特定的单点解决方案来解决 ML Ops 的许多其他挑战。

特征存储的组件

在我们探讨ClickHouse如何适用于特征存储之前,了解常见组件对于背景知识是有帮助的。通常,特征存储将通常具有的4个主要组件:

图片

  • 数据源 - 虽然这可以是一个简单的CSV文件,但通常是一个带有像Iceberg这样的文件格式的数据库或数据湖,并通过查询引擎访问。

  • 转换引擎(可选) - 原始数据需要转换为特征。在简单情况下,特征可以与列的值相关联。更可能的情况是,它是一个涉及连接、聚合和改变列值结构和/或类型的表达式的转换过程的结果。一些特征存储(参见特征存储的类型)可能提供内置功能来实现这一点;其他可能会将工作转移到本地Python函数,或者对于更大的数据集,通过材料化工具(甚至可能在底层使用dbt)或处理引擎(如Spark)来实现。使用ClickHouse,可以通过Materialized Views来实现这一点。经常需要更新的特征通常需要某种形式的流水线,通常使用诸如Flink或Spark Streaming之类的工具来实现。通常,如果这些转换被链接,并且需要跟踪依赖关系,就需要某种有向无环图(DAG)。

  • 离线(训练)存储 - 离线存储保存了前述转换流水线生成的特征。这些特征通常被分组为实体,并与标签(目标预测)关联。通常,模型需要有选择地使用这些特征,可以是迭代的,也可以是通过聚合,可能多次且随机地。模型通常需要不止一个特征,需要将特征组合在一起形成“特征组” - 通常由实体ID和时间维度组成。这要求离线存储能够为特定时间点交付特征和标签的正确版本。这种“时间点正确性”通常对模型至关重要,需要进行增量训练。

  • 在线(推理)存储 - 一旦模型经过训练,就可以部署并用于进行预测。

    这个推理过程需要在预测时才能获得的信息,例如交易的用户ID。

    然而,它还可以需要用于预测的特征,这些特征可能是预先计算的,例如代表历史购买的特征。即使对于ClickHouse来说,计算这些特征在推理时可能也太昂贵了。这些特征需要在对延迟敏感的情况下提供,基于数据的最新版本,特别是在需要实时进行预测的情景中,比如欺诈检测。特征可能会从离线存储材料化到在线存储以供服务。

上述省略了一些组件,虽然它们不一定是特征存储的组成部分,但它们与任何ML流水线都有很大的关联并且是必需的:

  • 训练引擎和模型托管 - 任何流水线都需要一个计算框架和引擎,用于使用离线存储中的特征训练模型。这个模型反过来需要进行版本控制和托管,以便能够调用它进行推理。模型注册表可能是这一过程的重要组成部分,提供模型谱系、版本控制、标记和注释。

  • 矢量数据库 - 我们在先前的博客文章中探讨了矢量搜索及其在RAG工作流中的应用。虽然传统上不是特征存储的组成部分,但它们与在线存储有相似之处。通常,矢量嵌入将与存储中存在的实体相关联。然后,数据库可以在经典的RAG工作流程中部署,或者使用嵌入来识别相似特征 - 这是在训练和推理时非常有用的功能。

上述所有内容都需要某种形式的状态管理,例如跟踪特征版本。这通常是局部于存储的,并且通常相对于源数据和特征本身来说较小。

特征存储的类型

并非所有的特征存储都能直接提供上述组件,它们在灵活性和所提供的功能方面各不相同。例如,一些可能具有现有的转换引擎,并部署诸如Postgres之类的数据库作为离线存储,或者Redis作为在线组件。因此,ClickHouse要集成到特征存储中,需要一定程度的架构灵活性和开放性。

我们将在下文中探讨:它们之间的差异,以及它们如何与ClickHouse共存。关于虚拟特征存储与其他存储的差异,以及字面和物理存储之间的更详细描述,我们推荐阅读Featureform的博客(https://www.featureform.com/post/feature-stores-explained-the-three-common-architectures)。

物理存储

物理存储提供了一种更集成的解决方案,计算和存储特征。这种存储类型在专有供应商中很常见,如Tecton,通常包括一个集成在线和离线存储的转换引擎,以及一些流处理功能。通常,它们与外部数据存储集成,并可以将一些工作推送到这些存储中,例如进行数据子集选择。在这种情况下,用户正在投资于一个完整的解决方案,灵活性有限。在历史上,这种缺乏灵活性通常是以更高的性能来弥补的。用户还需要学习的技术较少,但代价可能会出现在彻底的供应商锁定上。

图片

Tecton architecture - Credit: https://www.tecton.ai/

在这种架构中,ClickHouse充当训练数据的源存储库,几乎没有其他集成的机会。

字面存储

在字面存储中,特征在存储外部进行处理,存储仅充当中央存储库。特征通常被发送到离线存储,将这些特征实体化到在线存储的过程由用户完成。然后,这些特征用于推理,具有通常如上所述的“时效性”能力。在这个意义上,特征存储实际上是一个实际的数据存储,只能存储和提供特征,同时位于实际真实数据存储之上。这种架构的经典实现是Feast。这种方法提供了最大的灵活性,但对采纳者构建从源生成特征的转换流水线的负担最大。在这里,用户必须学习和连接各种技术,以构建强大的MLOps流水线。

图片

Feast architecture - Original: https://feast.dev/

虽然ClickHouse可能潜在地用作字面存储的存储引擎,但这种特征存储类型并未能充分利用ClickHouse的能力。ClickHouse不仅可用于存储和提供特征。虽然字面存储用户可能可以使用ClickHouse进行存储外部的转换,但它并不提供集成的体验。

虚拟存储

Featureform是一个自我描述为“虚拟特征存储”的开源项目。Featureform将虚拟存储的概念呈现为上述架构之间的平衡。在这种情况下,用户可以在基础架构中使用他们选择的任何存储、转换和流处理引擎。特征存储负责管理转换以及特征的持久性和版本控制,但仅充当协调器。这种插件架构使采纳者能够选择他们喜欢的每个组件的首选技术,从而在保留与字面存储相关的灵活性的同时,获得与物理存储类似的集成体验。在这个意义上,虚拟存储可以被看作是一个工作流管理和协调层,确保对于数据科学家和工程师来说,使用相同的抽象层。

图片

Featureform architecture - Credit: https://www.featureform.com/

具有ClickHouse的虚拟存储

这种架构的传统实现可能会牺牲物理存储的一些性能,以提供与字面存储相当的协调和管理层,同时保留字面存储的灵活性。这种灵活性还会带来一些部署成本,因为异构架构本质上具有更大的DevOps开销。然而,通过利用ClickHouse来支持架构的重要组件,用户可以实现比更异构架构更卓越的性能,并降低管理开销。对于PB数据集上的昂贵操作,如特征缩放和相关矩阵计算,可以在几秒钟内完成。灵活性也仍然得到保留 - 如果用户希望替换ClickHouse,他们可以自由地这么做,同时仍保留一致的版本方案和对特征定义的集中跟踪。

特征存储与ClickHouse

作为实时数据仓库,ClickHouse可以担当多个组件的角色,很可能会显著的简化特征存储架构。

图片

具体而言,ClickHouse可以担当以下角色:

  • 数据源 - 具备查询或摄取70多种不同文件格式的能力,包括数据湖格式如Iceberg和Delta Lake,ClickHouse成为一个理想的长期存储或查询数据的仓库。通过使用对象存储分离存储和计算,ClickHouse Cloud还允许数据无限期地持久化保留 - 可以将计算缩小或完全空闲以最小化成本。灵活的编解码器,与列式存储和数据在磁盘上的排序相结合,最大程度地提高了压缩率,从而最小化了所需的存储空间。用户可以轻松将ClickHouse与数据湖结合使用,并使用内置函数在对象存储中原地查询数据。

  • 转换引擎 - SQL提供了声明数据转换的自然手段。当与ClickHouse的分析和统计函数相结合时,这些转换变得简洁而优化。除了应用于ClickHouse表的情况外,在ClickHouse用作数据存储的情况下,表函数允许使用格式(如Parquet)存储的数据编写SQL查询,存储在磁盘或对象存储中,甚至是其他数据存储,如Postgres和MySQL。完全并行化的查询执行引擎,再加上列式存储格式,使ClickHouse能够在几秒钟内对PB级数据执行聚合操作 - 与在内存数据框上进行的转换不同,用户不受内存限制。此外,物化视图允许在插入时转换数据,从而在查询时间之前从计算时间过载到数据加载时间。这些视图可以利用与数据分析和汇总非常理想的相同范围的分析和统计函数。如果ClickHouse的现有分析函数不足或需要集成自定义库,用户还可以利用用户定义函数(UDF)。

    虽然用户可以直接在ClickHouse中或在使用SQL查询之前转换数据,但ClickHouse还可以在编程环境(如Python)中通过chDB使用。

    这允许嵌入式ClickHouse被公开为Python模块,并用于在笔记本中转换和操作大型数据框。

    这使得转换工作可以由数据工程师在客户端执行,结果可能被实现为集中的ClickHouse实例中的特征表。

  • 离线存储 - 借助从多个源读取数据并通过SQL应用转换的上述功能,通过INSERT INTO SELECT语句,这些查询的结果也可以在ClickHouse中持久化。由于转换通常按实体ID分组并返回多列结果,ClickHouse的模式推断可以自动从这些结果中检测到所需的类型,并生成适当的表模式来存储它们。用于生成随机数和统计抽样的函数允许数据以每秒数百万行的速度进行高效迭代和扩展,以供模型训练管道使用。

    通常,特征以表格的形式表示,其中时间戳表示实体和特征在特定时间点的值。如前所述,训练管道通常需要在特定时间点以及按组返回特征的状态。ClickHouse的稀疏索引允许快速过滤数据以满足时点查询和特征选择过滤的要求。虽然其他技术,如Spark、Redshift和BigQuery,依赖于缓慢的有状态窗口方法来确定特定时间点的特征状态,但ClickHouse支持ASOF(截至此时)LEFT JOIN查询和argMax函数。除了简化语法,这种方法通过使用排序和合并算法在大型数据集上实现高性能。这允许快速构建特征组,减少训练之前的数据准备时间。

图片

所有这些工作都可以下沉到ClickHouse中,进行并行化并在集群中执行。这使得离线存储可以扩展到PB级,而特征存储本身仍然是一个轻量级的协调层。

  • 在线存储 - 作为实时分析数据库,ClickHouse可以以低延迟服务于高并发查询工作负载。虽然这需要数据通常是非规范化的,但这与在训练和推理时使用的特征组的存储方式相一致。重要的是,由于其日志结构合并树,ClickHouse能够在高写入工作负载下交付这种查询性能。这些属性在在线存储中是必需的,以保持特征的最新状态。由于特征已经在离线存储中可用,因此它们可以轻松地被实现为同一ClickHouse集群内的新表,或通过现有的功能(例如remoteSecure)到不同实例中。

    通过Kafka的集成,可以通过Kafka Connect提供的确切一次提供或通过ClickHouse Cloud中的ClickPipes,从流源简单可靠地消费流数据。

对于需要非常高的请求并发性(即每秒数千次)和非常低延迟的用例,我们建议用户仍然考虑专用数据存储,例如为这些工作负载设计的Redis。

  • 向量数据库 - ClickHouse通过浮点数组内置支持向量嵌入。这些可以通过距离函数进行搜索和比较,允许ClickHouse用作向量数据库。这种线性比较可以轻松地扩展和并行化以适应更大的数据集。此外,ClickHouse对近似最近邻(ANN)索引以及使用纯SQL的超平面索引提供了成熟的支持,这对于更大的向量数据集是必需的。

通过满足上述每个角色,ClickHouse可以显著简化特征存储架构。除了简化操作外,该架构还允许更快地构建和部署特征。ClickHouse的单个实例可以垂直扩展以处理PB级的数据,只需在需要时动态地添加其他实例以实现高可用性。这最小化了在数据存储之间传输数据,从而减少了典型的网络瓶颈。ClickHouse Cloud通过仅在对象存储中存储数据的单一副本,并在需要时动态地响应负载而将节点垂直或水平扩展,进一步扩展了这一点。

上述架构仍然需要ClickHouse未满足的几个关键组件:流引擎,如Kafka + Flink,以及提供模型训练的计算框架。还需要一种托管模型的方式。为简单起见,我们假设使用云托管的解决方案,如Confluent和Amazon SageMaker。

ClickHouse 与 Featureform集成

为了实现我们对由ClickHouse强化的“虚拟”特征存储的愿景,我们确定Featureform是与之集成的理想解决方案。除了是开源的,因此可以轻松贡献外,Featureform还提供了成熟(设计上)的离线存储、在线存储和向量数据库的集成点。

在我们的初始集成中,我们将ClickHouse添加为离线存储。这代表了最大的工作量,使ClickHouse可以用作数据源和特征以及训练集的主要存储。用户还可以利用ClickHouse来在创建特征组并从其他源插入数据时推动转换。

这代表了我们与Featureform集成的第一步。预计不久将能够将ClickHouse用作在线存储和向量数据库!

结论

在本博客中,我们介绍了特征存储的概念及其在MLOps工作流中的用途。我们探讨了为什么要使用特征存储,特征存储的主要类型以及其核心架构组件。在此基础上,我们介绍了ClickHouse作为高性能实时数据仓库,如何用于支持“虚拟”特征存储的多个组件,并宣布了与Featureform的最新集成作为示例。

图片

??联系我们

手机号:13910395701

邮箱:[email protected]

满足您所有的在线分析列式数据库管理需求