生产级AI/ML特征存储平台:Feast全面使用指南 — Architecture

生产级AI/ML特征存储平台:Feast全面使用指南 — Architecture

Feast(Feature Store)是一个开源特征存储平台,通过帮助团队定义、管理、验证和提供生产级AI/ML特征,助力大规模生产机器学习系统的运营。

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。

在这里插入图片描述

概述

Feast 架构图

Feast的架构设计注重灵活性和可扩展性,由多个协同工作的组件构成,可提供用于训练和推理的特征存储服务。

  • Feast采用推送模型从不同数据源接收数据,并将特征值存储在在线存储(Online Store)中。这种机制使Feast能够以低延迟实时提供特征服务。

  • Feast支持特征转换功能(当前支持按需转换和流式数据源,未来将支持批处理转换)。对于流式(Streaming)和批处理(Batch)数据源,Feast需要独立的特征转换引擎(批处理场景下通常使用离线存储作为转换引擎)。我们正在探索为Feast添加默认的流式处理引擎。

  • 在将数据源与Feast集成时,建议结合领域专业知识,充分理解不同写入模式对应用程序的权衡影响。

  • 我们推荐使用Python作为特征存储微服务的开发语言。如文档所述,预计算特征是确保低延迟服务的最佳实践。将特征服务简化为轻量级数据库查询是理想模式,这意味着Python的边际性能开销应可接受。基于此,我们认为Python的优势(避免特征逻辑重复实现)大于其成本。同时我们也提供Java和Go客户端用于在线特征检索。

  • 基于角色的访问控制(RBAC)是一种根据组织内用户角色限制资源访问的安全机制。在Feast场景中,RBAC确保只有授权用户/组能访问或修改特定资源,从而维护数据安全和操作完整性。

Python

使用 Python 提供特征服务。

为什么应该使用 Python 进行机器学习特征服务?

Python 已成为机器学习领域的主要语言,这一优势同样适用于特征服务领域。Feast 推荐使用 Python 编写的微服务主要基于以下五个原因:

1. Python 是机器学习的首选语言

应选择用户最熟悉的工具。Python 在机器学习社区的主导地位毋庸置疑。其简洁性和可读性使其成为编写和理解复杂算法的理想语言。Python 拥有丰富的库生态系统,如 TensorFlow、PyTorch、XGBoost 和 scikit-learn,这些库为机器学习模型的开发和部署提供了强大支持。Feast 也致力于融入这一生态系统。

2. 预计算是必经之路

预计算特征是确保低延迟性能的推荐方案。将特征服务简化为轻量级数据库查询是最佳实践模式,这意味着 Python 带来的边际开销是可接受的。预计算还能确保下游服务的产品体验保持高效。缓慢的用户体验等于糟糕的用户体验。请尽可能多地预计算和持久化数据。

3. 使用其他语言提供特征会导致偏差

确保模型训练(离线服务)和在线预测(在线服务)使用的特征在生产环境中可用至关重要。特征开发初期通常使用 Python 编写,这得益于 Python 数据操作库的便利性和高效性。然而在生产环境中,出于性能考虑,常常会有改用 Java、Go 或 C++ 等其他语言重写这些特征的需求。这种重实现会带来重大风险:训练与服务偏差(training and serving skew)。请注意,虽然总存在少数特例(例如 Time Since Last Event 类型的特征),但这不应成为常态。

当模型训练使用的特征与预测阶段使用的特征存在差异时,就会产生训练与服务偏差。这会导致模型性能下降、预测结果不可靠,以及新特征和新模型的发布速度降低。用其他语言重写特征的过程容易产生错误和不一致,从而加剧这一问题。

4. 重复实现代价过高

用其他语言重写特征不仅存在风险,而且资源消耗巨大。需要工程师投入大量时间和精力确保特征的正确转换。这个过程可能引入错误和不一致,进一步增加训练与服务偏差的风险。此外,维护两个版本的特征代码库会增加不必要的复杂性和开销。更重要的是,这项工作的机会成本极高,需要双倍的资源投入。只有当性能提升值得投入时,才应考虑代码重实现。由于大部分特征应该被预计算,因此延迟性能优化不应成为团队工作的最高优先级。

5. 善用现有 Python 优化手段

