想象你是社区食堂的主厨,每天要给几百号人做饭。一开始,你每天亲自去菜市场挑菜、洗菜、切菜,忙得不可开交。后来食堂大了,你雇了专门的人负责买菜、洗菜,还建了一个中央食材库:所有食材统一登记、按标准分装,早餐窗口随取随用,晚餐窗口提前一天整批备料。从此,每个窗口出品的口味终于一致了,不用再担心“早上放盐,晚上忘放盐”。 在机器学习的世界里,特征就是模型的“食材”。数据科学家花大量时间做特征工程——清洗、变换、组合,产出一堆特征。但没有“中央食材库”时,训练用的特征是一套代码算的,线上推理用的又是另一套代码算的,两边很容易对不上,模型上线就“翻车”。Feast(Feature Store 的轻量级开源代表)就是这样一个中央食材库:它提供特征注册、离线批量读取、在线低延迟服务,让“训练和上线吃的是同一批食材”。

岗位关联

对 AI 从业者的价值:掌握 Feast,等于学会了用工程化手段根治“训练-服务特征不一致”这一顽疾,是特征平台方向的入门必修课,能显著提升特征管理与复用效率。

目录
  1. 可视化演示
  2. 特征平台定位
  3. 特征注册中心
  4. 离线批量读取
  5. 在线低延迟服务
  6. 多源存储扩展
  7. SDK与版本管理
  8. 训练服务一致性
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态展示Feast特征平台的核心架构:特征注册、离线批量读取与在线低延迟服务,以及训练服务特征一致性保障机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Feast特征平台 数据源 离线训练 在线服务 Train-Serve Consistency 注册→推送→一致性保障

特征平台定位

回到社区食堂的比喻。最开始,每个厨师自己记菜谱、自己备料,结果同一道“鱼香肉丝”,有的窗口偏甜、有的偏咸、有的甚至忘了放木耳。食客投诉多了,食堂才决定建中央食材库:统一采购、统一加工、统一分发。特征平台就是机器学习团队的那间“中央食材库”——在模型训练和线上推理之间,架起一座标准化的特征供给桥梁。

在没有特征平台的日子里,算法工程师通常把特征工程代码散落在训练脚本和在线服务里。训练时写一个 compute_features.py 离线跑批,上线时又用 Java 或 C++ 重写一遍同样的逻辑。两套代码、两批数据、两次实现,时间一长必然走样。这就是行业的“特征管理痛点”:特征没有统一户口,没有版本,没有清晰的上下游依赖。

Feast 正是为解决这些痛点而生的开源特征平台。它把自己定位为“轻量级”方案——不需要你重写整个数据架构,而是作为一个中间层,把你已有的数据源(如 Kafka、BigQuery、GCS)和特征存储连接起来。它提供三件事:注册(给特征上户口)、离线批量读取(整批出货给训练)、在线低延迟服务(即时出货给线上推理)。

有了这三块,团队内部不再各自为政。特征像食材一样进入中央库,按标准加工,按需分发——这就是特征平台的立身之本。

特征平台价值=注册⏟可发现+离线条取⏟可训练+在线服务⏟可推理\text{特征平台价值} = \underbrace{\text{注册}}_{可发现} + \underbrace{\text{离线条取}}_{可训练} + \underbrace{\text{在线服务}}_{可推理}
这个公式把特征平台拆成三块能力。注册解决“找不到”问题,离线条取解决“喂给训练”问题,在线服务解决“推理时快速拿”问题。
  1. 注册项把特征名、类型、数据来源登记到统一目录中,让每个特征有唯一身份。
    注册:  f↦(name,type,source)\text{注册}:\; f \mapsto (\text{name}, \text{type}, \text{source})
  2. 离线条取项训练任务一次性读取大范围历史特征,构建训练数据集。
    离线条取:  Dtrain={(xifeat,yi)}i=1n\text{离线条取}:\; \mathcal{D}_{\text{train}} = \{(x_i^{\text{feat}}, y_i)\}_{i=1}^{n}
  3. 在线服务项线上推理前,用主键实时获取最新特征值,毫秒级返回。
    在线服务:  latency<100 ms\text{在线服务}:\; \text{latency} < 100\,\text{ms}

