14 KiB
Техническое задание по оптимизации производительности GraphRAG
Обзор
Данное техническое задание описывает комплексные оптимизации производительности алгоритма GraphRAG (Graph Retrieval-Augmented Generation) в системе TrustGraph. Текущая реализация страдает от существенных проблем с производительностью, которые ограничивают масштабируемость и время отклика. Данное задание охватывает четыре основные области оптимизации:
- Оптимизация обхода графа: Устранение неэффективных рекурсивных запросов к базе данных и реализация пакетной обработки графа.
- Оптимизация разрешения меток: Замена последовательной выборки меток параллельными/пакетными операциями.
- Улучшение стратегии кэширования: Реализация интеллектуального кэширования с вытеснением по алгоритму LRU и предварительной загрузкой.
- Оптимизация запросов: Добавление мемоизации результатов и кэширования векторов для повышения скорости отклика.
Цели
- Сокращение количества запросов к базе данных: Достижение снижения общего количества запросов к базе данных на 50-80% за счет пакетной обработки и кэширования.
- Улучшение времени отклика: Ускорение построения подграфа в 3-5 раза и ускорение разрешения меток в 2-3 раза.
- Повышение масштабируемости: Поддержка более крупных графовых баз знаний с улучшением управления памятью.
- Сохранение точности: Сохранение существующей функциональности GraphRAG и качества результатов.
- Обеспечение параллельности: Улучшение возможностей параллельной обработки для множества одновременных запросов.
- Уменьшение занимаемой памяти: Реализация эффективных структур данных и управления памятью.
- Добавление наблюдаемости: Включение метрик производительности и возможностей мониторинга.
- Обеспечение надежности: Добавление механизмов обработки ошибок и таймаутов.
Описание проблемы
Текущая реализация GraphRAG, находящаяся в файле trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py, имеет ряд критических проблем с производительностью, которые серьезно влияют на масштабируемость системы:
Текущие проблемы с производительностью
1. Неэффективный обход графа (follow_edges function, строки 79-127)
- Выполняет 3 отдельных запроса к базе данных для каждой сущности на каждом уровне глубины.
- Шаблон запроса: запросы на основе субъекта, предиката и объекта для каждой сущности.
- Отсутствие пакетной обработки: Каждый запрос обрабатывает только одну сущность за раз.
- Отсутствие обнаружения циклов: Может повторно посещать одни и те же узлы несколько раз.
- Рекурсивная реализация без мемоизации приводит к экспоненциальной сложности.
- Временная сложность: O(entities × max_path_length × triple_limit³)
2. Последовательное разрешение меток (get_labelgraph function, строки 144-171)
- Обрабатывает каждый компонент тройки (субъект, предикат, объект) последовательно.
- Каждый вызов
maybe_labelпотенциально вызывает запрос к базе данных. - Отсутствует параллельное выполнение или пакетная обработка запросов меток.
- Приводит до 3 × subgraph_size отдельных запросов к базе данных.
3. Примитивная стратегия кэширования (maybe_label function, строки 62-77)
- Простой кэш в виде словаря без ограничений размера или TTL.
- Отсутствие политики вытеснения из кэша приводит к неограниченному росту использования памяти.
- Пропуски в кэше вызывают отдельные запросы к базе данных.
- Отсутствует предварительная загрузка или интеллектуальное "прогрев" кэша.
4. Субоптимальные шаблоны запросов
- Запросы на поиск сходства векторов сущностей не кэшируются между похожими запросами.
- Отсутствует мемоизация результатов для повторяющихся шаблонов запросов.
- Отсутствует оптимизация запросов для распространенных сценариев доступа.
5. Критические проблемы с временем жизни объектов (rag.py:96-102)
- Объект GraphRag пересоздается для каждого запроса: Новый экземпляр создается для каждого запроса, что приводит к потере всех преимуществ кэширования.
- Объект Query имеет очень короткое время жизни: Создается и уничтожается в рамках выполнения одного запроса (строки 201-207).
- Кэш меток сбрасывается для каждого запроса: "Прогрев" кэша и накопленные знания теряются между запросами.
- Накладные расходы на повторное создание клиента: Клиенты базы данных потенциально переподключаются для каждого запроса.
- Отсутствует оптимизация между запросами: Невозможно воспользоваться преимуществами шаблонов запросов или совместного использования результатов.
Анализ влияния на производительность
Текущий наихудший сценарий для типичного запроса:
- Извлечение сущности: 1 запрос на поиск сходства векторов.
- Обход графа: entities × max_path_length × 3 × triple_limit запросов.
- Разрешение меток: subgraph_size × 3 отдельных запросов на метки.
Для параметров по умолчанию (50 сущностей, глубина 2, лимит 30 троек, размер подграфа 150):
- Минимальное количество запросов: 1 + (50 × 2 × 3 × 30) + (150 × 3) = 9,451 запросов к базе данных.
- Время отклика: 15-30 секунд для графов умеренного размера.
- Использование памяти: Неограниченный рост кэша со временем.
- Эффективность кэша: 0% - кэш сбрасывается при каждом запросе.
- Накладные расходы на создание объектов: Объекты GraphRag + Query создаются/уничтожаются для каждого запроса.
Данное техническое задание решает эти проблемы путем реализации пакетных запросов, интеллектуального кэширования и параллельной обработки. Оптимизируя шаблоны запросов и доступ к данным, TrustGraph может:
- Поддерживать графовые базы знаний предприятия с миллионами сущностей.
- Обеспечивать время отклика менее 1 секунды для типичных запросов.
- Обрабатывать сотни одновременных запросов GraphRAG.
- Эффективно масштабироваться с ростом размера и сложности графа.
Технический дизайн
Архитектура
Оптимизация производительности GraphRAG требует следующих технических компонентов:
1. Архитектурная реорганизация для управления временем жизни объектов
- Сделать GraphRag долгоживущим: Перенести экземпляр GraphRag на уровень Processor для сохранения данных между запросами.
- Сохранить кэши: Поддерживать кэш меток, кэш векторов и кэш результатов запросов между запросами.
- Оптимизировать объект Query: Рефакторинг Query как легковесного контекста выполнения, а не контейнера данных.
- Сохранение подключений: Поддерживать подключения к базе данных между запросами.
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py (изменен)
2. Оптимизированный движок обхода графа
- Заменить рекурсивный
follow_edgesитеративным поиском в ширину. - Реализовать пакетную обработку сущностей на каждом уровне обхода.
- Добавить обнаружение циклов с отслеживанием посещенных узлов.
- Включить раннее завершение при достижении лимитов.
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/optimized_traversal.py
3. Параллельная система разрешения меток
- Пакетная обработка запросов меток для нескольких сущностей одновременно.
- Реализация паттернов async/await для параллельного доступа к базе данных.
- Добавление интеллектуальной предварительной загрузки для распространенных шаблонов меток.
- Включение стратегий "прогрева" кэша меток.
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/label_resolver.py
4. Консервативный слой кэширования меток
- Кэш LRU с коротким TTL только для меток (5 минут) для баланса между производительностью и согласованностью.
- Мониторинг метрик кэша и коэффициента попадания.
- Без кэширования векторов: Уже кэшируются на уровне запроса, нет пользы для между запросами.
- Без кэширования результатов запросов: Из-за проблем согласованности данных в графе.
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/cache_manager.py
5. Фреймворк оптимизации запросов
- Анализ шаблонов запросов и предложения по оптимизации.
- Координатор пакетных запросов для доступа к базе данных.
- Пулинг подключений и управление таймаутами запросов.
- Мониторинг производительности.