中文翻译暂不可用,显示俄语原文。
Как реализовать online/offline feature consistency для LLM?
Краткий тезис
feature feature Online/offline feature feature consistency — это критическая проблема MLOps, когда признаки (features), используемые при обучении модели (offline), отличаются от признаков, подаваемых на инференс (online). Для LLM (в том числе в архитектурах RAG|Agentic RAG) это ведёт к деградации качества ответов. Основные решения: point-in-time correct joins (batch scoring), использование feature store (например, Feast) и log-and-apply подход. Обязательны мониторинг распределений признаков (data drift) и периодическая валидация консистентности.
1. Проблема: почему возникает неконсистентность
Признаки для обучения LLM-моделей (или для retrieval/ранжирования в RAG-агентах) часто вычисляются из исторических логов с задержкой. В момент инференса (online) могут использоваться те же признаки, но вычисленные «на лету» — из-за разных источников данных, времени среза или логики вычисления расхождения неизбежны.
Пример расхождения
- Offline: «средний рейтинг товара за последние 7 дней» считается из таблицы с данными на вчерашний вечер.
- Online: тот же признак считается из live-стрима с учётом сегодняшних оценок.
- Результат: модель обучена на одних значениях, а видит совсем другие → падение accuracy / faithfulness.
Термин Feature consistency (консистентность признаков) — мера того, насколько распределения и конкретные значения признаков в offline и online совпадают.
2. Термины: offline vs online признаки
| Тип | Источник | Хранение | Цель | Риск |
|---|---|---|---|---|
| Offline | Исторические данные (Parquet, HDFS) | Озёра данных, feature repo (аналитические) | Обучение модели, backtesting | «Застывшие» срезы — не учитывают новые данные |
| Online | Реал-тайм потоки (Kafka, API) | Feature store (Redis, DynamoDB) | Инференс в момент запроса | Могут отличаться логикой или задержкой |
Для LLM в Agentic RAG признаки могут включать: эмбеддинги запроса, историю диалога, контекстные сигналы (время суток, гео, профиль пользователя). Любое расхождение сдвигает распределение и снижает качество.
3. Решение 1: Batch scoring (Point-in-time correct join)
Идея при обучении эмулировать онлайн-срез данных. Для каждого обучающего примера «замораживается» время и берутся признаки, которые были известны системе ровно в этот момент (point-in-time).
Реализация
- Для каждого события (например, клик, запрос к LLM) записываем timestamp.
- При join с таблицами признаков используем условие
feature_timestamp <= event_timestampи берем последнее доступное значение (AS OFjoin). - При инференсе также используем признак, вычисленный на момент запроса.
# Пример с Pandas (упрощённо)
import pandas as pd
events = pd.DataFrame({'user_id': [1], 'event_time': [pd.Timestamp('2025-04-10 12:30:00')]})
features = pd.DataFrame({
'user_id': [1, 1],
'feature_time': [pd.Timestamp('2025-04-10 11:00:00'), pd.Timestamp('2025-04-10 13:00:00')],
'7day_avg_rating': [4.2, 4.5]
})
# Point-in-time join: берем последний признак до event_time
result = pd.merge_asof(
events.sort_values('event_time'),
features.sort_values('feature_time'),
by='user_id',
left_on='event_time',
right_on='feature_time',
direction='backward'
)
print(result) # получит 4.2 (до 12:30), а не 4.5 (после)
Плюсы единая логика, консистентность гарантируется математически.
Минусы требует хранения временных меток, сложные join’ы для больших данных.
4. Решение 2: Использование Feature Store (Feast, Tecton, Hopsworks)
Feature store — единый репозиторий признаков, который предоставляет один и тот же признак для обучения (offline) и для инференса (online) из общего источника.
Как работает
- Признаки определяются один раз (feature definition) — код вычисления, источник, агрегация.
- Offline serving — из исторического хранилища (Parquet, BigQuery) с поддержкой point-in-time.
- Online serving — из low-latency хранилища (Redis, DynamoDB), которое обновляется стримингом или batch-загрузкой.
Пример на Feast
# feature_view.yaml
name: user_stats
entities: [user_id]
features:
- name: avg_rating_7d
dtype: float
timestamp_column: event_timestamp
batch_source:
type: parquet
path: s3://bucket/features/*
online_source:
type: redis
host: redis-cluster
Плюсы прозрачная синхронизация, автоматическая проверка схемы.
Минусы дополнительная инфраструктура, latency при записи онлайн.
5. Решение 3: Log-and-apply
Идея во время инференса логировать все признаки, которые были использованы для ответа LLM. Затем эти же признаки подавать на обучение/дообучение (fine-tuning).
Шаги:
- При получении запроса от пользователя вычислить онлайн-признаки.
- Сохранить их вместе с запросом и ответом в лог (например, в Kafka → S3).
- В обучающем пайплайне читать эти логи как «золотой стандарт» признаков.
- Обучать модель ровно на тех значениях, которые были в production.
Плюсы гарантированная консистентность «как есть сейчас», полезно для active learning.
Минусы большой объем логов (каждый запрос — копия признаков), запаздывание данных для обучения (надо ждать накопления логов).
6. Проверка консистентности: мониторинг дрейфа признаков
Даже при использовании feature store или point-in-time возможны расхождения из-за сбоев в ETL, изменения источника данных. Обязательны мониторинг дрейфа (data drift) между offline и online распределениями.
Метрики:
- Population Stability Index (PSI) — численная мера различия двух распределений.
- Kolmogorov–Smirnov test — для непрерывных признаков.
- Jensen–Shannon divergence — для дискретных.
Инструменты
Пример проверки PSI (Python):
import numpy as np
import pandas as pd
def psi(expected, actual, buckets=10):
breaks = np.percentile(expected, np.linspace(0, 100, buckets+1)[1:-1])
expected_bins = np.histogram(expected, bins=np.append(breaks, np.inf))[0] + 1e-10
actual_bins = np.histogram(actual, bins=np.append(breaks, np.inf))[0] + 1e-10
expected_pct = expected_bins / expected_bins.sum()
actual_pct = actual_bins / actual_bins.sum()
return np.sum((actual_pct - expected_pct) * np.log(actual_pct / expected_pct))
# Сравниваем offline и online распределение для признака 'avg_rating_7d'
offline_feat = pd.read_parquet('offline_features.parquet')['avg_rating_7d']
online_feat = pd.read_csv('online_logs.csv')['avg_rating_7d']
print(f"PSI: {psi(offline_feat, online_feat):.4f}") # >0.2 - критично
7. Связь с Agentic RAG
В Agentic RAG агент может динамически выбирать источники, инструменты (tools) и генерировать планы. Признаки для такого выбора (например, уверенность retrieval, свежесть документа, стоимость вызова LLM) должны быть консистентны между тем, на чём обучался policy-агент (RL или fine-tuning), и реальным использованием. Если в обучении признак «стоимость LLM» считался через усреднение по прошлым вызовам, а в production — как мгновенная цена — поведение агента ухудшится.
Пример: fine-tuning агента на offline-данных с фиксированным порогом retrieval, а в online этот порог динамический → расхождение.
8. Сравнение подходов
| Подход | Консистентность | Сложность инфраструктуры | Задержка (latency) | Применимость для LLM |
|---|---|---|---|---|
| Point-in-time (batch scoring) | Гарантирована | Средняя | Высокая (если пересчёт на лету) | Только для batch обучения |
| Feature store | Очень высокая (единый источник) | Высокая | Низкая (online — кэш) | Универсально |
| Log-and-apply | Абсолютная (логи) | Средняя | Нет влияния | Для дообучения (fine-tuning) |
| Мониторинг (контроль) | Не гарантирует, но выявляет | Низкая | Нет | Обязательный слой |
9. Рекомендуемая практика
- Определить все признаки, используемые LLM/агентом (как input, так и скрытые — например, эмбеддинги модели если они считаются отдельно).
- Выбрать базовый подход (обычно feature store + point-in-time для обучения).
- Развернуть мониторинг распределений (PSI для каждого признака, алерты при превышении порога 0.2).
- Периодически (раз в неделю/месяц) запускать валидацию — для случайной выборки запросов в production сравнивать online-признаки с теми, которые получились бы при offline-пересчёте.
- Автоматизировать retrain при обнаружении значительного дрейфа.
Пет-проект для закрепления
Задача построить демонстрацию online/offline feature consistency для простого ранжировщика документов в RAG-агенте.
Инструменты Python, Pandas, Redis, Feast (можно локально через Docker), Kafka или file-based лог.
Шаги:
- Создать синтетический датасет документов и запросов с меткой времени.
- Определить признак: «количество похожих запросов за последний час» (для оценки популярности).
- Реализовать три режима:
- Offline: считать признак из исторического Parquet с point-in-time join.
- Online: считать признак из Redis, обновляемого стримингом.
- Log-and-apply: каждый online-запрос сохранять признаки в CSV для обучения.
- Добавить симуляцию дрейфа (изменить источник данных для online).
- Написать скрипт проверки PSI между offline и online признаками.
- Обучить простую модель (логистическую регрессию) на offline-признаках и проверить точность на online— показать падение при расхождении.
Ожидаемый результат
- Понимание, как выглядит неконсистентность в цифрах.
- Рабочий feature store (даже упрощённый) с двумя сервинг-режимами.
- Метрика PSI, которая вовремя сигнализирует о проблеме.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 855 | Как синхронизировать эмбеддинги между обучением и инференсом |
| 858 | Как организовать A/B тестирование признаков для LLM |
| 860 | Как бороться с data drift в Agentic RAG |
| 820 | Feature engineering для retrieval |
| 835 | Мониторинг качества моделей в production |
Навигация
- Предыдущий: 856
- Следующий: 858
- Индекс: 00. Индекс разборов