特征注册中心

中央食材库的第一步,不是开火做饭,而是给每样食材建档案。土豆是哪个农场来的?保质期多久?适合炖还是炒?这些信息记在台账上,厨师才知道去哪领、怎么用。Feast 里同样有一本台账,叫特征注册中心(Feature Registry)。

注册中心保存的是特征的“元数据”——元数据就是“关于数据的数据”。比如特征 user_age 的元数据包括:它的类型是 int64、来源是用户资料表、更新频率是每天一次、责任人是谁。有了这些信息,新同事可以通过查询注册中心快速发现团队已有特征,而不是重新造一个 user_age_2 出来。

在 Feast 中,注册通过 Python SDK 完成:你先定义一个 FeatureView,声明它的数据源和特征列,然后调用 apply() 把它提交到注册中心。这个过程相当于“给特征上户口”。注册完成后,任何训练任务或在线服务都能通过 SDK 查询到这个特征是否存在、怎么取、从哪取。

注册中心的意义,在于让特征从“一次性脚本产物”升级为“可复用的组织资产”。就像食堂台账让食材不再依赖某一位厨师的个人记忆,特征的户口让团队协作变成可能。

FeatureView=(entities⏟主键,features⏟特征列,source⏟数据源)\text{FeatureView} = ( \underbrace{\text{entities}}_{\text{主键}}, \underbrace{\text{features}}_{\text{特征列}}, \underbrace{\text{source}}_{\text{数据源}} )
FeatureView 是 Feast 的核心抽象。entities 类似食材分类(猪肉/蔬菜),features 是具体特征(肥瘦/新鲜度),source 是食材产地。
  1. entities 主键每个特征都必须挂在一个业务实体下,如用户、商品。查询特征时,用实体 ID 定位到具体某一行。
    entities:  {user_id,  item_id,  … }\text{entities}:\; \{ \text{user\_id},\; \text{item\_id},\; \dots \}
  2. features 特征列实际参与模型计算的特征值列,如“近 30 天消费金额”。
    features:  {age,  spend_30,  city}\text{features}:\; \{ \text{age},\; \text{spend\_30},\; \text{city} \}
  3. source 数据源特征原始出处,可以是一张表、一个流或一个文件。
    source:  Pandas / BigQuery / Kafka\text{source}:\; \text{Pandas / BigQuery / Kafka}

离线批量读取

食堂每天早餐窗口要提前一晚备好几百份粥:整锅煮、批量分装、第二天直接卖。训练模型也是类似场景——你要准备成千上万个样本,每个样本带一批特征,一次性喂给模型学习。Feast 把这个过程称为离线批量读取(get historical features)。

离线批量读取面向的是“海量、离线、宽表”场景。Feast 会把特征仓库中的历史特征,按实体 ID 和事件时间对齐,拼接成一张大宽表,供训练使用。比如你要训练一个“用户流失预警”模型,需要过去 90 天的用户行为特征,Feast 可以一次性读回并组装好。

这个过程中,时间窗口过滤是灵魂。特征必须按“事件发生时刻”取值,而不是按“今天”取值,否则就引入了未来信息(称为 label leakage)。Feast 在离线读取时严格遵循 event_timestamp,保证每个样本看到的特征都是“当时已发生”的。

离线批量读取解决了“训练时特征从哪来”的问题。它让数据科学家不必每次重写 SQL 拼表,而是通过统一接口拿到标准化的宽表——相当于食堂每天都按统一菜谱准备半成品,不用厨师自己临时琢磨。

