中文翻译暂不可用,显示俄语原文。
Настроить RED metrics для LLM
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить RED metrics для LLM
1. Цель задачи
Освоить практику мониторинга production-сервисов на LLM по методологии RED (Rate, Errors, Duration) для каждого эндпоинта. Реализовать инструментирование LLM-приложения, сбор метрик в Prometheus и визуализацию в Grafana с дашбордом, позволяющим быстро оценить здоровье сервиса.
Ключевой результат Рабочий дашборд Grafana с панелями Rate, Error Rate и Latency (p50, p95, p99) для двух эндпоинтов LLM сервиса, с настроенными оповещениями (alerts) при превышении порогов.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
LLM сервис (минимальный – два эндпоинта, например, /v1/chat и /v1/embed) | Реальный или смоделированный |
| Docker и Docker Compose | Установить или проверить версию |
| Python 3.10+ с библиотеками | pip install flask prometheus_client |
| Prometheus | Образ prom/prometheus (docker) |
| Grafana | Образ grafana/grafana (docker) |
Если нет реального LLM сервиса — симулируем:
- Создать файл
llm_sim.pyс Flask-приложением, которое эмулирует два эндпоинта: - Инструментировать эндпоинты метриками RED с помощью библиотеки prometheus_client.
- Добавить генератор трафика (например, отдельный скрипт или Apache Bench) для постоянной нагрузки.
# llm_sim.py (фрагмент)
from flask import Flask, jsonify
from prometheus_client import Counter, Histogram, generate_latest
import random, time
app = Flask(__name__)
# Метрики RED
REQUEST_COUNT = Counter('llm_requests_total', 'Total request count', ['endpoint', 'status'])
REQUEST_LATENCY = Histogram('llm_request_duration_seconds', 'Request latency', ['endpoint'],
buckets=(0.1, 0.5, 1.0, 2.0, 5.0, 10.0))
@app.route('/v1/chat', methods=['POST'])
def chat():
start = time.time()
if random.random() < 0.05: # 5% ошибок
REQUEST_COUNT.labels(endpoint='/v1/chat', status='error').inc()
return jsonify({'error': 'simulated failure'}), 500
time.sleep(random.uniform(0.1, 2.0))
REQUEST_COUNT.labels(endpoint='/v1/chat', status='success').inc()
REQUEST_LATENCY.labels(endpoint='/v1/chat').observe(time.time() - start)
return jsonify({'response': 'ok'})
@app.route('/v1/embed', methods=['POST'])
def embed():
start = time.time()
time.sleep(random.uniform(0.05, 0.5))
REQUEST_COUNT.labels(endpoint='/v1/embed', status='success').inc()
REQUEST_LATENCY.labels(endpoint='/v1/embed').observe(time.time() - start)
return jsonify({'response': 'ok'})
@app.route('/metrics')
def metrics():
return generate_latest()
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| LLM сервис (симуляция) | Python Flask / FastAPI + prometheus_client | Эмуляция API, экспорт метрик |
| Система метрик | Prometheus (pull-based) | Сбор и хранение метрик |
| Визуализация | Grafana | Дашборд, алертинг |
| Контейнеризация | Docker, Docker Compose | Оркестрация компонентов |
| Генерация нагрузки | Python-скрипт (requests) или Apache Bench | Создание трафика для теста |
4. Этапы выполнения
Этап 1: Настройка локальной инфраструктуры (30-45 минут)
Действия
-
Создать структуру проекта
- docker-compose.yml
prometheus/prometheus.ymlllm_sim.py(код из п.2)- generator.py (простой скрипт для имитации пользователей)
grafana/datasources.yml(добавить Prometheus как datasource)
-
Docker Compose конфигурация (основные сервисы):
llm_sim: build из Dockerfile (на основе python:3.10-slim, установить flask, prometheus_client)- prometheus: образ prom/prometheus, проброс конфига prometheus.yml
- grafana: образ grafana/grafana, монтировать datasources и provisioning для дашборда
-
prometheus.yml – конфигурация scrape:
global: scrape_interval: 5s scrape_configs: - job_name: 'llm_service' static_configs: - targets: ['llm_sim:8000'] -
Сделать docker-compose up -d, проверить логи, что все сервисы запущены.
Ожидаемый результат этапа Все три контейнера (llm_sim, prometheus, grafana) работают. Grafana доступна на порту 3000, Prometheus на 9090, API llm_sim на 8000.
Этап 2: Инструментирование метрик RED (1-1.5 часа)
Действия
-
Добавить в код сервиса три типа метрик для каждого эндпоинта:
-
Обернуть каждый эндпоинт в middleware (или декоратор), который:
-
Экспортировать метрики на
/metricsс помощью prometheus_client.generate_latest(). -
Проверить метрики через curl localhost:8000/metrics. Убедиться, что присутствуют
llm_requests_totalиllm_request_duration_seconds. -
Написать скрипт-генератор generator.py, который в цикле отправляет POST-запросы на оба эндпоинта (по 50% трафика) с паузой 0.1-0.5 сек.
Ожидаемый результат этапа При запущенном генераторе метрики обновляются; в Prometheus (UI) можно увидеть target UP и получаемые метрики.
Этап 3: Создание дашборда Grafana с RED панелями (1.5-2 часа)
Действия
-
Создать дашборд в Grafana (UI или provisioning).
- Рекомендуется provisioning через YAML (папка
grafana/dashboards), чтобы дашборд воспроизводился.
- Рекомендуется provisioning через YAML (папка
-
Добавить панели (Panels) для каждого измерения RED:
-
Rate – запросов в секунду (за минуту). Graph с линиями для каждого эндпоинта (сумма success+error). Использовать запрос:
rate(llm_requests_total[1m])с legend{{endpoint}}. -
Error Rate – процент ошибок. Использовать две линии: ошибки/сек и общий rate, а также можно вывести процент через формулу:
rate(llm_requests_total{status="error"}[1m]) / rate(llm_requests_total[1m]) * 100. Легенда:Error % {{endpoint}}. -
Duration – p50/p95/p99 latency. Для каждого эндпоинта отдельная панель (или одна с несколькими линиями). Использовать
histogram_quantile:histogram_quantile(0.5, sum(rate(llm_request_duration_seconds_bucket{endpoint="/v1/chat"}[5m])) by (le))и т.д.
-
-
Настроить оповещения (alerts): (опционально, но желательно)
-
Добавить Time picker и описания панелей.
-
Экспортировать дашборд в JSON и сохранить в
grafana/dashboards/red_dashboard.json.
Ожидаемый результат этапа Дашборд с 3-4 панелями, обновляющимися в реальном времени. Видны динамика rate, латенси и ошибок.
Этап 4: Тестирование, анализ и документирование (30-45 минут)
Действия
- Провести стресс-тест – увеличить нагрузку генератором (уменьшить паузу до 0.01 сек), проверить, как меняются метрики на дашборде.
- Симулировать сбой – временно ввести
time.sleep(10)на эндпоинте, убедиться, что latency взлетает, графики показывают аномалию. - Проверить работу alerting при превышении порога должно появиться оповещение в Grafana (раздел Alerting).
- Написать короткий README с описанием архитектуры, как запустить, где смотреть дашборд.
Ожидаемый результат этапа Дашборд корректно отражает изменения нагрузки и сбои. Настроены alerts.
Этап 5: (Опционально) Интеграция с существующим LLM сервисом (1-2 часа)
Если есть доступ к реальному LLM сервису (например, на базе vLLM, Triton Inference Server), необходимо инструментировать его аналогично. Для production решений часто используют OpenTelemetry → Prometheus. В рамках задачи можно показать, как заменить симуляцию на реальный сервер.
5. Критерии приемки (Definition of Done)
- Дашборд Grafana содержит минимум три панели: Request Rate (запросов/сек), Error Rate (% или absolute), Latency (p50, p95, p99).
- Метрики собираются для каждого из двух эндпоинтов раздельно.
- Дашборд автообновляется (refresh interval ≤ 15 сек).
- Источник данных Prometheus настроен и подключён без ошибок.
- При запуске генератора метрики визуально растут, при остановке – падают до 0.
- Настроено как минимум одно alert-правило (например, на высокий error rate).
- Весь код и конфигурация находятся в репозитории (или папке) с README, воспроизводимы через
docker-compose up. - Скрипт генератора запускается отдельно и даёт стабильную нагрузку.
6. Ожидаемый результат
Файлы/артефакты в корне проекта:
| Артефакт | Содержание |
|---|---|
docker-compose.yml | Три сервиса: llm_sim, prometheus, grafana |
llm_sim.py | Flask-приложение с RED метриками, порт 8000 |
prometheus/prometheus.yml | Конфиг Prometheus, scrape job на llm_sim:8000 |
grafana/datasources/datasource.yml | Provisioning datasource Prometheus |
grafana/dashboards/red_dashboard.json | Экспортированный дашборд RED (3-4 панели) |
generator.py | Скрипт постоянной нагрузки |
README.md | Инструкция по запуску, описание метрик и панелей |
Дополнительные результаты (опционально):
- Скриншот дашборда с пиками нагрузки и ошибками.
- Документация по алертингу (какие пороги установлены и почему).
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Metrica latency не появляется в Prometheus | Убедиться, что при вызове эндпоинта Histogram.observe() вызывается. Проверить, что метрики доступны по /metrics. |
| Дашборд не отображает данные | Проверить datasource в Grafana (название должно совпадать с provisioning). Проверить Prometheus target UP. |
| Generator слишком быстро сжирает ресурсы | Уменьшить количество потоков, добавить time.sleep(0.1) |
| Docker контейнеры не общаются | Использовать сеть -net bridge в docker-compose; обращаться по имени сервиса (llm_sim, prometheus, grafana). |
| Alert rule не срабатывает | Проверить таймфрейм (for: 2m), правильный PromQL. Убедиться, что алерт active и настроен evaluation interval. |
| Histogram buckets не соответствуют распределению | В production выбирать buckets в 4-5 раз выше ожидаемой медианной задержки. Для симуляции оставить дефолтные. |
8. Бюджет времени (оценка)
| Этап | Время (часов) |
|---|---|
| Этап 1: Настройка инфраструктуры | 0.5 – 0.75 |
| Этап 2: Инструментирование метрик | 1.0 – 1.5 |
| Этап 3: Создание дашборда Grafana | 1.5 – 2.0 |
| Этап 4: Тестирование и документирование | 0.5 – 0.75 |
| Этап 5 (опционально): Реальный сервис | +1.0 – 2.0 |
| Итого (основные 4 этапа) | 3.5 – 5.0 часов |
Примечание для первого раза Если не знакомы с Prometheus и Grafana, добавьте 1-2 часа на ознакомление. Симуляция упрощает работу, поэтому реальный сервис может потребовать дополнительного времени.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 10 | Основы Prometheus: метрики, label, экспортеры |
| 42 | Написание PromQL запросов для rate и histogram_quantile |
| 105 | Конфигурация docker-compose для multi-service приложения |
| 203 | Инструментирование Python-сервиса prometheus_client |
| 311 | Создание дашборда в Grafana через provisioning |
| 428 | Настройка alert rules в Grafana |
| 550 | Наблюдаемость LLM сервисов: метрики, логи, трейсинг |
| 612 | RED методология: Rate, Errors, Duration |
| 707 | Использование histogram_quantile для перцентилей |
| 834 | Best practices по buckets для latency метрик |
10. Чек-лист самопроверки
- Я проверил, что метрики
/metricsотдают правильные данные для обоих эндпоинтов. - Prometheus успешно забирает метрики (target state = UP).
- В дашборде отображаются графики для Rate, Error Rate и Latency.
- Alert правила настроены и переходят в состояние Firing при создании искусственных ошибок.
- README содержит команды для быстрого развертывания (
docker-compose up --build). - Код не содержит закомментированных блоков или токенов.
- Я протестировал остановку генератора: метрики должны вернуться к нулю через ~2 scrape интервала.
- Все конфигурационные файлы (prometheus.yml, datasource, dashboard) лежат в соответствующих папках проекта.