English translation is not available yet. Showing Russian content.

Настроить 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

Если нет реального инструмента — симулируем:

  1. Сгенерировать 3 временных ряда длиной 10080 точек (7 дней * 1440 мин) с помощью Python:
    • retrieval_latency — base + случайный шум + периодический тренд + единичные всплески (аномалии).
    • context_length — пропорционален retrieval_latency с лагом 1-2 минуты.
    • llm_latency — линейно зависит от context_length + собственный шум + независимые аномалии.
  2. Сохранить в CSV-файл metrics_simulated.csv с колонками: timestamp, retrieval_latency, context_length, llm_latency.
  3. Для имитации аномалии — добавить участок, где 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 часа)

Действия

  1. Загрузить CSV metrics_simulated.csv (или подключиться к Prometheus API для экспорта метрик за 7 дней).
  2. Проверить пропуски, выбросы (interquartile range). Заполнить пропуски линейной интерполяцией.
  3. Построить временные ряды каждой метрики на одном графике с разными масштабами (использовать matplotlib и secondary y-axis).
  4. Рассчитать скользящие средние (окно 5 минут) для сглаживания шума.
  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 часа)

Действия

  1. Рассчитать корреляцию Пирсона между retrieval_latency и llm_latency (на всём ряде и на оконных выборках).
  2. Выполнить тест Грейнджера (Granger causality) для пар retrieval_latency → llm_latency и retrieval_latency → context_length → llm_latency с лагами от 1 до 5 минут. Использовать statsmodels.tsa.stattools.grangercausalitytests.
  3. Оценить взаимную корреляцию (cross-correlation) для выявления временного лага.
  4. Построить матрицу корреляций всех трёх метрик (включая 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 часов)

Действия

  1. Определить направленные связи на основе теста Грейнджера и экспертного знания (retrieval → context_length, context_length → llm_latency). Использовать библиотеку causalnex для автоматического обучения DAG из данных (алгоритм PC или GES).
  2. Если используете causalnex:
    • Дискретизировать непрерывные ряды (например, по квантилям) или использовать линейную версию.
    • Обучить модель from_pandas с параметрами (significant_level=0.05).
  3. Построить граф с помощью networkx и визуализировать его с весами (коэффициенты линейной регрессии или сила связи).
  4. Добавить на граф метрики аномалий (например, цвет узла в зависимости от текущего состояния – зелёный/красный).
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 часа)

Действия

  1. Разработать алгоритм RCA на основе графа и текущих значений метрик:
    • На входе: временное окно (start, end), где llm_latency аномально высока (например, превышает 95-й перцентиль за последние 2 часа).
    • Пройти по графу от узла llm_latency в обратном направлении: проверить изменения родителей (context_length, retrieval_latency) относительно их baseline.
    • Для каждого родителя рассчитать «вклад»: coef * (значение - baseline). Родитель с максимальным вкладом — кандидат в корневую причину.
  2. Реализовать функцию find_root_cause(window_df, graph, baseline_period='7d'), возвращающую словарь с вероятной причиной, вкладом и временем задержки.
  3. Протестировать на симулированных аномалиях: искусственно создать два типа сценариев:
    • Аномалия, вызванная ростом retrieval latency.
    • Аномалия, не связанная с retrieval (например, скачок LLM latency из-за перегрузки GPU).
  4. Оценить точность: 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 часа)

Действия

  1. Создать дашборд в Grafana (если есть доступ) или статический HTML-отчёт с Plotly/Dash.
  2. Отобразить:
    • Основной график временных рядов с аннотациями аномалий.
    • Граф зависимостей (интерактивный, с возможностью клика по узлу).
    • Результаты RCA: для каждой аномалии выводить корневую метрику и вклад.
  3. Если 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. Связанные вопросы из базы знаний

ВопросТема
45Prometheus: запросы rate и histogram_quantile для метрик latency
132OpenTelemetry: экспорт трейсов и метрик в Prometheus
278Корреляция Пирсона vs. Спирмена для нелинейных связей
311Root Cause Analysis на основе графа сервисных зависимостей
509RAG pipeline: источники задержки (retrieval, generation, post-processing)
644Grafana: настройка alerting на основе аномалий
788Причинно-следственный вывод (causal inference) в системах рекомендаций
821Анализ временных рядов: стационарность, ADF-тест, дифференцирование
893Distributed tracing: correlation-id и waterfall charts для latency

10. Чек-лист самопроверки

  • Я проверил, что сгенерированные данные содержат реалистичную зависимость: при росте retrieval latency через 1-2 минуты растёт LLM latency.
  • Я убедился, что тест Грейнджера выполнен на стационарных рядах (p-value достоверен).
  • Я построил граф с помощью causalnex и визуально подтвердил направление стрелок.
  • Я написал функцию RCA, которая для заданного окна возвращает имя метрики-причины, и протестировал её на 10 аномалиях (8+ успешных).
  • Я создал дашборд, который позволяет интерактивно просматривать аномалии и их причины без перезапуска кода.