Dtrain=⋃u∈U{feat(u,t)∣t∈[t0−Δ,t0]}\mathcal{D}_{\text{train}} = \bigcup_{u \in U} \left\{ \text{feat}(u, t) \mid t \in [t_0 - \Delta, t_0] \right\}
式子表示:对每个用户 u,取其从过去 Δ 天到当前时刻 t₀ 的特征快照,组成训练集。这确保训练时没有“偷看未来”。
  1. 用户集合 U对每个要建模的用户执行相同逻辑。
    ∀u∈U\forall u \in U
  2. 特征函数 feat按用户和时间戳取特征值,时间是取值的关键维度。
    feat(u,t)\text{feat}(u, t)
  3. 时间区间只取过去 Δ 天到当前时刻的数据,避免泄漏。
    t∈[t0−Δ,t0]t \in [t_0 - \Delta, t_0]

在线低延迟服务

到了饭点,窗口前排队的人可等不了你慢火炖汤。在线服务的场景恰恰相反:请求来了,几十毫秒内必须返回特征。比如推荐系统,用户点开 App 的瞬间,服务端就要拿出“该用户最近浏览了什么、当前商品是什么”等特征,喂给模型打分。

Feast 的在线服务能力依赖在线存储——一种专门为低延迟随机读取优化的存储介质,如 Redis、DynamoDB。这里和离线存储不同:离线存储要承受大吞吐扫描,在线存储要承受高频主键查询。Feast 在后台会把注册过的特征同步一份到在线存储,服务时直接按主键 get_online_features 获取。

为什么不能直接用离线存储回答在线请求?想象食堂里,你要的是一份菜,结果后厨告诉你“得把整锅粥都端出来才能找到你那勺”。离线存储是整锅粥,在线存储是分装好的小碗,后者才能即取即走。

在线低延迟服务让“线上推理时特征随取随到”成为可能。特征平台在这里扮演“分装小碗”的角色,把中央库里的特征预处理成即取即用的形态,供线上服务快速取用。

latencyonline=O(1)≪latencyoffline=O(N)\text{latency}_{\text{online}} = O(1) \quad \ll \quad \text{latency}_{\text{offline}} = O(N)
在线查询按主键索引直达单条记录,复杂度 O(1)(常数级);离线查询要扫描大量数据,复杂度 O(N)(随数据量增长)。
  1. O(1) 表示不管特征有多少条,按主键查单条的速度恒定,适合高并发。
    O(1)O(1)
  2. O(N) 表示离线全表扫描耗时随数据总量线性增长,不能用于线上实时路径。
    O(N)O(N)

多源存储扩展

社区食堂的食材不可能只从一个农场进货:蔬菜从郊区农场来,肉类从屠宰场来,海鲜从码头来。Feast 也坚持“数据源不设限”——它不把数据强行搬进自己的封闭系统,而是通过插件化的适配层,对接你已有的数据基础设施。

Feast 中有两个容易混淆的概念:data source(数据源)和 offline store / online store(离线/在线存储后端)。数据源是特征的原始出处,比如 Kafka 流、BigQuery 表;存储后端是 Feast 实际读取和写入特征的地方,比如用 BigQuery 做离线存储,用 Redis 做在线存储。你可以自由组合:数据源是 A,离线存储是 B,在线存储是 C。

这种“插件化”设计让 Feast 成为一个轻量中间层,而不是重型数据平台。你的团队可以保留原有大数据栈,只把特征管理这一层交给 Feast。它像一个“万能插座”,适配各类接口,而不是要求你换掉家里所有电器。

多源存储扩展让 Feast 能融入任意技术栈。这正是它“轻量”的底气:不绑架你的存储选型,而是做特征层的统一管理者。

Feast→适配层{Kafka,  Kinesis,  GCS,  BigQuery,  Redis,  … }\text{Feast} \xrightarrow{\text{适配层}} \{ \text{Kafka},\; \text{Kinesis},\; \text{GCS},\; \text{BigQuery},\; \text{Redis},\; \dots \}
适配层把 Feast 的核心逻辑与具体存储解耦:换一个存储,只需更换对应插件,不动业务代码。
  1. Feast 本身提供统一注册、统一读取 API,对外保持稳定接口。
    统一API\text{统一API}
  2. 适配层每种数据源实现一个适配器,完成格式转换和连接管理。
    适配器:数据源↦内部抽象\text{适配器}: \text{数据源} \mapsto \text{内部抽象}
  3. 各类后端适配目标可无限扩展,新增后端只需新写一个插件。
    Kafka,Redis,BigQuery∈支持列表\text{Kafka}, \text{Redis}, \text{BigQuery} \in \text{支持列表}

