特征平台(Feature Platform / Feature Store)是 MLOps 基础设施中近年来最受关注的组件之一。它的核心价值是解决一个长期困扰 ML 工程团队的问题:特征代码重复、训练与线上不一致、特征难以复用。本文深入解析 Feast(开源)、Tecton(商业)、字节跳动内部特征平台和阿里 FeatureStore 的设计思路与核心能力,并从工程师视角给出选型建议。
为什么需要特征平台
没有特征平台时的痛点
在没有特征平台之前,ML 团队通常面临以下问题:
特征代码四处散落:A 团队写了一个"用户近7天购买次数"的 Spark 脚本,B 团队也写了一个,两个脚本的逻辑细节不完全一样(时间窗口的边界处理、NULL 值处理方式不同),导致两个团队的模型用了"不同的"同名特征。特征代码难以发现、难以复用。
Training-Serving Skew(训练与线上不一致):离线训练用 Hive 计算特征,在线推理用 Java 代码查 Redis,两套实现逻辑不可能完全一致。差异可能很小(比如时区处理差了 8 小时),但足以让模型效果莫名变差,且极难排查。
重复计算浪费资源:同一个特征被多个团队、多个模型重复计算,浪费大量计算资源。一家中型互联网公司每天可能有数百个特征计算任务,其中相当比例是重复的。
Point-in-Time 正确性难以保证:训练样本拼接时,应该用事件发生时刻的特征值(而非当前值),否则会引入未来信息,导致模型在离线评估时表现虚高,上线后效果大幅下降。手动实现 Point-in-Time 正确的特征回填非常复杂且容易出错。
特征平台的核心价值
特征平台通过以下机制解决上述问题:
- 统一特征定义:一份 DSL/配置描述特征的计算逻辑,所有人共享同一份定义
- 批流统一生成:同一份定义自动生成离线(Spark)和在线(Flink/流处理)的计算代码,消除 Skew
- 特征复用:特征注册到中央仓库,其他团队可以直接使用,无需重复开发
- Point-in-Time 正确的历史特征:平台自动处理时间回溯,保证训练样本的特征值是事件发生时刻的值
- 统一的在线查询接口:推理服务通过统一 API 查询特征,屏蔽底层存储细节
Feast:开源特征平台的标杆
背景与定位
Feast(Feature Store)由 Gojek(东南亚出行公司)于 2019 年开源,后被 Tecton 团队接手维护,目前是最主流的开源特征平台。Feast 的定位是轻量级、可插拔的特征注册与服务层,不强绑定特定的计算引擎,用户自带 Spark/Flink 计算特征,Feast 负责存储、管理和服务。
核心概念
from feast import Entity, FeatureView, Field, FileSource
from feast.types import Float32, Int64
from datetime import timedelta
# 1. Entity:特征的主键(按什么维度聚合)
user = Entity(name="user_id", join_keys=["user_id"])
# 2. Data Source:特征数据的来源
user_stats_source = FileSource(
path="s3://my-bucket/user_stats/",
timestamp_field="event_timestamp", # 时间戳字段,用于 Point-in-Time 查询
)
# 3. Feature View:一组相关特征的集合(类似一张宽表)
user_stats_fv = FeatureView(
name="user_stats",
entities=[user],
ttl=timedelta(days=7), # 特征的有效期
schema=[
Field(name="buy_cnt_7d", dtype=Int64),
Field(name="total_amount_7d", dtype=Float32),
Field(name="last_buy_days", dtype=Int64),
],
source=user_stats_source,
)
from feast import FeatureStore
import pandas as pd
store = FeatureStore(repo_path=".")
# 离线特征查询(Point-in-Time Correct)
# 给定一批样本(user_id + event_timestamp),查询每个时间点的特征值
entity_df = pd.DataFrame({
"user_id": [1001, 1002, 1003],
"event_timestamp": pd.to_datetime(["2026-04-01", "2026-04-02", "2026-04-03"]),
"label": [1, 0, 1],
})
# Feast 自动处理 Point-in-Time:
# 对于 user_id=1001, event_timestamp=2026-04-01,
# 查询的是 2026-04-01 之前最新的特征值,而非当前值
training_df = store.get_historical_features(
entity_df=entity_df,
features=["user_stats:buy_cnt_7d", "user_stats:total_amount_7d"],
).to_df()
# 在线特征查询(实时推理时调用)
online_features = store.get_online_features(
features=["user_stats:buy_cnt_7d", "user_stats:total_amount_7d"],
entity_rows=[{"user_id": 1001}],
).to_dict()
架构设计
Feast 的架构分为三层:
- Registry(特征注册表):存储特征定义的元数据(特征名、类型、来源、TTL),默认用本地文件或 GCS/S3,生产环境用 SQL 数据库(PostgreSQL)。
- Offline Store(离线存储):存储历史特征数据,用于训练样本生成。支持 BigQuery、Redshift、Snowflake、Spark(文件系统)等。Feast 的 Point-in-Time 查询通过 SQL 的 ASOF JOIN 或 Spark 实现。
- Online Store(在线存储):存储最新特征值,用于在线推理。支持 Redis、DynamoDB、Bigtable、SQLite(开发环境)。通过
feast materialize命令将离线数据同步到在线存储。
Feast 的局限
Feast 是"特征服务层"而非"特征计算层"——它不负责计算特征,只负责存储和查询。这意味着:
- 用户需要自己用 Spark/Flink 计算特征,再将结果写入 Feast 管理的数据源
- 没有内置的批流统一能力(同一份定义生成 Spark 和 Flink 代码)
- 实时特征支持有限,主要面向批量特征场景
这是 Feast 与 Tecton 最大的差异:Feast 是"特征仓库",Tecton 是"特征平台"(包含计算)。
Tecton:批流统一的商业特征平台
背景与定位
Tecton 由 Uber 前工程师(Michelangelo 平台的创始团队)于 2020 年创立,是目前功能最完整的商业特征平台。Tecton 的核心卖点是批流统一:用同一套 Python SDK 定义特征,平台自动生成并管理 Spark 批处理作业和 Flink/Spark Streaming 流处理作业,消除 Training-Serving Skew。
核心概念:Feature Pipeline
from tecton import batch_feature_view, stream_feature_view, Entity, FeatureService
from tecton.types import Field, Float64, Int64, String
from datetime import timedelta
user = Entity(name="user", join_keys=["user_id"])
# 批量特征视图:自动生成 Spark 作业
@batch_feature_view(
sources=[orders_batch_source], # 批量数据源(Hive/S3)
entities=[user],
mode="spark_sql",
batch_schedule=timedelta(hours=1), # 每小时重新计算
ttl=timedelta(days=30),
)
def user_purchase_stats(orders):
return f"""
SELECT
user_id,
COUNT(*) AS buy_cnt_7d,
SUM(amount) AS total_amount_7d
FROM orders
WHERE event_time >= NOW() - INTERVAL 7 DAYS
GROUP BY user_id
"""
# 流式特征视图:自动生成 Flink 作业,与批量特征语义一致
@stream_feature_view(
sources=[orders_stream_source], # 流数据源(Kafka)
entities=[user],
mode="spark_sql",
stream_processing_mode="continuous",
batch_schedule=timedelta(hours=1),
ttl=timedelta(days=1),
)
def user_realtime_stats(orders):
return f"""
SELECT
user_id,
COUNT(*) AS buy_cnt_1h,
SUM(amount) AS total_amount_1h
FROM orders
WHERE event_time >= NOW() - INTERVAL 1 HOUR
GROUP BY user_id
"""
# Feature Service:将多个特征视图打包为一个服务接口
recommendation_features = FeatureService(
name="recommendation_features",
features=[user_purchase_stats, user_realtime_stats],
)
Tecton 的架构亮点
统一的特征管道(Feature Pipeline):Tecton 将批量和流式特征定义为同一个抽象,内部自动管理对应的计算作业。开发者只需关注"特征是什么",不需要关心"如何计算"。
自动回填(Backfill):新定义一个特征后,Tecton 自动触发历史数据回填,生成过去 N 天的特征数据,无需手动编写回填脚本。
特征新鲜度保证:Tecton 监控每个特征的更新时间,如果特征超过预期时间未更新(上游数据管道故障),自动告警并在推理时返回降级值(如历史均值)。
On-Demand 特征:支持在推理时实时计算的特征(不需要预先物化存储),适合依赖请求上下文的特征(如"当前请求的商品价格与用户历史平均消费的比值")。
Tecton 的局限
- 商业产品,价格昂贵,中小团队难以承受
- 强依赖 AWS/GCP 云环境,私有化部署复杂
- 对国内大数据生态(Hive/Flink on YARN)的支持不如原生支持好
字节跳动 Feature Platform
背景与规模
字节跳动的特征平台(内部代号 ByteFeature 或 Feature Platform)是为了支撑抖音、今日头条、西瓜视频等超大规模推荐系统而建设的,特征数量在百万级,每天特征查询请求在百亿次以上。这个规模远超 Feast/Tecton 的设计目标,需要大量定制化设计。
统一特征 DSL
字节特征平台的核心是一套自研的特征定义 DSL,用声明式的方式描述特征的计算逻辑,平台负责将 DSL 翻译为具体的计算代码。
# 字节特征 DSL 示例(概念性,非真实语法)
feature_group:
name: user_engagement_features
entity: user_id
features:
- name: video_watch_cnt_1h
type: INT64
description: 用户近1小时观看视频次数
source:
type: kafka_stream
topic: video_watch_events
filter: "event_type = 'watch_complete'"
window:
type: sliding
size: 1h
slide: 1m
aggregation: count
- name: video_watch_cnt_7d
type: INT64
description: 用户近7天观看视频次数
source:
type: hive_table
table: dwd.video_watch_events
partition: dt
window:
type: fixed
size: 7d
aggregation: count
平台自动将上述 DSL 翻译为:
video_watch_cnt_1h:Flink 流处理作业,消费 Kafka,维护滑动窗口计数,写入 Redisvideo_watch_cnt_7d:Spark 批处理作业,读取 Hive 表,每天重新计算,写入 HBase
两个特征的定义方式完全一致,只是窗口类型和数据源不同,平台自动选择合适的执行引擎。
架构亮点
超大规模在线查询优化:字节的推荐系统每次请求需要查询数百个特征,涉及多个存储(Redis、HBase、本地缓存)。特征平台通过特征批量查询(一次 RPC 查多个特征)、多级缓存(本地内存缓存 + Redis)、异步预取(提前加载预测下一次会用到的特征)将特征查询延迟控制在 5ms 以内。
特征血缘与影响分析:百万级特征之间存在复杂的依赖关系(特征 A 依赖特征 B 的计算结果)。平台维护完整的特征血缘图,当上游数据发生变化时,自动分析受影响的下游特征和模型,触发必要的重新计算。
特征质量监控:自动监控每个特征的缺失率、分布(均值、方差、分位数),与历史基线对比,超出阈值自动告警。特征质量问题是推荐系统效果下降的常见原因,早发现早处理。
在线学习特征:字节的推荐系统支持分钟级的模型更新(在线学习),需要特征平台提供秒级延迟的实时特征。Flink 流处理 + Redis 的组合支持秒级特征更新,满足在线学习的需求。
阿里 FeatureStore
背景与定位
阿里巴巴的 FeatureStore 是 PAI(Platform for AI)机器学习平台的核心组件,面向阿里内部的电商推荐、搜索广告、金融风控等场景。阿里 FeatureStore 的特点是与阿里云大数据生态深度集成(MaxCompute/Hologres/Flink),并对外以阿里云产品形式提供服务。
核心设计
特征视图(Feature View)与特征实体(Feature Entity):与 Feast 类似,阿里 FeatureStore 也以 Feature View + Entity 为核心抽象,但在此基础上增加了特征版本管理(同一特征的多个版本并存,用于 AB 测试)和特征权限管理(不同业务线的特征隔离)。
Hologres 作为在线存储:阿里 FeatureStore 使用 Hologres(阿里云的实时数仓,兼容 PostgreSQL 协议)作为在线特征存储,而非 Redis。Hologres 支持行列混存,对宽表(数百列特征)的查询比 Redis Hash 更高效,且支持 SQL 查询,便于特征调试。
MaxCompute + Flink 批流统一:离线特征用 MaxCompute(阿里云的大数据计算服务,类似 Hive)计算,实时特征用 Flink 计算,两者通过统一的特征定义 DSL 管理,保证语义一致。
# 阿里 FeatureStore Python SDK 示例(概念性)
from feature_store import FeatureStoreClient, FeatureView, Entity
client = FeatureStoreClient(project="my_project")
# 定义特征视图
fv = FeatureView(
name="user_purchase_features",
entity_names=["user_id"],
features=["buy_cnt_7d", "total_amount_30d", "last_buy_category"],
ttl=7 * 24 * 3600, # 7天有效期
)
# 在线查询(推理时调用)
result = client.get_online_features(
feature_view="user_purchase_features",
entity_values={"user_id": ["1001", "1002", "1003"]},
features=["buy_cnt_7d", "total_amount_30d"],
)
# 离线查询(训练时调用,支持 Point-in-Time)
training_data = client.get_offline_features(
feature_view="user_purchase_features",
entity_df=entity_df, # 包含 user_id 和 event_timestamp 的 DataFrame
features=["buy_cnt_7d", "total_amount_30d"],
)
阿里 FeatureStore 的特色
特征市场(Feature Market):阿里内部建立了特征共享市场,各业务团队将高质量特征发布到市场,其他团队可以搜索和订阅使用。这解决了大型组织中特征重复建设的问题,据称阿里内部特征复用率超过 60%。
自动特征工程(AutoFE):基于历史数据自动发现有预测价值的特征组合(特征交叉、特征变换),减少人工特征工程的工作量。AutoFE 生成的候选特征经过 IV 值筛选后自动加入特征库。
特征漂移自动检测:自动监控特征分布变化(PSI 检验),当特征分布偏移超过阈值时,自动触发告警和模型再训练流程。
四平台横向对比
核心能力对比
- 批流统一计算:Tecton ✓(核心卖点)、字节 ✓(自研 DSL)、阿里 ✓(MaxCompute+Flink)、Feast ✗(只管存储,不管计算)
- Point-in-Time 正确性:Feast ✓(核心功能)、Tecton ✓、阿里 ✓、字节 ✓
- 在线低延迟查询:字节 ✓✓(百亿次/天,<5ms)、阿里 ✓(Hologres 毫秒级)、Feast ✓(Redis 后端)、Tecton ✓
- 特征复用与共享:阿里 ✓✓(特征市场)、字节 ✓(特征注册表)、Tecton ✓、Feast ✓(基础)
- 开源可自托管:Feast ✓✓、其余均为商业/内部系统
- 国内大数据生态支持:阿里 ✓✓(MaxCompute/Hologres 原生)、字节 ✓✓(Hive/Flink 原生)、Feast ✓(需配置)、Tecton ✗(偏 AWS/GCP)
选型建议
- 初创公司 / 中小团队:从 Feast 开始。开源免费,社区活跃,能解决特征注册和 Point-in-Time 的核心问题。先用 Feast 管理特征元数据,自己用 Spark/Flink 计算特征,等规模大了再考虑升级。
- 已上阿里云的团队:优先考虑阿里 FeatureStore(PAI 平台的一部分),与 MaxCompute/Flink/Hologres 无缝集成,减少集成工作量。
- 英文环境 / 海外业务 / 预算充足:Tecton 是功能最完整的方案,批流统一能力最强,但价格昂贵。
- 超大规模推荐系统(DAU 亿级):Feast/Tecton 的设计目标都不是这个量级,需要参考字节/阿里的思路自研,或在 Feast 基础上大量定制。
自建特征平台的核心模块
如果决定自建,最小可行的特征平台需要以下模块:
- 特征注册表:存储特征定义(名称、类型、来源、计算逻辑、所有者),提供搜索和浏览界面。用 MySQL + 简单的 Web UI 即可起步。
- 离线特征存储:Hive/HDFS,存储历史特征数据,支持 Point-in-Time 查询(通过 Spark 的 ASOF JOIN 实现)。
- 在线特征存储:Redis(实时特征)+ HBase(批量特征),提供统一的查询 SDK,屏蔽底层存储差异。
- 特征物化管道:定时将离线特征同步到在线存储(Spark 批量写 HBase),实时特征用 Flink 直接写 Redis。
- 特征质量监控:监控缺失率、分布漂移,超阈值告警。
不要一开始就追求"完美的特征平台",先解决最痛的问题(Training-Serving Skew 和特征复用),再逐步完善。
总结
特征平台的本质是将特征工程从各个模型项目中抽离出来,变成可共享、可管理、可信赖的基础设施。四个平台的设计哲学有所不同:
- Feast:极简主义,只做特征注册和服务,不涉及计算,最灵活也最需要自己补全
- Tecton:全栈方案,批流统一是核心,功能最完整,适合有预算的团队
- 字节 Feature Platform:极致性能导向,为超大规模推荐系统定制,百亿次/天查询是设计目标
- 阿里 FeatureStore:生态集成导向,与阿里云大数据体系深度融合,特征市场促进组织内复用
对于大多数团队而言,特征平台的建设是一个渐进过程:先用 Feast 解决特征注册和 Point-in-Time 问题,再根据实际痛点(批流统一、超大规模查询、自动化监控)逐步增强。不要为了建平台而建平台——特征平台的价值在于减少重复工作、提升模型质量,如果团队只有 2-3 个模型,一个 Excel 表格管理特征元数据可能就够了。