English translation is not available yet. Showing Russian content.

Что такое Layout-Aware Chunking и как он связан с мультимодальностью?

Краткий тезис

Layout-Aware Chunking — это стратегия разбиения документов на фрагменты (чанки) с учётом визуальной структуры страницы: заголовков, колонок, таблиц, блоков текста, изображений. В отличие от наивного разбиения по фиксированному числу токенов, такой подход сохраняет семантическую целостность фрагментов и критически важен для мультимодального RAG, где документы содержат не только текст, но и графику, вёрстку, таблицы. Связь с мультимодальностью прямая: Chunking|layout-aware chunking использует визуальные признаки (расположение, размер шрифта, границы блоков), чтобы определить логические границы чанка, что позволяет извлекать из мультимодальных документов (PDF, сканы, веб-страницы) не только чистый текст, но и структурированные данные, которые затем могут быть заиндексированы вместе с визуальными элементами (например, эмбеддингами изображений).


1. Термин: Layout-Aware Chunking

Layout-Aware Chunking (разбиение с учётом разметки) — метод разделения документа на фрагменты, при котором границы чанков определяются не по числу токенов или символов, а по логическим и визуальным элементам документа: абзацам, секциям, заголовкам, таблицам, колонкам, подписям к рисункам.

Основная идея: чанк должен быть семантически когерентным — содержать законченную мысль или блок информации, который легко интерпретировать изолированно. Для этого надо понимать, где заканчивается один логический блок (например, колонка в газете) и начинается другой.

В наивном подходе (фиксированный размер – sliding window) чанки часто обрезают таблицы пополам, смешивают текст из разных колонок или разрывают заголовок и относящийся к нему абзац. Это ухудшает retrieval (поиск) и качество ответа.


2. Проблема наивного chunking в документах со сложной вёрсткой

Типичные проблемы при разбиении документов (статьи, отчёты, руководства) по фиксированной длине:

Тип сложностиПримерПроблема при наивном chunking
Многоколоночная вёрсткаГазета, научная статья в две колонкиТекст из левой и правой колонок сливается в один чанк, теряется порядок чтения
ТаблицыФинансовый отчёт с таблицей на полстраницыТаблица разрезается на два чанка; retrieval не может найти все строки
Врезки / выносыОпределение, выделенное рамкой, внутри текстаВрезка воспринимается как часть соседнего абзаца, хотя семантически самостоятельна
Заголовки и подписиПодпись к рисунку на следующей страницеПодпись оказывается в чанке без самого рисунка, контекст теряется
СпискиМаркированный список, переходящий на новую страницуОдин пункт списка в разных чанках — нарушение структуры

Итог: retrieval возвращает фрагменты, которые трудно понять LLM (модели теряют контекст), а faithfulness (точность ответа) падает.


3. Как работает Layout-Aware Chunking: пайплайн

Типовой пайплайн для Chunking|layout-aware chunking:

Документ (PDF/скан) → Парсинг (извлечение текста + bounding boxes) 
                    → Layout detection (обнаружение блоков) 
                    → Семантическая кластеризация 
                    → Разбиение на чанки по блокам 
                    → Индексация (текстовые эмбеддинги + метаданные структуры)

3.1 Парсинг и извлечение макета

Из документа извлекаются raw text (сырой текст) и визуальные координаты (позиция каждого слова/символа на странице). Инструменты: PyMuPDF (fitz), pdfplumber, Camelot (для таблиц), Tesseract (OCR для сканов).

3.2 Layout Detection

Обнаружение структурных блоков: заголовков (по размеру шрифта, жирности), колонок (по пробелам, расположению текста), таблиц (по пересечению линий), врезок (по ограничивающим рамкам). Используются:

  • Rule-based методы: сравнение координат, поиск пустых областей, кластеризация по y-координатам.
  • ML-модели: LayoutLM, Detectron2 (Faster R-CNN, Mask R-CNN), Unstructured.io (использует pdfminer.six + эвристики).

3.3 Семантическая кластеризация

Сгруппировать близкие по смыслу блоки, которые должны остаться в одном чанке. Например, заголовок + следующий за ним абзац, все ячейки одной строки таблицы, элементы одного списка. Границы между чанками часто проводят по:

  • смене раздела (заголовок, уровень 1);
  • пустой строке более определённой высоты;
  • переходу на другую колонку;
  • полю "новый блок" в разметке ML.

3.4 Разбиение

После кластеризации каждый семантический кластер становится чанком. Дополнительно можно задать допустимый диапазон длины (например, 200–1500 токенов), чтобы избежать слишком коротких или слишком длинных фрагментов. Если кластер слишком большой – применяют рекурсивное разбиение по подзаголовкам.


4. Связь с мультимодальностью