与其切换编程语言,不如在保持 Python 作为主要语言的同时优化特征存储性能。优化过程分为两个步骤:

步骤 1:量化特征计算的延迟瓶颈

使用 CProfile 等工具定位代码中的延迟瓶颈。这有助于优先解决最大的效率问题。当我们最初在 Python 中实现原生转换时,代码性能分析 帮助我们发现 Pandas 的类型转换会导致 10 倍的开销。

步骤 2:优化特征计算

如前所述,预计算是推荐方案。某些情况下可能需要数据生产者到在线特征存储的完全同步写入,这时就需要极快的特征计算和写入速度。我们建议首先优化特征计算代码。

应通过库、工具和缓存进行代码优化。例如:判断能否通过 NumPy 的矢量化计算优化特征计算;探索 Numba 等加速工具;使用 lru_cache 等工具缓存频繁访问的数据。

最后,Feast 将持续优化 Python 的服务性能并提升整体基础设施效率,这将更好地服务社区。因此我们建议:重点优化特征相关代码,向维护者报告延迟瓶颈,并通过贡献代码帮助提升基础设施性能。

通过保持 Python 特征实现并优化性能,可以确保训练与服务的一致性,降低错误风险,并专注于为客户提供更多产品体验。

拥抱 Python 进行特征服务,充分利用其优势来构建稳健可靠的机器学习系统。

Push 模型 vs Pull 模型

Push 模型 vs Pull 模型

Feast 采用推送模型(Push Model),即数据生产者将数据推送至特征存储(Feature Store),并由 Feast 将特征值存储于在线存储(online store)中,从而实现实时特征服务。

拉取模型(Pull Model)中,Feast 会在请求时从数据生产者处拉取数据,并在提供服务前将特征值存储至在线存储(实际上这种存储并无必要)。该方法会引入额外的网络延迟,因为 Feast 需要协调对每个数据生产者的请求,这意味着延迟至少等同于最慢的调用耗时。因此,为了实现最低延迟的特征服务,我们选择将数据推送至 Feast 并存储特征值至在线存储。

采用推送模型的权衡在于无法直接保证强一致性(strong consistency),而必须通过显式设计更新 Feast 的协调机制和客户端使用方式来实现强一致性。

这种方法的显著优势在于 Feast 针对低延迟特征检索进行了读取优化。

推送实现方式

推送模型隐式包含了关于_如何_及_何时_将特征值推送至在线存储的决策。

从开发者视角来看,有三种推送特征值至在线存储的方式,各自具有不同的权衡取舍(详见写入模式章节)。

向 Feast 写入数据

Feast 采用推送模型将特征推送到在线存储。

这带来两个重要影响:(1) 数据生产者(即客户端)与 Feast(即服务端)之间的通信模式;(2) 特征计算和特征值写入 Feast 在线存储的模式。

数据生产者(即生成数据的服务)将数据发送至 Feast,以便 Feast 将特征值写入在线存储。这些数据可以是需要 Feast 计算特征值的原始数据,也可以是预计算好的特征值。

通信模式

客户端(或数据生产者)有两种方式向在线存储发送数据:

  1. 同步方式

  2. 异步方式

注意:在某些场景中,开发者可能将一组实体"批量"处理并通过单次 API 调用写入在线存储。这是减少写入负载的常见模式,但我们不将其归类为批处理作业。

特征值写入模式

向在线存储(即服务端)写入特征值有两种方式:客户端预计算转换 或 服务端按需计算转换。

组合方法

在某些场景中,结合使用预计算和按需转换可能是最优方案。

选择特征值写入模式时,必须考虑应用程序的具体需求、可接受的数据正确性、延迟容忍度以及可用计算资源。审慎选择有助于提升服务性能和可靠性。

客户端可通过三种方式向在线存储写入特征值

  1. 预计算转换
  2. 按需计算转换
  3. 混合模式(预计算 + 按需)

1. 预计算转换

预计算转换可在 Feast 外部完成(例如通过批处理作业或流式应用),也可通过 pushwrite-to-online-store API 在写入在线存储时由 Feast 特征服务端完成。

2. 按需计算转换

