Как вы проектируете multimodal RAG для диаграмм (flowchart, architecture diagram)?
Краткий тезис
Multimodal RAG для диаграмм — это система, которая извлекает из изображения диаграммы структурированное представление (граф узлов и связей с текстовыми метками), индексирует его для поиска и использует LLM для ответа на вопросы. Ключевые этапы: детекция узлов и стрелок (YOLO), OCR текста внутри них, построение графа отношений, сериализация в текст, гибридный retrieval (текстовый + графовый) и опционально VL-LLM для прямого анализа изображения. Такой подход позволяет отвечать на вопросы о логике, потоке данных и архитектуре, сохраняя контекст диаграммы.
1. Термины и определения
Multimodal RAG — Retrieval-Augmented Generation, работающий с данными разных модальностей (изображение + текст). В контексте диаграмм — извлечение информации из визуального представления и её текстовое описание.
Диаграммы (flowchart, architecture diagram) — схематичные изображения, состоящие из узлов (прямоугольники, ромбы, облака) и связей (стрелки, линии). Flowchart описывает алгоритм/процесс, architecture diagram — структуру системы.
Node detection — задача компьютерного зрения: найти на изображении все геометрические фигуры, являющиеся узлами диаграммы. Часто решается с помощью YOLO (You Only Look Once) или Faster R-CNN.
OCR (Optical Character Recognition) — распознавание текста внутри обнаруженных узлов. Инструменты: Tesseract, PaddleOCR, EasyOCR.
Граф отношений — направленный граф, где вершины — узлы диаграммы, рёбра — стрелки. Каждое ребро может иметь метку (текст на стрелке).
Сериализация — преобразование графа в текстовый формат (JSON, естественный язык) для индексации и передачи LLM.
Graph embedding — векторное представление графа (например, Node2Vec, GraphSAGE) для поиска похожих структур.
VL-LLM (Vision-Language Large Language Model) — мультимодальная LLM, способная обрабатывать изображения напрямую (GPT-4V, LLaVA, Qwen-VL).
2. Общая архитектура pipeline
Pipeline multimodal RAG для диаграмм состоит из этапов:
- Вход: изображение диаграммы (PNG, JPEG, PDF).
- Детекция узлов и стрелок: модель CV (YOLO) находит bounding boxes для узлов (классы: rectangle, diamond, circle, arrow) и их типов.
- OCR: для каждого bounding box узла распознаётся текст (если есть). Для стрелок — текст метки (если есть).
- Построение графа: на основе координат стрелок и узлов определяются связи: от какого узла к какому идёт стрелка, какая у неё метка.
- Сериализация: граф превращается в текстовое описание (например, JSON или предложения).
- Индексация: сериализованный текст эмбеддируется (Sentence-BERT) и сохраняется в векторной БД (FAISS, Qdrant). Дополнительно можно индексировать графовые эмбеддинги.
- Retrieval: по запросу пользователя ищем релевантные диаграммы/части (текстовый поиск + графовый поиск).
- Генерация: найденный контекст (текстовое описание диаграммы) подаётся в LLM для ответа. Опционально — передача изображения в VL-LLM.
3. Детекция узлов и стрелок (YOLO)
Для детекции элементов диаграммы используется object detection. YOLOv8 — хороший выбор из-за скорости и точности.
Классы для детекции:
rectangle— процесс/действие (flowchart)diamond— условие/ветвлениеcircle— начало/конецarrow— стрелка (может быть отдельный класс или детектировать как линию)text_block— текстовая метка на стрелке (опционально)
Обучение модели:
- Собрать датасет из 500–2000 изображений диаграмм (можно синтезировать с помощью graphviz + random layout).
- Разметить bounding boxes и классы (LabelImg, Roboflow).
- Обучить YOLOv8 на 50–100 эпох, аугментации: поворот, масштаб, яркость.
Альтернативы: Faster R-CNN (точнее, но медленнее), DETR (end-to-end, но требует больше данных).
Постобработка: Non-Maximum Suppression (NMS) для удаления дубликатов. Для стрелок можно дополнительно использовать Hough transform или детекцию линий.
4. OCR текста внутри узлов
После детекции для каждого bounding box узла применяется OCR.
Tesseract — бесплатный, хорошо работает с печатным текстом на английском, но чувствителен к шуму и повороту. PaddleOCR — лучше для китайского и сложных фонов, поддерживает детекцию текста.
Проблемы:
- Текст может быть мелким или повёрнутым.
- На диаграммах часто используются шрифты без засечек, что хорошо для OCR.
- Метки на стрелках могут быть расположены не внутри bounding box стрелки, а рядом — нужно дополнительно сопоставлять.
Решение: перед OCR можно применить предобработку изображения (бинаризация, устранение шума, deskew). Для меток стрелок — после детекции стрелки взять область вокруг её середины.
5. Построение графа отношений
На основе координат узлов и стрелок нужно определить, какие узлы соединены.
Алгоритм:
- Для каждой стрелки найти ближайший узел, из которого она выходит (по направлению от начала стрелки) и в который входит (по концу стрелки). Использовать расстояние между центром стрелки и центром узла, порог.
- Если стрелка имеет метку (текст), привязать её к ребру.
- Построить направленный граф:
(source_node, target_node, label).
Инструменты: NetworkX (Python) для хранения и анализа графа.
Пример кода:
import networkx as nx
G = nx.DiGraph()
# node1, node2 — объекты с id, text, bbox
# arrow — объект с source_bbox, target_bbox, label_text
G.add_edge(node1.id, node2.id, label=arrow.label_text)
Сложности: пересекающиеся стрелки, вложенные узлы (sub-diagrams). Для вложенных узлов можно построить иерархический граф.
6. Сериализация в текст
Граф нужно преобразовать в формат, понятный LLM и пригодный для векторного поиска.
Вариант 1: JSON — структурированное представление:
{
"nodes": [
{"id": "A", "type": "process", "text": "Validate input"},
{"id": "B", "type": "decision", "text": "Is valid?"}
],
"edges": [
{"source": "A", "target": "B", "label": ""},
{"source": "B", "target": "C", "label": "yes"}
]
}
Вариант 2: Естественный язык — более читаемо для LLM:
Node A (process) with text "Validate input" is connected to Node B (decision) with text "Is valid?" via arrow. From Node B, if "yes", go to Node C (process) "Send email".
Выбор: для retrieval лучше использовать текст на естественном языке (эмбеддинги Sentence-BERT лучше работают с предложениями). JSON можно использовать как дополнительный структурированный контекст.
7. Индексация и retrieval
Два подхода к поиску релевантных диаграмм/частей:
Текстовый retrieval:
- Сериализованное описание диаграммы (или отдельных фрагментов) эмбеддируется с помощью Sentence-BERT (all-MiniLM-L6-v2).
- Индекс в FAISS (IVF, HNSW).
- По запросу пользователя ищем топ-k описаний.
Графовый retrieval:
- Для каждой диаграммы вычисляем graph embedding (Node2Vec, GraphSAGE) — вектор, представляющий всю структуру.
- По запросу, если он содержит структурные паттерны (например, "цикл в процессе"), можно искать по графовым эмбеддингам.
- Комбинированный подход: взвешенная сумма текстового и графового сходства.
- Сначала текстовый поиск (быстрый), затем ранжирование с учётом графовой близости.
- Или мультимодальный эмбеддинг (CLIP) для прямого поиска по изображению, но CLIP плохо понимает структуру диаграмм.
8. Использование VL-LLM
Если контекст позволяет (диаграмма небольшая, вопрос требует визуального анализа), можно передать изображение напрямую в VL-LLM (GPT-4V, LLaVA).
Плюсы:
- Не нужен сложный pipeline детекции и OCR.
- Модель может понять общую логику, даже если детекция ошибается.
Минусы:
- Высокая стоимость и latency.
- Ограничение по размеру изображения (токены).
- Не подходит для большого количества диаграмм (retrieval всё равно нужен).
Стратегия: использовать VL-LLM как fallback, когда текстовый retrieval не дал уверенного ответа, или для верификации.
9. Оценка качества
Метрики для оценки pipeline:
- Точность детекции: mAP (mean Average Precision) для узлов и стрелок.
- Точность OCR: Character Error Rate (CER) на тестовых изображениях.
- Точность графа: F1-score по узлам и рёбрам (сравнение с ground truth графом).
- Retrieval: recall@k, MRR на наборе вопросов (например, "Какой узел следует после 'Validate input'?").
- Faithfulness ответа: доля ответов LLM, которые не противоречат извлечённому графу (оценка с помощью LLM-as-judge).
10. Проблемы и решения
| Проблема | Решение |
|---|---|
| Пересекающиеся стрелки | Использовать алгоритмы трассировки линий (например, LSD) или детекцию ключевых точек. |
| Вложенные диаграммы (sub-diagrams) | Иерархическая детекция: сначала найти внешние блоки, затем внутренние. |
| Рукописный текст | Использовать OCR на основе Transformer (TrOCR) или дообучить на рукописных данных. |
| Большие диаграммы (много узлов) | Разбивать на фрагменты (sliding window) и индексировать каждый фрагмент отдельно. |
| Латенси (VL-LLM медленный) | Использовать кэширование ответов, ставить VL-LLM только для сложных вопросов. |
11. Пример кода (Python)
import cv2
from ultralytics import YOLO
import pytesseract
import networkx as nx
from sentence_transformers import SentenceTransformer
import faiss
# 1. Детекция
model = YOLO('diagram_detector.pt')
results = model('diagram.png')
nodes = []
for box in results[0].boxes:
x1, y1, x2, y2 = box.xyxy[0]
cls = int(box.cls[0])
nodes.append({'bbox': (x1, y1, x2, y2), 'class': cls})
# 2. OCR
for node in nodes:
crop = img[int(y1):int(y2), int(x1):int(x2)]
text = pytesseract.image_to_string(crop, lang='eng')
node['text'] = text.strip()
# 3. Построение графа (упрощённо)
G = nx.DiGraph()
# ... логика сопоставления стрелок ...
# 4. Сериализация
description = ""
for node in nodes:
description += f"Node {node['id']} ({node['class']}): {node['text']}\n"
for edge in G.edges(data=True):
description += f"{edge[0]} -> {edge[1]}: {edge[2].get('label', '')}\n"
# 5. Индексация
encoder = SentenceTransformer('all-MiniLM-L6-v2')
embedding = encoder.encode([description])
index = faiss.IndexFlatL2(384)
index.add(embedding)
# 6. Retrieval
query = "What happens after validation?"
q_emb = encoder.encode([query])
D, I = index.search(q_emb, k=1)
retrieved_desc = descriptions[I[0][0]]
Пет-проект для закрепления
Задача: Создать RAG-систему, которая отвечает на вопросы по архитектурным диаграммам AWS (например, "Какие сервисы используются для хранения данных?").
Инструменты: YOLOv8, Tesseract, NetworkX, Sentence-Transformers, FAISS, GPT-4V API (опционально).
Шаги:
- Собрать 100–200 изображений AWS architecture diagrams (можно из статей).
- Разметить узлы (сервисы: EC2, S3, Lambda) и стрелки (связи).
- Обучить YOLO на 5–10 классах (EC2, S3, Lambda, RDS, API Gateway, стрелка).
- Написать pipeline: детекция → OCR → граф → сериализация.
- Индексировать описания в FAISS.
- Реализовать retrieval по текстовому запросу.
- Добавить fallback: если retrieval не уверен (< порога), отправить изображение в GPT-4V.
Ожидаемый результат: Система отвечает на вопросы типа "Какой сервис обрабатывает запросы перед Lambda?" с точностью >80% на тестовом наборе из 20 вопросов.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 560 | Как проектировать multimodal RAG для таблиц и графиков? |
| 562 | Как вы обрабатываете изображения в RAG (схемы, графики)? |
| 563 | Как вы оцениваете качество multimodal RAG? |
| 550 | Что такое multimodal embedding и как его использовать? |
| 555 | Как вы строите гибридный поиск (текст + изображение)? |
| 570 | Как вы используете VL-LLM в RAG? |
Навигация
- Предыдущий: 560
- Следующий: 562
- Индекс: 00. Индекс разборов