48 KiB
| layout | title | parent |
|---|---|---|
| default | Техническая спецификация оптимизации производительности GraphRAG | Russian (Beta) |
Техническая спецификация оптимизации производительности GraphRAG
Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
Обзор
Эта спецификация описывает комплексные оптимизации производительности для алгоритма GraphRAG (Graph Retrieval-Augmented Generation) в TrustGraph. Текущая реализация страдает от значительных узких мест в производительности, которые ограничивают масштабируемость и время отклика. Эта спецификация охватывает четыре основные области оптимизации:
- Оптимизация обхода графа: Исключение неэффективных рекурсивных запросов к базе данных и реализация пакетной обработки графа.
- Оптимизация разрешения меток: Замена последовательной загрузки меток параллельными/пакетными операциями.
- Улучшение стратегии кэширования: Реализация интеллектуального кэширования с вытеснением по принципу LRU и предварительной загрузкой.
- Оптимизация запросов: Добавление мемоизации результатов и кэширования вложений для повышения скорости отклика.
Цели
Сокращение объема запросов к базе данных: Достижение снижения общего количества запросов к базе данных на 50-80% за счет пакетной обработки и кэширования. Улучшение времени отклика: Целевое увеличение скорости построения подграфов в 3-5 раз и ускорение разрешения меток в 2-3 раза. Повышение масштабируемости: Поддержка более крупных графов знаний с улучшением управления памятью. Сохранение точности: Сохранение существующей функциональности GraphRAG и качества результатов. Обеспечение параллельности: Улучшение возможностей параллельной обработки для нескольких одновременных запросов. <<<<<<< HEAD Уменьшение объема памяти: Реализация эффективных структур данных и управления памятью.
Уменьшение объема используемой памяти: Реализация эффективных структур данных и управления памятью.
82edf2d (New md files from RunPod) Добавление возможностей мониторинга: Включение показателей производительности и возможностей мониторинга. Обеспечение надежности: Добавление надлежащей обработки ошибок и механизмов таймаута.
Предыстория
Текущая реализация GraphRAG в trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py имеет несколько критических проблем с производительностью, которые серьезно влияют на масштабируемость системы:
Текущие проблемы с производительностью
1. Неэффективный обход графа (функция follow_edges, строки 79-127)
Выполняет 3 отдельных запроса к базе данных для каждой сущности на каждом уровне глубины.
Шаблон запроса: запросы на основе субъекта, запросы на основе предиката и запросы на основе объекта для каждой сущности.
Без пакетной обработки: Каждый запрос обрабатывает только одну сущность за раз.
Без обнаружения циклов: Может повторно посещать одни и те же узлы несколько раз.
Рекурсивная реализация без мемоизации приводит к экспоненциальной сложности.
Временная сложность: O(entities × max_path_length × triple_limit³)
2. Последовательное разрешение меток (функция get_labelgraph, строки 144-171)
Обрабатывает каждый компонент тройки (субъект, предикат, объект) последовательно.
Каждый вызов maybe_label потенциально вызывает запрос к базе данных.
Без параллельного выполнения или пакетной обработки запросов меток.
<<<<<<< HEAD
В результате получается до 3 × subgraph_size отдельных вызовов базы данных.
Приводит до 3 × subgraph_size отдельных вызовов базы данных.
82edf2d (New md files from RunPod)
3. Примитивная стратегия кэширования (функция maybe_label, строки 62-77)
Простой кэш в виде словаря без ограничений размера или TTL.
Отсутствие политики вытеснения кэша приводит к неограниченному росту памяти.
Пропуски кэша вызывают отдельные запросы к базе данных.
Без предварительной загрузки или интеллектуального подогрева кэша.
4. Субоптимальные шаблоны запросов Запросы на сравнение векторного сходства сущностей не кэшируются между похожими запросами. Без мемоизации результатов для повторяющихся шаблонов запросов. <<<<<<< HEAD Отсутствие оптимизации запросов для распространенных шаблонов доступа.
Отсутствует оптимизация запросов для распространенных шаблонов доступа.
82edf2d (New md files from RunPod)
5. Критические проблемы с жизненным циклом объектов (rag.py:96-102)
Объект GraphRag создается для каждого запроса: Новый экземпляр создается для каждого запроса, что приводит к потере всех преимуществ кэша.
Объект запроса имеет очень короткий срок службы: Создается и уничтожается в течение выполнения одного запроса (строки 201-207).
Кэш меток сбрасывается для каждого запроса: Подогрев кэша и накопленные знания теряются между запросами.
<<<<<<< HEAD
Накладные расходы на повторное создание клиента: Клиенты базы данных потенциально повторно устанавливаются для каждого запроса.
Без оптимизации между запросами: Невозможно извлечь выгоду из шаблонов запросов или совместного использования результатов.
Накладные расходы на повторное создание клиента: Клиенты базы данных потенциально пересоздаются для каждого запроса. Отсутствие оптимизации между запросами: Невозможно извлечь выгоду из шаблонов запросов или обмена результатами.
82edf2d (New md files from RunPod)
Анализ влияния на производительность
Текущий наихудший сценарий для типичного запроса: Извлечение сущности: 1 запрос на сравнение векторного сходства. Обход графа: entities × max_path_length × 3 × triple_limit запросов. Разрешение меток: subgraph_size × 3 отдельных запросов на разрешение меток.
<<<<<<< HEAD Для параметров по умолчанию (50 сущностей, длина пути 2, ограничение в 30 тройки, размер подграфа 150): Минимальное количество запросов: 1 + (50 × 2 × 3 × 30) + (150 × 3) = 9451 запрос к базе данных Время отклика: 15-30 секунд для графов среднего размера Использование памяти: Неограниваемый рост кэша со временем
Для параметров по умолчанию (50 сущностей, длина пути 2, ограничение в 30 троек, размер подграфа 150): Минимальное количество запросов: 1 + (50 × 2 × 3 × 30) + (150 × 3) = 9451 запрос к базе данных Время отклика: 15-30 секунд для графов среднего размера Использование памяти: Неограниченный рост кэша со временем
82edf2d (New md files from RunPod) Эффективность кэша: 0% - кэши сбрасываются при каждом запросе Накладные расходы на создание объектов: Объекты GraphRag + Query создаются/удаляются для каждого запроса
Эта спецификация решает эти проблемы, реализуя пакетные запросы, интеллектуальное кэширование и параллельную обработку. Оптимизируя шаблоны запросов и доступ к данным, TrustGraph может: Поддерживать графы знаний корпоративного уровня с миллионами сущностей Обеспечивать время отклика менее 1 секунды для типичных запросов Обрабатывать сотни одновременных запросов GraphRAG <<<<<<< HEAD Эффективно масштабироваться в зависимости от размера и сложности графа
Эффективно масштабироваться с увеличением размера и сложности графа
82edf2d (New md files from RunPod)
Технический дизайн
Архитектура
Оптимизация производительности GraphRAG требует следующих технических компонентов:
1. Архитектурная реорганизация жизненного цикла объектов
<<<<<<< HEAD Сделать GraphRag долгоживущим: Переместить экземпляр GraphRag на уровень Processor для сохранения между запросами Сохранять кэши: Поддерживать кэш меток, кэш вложений и кэш результатов запросов между запросами Оптимизировать объект Query: Переработать Query как легковесный контекст выполнения, а не контейнер данных Сохранять подключения к базе данных: Поддерживать подключения к базе данных между запросами
Сделать GraphRag долгоживущим: Переместить экземпляр GraphRag на уровень Processor для сохранения данных между запросами Сохранять кэши: Поддерживать кэш меток, кэш вложений и кэш результатов запросов между запросами Оптимизировать объект Query: Переработать Query как легковесный контекст выполнения, а не контейнер данных Сохранять соединения с базой данных: Поддерживать соединения с базой данных между запросами
82edf2d (New md files from RunPod)
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py (изменен)
2. Оптимизированный движок обхода графа
<<<<<<< HEAD
Заменить рекурсивную follow_edges на итеративный поиск в ширину
Реализовать пакетную обработку сущностей на каждом уровне обхода
Добавить обнаружение циклов с помощью отслеживания посещенных узлов
Заменить рекурсивную функцию follow_edges на итеративный поиск в ширину
Реализовать пакетную обработку сущностей на каждом уровне обхода
Добавить обнаружение циклов с использованием отслеживания посещенных узлов
82edf2d (New md files from RunPod) Включить раннее завершение при достижении лимитов
Модуль: 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 минут) для баланса между производительностью и согласованностью <<<<<<< HEAD Мониторинг метрик кэша и коэффициента попадания Без кэширования вложений: Уже кэшируются для каждого запроса, нет преимуществ для межзапросных данных
Мониторинг метрик кэша и коэффициента попаданий Без кэширования вложений: Уже кэшируются для каждого запроса, нет преимуществ для межзапросных операций
82edf2d (New md files from RunPod) Без кэширования результатов запросов: Из-за проблем согласованности изменений графа
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/cache_manager.py
5. Фреймворк оптимизации запросов
Анализ шаблонов запросов и предложения по оптимизации Пакетный координатор запросов для доступа к базе данных <<<<<<< HEAD Управление пулами соединений и временем ожидания запросов
Управление пулом соединений и временем ожидания запросов
82edf2d (New md files from RunPod) Мониторинг производительности и сбор метрик
Модуль: trustgraph-flow/trustgraph/retrieval/graph_rag/query_optimizer.py
Модели данных
Оптимизированное состояние обхода графа
Движок обхода поддерживает состояние для предотвращения избыточных операций:
@dataclass
class TraversalState:
visited_entities: Set[str]
current_level_entities: Set[str]
next_level_entities: Set[str]
subgraph: Set[Tuple[str, str, str]]
depth: int
query_batch: List[TripleQuery]
Этот подход позволяет: Эффективное обнаружение циклов за счет отслеживания посещенных сущностей. Подготовку запросов пакетами на каждом уровне обхода. Экономичное использование памяти для управления состоянием. Раннее завершение, когда достигнуты ограничения по размеру.
Улучшенная структура кэша
@dataclass
class CacheEntry:
value: Any
timestamp: float
access_count: int
ttl: Optional[float]
class CacheManager:
label_cache: LRUCache[str, CacheEntry]
embedding_cache: LRUCache[str, CacheEntry]
query_result_cache: LRUCache[str, CacheEntry]
cache_stats: CacheStatistics
Структуры пакетных запросов
@dataclass
class BatchTripleQuery:
entities: List[str]
query_type: QueryType # SUBJECT, PREDICATE, OBJECT
limit_per_entity: int
@dataclass
class BatchLabelQuery:
entities: List[str]
predicate: str = LABEL
API
Новые API:
API GraphTraversal
async def optimized_follow_edges_batch(
entities: List[str],
max_depth: int,
triple_limit: int,
max_subgraph_size: int
) -> Set[Tuple[str, str, str]]
API для разрешения меток пакетов
async def resolve_labels_batch(
entities: List[str],
cache_manager: CacheManager
) -> Dict[str, str]
API управления кэшем
class CacheManager:
async def get_or_fetch_label(self, entity: str) -> str
async def get_or_fetch_embeddings(self, query: str) -> List[float]
async def cache_query_result(self, query_hash: str, result: Any, ttl: int)
def get_cache_statistics(self) -> CacheStatistics
Измененные API:
GraphRag.query() - Улучшено с оптимизациями производительности: Добавлен параметр cache_manager для управления кэшем. Добавлено возвращаемое значение performance_metrics. Добавлен параметр query_timeout для повышения надежности.
Класс Query - Рефакторинг для пакетной обработки: Замена обработки отдельных сущностей на пакетные операции. Добавлены асинхронные контекстные менеджеры для очистки ресурсов. Добавлены обратные вызовы для отслеживания прогресса длительных операций.
Детали реализации
Фаза 0: Критическая архитектурная реорганизация жизненного цикла
Текущая проблемная реализация:
# INEFFICIENT: GraphRag recreated every request
class Processor(FlowProcessor):
async def on_request(self, msg, consumer, flow):
# PROBLEM: New GraphRag instance per request!
self.rag = GraphRag(
embeddings_client = flow("embeddings-request"),
graph_embeddings_client = flow("graph-embeddings-request"),
triples_client = flow("triples-request"),
prompt_client = flow("prompt-request"),
verbose=True,
)
# Cache starts empty every time - no benefit from previous requests
response = await self.rag.query(...)
# VERY SHORT-LIVED: Query object created/destroyed per request
class GraphRag:
async def query(self, query, user="trustgraph", collection="default", ...):
q = Query(rag=self, user=user, collection=collection, ...) # Created
kg = await q.get_labelgraph(query) # Used briefly
# q automatically destroyed when function exits
Оптимизированная архитектура с длительным сроком службы:
class Processor(FlowProcessor):
def __init__(self, **params):
super().__init__(**params)
self.rag_instance = None # Will be initialized once
self.client_connections = {}
async def initialize_rag(self, flow):
"""Initialize GraphRag once, reuse for all requests"""
if self.rag_instance is None:
self.rag_instance = LongLivedGraphRag(
embeddings_client=flow("embeddings-request"),
graph_embeddings_client=flow("graph-embeddings-request"),
triples_client=flow("triples-request"),
prompt_client=flow("prompt-request"),
verbose=True,
)
return self.rag_instance
async def on_request(self, msg, consumer, flow):
# REUSE the same GraphRag instance - caches persist!
rag = await self.initialize_rag(flow)
# Query object becomes lightweight execution context
response = await rag.query_with_context(
query=v.query,
execution_context=QueryContext(
user=v.user,
collection=v.collection,
entity_limit=entity_limit,
# ... other params
)
)
class LongLivedGraphRag:
def __init__(self, ...):
# CONSERVATIVE caches - balance performance vs consistency
self.label_cache = LRUCacheWithTTL(max_size=5000, ttl=300) # 5min TTL for freshness
# Note: No embedding cache - already cached per-query, no cross-query benefit
# Note: No query result cache due to consistency concerns
self.performance_metrics = PerformanceTracker()
async def query_with_context(self, query: str, context: QueryContext):
# Use lightweight QueryExecutor instead of heavyweight Query object
executor = QueryExecutor(self, context) # Minimal object
return await executor.execute(query)
@dataclass
class QueryContext:
"""Lightweight execution context - no heavy operations"""
user: str
collection: str
entity_limit: int
triple_limit: int
max_subgraph_size: int
max_path_length: int
class QueryExecutor:
"""Lightweight execution context - replaces old Query class"""
def __init__(self, rag: LongLivedGraphRag, context: QueryContext):
self.rag = rag
self.context = context
# No heavy initialization - just references
async def execute(self, query: str):
# All heavy lifting uses persistent rag caches
return await self.rag.execute_optimized_query(query, self.context)
Это архитектурное изменение обеспечивает: Сокращение количества запросов к базе данных на 10-20% для графов с общими связями (по сравнению с текущими 0%) Устранение накладных расходов на создание объектов для каждого запроса Постоянное использование пула соединений и повторное использование клиентов Оптимизация между запросами в пределах временных окон TTL кэша
Важное ограничение согласованности кэша: Долгосрочное кэширование создает риск устаревания данных, когда сущности/метки удаляются или изменяются в базовом графе. Кэш LRU с TTL обеспечивает баланс между повышением производительности и актуальностью данных, но не может обнаруживать изменения в графе в режиме реального времени.
Фаза 1: Оптимизация обхода графа
Проблемы текущей реализации:
# INEFFICIENT: 3 queries per entity per level
async def follow_edges(self, ent, subgraph, path_length):
# Query 1: s=ent, p=None, o=None
res = await self.rag.triples_client.query(s=ent, p=None, o=None, limit=self.triple_limit)
# Query 2: s=None, p=ent, o=None
res = await self.rag.triples_client.query(s=None, p=ent, o=None, limit=self.triple_limit)
# Query 3: s=None, p=None, o=ent
res = await self.rag.triples_client.query(s=None, p=None, o=ent, limit=self.triple_limit)
Оптимизированная реализация:
async def optimized_traversal(self, entities: List[str], max_depth: int) -> Set[Triple]:
visited = set()
current_level = set(entities)
subgraph = set()
for depth in range(max_depth):
if not current_level or len(subgraph) >= self.max_subgraph_size:
break
# Batch all queries for current level
batch_queries = []
for entity in current_level:
if entity not in visited:
batch_queries.extend([
TripleQuery(s=entity, p=None, o=None),
TripleQuery(s=None, p=entity, o=None),
TripleQuery(s=None, p=None, o=entity)
])
# Execute all queries concurrently
results = await self.execute_batch_queries(batch_queries)
# Process results and prepare next level
next_level = set()
for result in results:
subgraph.update(result.triples)
next_level.update(result.new_entities)
visited.update(current_level)
current_level = next_level - visited
return subgraph
Фаза 2: Параллельное разрешение меток
Текущая последовательная реализация:
# INEFFICIENT: Sequential processing
for edge in subgraph:
s = await self.maybe_label(edge[0]) # Individual query
p = await self.maybe_label(edge[1]) # Individual query
o = await self.maybe_label(edge[2]) # Individual query
Оптимизированная параллельная реализация:
async def resolve_labels_parallel(self, subgraph: List[Triple]) -> List[Triple]:
# Collect all unique entities needing labels
entities_to_resolve = set()
for s, p, o in subgraph:
entities_to_resolve.update([s, p, o])
# Remove already cached entities
uncached_entities = [e for e in entities_to_resolve if e not in self.label_cache]
# Batch query for all uncached labels
if uncached_entities:
label_results = await self.batch_label_query(uncached_entities)
self.label_cache.update(label_results)
# Apply labels to subgraph
return [
(self.label_cache.get(s, s), self.label_cache.get(p, p), self.label_cache.get(o, o))
for s, p, o in subgraph
]
Фаза 3: Продвинутая стратегия кэширования
Кэш LRU с TTL:
class LRUCacheWithTTL:
def __init__(self, max_size: int, default_ttl: int = 3600):
self.cache = OrderedDict()
self.max_size = max_size
self.default_ttl = default_ttl
self.access_times = {}
async def get(self, key: str) -> Optional[Any]:
if key in self.cache:
# Check TTL expiration
if time.time() - self.access_times[key] > self.default_ttl:
del self.cache[key]
del self.access_times[key]
return None
# Move to end (most recently used)
self.cache.move_to_end(key)
return self.cache[key]
return None
async def put(self, key: str, value: Any):
if key in self.cache:
self.cache.move_to_end(key)
else:
if len(self.cache) >= self.max_size:
# Remove least recently used
oldest_key = next(iter(self.cache))
del self.cache[oldest_key]
del self.access_times[oldest_key]
self.cache[key] = value
self.access_times[key] = time.time()
Фаза 4: Оптимизация запросов и мониторинг
Сбор показателей производительности:
@dataclass
class PerformanceMetrics:
total_queries: int
cache_hits: int
cache_misses: int
avg_response_time: float
subgraph_construction_time: float
label_resolution_time: float
total_entities_processed: int
memory_usage_mb: float
Тайм-аут запроса и предохранитель:
async def execute_with_timeout(self, query_func, timeout: int = 30):
try:
return await asyncio.wait_for(query_func(), timeout=timeout)
except asyncio.TimeoutError:
logger.error(f"Query timeout after {timeout}s")
raise GraphRagTimeoutError(f"Query exceeded timeout of {timeout}s")
Соображения по обеспечению согласованности кэша
Компромиссы между актуальностью данных: Кэш меток (TTL 5 минут): Риск предоставления устаревших меток сущностей (удаленных или переименованных). <<<<<<< HEAD Отсутствие кэширования вложений: Не требуется, так как вложения уже кэшируются для каждого запроса.
Отсутствие кэширования вложений: Не требуется - вложения уже кэшируются для каждого запроса.
82edf2d (New md files from RunPod) Отсутствие кэширования результатов: Предотвращает получение устаревших результатов подграфов из-за удаленных сущностей/связей.
Стратегии смягчения: Консервативные значения TTL: Баланс между приростом производительности (10-20%) и актуальностью данных. <<<<<<< HEAD Хуки для аннулирования кэша: Необязательная интеграция с событиями изменения графа. Панели мониторинга: Отслеживание показателей попадания в кэш по сравнению с инцидентами устаревания данных. Настраиваемые политики кэширования: Возможность тонкой настройки для каждого развертывания в зависимости от частоты изменений.
Рекомендуемая конфигурация кэша в зависимости от частоты изменений графа: Высокая частота изменений (>100 изменений/час): TTL=60 секунд, меньшие размеры кэша. Средняя частота изменений (10-100 изменений/час): TTL=300 секунд (по умолчанию). Низкая частота изменений (<10 изменений/час): TTL=600 секунд, большие размеры кэша.
Механизмы аннулирования кэша: Необязательная интеграция с событиями изменения графа. Информационные панели мониторинга: Отслеживание показателей попадания в кэш по сравнению с инцидентами устаревания данных. Настраиваемые политики кэширования: Возможность тонкой настройки для каждого развертывания в зависимости от частоты изменений.
Рекомендуемая конфигурация кэша в зависимости от скорости изменений графа: Высокая скорость изменений (>100 изменений/час): TTL=60 секунд, меньшие размеры кэша. Средняя скорость изменений (10-100 изменений/час): TTL=300 секунд (по умолчанию). Низкая скорость изменений (<10 изменений/час): TTL=600 секунд, большие размеры кэша.
82edf2d (New md files from RunPod)
Соображения безопасности
Предотвращение внедрения запросов: Проверка всех идентификаторов сущностей и параметров запроса. Использование параметризованных запросов для всех взаимодействий с базой данных. Реализация ограничений на сложность запросов для предотвращения атак типа "отказ в обслуживании" (DoS).
Защита ресурсов: Применение ограничений на максимальный размер подграфа. Реализация таймаутов запросов для предотвращения исчерпания ресурсов. Добавление мониторинга и ограничений использования памяти.
Контроль доступа: Поддержание существующей изоляции пользователей и коллекций. Добавление ведения журнала аудита для операций, влияющих на производительность. Реализация ограничения скорости для дорогостоящих операций.
Соображения производительности
<<<<<<< HEAD
Ожидаемые улучшения производительности
Сокращение количества запросов: Сейчас: ~9000+ запросов для типичного запроса. Оптимизировано: ~50-100 пакетных запросов (снижение на 98%).
Ожидаемое повышение производительности
Сокращение количества запросов: Текущее: ~9000+ запросов для типичного запроса. Оптимизированное: ~50-100 пакетных запросов (снижение на 98%).
82edf2d (New md files from RunPod)
Улучшение времени отклика: Обход графа: 15-20 секунд → 3-5 секунд (в 4-5 раза быстрее). Разрешение меток: 8-12 секунд → 2-4 секунды (в 3 раза быстрее). Общий запрос: 25-35 секунд → 6-10 секунд (улучшение в 3-4 раза).
Эффективность использования памяти: Ограниченные размеры кэша предотвращают утечки памяти. Эффективные структуры данных уменьшают объем используемой памяти примерно на 40%. <<<<<<< HEAD Улучшен сбор мусора благодаря правильной очистке ресурсов.
Улучшенная сборка мусора благодаря правильной очистке ресурсов.
82edf2d (New md files from RunPod)
Реалистичные ожидания производительности: Кэш меток: Уменьшение количества запросов на 10-20% для графов с общими связями. Оптимизация пакетной обработки: Уменьшение количества запросов на 50-80% (основная оптимизация). Оптимизация времени жизни объектов: Исключение накладных расходов на создание объектов для каждого запроса. Общее улучшение: Улучшение времени отклика в 3-4 раза, в основном за счет пакетной обработки.
Улучшения масштабируемости: Поддержка графов знаний в 3-5 раза большего размера (ограничено потребностями согласованности кэша). Увеличение количества одновременных запросов в 3-5 раза. Лучшее использование ресурсов благодаря повторному использованию соединений.
Мониторинг производительности
Метрики в реальном времени: Время выполнения запросов по типу операции. Показатели попадания в кэш и его эффективность. Использование пула соединений с базой данных. Использование памяти и влияние сборки мусора.
Бенчмаркинг производительности: Автоматизированное регрессионное тестирование производительности Тестирование нагрузки с использованием реалистичных объемов данных Сравнительные тесты с текущей реализацией
Стратегия тестирования
Модульное тестирование
Тестирование отдельных компонентов для обхода графа, кэширования и разрешения меток Эмуляция взаимодействия с базой данных для тестирования производительности Тестирование вытеснения из кэша и истечения срока действия TTL Обработка ошибок и сценарии таймаутов
Интеграционное тестирование
Комплексное тестирование запросов GraphRAG с оптимизациями Тестирование взаимодействия с базой данных с использованием реальных данных Обработка одновременных запросов и управление ресурсами Обнаружение утечек памяти и проверка очистки ресурсов
Тестирование производительности
Тестирование производительности по сравнению с текущей реализацией <<<<<<< HEAD Тестирование нагрузки с различными размерами и сложностью графов
Тестирование нагрузки с графами различного размера и сложности
82edf2d (New md files from RunPod) Стресс-тестирование для проверки лимитов памяти и соединений Регрессионное тестирование для проверки улучшений производительности
Тестирование совместимости
Проверка совместимости существующего API GraphRAG Тестирование с различными бэкендами графовых баз данных Проверка точности результатов по сравнению с текущей реализацией
План реализации
Прямой подход к реализации
Поскольку API могут изменяться, реализуйте оптимизации напрямую без сложности миграции:
- Замените метод
follow_edges: Перепишите с использованием пакетного итеративного обхода - Оптимизируйте
get_labelgraph: Реализуйте параллельное разрешение меток - Добавьте долгоживущий GraphRag: Измените Processor для поддержания постоянной инстанции <<<<<<< HEAD
- Реализуйте кэширование меток: Добавьте кэш LRU с TTL в класс GraphRag =======
- Реализуйте кэширование меток: Добавьте кэш LRU со сроком действия TTL в класс GraphRag
82edf2d (New md files from RunPod)
Область изменений
Класс запроса: Замените ~50 строк в follow_edges, добавьте ~30 строк для обработки пакетов
Класс GraphRag: Добавьте слой кэширования (~40 строк)
Класс Processor: Измените для использования постоянной инстанции GraphRag (~20 строк)
<<<<<<< HEAD
Всего: ~140 строк целенаправленных изменений, в основном в существующих классах
Всего: ~140 строк изменений, в основном в существующих классах
82edf2d (New md files from RunPod)
Временная шкала
Неделя 1: Основная реализация
Замените follow_edges пакетным итеративным обходом
Реализуйте параллельное разрешение меток в get_labelgraph
Добавьте долгоживущую инстанцию GraphRag в Processor
Реализуйте слой кэширования меток
Неделя 2: Тестирование и интеграция Модульные тесты для новой логики обхода и кэширования Бенчмаркинг производительности по сравнению с текущей реализацией <<<<<<< HEAD Интеграционное тестирование с реальными данными графа
Интеграционное тестирование с реальными графовыми данными
82edf2d (New md files from RunPod) Проверка кода и оптимизация
Неделя 3: Развертывание Разверните оптимизированную реализацию Отслеживайте улучшения производительности <<<<<<< HEAD Тонкая настройка TTL кэша и размеров пакетов на основе реального использования
Открытые вопросы
Пул соединений с базой данных: Следует ли нам реализовать собственный пул соединений или использовать существующий пул соединений от клиента базы данных? Постоянство кэша: Должны ли кэши меток и внедрений сохраняться после перезапуска службы? Распределенное кэширование: Для развернутых в нескольких экземплярах систем следует ли нам реализовать распределенное кэширование с использованием Redis/Memcached? Формат результата запроса: Следует ли нам оптимизировать внутреннее представление тройки для повышения эффективности использования памяти?
Тонкая настройка срока действия TTL кэша и размеров пакетов на основе реального использования
Открытые вопросы
Пул соединений с базой данных: Следует ли нам реализовывать собственный пул соединений или использовать существующий пул соединений от клиента базы данных? Постоянство кэша: Должны ли кэши меток и вложений сохраняться после перезапуска сервиса? Распределенное кэширование: Для развернутых в нескольких инстанциях систем следует ли реализовывать распределенное кэширование с использованием Redis/Memcached? Формат результата запроса: Следует ли оптимизировать внутреннее представление тройки для повышения эффективности использования памяти?
82edf2d (New md files from RunPod) Интеграция мониторинга: Какие метрики следует предоставлять существующим системам мониторинга (Prometheus и т. д.)?
Ссылки
<<<<<<< HEAD Оригинальная реализация GraphRAG
82edf2d (New md files from RunPod) Принципы архитектуры TrustGraph Спецификация управления коллекциями