按需转换只能在 Feast 内部进行,时机可以是:(1) 客户端请求时 或 (2) 数据生产者写入在线存储时。通过 transform_on_write 参数可控制是否在写入操作时应用转换,允许对预处理数据跳过转换,同时在 API 调用时仍启用转换。

3. 混合模式(预计算 + 按需)

混合模式允许在 Feast 内外进行预计算转换,并在客户端请求时执行按需转换。这对于"时间自上次"类型的特征(例如上次购买时间)特别适用。

权衡考量

在同步与异步数据写入之间抉择时,需考虑以下权衡因素:

  • 数据一致性:异步写入允许数据生产者不等待写入完成即发送数据,可能导致在线存储中的数据过时。这在数据实时性要求不高的场景中可以接受。但对于关键操作(如金融应用中的贷款金额计算),陈旧数据可能导致错误决策,此时必须使用同步写入。
  • 正确性:必须权衡数据过时风险与操作需求。例如在借贷应用中,特征数据的新鲜度对正确性至关重要(取决于具体特征和原始数据),此时应优先同步写入。在敏感性较低的场景中,异步写入提供的最终一致性可能已足够。
  • 服务耦合度:同步写入会导致服务间更紧密的耦合。若写入操作失败,可能导致依赖服务操作失败,这对需要高可靠性和服务独立性的系统是重大缺陷。
  • 应用延迟:异步写入通常能降低客户端感知的延迟,因为客户端无需等待写入完成。这在操作不依赖即时数据新鲜度的环境中可提升用户体验和效率。

下表根据具体应用需求和数据敏感性,指导选择最合适的数据写入和特征计算策略:

数据写入类型特征计算方式应用场景推荐方案
异步按需计算容忍数据延迟的数据密集型应用采用异步写入配合按需计算,平衡负载并高效管理资源
异步预计算高吞吐非关键数据处理使用异步批处理作业配合预计算转换,提升效率和扩展性
同步按需计算高风险决策场景采用同步写入配合按需特征计算,确保数据新鲜度和正确性
同步预计算需要快速反馈的用户界面应用使用同步写入配合预计算特征,降低延迟并提升用户体验
同步混合(预计算+按需)需在约束条件下优化延迟的高风险决策在可能时使用同步写入配合预计算特征,辅以选择性按需计算来降低延迟提升体验

特征转换

特征转换(Feature Transformation) 是指接收输入数据集并返回输出数据集的函数。特征转换可作用于原始数据或衍生数据。

特征转换引擎

特征转换可通过以下三类「转换引擎」执行:

  1. Feast Feature Server
  2. 离线存储(如 Snowflake、BigQuery、DuckDB、Spark 等)
  3. 计算引擎

这三类转换引擎需与写入时使用的通信模式配合使用。

需特别注意,这意味着不同的特征转换代码可能在不同的转换引擎下使用。因此,理解各类转换引擎/通信模式的适用场景及其权衡取舍,对实施方案的成功至关重要。

总体而言,我们建议根据数据生产者、特征/模型使用场景及整体产品的适配性,选择合适的转换引擎和网络调用方式。

特征服务与模型推理

Feast 模型推理架构

注意: 该ML基础架构图展示了一种由客户端应用驱动的编排模式。这并不是唯一可行的方法,不同模式会产生不同的权衡取舍。

生产机器学习系统可选择以下四种方式提供机器学习预测(模型推理的输出):

  1. 在线模型推理配合在线特征
  2. 离线模式推理不依赖在线特征
  3. 在线模型推理配合在线特征和缓存预测
  4. 不依赖特征的在线模型推理

注:在线特征可来源于批处理、流式处理或请求数据源

这三种方法各有不同的权衡取舍,但通常具有显著的实现差异。

1. 在线模型推理配合在线特征

该方法通过特征存储(feature store)提供在线特征,模型服务器(如 KServe)提供模型预测,是构建数据驱动型机器学习应用的强大方案。特别适用于需要实时请求数据运行推理的场景。

features = store.get_online_features(
    feature_refs=[
        "user_data:click_through_rate",
        "user_data:number_of_clicks",
        "user_data:average_page_duration",
    ],
    entity_rows=[{"user_id": 1}],
)
model_predictions = model_server.predict(features)

2. 离线模式推理不依赖在线特征

