资讯动态

Feast on RHOAI 快速上手:在 Red Hat OpenShift AI 上端到端跑通本地与远程拓扑的 Feature Store

发布时间:2026/9/19 17:54:45 来源:尧图企业网站定制
Feast on RHOAI 快速上手在 Red Hat OpenShift AI 上端到端跑通本地与远程拓扑的 Feature Store【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast本篇技术指南基于仓库中的 RHOAI 快速入门示例examples/rhoai-quickstart/README.md 与配套笔记本 feast-demo-quickstart.ipynb演示如何把 Feast 作为特征存储运行在 Red Hat OpenShift AIRHOAI平台上。读完本文你将能够在 RHOAI 沙箱中创建 Workbench 并运行 Feast 示例笔记本用 Driver 样例数据完成特征仓库初始化、历史特征生成、批量推理、在线物化与在线特征读取并进一步搭建 remote online server 与 remote registry server 两种客户端-服务端拓扑理解各端口、配置项与 Feast SDK 的实际行为。环境准备两种运行方式与适用前提README 给出的前提是示例以 Jupyter Notebook 展示 Feast 能力你需要一个可以执行 Jupyter 的环境二选一在本地机器运行 Jupyter适合希望脱离平台独立验证的读者按 Jupyter 官方文档安装即可。在 RHOAI 平台运行 Jupyter本快速入门的目标场景直接在 RHOAI 的 WorkbenchNotebook 环境里执行示例。如果还没有 RHOAI 集群README 建议使用 Red Hat OpenShift AI 的开发者沙箱developer sandbox来体验本示例并建议新用户在动手前先用官方渠道的入门视频和产品文档Red Hat OpenShift AI 文档中的 Data Science Projects 章节熟悉平台。在 RHOAI 沙箱上创建 WorkbenchREADME 给出的操作步骤进入你的项目namespace下的Dev页面打开Workbenches标签页点击Create Workbench填写所需信息点击Create。Workbench 就绪后README 给出两种方式把示例导入并运行克隆仓库把 Feast 仓库克隆进 Workbench然后运行examples/rhoai-quickstart/下的笔记本上传文件把必要文件上传到已有 Workbench直接执行笔记本。笔记本整体流程围绕 Driver 实体的三段式演示feast-demo-quickstart.ipynb 以Driver司机实体为载体演示 Feast 的核心能力。README 将笔记本归纳为三部分设置 Feast 仓库加载样例 driver 数据、生成训练数据集、执行离线推理批量打分、把批量特征摄入在线存储并学习如何用FeatureView与FeatureService拉取推理特征配置 Remote Online 拓扑启动 remote online server 与客户端用 remote online client 实时取特征配置 Remote Registry 拓扑启动 remote registry server 与客户端用 remote registry client 读取 Feast 元数据FeatureView、FeatureService 等。README 同时说明该笔记本也可以在独立环境standalone中完整执行并不强依赖 RHOAI。第 1 步安装 Feast 与版本一致性要求笔记本的第一个代码单元# WE MUST ENSURE PYTHON CONSISTENCY BETWEEN NOTEBOOK AND FEAST SERVERS # LAUNCH THIS NOTEBOOK FROM A CLEAN PYTHON ENVIRONMENT 3.9 %pip install -q feast0.40.1 # grpcio is needed as a later section to run the feast registry server. %pip install -q grpcio两个要点值得注意Python 版本与一致性注释明确要求从干净的 Python 环境3.9启动笔记本且笔记本端与 Feast 服务端之间的 Python 版本必须保持一致。这是远程拓扑能正常工作的隐含前提grpcio 依赖笔记本后段要用到feast serve_registry启动 gRPC 协议的 Registry 服务因此提前安装grpcio。示例固定的 Feast 版本为 0.40.1且从输出可见 RHOAI Workbench 的默认内核为 Python 3.9.16路径位于容器内/opt/app-root/如/opt/app-root/src/feast。如果你在本机复现需把笔记本中出现的绝对路径替换为自己环境下的实际路径。第 2 步feast init创建项目并解读 feature_store.yaml!rm -rf my_feast_project !feast init my_feast_project %cd my_feast_project/feature_repofeast init会打印Creating a new Feast repository in .../my_feast_project。从源码看init命令定义在 cli.py支持--minimal与--template选项模板可选local、aws、gcp、snowflake、postgres等默认local实际建库逻辑在 repo_operations.py 的init_repo。本示例未传模板参数即使用默认 local 模板生成带示例数据的完整 feature store 骨架。生成的仓库结构笔记本中的find输出. -- data -- |-- driver_stats.parquet -- __init__.py -- feature_store.yaml -- example_repo.py -- test_workflow.py各文件职责README/笔记本的说明data/存放本示例的 parquet 样例数据example_repo.py创建 Feast 对象FeatureView、FeatureService、OnDemandFeatureView的代码feature_store.yamlFeast 的全部仓库级配置test_workflow.py演示 Feast 关键命令定义、读取、推送特征的 Python 代码。feature_store.yaml实际内容project: my_feast_project # By default, the registry is a file (but can be turned into a more scalable SQL-backed registry) registry: data/registry.db # The provider primarily specifies default offline / online stores storing the registry in a given cloud provider: local online_store: type: sqlite path: data/online_store.db entity_key_serialization_version: 2参数解读配置项示例值含义projectmy_feast_project项目名用于命名空间隔离在线存储的表名会带此前缀后文可见my_feast_project_driver_hourly_statsregistrydata/registry.db注册表默认是文件型SQLite可换成 SQL 支持的注册表以获得更好的可扩展性providerlocalprovider 主要决定默认的离线/在线存储与注册表落盘位置参见 local provider 文档online_store.typesqlite本地在线存储见 sqlite online store 参考entity_key_serialization_version2实体键序列化版本决定在线存储中实体键的编码方式feature_store.yaml的完整字段说明可参考 feature-store-yaml 参考文档。第 3 步样例数据与 Feast 对象定义driver_stats.parquet1807 行的司机小时级统计data/driver_stats.parquet由feast init生成是本示例的“离线数据源”。用 pandas 读取后可见 1807 行 × 6 列schema 如下列类型说明event_timestampdatetime64[ns, UTC]事件时间司机统计的小时时间戳driver_idint64实体 join key1001–1005 等司机 IDconv_ratefloat32接单转化率acc_ratefloat32事故率avg_daily_tripsint32日均行程数createddatetime行写入时间created timestamp 列FileSource 定义笔记本展示该数据源在特征定义文件中的写法路径为 RHOAI 容器内的绝对路径本机复现时请替换driver_stats_source FileSource( namedriver_hourly_stats_source, path/opt/app-root/src/feast/examples/rhoai-quickstart/my_feast_project/feature_repo/data/driver_stats.parquet, timestamp_fieldevent_timestamp, created_timestamp_columncreated, )timestamp_field与created_timestamp_column分别指定事件时间与物化时间列是点-in-time join 与增量物化后文materialize-incremental的依据。feast apply把代码定义落成注册表对象在存在feature_store.yaml的目录下执行feast apply。注意笔记本先执行了rm -rf .ipynb_checkpoints/——Jupyter 的 checkpoints 目录会干扰feast apply的仓库扫描。feast apply的实际输出创建了实体driver批量特征视图driver_hourly_stats与driver_hourly_stats_fresh后者同时挂了 push source支持在线推送按需特征视图OnDemand FeatureViewtransformed_conv_rate与transformed_conv_rate_fresh对conv_rate做加值变换输出conv_rate_plus_val1/conv_rate_plus_val2特征服务driver_activity_v2、driver_activity_v1、driver_activity_v3SQLite 在线表my_feast_project_driver_hourly_stats与my_feast_project_driver_hourly_stats_fresh。输出中还有一条提示On demand feature view is an experimental feature... the functionality does not scale well for offline retrieval即按需特征视图目前是实验性能力离线批量读取场景的扩展性有限。第 4 步生成训练数据集get_historical_features训练数据需要“实体 时间戳 标签”。笔记本先构造 entity dataframeentity_df pd.DataFrame.from_dict( { # entitys join key - entity values driver_id: [1001, 1002, 1003], # event_timestamp (reserved key) - timestamps event_timestamp: [ datetime(2021, 4, 12, 10, 59, 42), datetime(2021, 4, 12, 8, 12, 10), datetime(2021, 4, 12, 16, 40, 26), ], # (optional) label name - label values. Feast does not process these label_driver_reported_satisfaction: [1, 5, 3], # values were using for an on-demand transformation val_to_add: [1, 2, 3], val_to_add_2: [10, 20, 30], } )要点event_timestamp是保留键label_*列原样透传Feast 不处理val_to_add/val_to_add_2是喂给 OnDemand 变换的输入列。然后store FeatureStore(repo_path.) training_df store.get_historical_features( entity_dfentity_df, features[ driver_hourly_stats:conv_rate, driver_hourly_stats:acc_rate, driver_hourly_stats:avg_daily_trips, transformed_conv_rate:conv_rate_plus_val1, transformed_conv_rate:conv_rate_plus_val2, ], ).to_df()返回的training_df共 10 列3 个司机 ID 行包含原始特征conv_rate/acc_rate/avg_daily_tripsfloat32/int32、按需变换特征conv_rate_plus_val1/conv_rate_plus_val2float64以及透传的 label 列。注意按需特征的值等于conv_rate val_to_add如 0.058821 1 1.058821验证了变换逻辑生效。README 强调带时间戳的原因我们希望同一司机在不同时间点的特征分别入模点-in-time join。第 5 步离线推理批量打分批量打分的做法与训练数据生成相同只是把event_timestamp换成当前时间entity_df[event_timestamp] pd.to_datetime(now, utcTrue) training_df store.get_historical_features( entity_dfentity_df, features[ driver_hourly_stats:conv_rate, driver_hourly_stats:acc_rate, driver_hourly_stats:avg_daily_trips, transformed_conv_rate:conv_rate_plus_val1, transformed_conv_rate:conv_rate_plus_val2, ], ).to_df()输出显示三行司机在“now”时刻拿到的特征向量如 driver 1002 的conv_rate_plus_val1 2.311688说明历史特征接口在推理场景下的用法。第 6 步把批量特征物化进在线存储!feast materialize-incremental $(date -u %Y-%m-%dT%H:%M:%S)该命令从离线存储取特征写入在线存储。实际输出Materializing 2 feature views to 2024-09-24 18:02:0600:00 into the sqlite online store. driver_hourly_stats from 2024-09-23 18:02:0900:00 to 2024-09-24 18:02:0600:00: 100%|████████...| 5/5 driver_hourly_stats_fresh from 2024-09-23 18:02:0900:00 to 2024-09-24 18:02:0600:00: 100%|████████...| 5/5解读物化窗口为“上次物化时间2024-09-23 18:02→ 传入的截止时间2024-09-24 18:02”即增量模式apply时记录的materialization_intervals决定了起点这也解释了为什么driver_hourly_stats输出里先打印了一个 0/5 的进度条——首次物化需要分片扫描离线 parquet。OnDemand 特征视图不参与物化feast apply时也未为它们建表。第 7 步在线特征读取与 FeatureService直接按特征字符串读取feature_vector store.get_online_features( features[ driver_hourly_stats:conv_rate, driver_hourly_stats:acc_rate, driver_hourly_stats:avg_daily_trips, ], entity_rows[ # {join_key: entity_value} {driver_id: 1004}, {driver_id: 1005}, ], ).to_dict()输出{acc_rate: [0.49898454546928406, 0.2943153381347656], avg_daily_trips: [178, 74], conv_rate: [0.19129787385463715, 0.5790505409240723], driver_id: [1004, 1005]}entity_rows是{join_key: entity_value}字典列表每个字典对应一个实体的“最新值”读取。用 FeatureService 解耦消费端FeatureService用于把“特征视图定义”和“应用需要的特征集合”解耦。笔记本额外定义并注册了driver_activity_v4指向driver_stats_fresh_fvdriver_activity_v4 FeatureService( namedriver_activity_v4, features[example_repo.driver_stats_fresh_fv], ) feature_store FeatureStore(.) feature_store.apply([driver_activity_v4])随后可以用 FeatureService 对象而不仅是字符串列表调用同一套 APIfeature_vector feature_store.get_online_features( featuresdriver_activity_v4, entity_rows[{driver_id: 1004}, {driver_id: 1005}], ).to_dict()结果与直接按字符串读取完全一致证明两种引用方式等价。第 8 步Remote Online 拓扑——feast serve 与 remote 客户端启动在线服务在 feature_repo 目录下后台启动在线服务import subprocess # Run feast serve in the background feast_online_server_process subprocess.Popen([feast, serve])输出显示 gunicornuvicorn worker在http://127.0.0.1:6566上监听。随后用ps -ef | grep feast serve确认进程存在。默认端口6566并非魔法数字serve命令在 serve.py 中定义--port默认值即 6566--host默认127.0.0.1。该命令还有若干对生产环境有价值的参数默认值如下摘自同一源码参数默认值说明--host127.0.0.1监听地址--port6566监听端口--typehttp服务类型http或grpc--workers1worker 进程数-1表示按 CPU 核数自动计算2*cores1--worker-connections1000每个 worker 的最大并发连接--max-requests1000worker 处理多少请求后重启防内存泄漏--max-requests-jitter50防 worker 同时重启的抖动量--keep-alive-timeout30keep-alive 连接超时秒--registry_ttl_sec60注册表元数据刷新周期秒--cert/--key空两者必须成对提供以启动 TLS 模式见 TLS 启动指南--metrics关闭启用 Metrics Server完整服务参考见 feature servers 文档。构造 remote online 客户端配置笔记本在remote-online/目录动态生成feature_store.yamlproject: my_feast_project registry: ./../my_feast_project/feature_repo/data/registry.db # 复用本地注册表简化演示 provider: local online_store: type: remote path: http://127.0.0.1:6566 entity_key_serialization_version: 3两个关键细节online_store.type: remote时path就是在线服务地址。从源码看RemoteOnlineStoreConfig 的path默认值正是http://localhost:6566且还提供certTLS 模式下的客户端证书路径、connection_pool_size默认 50、connection_idle_timeout默认 300 秒、connection_retries默认 3 次指数退避等连接池参数——笔记本示例未显式配置全部走默认值entity_key_serialization_version从主仓库的2变成3客户端与服务端序列化版本必须对齐否则实体键无法正确解码。这是 remote 拓扑最容易被忽略的坑。初始化并读取online_feature_store_client FeatureStore(.) online_feature_store_client.apply([]) online_features_stores_client online_feature_store_client.get_online_features( featuresdriver_activity_v4, entity_rows[{driver_id: 1004}, {driver_id: 1005}], ).to_dict()输出与本地直读完全一致同时在线服务日志打印POST /get-online-features HTTP/1.1 200——证明请求确实经由 6566 端口的 HTTP 接口完成而不是走了本地 SQLite。笔记本的说明指出为了演示简洁此处客户端仍指向my_feast_project的本地注册表而生产环境可以进一步把 registry、online、offline 三类服务全部远程化用 feature store client 统一访问相关拓扑见 生产部署拓扑指南。第 9 步Remote Registry 拓扑——feast serve_registry 与元数据读取Registry 保存 FeatureService、FeatureView 等全部 Feast 元数据。除直接读本地注册表外还可以以客户端-服务端模式访问启动 registry server客户端通过 remote registry 读取。默认端口为6570。启动 registry server先切回my_feast_project/feature_repo目录registry server 需要在含feature_store.yaml的仓库目录下启动然后import subprocess feast_remote_registry_server_process subprocess.Popen([feast, serve_registry]) # 用 ps -ef | grep feast serve_registry 确认进程serve_registry命令定义见 serve.py--port默认DEFAULT_REGISTRY_SERVER_PORT即 constants.py 中的6570--grpc/--no-grpc默认开启 gRPC本例使用的就是 gRPC 通道这也是第 1 步要装grpcio的原因--rest-api可额外启用 REST 注册表服务--cert/--key同样支持 TLS。构造 remote registry 客户端配置在remote-registry/目录生成feature_store.yamlproject: my_feast_project registry: registry_type: remote path: localhost:6570 provider: local online_store: type: remote path: http://127.0.0.1:6566 entity_key_serialization_version: 3注意 registry 的path是host:port形式gRPC 地址与 online 的http://...URL 形式不同。通过远程注册表读取元数据registry_feature_store_client FeatureStore(.) registry_feature_store_client.apply([]) # Listing all feature views using remote registry client registry_feature_store_client.list_all_feature_views(allow_cacheFalse) # Listing all feature services using remote registry client registry_feature_store_client.list_feature_services()list_all_feature_views返回的元数据对象信息量很大可核对第 3 步feast apply的产物driver_hourly_statsentities[driver]、ttl1 天、batch_source 为 parquet FileSource、features 为conv_rate-Float32/acc_rate-Float32/avg_daily_trips-Int64、materialization_intervals记录了物化窗口driver_hourly_stats_fresh额外带 PUSH_SOURCE 流数据源两个 OnDemand 特征视图mode pandassource 指向对应 feature view 投影与RequestSource。list_feature_services则返回driver_activity_v1/v2/v3/v4及其feature_view_projections组成。收尾停止服务并核对进程笔记本最后把两个后台进程终止feast_online_server_process.terminate() # Stop the remote Feast online server feast_remote_registry_server_process.terminate() # stops the remote registry server随后ps -ef | grep feast serve应只剩 grep 自身。从输出日志看feast serve收到 SIGTERM 后 gunicorn 会走Handling signal: term → Shutting down → Application shutdown complete的优雅关闭流程其中Error while closing socket [Errno 9] Bad file descriptor是容器内常见噪声可忽略。小结与延伸阅读本示例完整覆盖了 Feast “本地仓库 → 批量摄取 → 在线服务 → 客户端-服务端拓扑” 的闭环且每个环节都给出了可直接复制的配置与 API 调用。示例目录只有两个文件README 与 笔记本其余所有能力FileSource、FeatureView/OnDemandFeatureView、FeatureService、get_historical_features/get_online_features、materialize-incremental、feast serve/serve_registry都来自当前仓库的 Python SDKsdk/python/feast。若继续深入建议按以下路径概念实体、点-in-time join、特征拉取、feature_store.yaml 全字段参考服务与部署feature servers 参考、远程在线存储、生产部署拓扑、TLS 模式启动服务器同类示例仓库 examples 目录下的 quickstart、operator-quickstart 等可对照本例的 local 拓扑理解 Kubernetes Operator 方式部署的差异。【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价