ML Infrastructure
~25 мин

Feature Store

Online/offline features, Feast, Tecton — централизованное управление фичами.

Feature Store — одна фича считается один раз, используется везде

Загрузка интерактивного виджета...

В компании 5 ML-команд. Каждая считает «средний чек пользователя» по-своему: разные SQL, разные окна, разные фильтры. Результат — разные числа для одного и того же. Feature Store решает эту проблему: фича определяется один раз, хранится в одном месте, используется всеми моделями. Плюс решает ещё одну боль — training-serving skew, когда на обучении фичи считаются одним способом, а на inference — другим.

Зачем это нужно

  • Переиспользование — фичи считаются один раз. Новая модель? Бери готовые фичи из каталога, не пиши SQL заново
  • Нет training-serving skew — на обучении и на inference фичи считаются одинаково. Одно определение → одинаковый результат
  • Point-in-time correctness — при обучении получаешь фичи на момент события, а не текущие (нет data leakage)
  • Online serving — фичи с латентностью < 10 мс для real-time inference. Бэкенд не ждёт SQL-запрос
  • Каталог — все фичи с описаниями, владельцами, статистикой. Новый человек в команде видит, что доступно

Offline vs Online Store

Feature Store состоит из двух хранилищ. Offline store — для обучения. Хранит исторические значения фичей по датам. Можно спросить: «какие фичи были у пользователя 15 января?» Лежит в BigQuery, S3, Hive. Online store — для inference. Хранит ПОСЛЕДНЕЕ значение каждой фичи. Отвечает за < 10 мс. Лежит в Redis или DynamoDB.

Feast — open-source Feature Store

Feast — самый популярный open-source Feature Store. Определяешь фичи в Python-коде, Feast берёт на себя хранение, версионирование и подачу.

# feature_repo/features.py — определяем фичи
from feast import Entity, FeatureView, Field, FileSource
from feast.types import Float32, Int64
from datetime import timedelta

# Откуда берём данные
user_stats_source = FileSource(
    path="s3://feature-store/user_stats.parquet",
    timestamp_field="event_timestamp",
)

# Сущность — к чему привязаны фичи (к пользователю)
user = Entity(name="user_id", join_keys=["user_id"])

# Feature View — набор фичей
user_features = FeatureView(
    name="user_features",
    entities=[user],
    ttl=timedelta(days=1),  # время жизни в online store
    schema=[
        Field(name="total_orders_30d", dtype=Int64),
        Field(name="total_revenue_30d", dtype=Float32),
        Field(name="avg_order_value", dtype=Float32),
        Field(name="days_since_last_order", dtype=Int64),
    ],
    source=user_stats_source,
    online=True,  # материализовать в online store (Redis)
)
from feast import FeatureStore
import pandas as pd

store = FeatureStore(repo_path="feature_repo/")

# === Для обучения: получить фичи на конкретные даты ===
entity_df = pd.DataFrame({
    "user_id": [1, 2, 3],
    "event_timestamp": pd.to_datetime(["2024-01-15", "2024-01-15", "2024-01-15"]),
})

training_data = store.get_historical_features(
    entity_df=entity_df,
    features=[
        "user_features:total_orders_30d",
        "user_features:total_revenue_30d",
        "user_features:avg_order_value",
    ],
).to_df()
# Point-in-time correct! Для даты 2024-01-15 берёт фичи ДО этой даты — нет leakage

# === Для inference: получить ПОСЛЕДНИЕ фичи за < 10 мс ===
online_features = store.get_online_features(
    features=["user_features:total_orders_30d", "user_features:total_revenue_30d"],
    entity_rows=[{"user_id": 12345}],
).to_dict()
# Повседневные команды Feast
feast apply              # создать/обновить feature views
feast materialize-incremental (date +%Y-%m-%dT%H:%M:%S)  # offline → online
feast ui                 # веб-каталог фичей

Training-Serving Skew — главная ловушка

Training-serving skew — когда фичи на обучении и на inference считаются по-разному. Типичный сценарий: на обучении avg_order_value считался PySpark-ом по полной истории заказов, а на inference — Python-скриптом по кешу за последние 7 дней. Числа разные → модель работает хуже на проде. Feature Store решает это: одно определение фичи → одинаковый результат и offline, и online.

⚠️ Point-in-time correctness

При создании обучающей выборки используй данные ТОЛЬКО до момента предсказания. Если считаешь avg_order_value за весь период (включая будущие заказы) — это data leakage: модель на обучении «подглядывает» в будущее. Feast и другие Feature Store обеспечивают point-in-time join автоматически.

Альтернативы и варианты

  • Feast — open-source, self-hosted. Хороший старт. Поддерживает AWS, GCP, local
  • Tecton — enterprise-платформа от создателей Feast. Managed, real-time, мониторинг
  • Vertex AI Feature Store (Google), SageMaker Feature Store (AWS) — managed решения, привязаны к облаку
  • Самописный: Redis (online) + BigQuery (offline) + Python-код. Для простых случаев хватает

💡 Как это в реальной работе

Новая модель рекомендаций? Открываешь каталог фичей в Feast UI — уже есть total_orders_30d, avg_order_value, days_since_last_order. Берёшь готовые, добавляешь свои. На inference фичи подаются из Redis за 5 мс. На обучении — из S3 с point-in-time join. Одно определение фичи — нет расхождений.

🎯 На собесе

Зачем Feature Store? 1) Одно определение фичи — нет дублирования кода. 2) Нет training-serving skew — одинаковые фичи offline и online. 3) Point-in-time correctness — нет data leakage при обучении. 4) Online store для real-time inference (< 10 мс). 5) Каталог фичей для всей компании.