SDK与版本管理

食堂的菜谱如果只写在某位厨师脑子里,他一离职,招牌菜就消失了。于是食堂把菜谱写成文件、放进文件柜,还标了版本号:v1 是初版,v2 改良了火候,v3 换了供应商。代码化 + 版本化,才能长期演进。Feast 的设计哲学同样是“定义即代码”。

一切特征定义都通过 Python SDK 描述,存放在一个 git 仓库中。团队成员修改特征定义时,走的是普通代码评审流程:提 PR、讨论、合并、打 tag。Feast 拿到仓库中的定义文件后,执行 feast apply 将变更同步到注册中心和存储中。这带来两个好处:可追溯(谁在什么时候改了什么看得一清二楚)和可回滚(新特征有问题,直接回退到上一个稳定版本)。

想象你把菜谱存进 git,哪天新配方翻车了,git checkout 切回旧版本,明天照常营业。这就是版本管理的价值——它让试错变得便宜,让特征演进变得安全。没有版本管理,特征改动就像厨师随手改配方,谁也不敢保证明天的菜还是昨天的味道。

“定义即代码 + 版本管理”是 Feast 工程化气质的集中体现。它把特征当作需要敬畏的一等公民来对待,而不是随手一写的脚本变量。

version(f)=git commit hash⟹f 的完整历史可复现\text{version}(f) = \text{git commit hash} \Longrightarrow f \text{ 的完整历史可复现}
特征的每个版本对应一个 git 提交哈希。只要记住哈希,就能复现出当时线上用的那批特征。
  1. version(f)给特征 f 标注版本号,作为其身份的一部分。
    version(f)\text{version}(f)
  2. git commit hash用代码仓库的提交标识作为唯一版本 ID,天然关联代码变更。
    hasht\text{hash}_{t}
  3. 可复现性任意历史时刻的特征定义都能重新加载,团队协作不混乱。
    ∀t,  ∃定义t\forall t,\; \exists \text{定义}_t

训练服务一致性

最后也是最重要的一道关:训练和服务必须用同一批特征。食堂最怕的事,是培训新厨师时用一套菜谱,实际营业时又按另一套做——客人会发现“试吃的时候很好吃,上桌的菜却变了味”。机器学习把这叫作 training-serving skew(训练-服务特征偏差)。

偏差的根源常见于:离线训练时特征由 Python 脚本计算,在线服务时特征由 Java 服务计算,两边逻辑稍有不一致,模型上线后效果就断崖式下跌。Feast 的解法很直接:只维护一份特征定义,离线读和在线读都从同一个注册中心出发、取同一个存储后端的数据。特征只生产一次,被两条管道消费。

业界有句谚语:Don't train on features you can't serve.——不要用你没法上线的特征来训练。Feast 通过“单一特征仓库”确保这个原则落地。训练时用 get_historical_features,服务时用 get_online_features,底层是同一份元数据和同一套计算逻辑。这不是魔法,而是工程纪律的产物。

作为轻量级特征平台的代表,Feast 用“一份定义、双路读取”的思路,把最棘手的训练-服务一致性问题消解在架构层面。对于从零搭建 ML 系统的团队而言,这份工程化的“中央厨房”理念,远比堆砌算法技巧更重要。

