Настроить correlation между метриками (граф зависимостей retrieval latency → LLM latency)
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить correlation между метриками (граф зависимостей retrieval latency → LLM latency)
1. Цель задачи
Разработать систему автоматического построения графа причинно-следственных связей между метриками задержки этапа retrieval и задержки генерации LLM в RAG-пайплайне. На основе временных рядов метрик (реальных или симулированных) необходимо выявить направленные зависимости и реализовать механизм автоматического определения корневой причины (root cause) при возникновении аномалий. Ключевой результат рабочий прототип, который по заданному временному окну аномалии в LLM latency автоматически находит, связана ли она с изменением retrieval latency, и выдаёт диагноз (например, «рост LLM latency вызван увеличением числа токенов контекста из-за роста retrieval latency»).
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Метрики retrieval latency (p50, p99, среднее) за последние 7 дней с шагом 1 минута | Экспорт из Prometheus (или смоделировать) |
| Метрики LLM latency (p50, p99, среднее) за тот же период | Экспорт из Prometheus (или смоделировать) |
| Метрики количества токенов контекста (context_length) | Экспорт из Prometheus / логирование |
| Инструмент для анализа временных рядов | Python (pandas, statsmodels) |
| Библиотека для графов зависимостей | networkx, causalnex или DoWhy |
Если нет реального инструмента — симулируем:
- Сгенерировать 3 временных ряда длиной 10080 точек (7 дней * 1440 мин) с помощью Python:
retrieval_latency— base + случайный шум + периодический тренд + единичные всплески (аномалии).- context_length — пропорционален retrieval_latency с лагом 1-2 минуты.
llm_latency— линейно зависит от context_length + собственный шум + независимые аномалии.
- Сохранить в CSV-файл metrics_simulated.csv с колонками: timestamp,
retrieval_latency, context_length,llm_latency. - Для имитации аномалии — добавить участок, где retrieval_latency резко возрастает (например, 5-кратно) на 30 минут, что вызывает рост llm_latency через 2 минуты.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык реализации | Python 3.10+ | Скрипты анализа и моделирования |
| Работа с данными | pandas, numpy | Загрузка, очистка, преобразование временных рядов |
| Статистический анализ | scipy.stats, statsmodels.tsa | Корреляция Пирсона, тест Грейнджера на причинность |
| Графы зависимостей | networkx, causalnex | Построение DAG, расчёт путей влияния |
| Визуализация | matplotlib, plotly, Grafana (опционально) | Графики рядов, граф зависимостей |
| Хранилище метрик | Prometheus (или CSV) | Источник данных |
| Дашборд | Grafana (опционально) | Отображение результата анализа |
4. Этапы выполнения
Этап 1: Подготовка данных и разведочный анализ (3 часа)
Действия
- Загрузить CSV metrics_simulated.csv (или подключиться к Prometheus API для экспорта метрик за 7 дней).
- Проверить пропуски, выбросы (interquartile range). Заполнить пропуски линейной интерполяцией.
- Построить временные ряды каждой метрики на одном графике с разными масштабами (использовать matplotlib и secondary y-axis).
- Рассчитать скользящие средние (окно 5 минут) для сглаживания шума.
- Найти участки с аномалиями визуально и пометить их (например,
is_anomaly).
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('metrics_simulated.csv', parse_dates=['timestamp'])
df.set_index('timestamp', inplace=True)
df = df.resample('1T').mean().interpolate()
# Скользящее среднее
df_ma = df.rolling(5).mean()
fig, ax1 = plt.subplots(figsize=(12,6))
ax1.plot(df_ma.index, df_ma['retrieval_latency'], 'b-', label='retrieval_latency (MA5)')
ax2 = ax1.twinx()
ax2.plot(df_ma.index, df_ma['llm_latency'], 'r-', label='llm_latency (MA5)')
plt.legend()
plt.show()
Ожидаемый результат этапа
- Очищенный датафрейм
df_cleanс метками аномалий. - Визуальный график, подтверждающий наличие корреляции между всплесками.
Этап 2: Корреляционный анализ и тест на причинность (4 часа)
Действия
- Рассчитать корреляцию Пирсона между
retrieval_latencyиllm_latency(на всём ряде и на оконных выборках). - Выполнить тест Грейнджера (Granger causality) для пар
retrieval_latency → llm_latencyи retrieval_latency → context_length → llm_latency с лагами от 1 до 5 минут. Использовать statsmodels.tsa.stattools.grangercausalitytests. - Оценить взаимную корреляцию (cross-correlation) для выявления временного лага.
- Построить матрицу корреляций всех трёх метрик (включая context_length).
from statsmodels.tsa.stattools import grangercausalitytests
# Подготовка стационарных рядов (дифференцирование)
df_diff = df_clean[['retrieval_latency', 'llm_latency']].diff().dropna()
gc_result = grangercausalitytests(df_diff, maxlag=5, verbose=True)
Ожидаемый результат этапа
- Таблица с p-value для теста Грейнджера (направление от retrieval к LLM значимо с p<0.05 минимум на одном лаге).
- График cross-correlation с пиком на положительном лаге.
Этап 3: Построение графа зависимостей (DAG) (5 часов)
Действия
- Определить направленные связи на основе теста Грейнджера и экспертного знания (retrieval → context_length, context_length → llm_latency). Использовать библиотеку causalnex для автоматического обучения DAG из данных (алгоритм PC или GES).
- Если используете causalnex:
- Дискретизировать непрерывные ряды (например, по квантилям) или использовать линейную версию.
- Обучить модель
from_pandasс параметрами (significant_level=0.05).
- Построить граф с помощью networkx и визуализировать его с весами (коэффициенты линейной регрессии или сила связи).
- Добавить на граф метрики аномалий (например, цвет узла в зависимости от текущего состояния – зелёный/красный).
import causalnex
from causalnex.structure import StructureModel
from causalnex.structure.notears import from_pandas
sm = from_pandas(df_clean[['retrieval_latency', 'context_length', 'llm_latency']], beta=0.1)
sm.remove_edges_below_threshold(0.1)
print(sm.edges)
# Визуализация
import networkx as nx
G = nx.DiGraph(sm.edges)
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray')
Ожидаемый результат этапа
- Файл
dependency_graph.gml(или структура в коде). - Визуализация графа с направленными рёбрами и весами.
Этап 4: Автоматическое определение корневой причины (Root Cause Analysis) (4 часа)
Действия
- Разработать алгоритм RCA на основе графа и текущих значений метрик:
- На входе: временное окно (start, end), где
llm_latencyаномально высока (например, превышает 95-й перцентиль за последние 2 часа). - Пройти по графу от узла
llm_latencyв обратном направлении: проверить изменения родителей (context_length, retrieval_latency) относительно их baseline. - Для каждого родителя рассчитать «вклад»: coef * (значение - baseline). Родитель с максимальным вкладом — кандидат в корневую причину.
- На входе: временное окно (start, end), где
- Реализовать функцию find_root_cause(window_df, graph, baseline_period='7d'), возвращающую словарь с вероятной причиной, вкладом и временем задержки.
- Протестировать на симулированных аномалиях: искусственно создать два типа сценариев:
- Аномалия, вызванная ростом retrieval latency.
- Аномалия, не связанная с retrieval (например, скачок LLM latency из-за перегрузки GPU).
- Оценить точность: TP / (TP+FP) для обнаружения связи с retrieval latency.
def find_root_cause(window, G, coefs, baseline):
# window - DataFrame за время аномалии
# G - граф networkx
# coefs - словарь коэффициентов влияния (edge: weight)
# baseline - средние значения за неделю
anomalies = {}
for node in G.predecessors('llm_latency'):
delta = window[node].mean() - baseline[node]
anomalies[node] = delta * coefs[(node, 'llm_latency')]
root = max(anomalies, key=anomalies.get)
return root, anomalies
Ожидаемый результат этапа
- Функция RCA, корректно определяющая корень в >80% тестовых аномалий.
- Скрипт, запускающий RCA на всех аномальных окнах в данных.
Этап 5: Визуализация и дашборд (2 часа)
Действия
- Создать дашборд в Grafana (если есть доступ) или статический HTML-отчёт с Plotly/Dash.
- Отобразить:
- Основной график временных рядов с аннотациями аномалий.
- Граф зависимостей (интерактивный, с возможностью клика по узлу).
- Результаты RCA: для каждой аномалии выводить корневую метрику и вклад.
- Если Grafana не доступна: записать результаты в CSV
rca_results.csvи построитьplotlyфигуру с подписями.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(rows=2, cols=1, subplot_titles=("Metrics", "Root Cause Contribution"))
# ... добавить линии и столбцы
fig.write_html("rca_dashboard.html")
Ожидаемый результат этапа
- Интерактивная HTML-страница
rca_dashboard.htmlили настроенный дашборд в Grafana. - Отображается связь retrieval latency → LLM latency и результаты RCA.
5. Критерии приемки (Definition of Done)
- Сгенерирован датасет с реалистичной симуляцией метрик (или получен из реальной системы).
- Выполнен тест Грейнджера, который показывает статистически значимое влияние
retrieval_latencyнаllm_latency(p-value < 0.05). - Построен направленный ациклический граф (DAG) с узлами
retrieval_latency,context_length,llm_latency. - Реализована функция
find_root_cause, которая для аномалии вllm_latencyвозвращает родительскую метрику с наибольшим вкладом. - Функция корректно определяет корневую причину не менее чем в 80% симулированных аномалий (проверка на 10 искусственных сценариях).
- Создан визуальный отчёт (дашборд), где отображаются временные ряды, граф зависимостей и результаты RCA.
- Весь код оформлен в виде Python-скриптов или Jupyter notebook с комментариями.
- README с инструкцией по запуску (установка зависимостей, генерация данных, запуск анализа).
6. Ожидаемый результат
Основной артефакт репозиторий с кодом, содержащий:
rca_pipeline.py— основной скрипт анализа (загрузка, очистка, корреляция, обучение DAG, RCA).metrics_simulated.csv— сгенерированные данные (если нет реальных).dependency_graph.gml— файл графа зависимостей.rca_results.csv— результаты RCA для всех аномалий.rca_dashboard.html— интерактивный дашборд.
Дополнительно
- Notebook
analysis.ipynbс пошаговым исследованием. - График cross-correlation и матрица корреляций.
- Метрики качества RCA (accuracy, precision, recall).
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Ложные корреляции из-за трендов и сезонности | Предварительно вычесть тренд (дифференцирование, STL-декомпозиция). Использовать тест Грейнджера на стационарных рядах. |
| Временной лаг между retrieval и LLM latency не постоянен | Рассчитать cross-correlation для нескольких лагов и выбрать лаг с максимальной корреляцией. |
| Обратная связь (LLM latency влияет на retrieval?) | Включить в тест Грейнджера двунаправленную проверку; при построении DAG использовать методы, допускающие циклы (если необходимо, но в нашем случае causality ациклична). |
| Нехватка данных для обучения графа | Использовать симуляцию с достаточным числом точек (7 дней = 10080 точек). Если реальных данных мало — увеличить частоту сбора (каждые 10 секунд). |
| Сложность интерпретации графа в production | Добавить пороговые значения для коэффициентов влияния и цветовую индикацию на дашборде. |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
| Этап 1: Подготовка данных и разведочный анализ | 3 |
| Этап 2: Корреляционный анализ и тест на причинность | 4 |
| Этап 3: Построение графа зависимостей (DAG) | 5 |
| Этап 4: Автоматическое определение корневой причины | 4 |
| Этап 5: Визуализация и дашборд | 2 |
| Итого | 18 |
Примечание При первом выполнении может потребоваться на 20% больше времени (до 22 часов) из-за изучения библиотек causalnex и тонкостей теста Грейнджера.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 45 | Prometheus: запросы rate и histogram_quantile для метрик latency |
| 132 | OpenTelemetry: экспорт трейсов и метрик в Prometheus |
| 278 | Корреляция Пирсона vs. Спирмена для нелинейных связей |
| 311 | Root Cause Analysis на основе графа сервисных зависимостей |
| 509 | RAG pipeline: источники задержки (retrieval, generation, post-processing) |
| 644 | Grafana: настройка alerting на основе аномалий |
| 788 | Причинно-следственный вывод (causal inference) в системах рекомендаций |
| 821 | Анализ временных рядов: стационарность, ADF-тест, дифференцирование |
| 893 | Distributed tracing: correlation-id и waterfall charts для latency |
10. Чек-лист самопроверки
- Я проверил, что сгенерированные данные содержат реалистичную зависимость: при росте retrieval latency через 1-2 минуты растёт LLM latency.
- Я убедился, что тест Грейнджера выполнен на стационарных рядах (p-value достоверен).
- Я построил граф с помощью
causalnexи визуально подтвердил направление стрелок. - Я написал функцию RCA, которая для заданного окна возвращает имя метрики-причины, и протестировал её на 10 аномалиях (8+ успешных).
- Я создал дашборд, который позволяет интерактивно просматривать аномалии и их причины без перезапуска кода.