Перейти к содержимому
RAGRAF

GPU-вычисления: когда графы и эмбеддинги считают на видеокарте

Два GPU-пути RAGRAF (эмбеддинги и тензорный обход графов), измеренные пороги переключения, backend-каскад и честная экономика ускорения.

Два независимых GPU-пути #

RAGRAF умеет использовать GPU в двух разных задачах, и их экономика отличается на порядок. Путать их — главная ошибка при планировании железа.

ПутьГде живётЧто ускоряетПорог включения
Эмбеддингиcompute.py (sentence-transformers + torch)пакетное векторизование чанков при индексации~1 800 текстов за проход
Обход графовgraph_algo.py (torch.sparse, CSR)батч-достижимость/срезы на больших графах~5 000 вершин

Оба пути опциональны: без torch/CUDA продукт полностью функционален на CPU (backend-каскад torch-gpu → torch-cpu → none выбирается автоматически и записывается в метаданные ревизии с полем reason — никогда не подразумевается).

Путь 1: эмбеддинги (compute.py) #

Базовый путь продукта — fastembed/ONNX Runtime (CPU, без torch). GPU-путь включается, когда torch+ CUDA присутствуют и объём текста превышает порог окупаемости:

Text
GPU-режим: подготовка карты устройства — ~15 с (разово на процесс)
Порог окупаемости: ~1 800 текстов за индексацию
Ниже порога: CPU быстрее (накладные GPU не окупаются)

Практический смысл: на пилотном корпусе (457 чанков) GPU медленнее — 15-секундная подготовка карты съедает выигрыш. На корпусе в 5–10 тысяч файлов (десятки тысяч чанков) GPU-индексация даёт кратное ускорение векторизации. Одиночные поисковые запросы GPU почти не ускоряет (один эмбеддинг запроса — микросекунды работы против 15 с подготовки); поэтому search остаётся ~1 с на CPU — доминирует не устройство, а отсутствие кэша запросов (R-PERF-3).

Измерения пишутся честно: last_seconds и reason (почему выбран путь) — в метаданные; панель показывает их во вкладке качества.

Путь 2: тензорный обход графов (graph_algo.py) #

Достижимость и срезы на больших графах — это матричные операции. При ≥ ~5 000 вершин граф перекладывается в CSR-представление torch.sparse и обходится батчами:

BackendКогдаЧто это даёт
torch-gpuCUDA + большой графimpact/slice батчами на видеокарте; латентность p95 укладывается в контракт ≤1 с на графах, где CPU-обход выходит за рамки
torch-cputorch без CUDAтот же тензорный код на CPU — всё равно быстрее наивного обхода на больших графах
noneбез torchрекурсивные CTE SQLite — контракт производительности выполняется на пилотных размерах (487 узлов: impact ≤ 1 с с запасом)

Ограничение CSR (документировано честно): CSR-представление не любит мутаций — добавление рёбер на лету требует пересборки матрицы. Отсюда следствие: CPG пересобирается полным прогоном, а «живой граф» (мутации между ревизиями) — не цель архитектуры (ревизия иммутабельна, принцип P1).

Конфигурация #

YAML
embedding:
  device: auto        # auto | cpu | cuda — auto выбирает по порогам и наличию torch
compute:
  gpu_vector_threshold: 1800    # текстов; ниже — CPU
  gpu_graph_threshold: 5000     # вершин; ниже — обычный обход

Пороги настраиваются, потому что «окупаемость» зависит от конкретной карты и корпуса; значения по умолчанию — измерены, не взяты с потолка (config.py, секция compute). Переменные окружения: RAGRAF_JOERN_HEAP_GB (Joern), стандартные CUDA_VISIBLE_DEVICES (torch).

Экономика ускорения: сводная таблица #

ЗадачаCPU (пилот: 123 файла / 457 чанков / 487 узлов)GPUВердикт
Полная индексация71 с (CPG 64 с, эмбеддинги ~5 с)подготовка карты 15 с + эмбеддинги ~1 сCPU — Joern доминирует, GPU не помогает
Индексация 10k файловдесятки минут (эмбеддинги)кратное ускорение векторизацииGPU
impact/callers (487 узлов)0,7 мс — 1 снет смыслаCPU
slice на графе 50k+ вершинвыходит за контрактбатч-обход в контрактеGPU
Одиночный search~1 с~1 с (подготовка не окупается)CPU (кэш запросов — R-PERF-3)

Границы и roadmap #

  • torch не объявлен в зависимостях (осознанно: базовый продукт обязан ставиться без 2 ГБ фреймворка). Формализация — extras ragraf[gpu] (R-PKG-1 в roadmap).
  • CUDA-версии не пинятся — совместимость torch/CUDA/dрайвера остаётся на стороне окружения; selftest сообщает фактический backend.
  • Смешанных режимов нет: эмбеддинги и граф выбираются независимо, но «половина индексации на GPU, половина на CPU» внутри одного этапа не балансируется динамически (перспектива — см. future).
  • Измерения порогов выполнены на пилотном оборудовании; на других картах пороги стоит перепроверить --json-таймингами (last_seconds/reason).

Как проверить свой режим #

Shell
ragraf -p cfg.yaml status --json
# → "compute": {"embedding_backend": "fastembed-cpu", "graph_backend": "none",
#               "reason": "gpu_vector_threshold не достигнут (457 < 1800)"}

Панель администратора показывает backend и reason во вкладке качества; эмулятор панели демонстрирует оба состояния (CPU/GPU-корпус) на реальных числах пилота.


Смежное: CPG/Joern → · конфигурация → · замеры →