若  Feattrain≡Featserve,则  模型效果上线≈模型效果实验\text{若}\; \text{Feat}_{\text{train}} \equiv \text{Feat}_{\text{serve}}, \quad \text{则}\; \text{模型效果}_{\text{上线}} \approx \text{模型效果}_{\text{实验}}
如果训练和服务的特征在语义、取值、时序上完全一致,模型上线后的表现就能逼近离线实验效果,不会“翻车”。
  1. Feat_train训练时喂给模型的特征矩阵,由离线批量读取产生。
    Feattrain\text{Feat}_{\text{train}}
  2. Feat_serve线上推理时的特征向量,由在线低延迟服务产生。
    Featserve\text{Feat}_{\text{serve}}
  3. 等价符号要求二者在分布和语义上等价,是模型稳定性的前提。
    ≡\equiv
  4. 结果近似离线与在线效果近似,业务指标才有可预期性。
    ≈\approx

AI 应用场景

实时推荐系统的特征统一

阶段:特征工程与特征平台建设

解决的问题:推荐系统训练时使用 T+1 离线特征,在线推理时却要用实时特征,两边特征口径经常不一致。传统做法是离线一套 Python 脚本、在线一套 Java 服务,双倍维护成本且极易产生偏差。

具体案例:某电商平台的“猜你喜欢”场景,用户特征(近期点击、品类偏好)先通过 Flink 写入 Kafka,Feast 将 Kafka 注册为数据源,同步到离线存储(BigQuery)用于每日训练,同步到在线存储(Redis)用于实时推理。训练和服务共用同一 FeatureView 定义,上线后 CTR 预估 AUC 提升约 4%,且模型回滚率明显下降。

风控模型的秒级特征服务

阶段:在线推理阶段

解决的问题:反欺诈模型需要在用户点击的几十毫秒内返回风险评分,特征获取延迟是硬指标。传统方式是每次请求实时查多张业务表,SQL 复杂且延迟不稳定。

具体案例:某金融科技公司用 Feast 管理设备指纹、IP 风险分、历史交易统计等特征。特征预先把最新值写进在线存储,风控服务通过 get_online_features 按 user_id 批量取 20 个特征,P99 延迟稳定在 30ms 以内,满足风控决策时限。

Python 演示

python63 行
# 模拟 Feast SDK 核心流程的最小演示# 真实 Feast 需 pip install feast,并用 feast init 创建仓库class FeatureStore:    def __init__(self):        self.registry = {}        self.offline_store = {}        self.online_store = {}     def apply(self, feature_view):        name = feature_view["name"]        self.registry[name] = feature_view        print("[registry] 特征登记:", name)     def get_historical_features(self, entity_df, feature_names):        print("[offline] 为训练批量组装特征:", feature_names)        result = []        for _, row in entity_df.iterrows():            item = {"entity_id": row["entity_id"]}            for f in feature_names:                item[f] = self.offline_store.get(f, 0)            result.append(item)        return result     def get_online_features(self, entity_id, feature_names):        print("[online] 低延迟返回特征, entity =", entity_id)        return {f: self.online_store.get(f, 0) for f in feature_names}     def materialize(self, feature_name, value):        self.offline_store[feature_name] = value        self.online_store[feature_name] = value        print("[materialize] 特征已同步到离线+在线:", feature_name)  def main():    store = FeatureStore()     store.apply({        "name": "user_age",        "entities": ["user_id"],        "source": "user_profile_table",    })    store.apply({        "name": "spend_30d",        "entities": ["user_id"],        "source": "order_events",    })     store.materialize("user_age", 28)    store.materialize("spend_30d", 3560)     import pandas as pd    entity_df = pd.DataFrame({"entity_id": [1001, 1002]})    train_df = store.get_historical_features(        entity_df, ["user_age", "spend_30d"]    )    print("训练样本:", train_df)     online_feat = store.get_online_features(1001, ["user_age"])    print("在线特征:", online_feat)  if __name__ == "__main__":    main()
目的:用最简代码模拟 Feast 的 apply(注册)、materialize(特征物化)、get_historical_features(离线批量读取)和 get_online_features(在线获取)四个核心 API,帮助理解特征平台的工作流。
  1. store.apply({...})提交特征定义到注册中心,相当于给特征上户口。
  2. store.materialize("user_age", 28)把特征值写入离线和在线两个存储,让两边的数据保持一致。
  3. entity_df = pd.DataFrame(...)构造训练样本的实体 ID 列表,Feast 会按它逐行拼接特征。
  4. store.get_historical_features(entity_df, ...)离线批量读取,供训练任务使用。
  5. store.get_online_features(1001, ["user_age"])在线单实体快速获取特征,供推理服务使用。