Layout-Aware Chunking является ключевым элементом мультимодального RAG, потому что:

  • Использование визуальных признаков – chunking опирается не только на текст, но и на то, как выглядит страница (расположение, шрифты, границы). Это мультимодальный сигнал (визуальная модальность).
  • Индексация не только текста – после выделения блоков можно параллельно извлекать изображения, таблицы, графики и создавать для них отдельные мультимодальные представления (эмбеддинги с помощью CLIP или BLIP). Чанк может содержать как текст блока, так и ссылку на изображение или эмбеддинг таблицы.
  • Сохранение целостности мультимодальных элементов – таблица, состоящая из текста и визуальной сетки, при layout-aware разбиении остаётся одним чанком. Это даёт возможность послать LLM и таблицу, и её визуальное представление (как изображение) для более точного ответа.
  • Обработка сканированных документов – через OCR извлекается текст и его позиции, что позволяет делать layout-aware разбиение даже для документов без цифровой разметки. OCR – тоже мультимодальный процесс (изображение → текст с координатами).

Таким образом, Layout-Aware Chunking — это мост между текстовыми и визуальными модальностями в RAG: он учится структуре документа, чтобы создавать чанки, которые можно мультимодально индексировать и искать.


5. Инструменты и библиотеки

ИнструментНазначениеТипПримечание
PyMuPDF (fitz)Извлечение текста + bounding boxesRule-basedБыстро, работает с любым PDF
pdfplumberРабота с текстом и таблицамиRule-basedХорош для таблиц (поиск линий)
Unstructured.ioLayout detection + chunkingRule-based + MLOpen-source, поддерживает PDF, Word, PPT, сканы
LayoutLMv3Распознавание структуры документа (токены + позиции)MLТребует GPU, обучен на большом корпусе
Detectron2 (Facebook)Обнаружение блоков на странице (как объекты)MLПодходит для сложной вёрстки, но сложен в настройке
TesseractOCR для скановMLИзвлекает текст и координаты
LangChain (RecursiveCharacterTextSplitter с сепараторами)Простой вариант layout-aware через разделителиRule-basedНе совсем layout-aware, но можно задать разделители по заголовкам
Docling (IBM)Извлечение структуры из PDF (включая таблицы)Rule-based + MLНедавний инструмент, хорошо интегрируется с RAG

Для production часто используют комбинацию: PyMuPDF для быстрого извлечения + Unstructured.io для layout detection + LayoutLM (если нужна глубокая ML) + CLIP для создания мультимодальных эмбеддингов изображений.


6. Преимущества для RAG

  • Лучшая семантическая когерентность – чанки не обрывают логический блок (таблицу, список, доказательство).
  • Повышение Recall и MRRretrieval реже даёт пустые или «половинные» результаты.
  • Поддержка мультимодальных запросов – можно найти чанк, содержащий таблицу, и отправить LLM её как в тексте, так и как изображение.
  • Уменьшение noise – меньше токенов, не относящихся к сути (shingles).
  • Улучшение faithfulness – LLM получает цельный контекст, меньше галлюцинаций.

7. Вызовы и ограничения

  • Производительность – детекция макета медленнее, чем простое рекурсивное разбиение (особенно с ML моделями).
  • Сложные сканы – плохое качество OCR (шумы, нестандартные шрифты) может приводить к неверному определению блоков.
  • Языки и шрифты – эвристики, основанные на пробелах/размерах шрифта, могут не работать для азиатских языков.
  • Динамические документы – веб-страницы с адаптивной вёрсткой; layout-aware разбиение должно быть адаптивным под разные разрешения экрана.
  • Отсутствие структуры – для документов без какой-либо разметки (plain text, простые PDF) layout-aware не даёт выигрыша, только overhead (накладные расходы).

8. Пример: Простой Layout-Aware Chunker на PyMuPDF

import fitz  # PyMuPDF
import json

def pdf_to_blocks(pdf_path):
    doc = fitz.open(pdf_path)
    blocks_by_page = []
    for page_num, page in enumerate(doc):
        # Получаем блоки текста с координатами
        text_blocks = page.get_text("dict")["blocks"]
        # Фильтруем только текстовые блоки (блоки изображений могут быть отдельно)
        text_blocks = [b for b in text_blocks if b["type"] == 0]
        blocks = []
        for block in text_blocks:
            # Получаем текст и bounding box
            text = "".join([span["text"] for line in block["lines"] for span in line["spans"]])
            bbox = block["bbox"]  # x0, y0, x1, y1
            # Кластеризуем: испускаем as is, но можно группировать по y0
            blocks.append({
                "page": page_num,
                "bbox": bbox,
                "text": text
            })
        # Сортируем по y0 (сверху вниз)
        blocks.sort(key=lambda b: b["bbox"][1])
        # Группируем по логике: если distance между bbox меньше порога - один чанк
        chunks = []
        current_group = []
        for blk in blocks:
            if not current_group:
                current_group.append(blk)
                continue
            last = current_group[-1]
            # Проверяем, что блок находится на той же колонке и расстоянии по y меньше 10pt
            if (abs(blk["bbox"][0] - last["bbox"][0]) < 50
                and blk["bbox"][1] - last["bbox"][3] < 10):
                current_group.append(blk)
            else:
                # Завершаем группу
                chunk_text = "\n".join([b["text"] for b in current_group])
                chunks.append(chunk_text)
                current_group = [blk]
        if current_group:
            chunk_text = "\n".join([b["text"] for b in current_group])
            chunks.append(chunk_text)
        blocks_by_page.extend(chunks)
    return blocks_by_page

