Автоматический аудит договоров для участников Сколково: Подготовка "глаз" для нейросети. Часть 2

В предыдущей заметке я рассказал, почему для поиска юридических формулировок в сканах лучше использовать Vision-модели (VLM), а не обычный OCR. Сегодня перейдем к практике: как подготовить PDF-файл, чтобы нейросеть смогла его "прочитать".

Зачем превращать PDF в картинки?

Обычные LLM (ChatGPT, Claude, Llama) работают с текстом. Vision-модели (как Qwen-VL, которую я использую локально через LM Studio) работают с изображениями. Им всё равно, есть ли в PDF текстовый слой или это просто фотография мятого листа. Главное — подать на вход качественную картинку.

Моя задача — превратить каждую страницу многостраничного договора в отдельное изображение, закодированное в формате Base64, чтобы отправить его в API.

Инструмент: PyMuPDF (fitz)

Для работы с PDF в Python стандартом де-факто стала библиотека

PyMuPDF (импортируется как fitz). Она невероятно быстрая и умеет рендерить страницы с высокой точностью.

Вот ключевая функция из моего скрипта:

import fitz # PyMuPDF import base64 def render_page_as_base64(page): # 1. Рендерим страницу в pixmap (растровое изображение) # fitz.Matrix(1, 1) — стандартный масштаб (72 DPI), обычно достаточно для текста # colorspace=fitz.csGRAY — конвертируем в оттенки серого pix = page.get_pixmap(matrix=fitz.Matrix(1, 1), alpha=False, colorspace=fitz.csGRAY) # 2. Получаем байты в формате PNG img_bytes = pix.tobytes("png") # 3. Кодируем в Base64 для передачи через JSON API return base64.b64encode(img_bytes).decode("utf-8")

Почему именно так?

Перевод в оттенки серого (`fitz.csGRAY`):

Юридические документы обычно черно-белые. Цветная печать или синие подписи не несут смысловой нагрузки для поиска текста, но увеличивают размер файла в 3 раза. Конвертация в Grayscale ускоряет передачу данных и снижает нагрузку на VLM.

Матрица масштабирования (`fitz.Matrix(1, 1)`):

По умолчанию PyMuPDF рендерит с разрешением 72 DPI. Для Vision-моделей этого часто достаточно, если шрифт не слишком мелкий (10-12pt). Если качество распознавания падает, можно увеличить масштаб до Matrix(2, 2) (144 DPI), но это увеличит размер картинки в 4 раза и замедлит инференс.

Формат PNG:

PNG — сжатие без потерь. Для текста это критично, так как артефакты JPEG (размытие вокруг букв) могут сбить нейросеть, особенно на мелком шрифте.

Как это работает в потоке

В основном цикле скрипта я открываю PDF и прохожусь по страницам пачками (batch processing):

doc = fitz.open(pdf_path) for page_num in range(len(doc)): page = doc[page_num] base64_image = render_page_as_base64(page) # ... добавляем картинку в запрос к API ...

Таким образом, мы скармливаем модели документ страница за страницей, не перегружая память компьютера.

В следующей части я покажу самое интересное — как правильно составить промпт (запрос) для модели, чтобы она не просто "смотрела", а искала нужные нам юридические нюансы.

Кому, как и мне, интересно автоматизировать юридические процессы, присоединяйтесь ко мне в телеграме, там я пишу "человеческим языком", а не вот это вот всё)

Начать дискуссию