常见误区

误区我以为 Feast 就是一个专门存特征的数据库,把特征往里一塞,训练和线上直接查就行。

正解Feast 更像“中央厨房”而非“冰箱”。它确实借助存储(Redis/BigQuery)保存特征,但核心价值在管理:注册、版本、血缘、双路读取一致性。冰箱只解决“放哪”的问题,厨房解决“怎么管、怎么给到两个窗口”的问题。只把它当数据库用,等于买回一台冰箱却雇了整套后厨团队。

为何常见:因为资料里大量出现 offline store / online store 这些存储词,容易让人先入为主地把平台等同于存储。

误区我听说特征平台能在线服务,以为它像 Flink 一样在毫秒级做流式计算,数据一到就能实时产出特征。

正解Feast 本身不负责流式计算,它负责“管”和“取”。实时特征通常还是由 Flink/Kafka Streams 算出,再写入 Feast 的在线存储;Feast 保证的是线上能以低延迟取到这些已经算好的特征。它更像分装小碗的配餐台,而不是灶台——菜是后厨(计算引擎)做的,配餐台负责让出菜更快。

为何常见:在线低延迟服务让初学者误以为平台内建了实时计算能力,混淆了“计算层”和“服务层”。

误区我觉得只要用定时任务把离线特征表灌进 Redis,让线上能查到,就等于解决了训练-服务一致性。

正解复制数据只是消除了“存储上的不一致”,但没解决“定义上的不一致”。如果训练时读的列叫 spend_30d,线上服务因代码 bug 读成了 spend_30d_total,复制再多遍也是错的。Feast 的一致性在于单一 FeatureView 定义:训练和服务用同一个名字、同一份元数据解析,从源头杜绝“同名不同义”。复制数据相当于把同样的食材送到两个厨房,但菜谱不同,菜还是不一样。

为何常见:看到一致性第一反应是“数据要一样”,而忽略了一致性的根源在“定义和逻辑要一样”。

误区Feast 能管理特征又能离线读取,那数据仓库是不是可以拆掉了?

正解Feast 的离线存储后端往往就是数据仓库(如 BigQuery、Snowflake)。它不替代数仓,而是建立在数仓之上的管理面。数据湖和数仓负责存全量数据,Feast 负责把其中加工好的特征以可复用的方式暴露出来。就像中央厨房虽然有自己的小仓库,但大宗食材还是要靠供应链体系送货上门,厨房不会自己养猪。

为何常见:因为 Feast 文档里有"offline store"字样,让人误以为它要连存储一起包办。

误区很多特征就是一条 SQL 的事,训练时 join 一下表就行了,何必再引入一个平台增加复杂度?

正解单个特征确实一条 SQL 足够,但生产环境是几十个特征、多个版本、多团队协作。直接 SQL 会让每个脚本都有自己的“私有特征定义”,版本混乱、无法复用、无人维护。Feast 把特征变成组织级资产:别人能搜到、能复用、能追溯变更。好比做菜确实可以自己买菜自己做,但一旦要开连锁饭店,没有中央厨房,每家店味道必然走样。

为何常见:小团队时期数据量小、特征少,感受不到管理的必要性,误把平台的复杂度当成绝对的复杂度。

面试题

Q1. Feast 最核心要解决的工程难题是什么?

单选题 · easy

  • A.特征在训练与线上服务时的偏差← 正确答案
  • B.模型调参自动化的效率问题
  • C.数据采集管道的高吞吐传输
  • D.模型解释性欠缺的合规问题

答案:A。Feast 的核心定位是特征平台,首要解决训练-服务特征一致性偏差问题。它不负责调参、不负责采集传输、不负责解释性,那些是别的工具或流程的范畴。

Q2. Feast 中“给特征上户口”对应哪个能力?