# Использование
chunks = pdf_to_blocks("sample.pdf")
for i, c in enumerate(chunks[:5]):
    print(f"Chunk {i}: {c[:100]}...")

Этот пример использует только координаты; в реальной задаче стоит использовать Unstructured или Detectron2 для более точной разметки.


9. Метрики оценки качества Layout-Aware Chunking

Оценить, насколько хорошо выбран метод, можно через offline метрики retrieval (как в вопросе 5) на специально размеченном датасете (gold standard). Эталонные чанки создаются вручную человеком, затем сравниваются с результатами chunker с помощью:

  • Чанкового IoU (Intersection over Union) – насколько границы автоматических чанков совпадают с эталонными.
  • Recall@k и MRR – если проиндексировать эталонные чанки и автоматические чанки, можно замерить retrieval.
  • Semantic Coherence Score – через эмбеддинги (например, Sentence-BERT) измерить среднее косинусное сходство внутри чанка (должно быть высоким) и различие между чанками (может быть низким).

Пример эксперимента: наивный chunker (sliding window 512 токенов) vs layout-aware (PyMuPDF + clustering). На PDF-датасете с 2000 страницами (статьи, отчёты) layout-aware даёт прирост Recall@10 на 12–18% и улучшение MRR на 0.07–0.10.


10. Практические советы

  • Для документов с простой структурой (одна колонка, только текст) можно обойтись рекурсивным разбиением по разделителям (. \n\n).
  • Для документов с таблицами – обязательно использовать специализированные инструменты (pdfplumber, Camelot).
  • Если документы сканированные – сначала применить OCR и сохранить позиции символов (Tesseract с --psm 6).
  • Для production используйте библиотеку unstructured[pdf] – она уже содержит готовые пайплайны для chunking с учётом layout.
  • Сочетайте текстовые эмбеддинги чанков с эмбеддингами изображений (CLIP) для мультимодального поиска.

Пет-проект для закрепления

Задача Разработать и сравнить naive и layout-aware chunking на коллекции из 20 PDF-документов (статьи, отчёты, таблицы). Оценить влияние на retrieval в RAG-системе.

Инструменты

  • PyMuPDF, Unstructured, pdfplumber – для парсинга;
  • LangChain – для построения простого RAG пайплайна;
  • ChromaDB – векторное хранилище;
  • OpenAI Embeddings (или sentence-transformers);
  • RAGAS – для оценки faithfulness, answer relevance.

Шаги:

  1. Собрать 20 PDF разной сложности (статья с колонками, финансовый отчёт с таблицами, научная статья с рисунками).
  2. Разметить эталонные чанки вручную (10-15 на документ).
  3. Реализовать наивный chunker (RecursiveCharacterTextSplitter, chunk_size=1000, overlap=200).
  4. Реализовать layout-aware chunker на основе Unstructured (или PyMuPDF + pdfplumber).
  5. Для обоих методов сохранить чанки в ChromaDB (текст + эмбеддинг).
  6. Подготовить 50 тестовых запросов (например, «Каковы показатели прибыли за 2023 год?»).
  7. Для каждого запроса получить top-3 чанка от обоих методов, вручную оценить релевантность.
  8. Посчитать Hit@3, MRR, Recall@3 для каждого метода.
  9. С помощью RAGAS оценить качество ответов LLM (gpt-3.5-turbo).

Ожидаемый результат Layout-aware chunking покажет на 15–25% лучшие метрики retrieval и на 10–15% higher faithfulness, особенно для запросов, затрагивающих таблицы и структурированные данные. Вы также получите практический опыт интеграции мультимодального анализа.


Связь с другими вопросами

ВопросТема
3Стратегии chunking (наивный vs семантический)
5Оценка качества retrieval в RAG
73Обработка PDF и извлечение структуры
111Что такое мультимодальный RAG
115Как индексировать изображения и таблицы в RAG
120Инструменты для мультимодального RAG (Unstructured, Docling)

Навигация