机器学习团队通常认为提供预计算模型预测是最易实现的方案。该方法将模型预测视为特征,通过标准Feast SDK从特征存储中获取。这些预测通常通过批量处理预先生成(如本地运行模型推理生成CSV文件),再物化到在线存储。

model_predictions = store.get_online_features(
    feature_refs=[
        "user_data:model_predictions",
    ],
    entity_rows=[{"user_id": 1}],
)

此方案无需模型服务器参与,但存在数据时效性问题,且只能服务批量计算时存在的用户/实体。某些场景下这种折衷是可接受的。

3. 在线模型推理配合在线特征和缓存预测

这是最复杂的方案,通过缓存预测结果和在特征写入时触发推理来实现低延迟优化。适用于多源特征输入、计算密集型模型或高延迟敏感场景。

# 客户端读取
features = store.get_online_features(
    feature_refs=[
        "user_data:click_through_rate",
        "user_data:number_of_clicks",
        "user_data:average_page_duration",
        "user_data:model_predictions",
    ],
    entity_rows=[{"user_id": 1}],
)
if features.to_dict().get('user_data:model_predictions') is None:
    model_predictions = model_server.predict(features)
    store.write_to_online_store(feature_view_name="user_data", df=pd.DataFrame(model_predictions))

当底层数据变更时需单独调用write_to_online_store更新预测。

# 数据生产者的客户端写入
user_data = request.POST.get('user_data')
model_predictions = model_server.predict(user_data) # 假设DataFrame包含`user_data`
store.write_to_online_store(feature_view_name="user_data", df=pd.DataFrame(model_predictions))

虽然需要为每个数据生产者增加写入操作,但能实现最低推理延迟。

4. 不依赖特征的在线模型推理

此方案无需使用Feast。模型服务器直接提供预测,常见于LLM等无需特征的模型。但使用检索增强生成(RAG)的生成式模型需要特征(如文档嵌入),此时属于"在线模型推理配合在线特征"范畴。

客户端编排

上述代码示例隐含了客户端协调特征获取与模型推理的设计选择。示例采用以Feast为中心的编排模式,另一种方案可采用以推理服务为中心的编排模式:客户端调用推理端点,由推理服务负责协调。

基于角色的访问控制(RBAC)

简介

基于角色的访问控制(RBAC)是一种安全机制,它根据组织内用户的角色来限制对资源的访问。在 Feast 场景中,RBAC 确保只有经过授权的用户或组才能访问或修改特定资源,从而维护数据安全和操作完整性。

功能需求

Feast 中的 RBAC 实现旨在:

  • 权限分配:允许管理员根据用户角色,为其分配各类操作和资源的访问权限
  • 无缝集成:无需大幅修改即可与现有业务代码平滑集成
  • 向后兼容:默认保持对非授权模型的支持以确保向后兼容性

业务目标

在 Feast 中实施 RBAC 的主要业务目标包括:

  1. 特征共享:实现多团队在受控访问下的特征存储共享,在保障数据安全的前提下支持协作开发
  2. 访问控制管理:防止对团队专属资源和空间的未授权访问,管控每个用户/组可执行的操作

参考架构

Feast 作为互联服务集合运行,每个服务都会执行授权检查。架构采用分布式微服务设计,包含以下核心组件:

  • 服务端点:执行授权检查,确保仅处理合法请求
  • 客户端集成:客户端通过在每个请求附加授权令牌与特征服务进行认证
  • 服务间通信:始终授予通信权限

RBAC

权限模型

Feast 的 RBAC 系统采用包含以下核心概念的权限模型:

  • 资源(Resource):Feast 中需要实施安全防护的实体对象
  • 操作(Action):对资源执行的逻辑操作(如 Create/Describe/Update/Delete/Read/write)
  • 策略(Policy):强制执行资源授权决策的规则集合,默认实现采用基于角色的策略

授权架构

Feast 的授权架构包含以下核心组件:

  • 令牌提取器(Token Extractor):从请求头中提取授权令牌
  • 令牌解析器(Token Parser):解析令牌获取用户详情
  • 策略执行器(Policy Enforcer):基于用户详情验证受保护端点
  • 令牌注入器(Token Injector):为每个受保护请求头添加授权令牌

风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

船长Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值