单选题 · easy

  • A.离线批量读取
  • B.在线低延迟服务
  • C.特征注册中心← 正确答案
  • D.自动特征选择

答案:C。注册中心保存特征的元数据与定义,像给特征上了户口。离线读取、在线服务是注册之后的数据消费行为,特征选择则不是 Feast 的能力。

Q3. 训练任务需要一次性读回整批历史特征,应使用哪个 API?

单选题 · mid

  • A.get_historical_features← 正确答案
  • B.get_online_features
  • C.apply_features
  • D.materialize_features

答案:A。get_historical_features 是离线批量读取接口,适合训练场景。get_online_features 面向在线实时推理;apply 用于注册定义;materialize 用于把特征写入存储。

Q4. 在线低延迟服务中,Feast 通常将特征存放于哪种存储?

单选题 · mid

  • A.文本文件系统
  • B.数仓大宽表
  • C.在线键值存储← 正确答案
  • D.数据湖分区表

答案:C。在线服务需要按主键 O(1) 查单条特征,因此用 Redis、DynamoDB 这类键值存储。数仓、数据湖适合离线大扫描,文本文件系统既不支持索引也不适合高并发。

Q5. 下列哪些属于 Feast 的存储后端选型?

多选题 · mid

  • A.BigQuery 作为离线存储← 正确答案
  • B.Redis 作为在线存储← 正确答案
  • C.Kafka 作为在线存储
  • D.DynamoDB 作为在线存储← 正确答案

答案:ABD。Feast 支持 BigQuery 作为离线存储,支持 Redis、DynamoDB 等作为在线存储。Kafka 是消息流数据源,不是键值型在线存储后端,不能直接作为在线特征查询存储。

Q6. 特征定义存在 git 仓库并走代码评审,这体现了 Feast 的什么设计?

单选题 · mid

  • A.定义即代码与版本管理← 正确答案
  • B.数据源插件化扩展
  • C.在线离线存储分离
  • D.内存级特征计算加速

答案:A。把特征定义作为代码管理,利用 git 做评审、追溯和回滚,正是“定义即代码”的思想。插件化扩展说的是多数据源适配能力,与版本管理无关。

Q7. 训练-服务特征偏差的主要根源是什么?

单选题 · hard

  • A.训练与服务使用不同特征定义← 正确答案
  • B.模型网络层数配置不一致
  • C.训练数据量过大导致过拟合
  • D.线上请求并发过高产生限流

答案:A。偏差最常见的原因是离线训练和在线推理各写一套特征逻辑,导致口径不一。网络结构、数据量、并发限流都不属于特征层面的偏差问题。

Q8. Feast 给人的整体定位是哪一种?

单选题 · easy

  • A.轻量级开源特征平台← 正确答案
  • B.分布式深度学习框架
  • C.数据可视化报表工具
  • D.自动化机器学习平台

答案:A。Feast 官方定位是开源特征平台,提供注册、离线批量读取与在线服务。它不做模型训练、可视化或 AutoML。

Q9. 在 Feast 中,get_historical_features 与 get_online_features 的差异体现在哪些方面?

多选题 · hard

  • A.读取数据的存储介质不同← 正确答案
  • B.服务的业务场景不同← 正确答案
  • C.查询单条还是批量数据不同← 正确答案
  • D.特征定义逻辑完全不同

答案:ABC。两个接口一个走离线存储做批量扫描,一个走在线存储做单条主键查询,服务于训练与推理两类场景。但二者读取的是同一份特征定义,逻辑一致,故 D 错。

Q10. 下列哪个是 Feast 的一个典型应用场景?

单选题 · easy

  • A.统一管理推荐场景的用户画像特征← 正确答案
  • B.替代 Spark 做大规模数据清洗
  • C.替代 Flink 做实时流计算
  • D.替代 Grafana 做监控告警展示

答案:A。Feast 典型应用于把用户画像等特征统一注册、统一供给训练与在线推理。它不做数据清洗、流计算和监控展示,那些是其他系统的工作。