ETL
Данный модуль платформы Compressa позволяет извлекать данные из неструктурированных документов и нарезать их на чанки с учетом структуры документов. Это важно для эффективного поиска / RAG или использования в LLM.
Модель запускается в качетсве самостоятельного сервиса вне платформы и является форком Unstructured-API project, адаптированным для запуска на CUDA. Вариант на GPU работает приблизительно в 1,5 раза быстрее CPU варианта, но при этом требует 1-2 ГБ дополнительной видеопамяти.
По умолчанию compose файл платформы включает только CPU версию, однако, отредактировав docker-compose.yaml и .env файлы можно запустить сервис на GPU.
Сервис будет подключен к nginx в обход Compressa-Dispatcher.
UI будет доступен по адресу http://ваш_адрес:8080/v1/ui-layout
# .env
...
LAYOUT_RESOURCES_PATH=/data/shared/CompressaAI/<DEPLOY>
NETWORK=test_network
PROJECT=dev
PORT=8100
LAYOUT_GPU_IDS=2
...
...
unstructured-api:
environment:
- LAYOUT_RESOURCES_PATH=${LAYOUT_RESOURCES_PATH:-./resources} # somewhere in RESOURCES_PATH
- PROJECT=${PROJECT:-compressa}
- PIPELINE_PACKAGE=${PIPELINE_PACKAGE:-general}
container_name: ${PROJECT:-compressa}-unstructured-api
volumes:
- ${LAYOUT_RESOURCES_PATH:-./resources}:/home/notebook-user/.cache
ports:
- ${PORT:-8100}:8000
deploy:
resources:
reservations:
devices:
- capabilities:
- gpu
device_ids:
- ${LAYOUT_GPU_IDS:-0}
driver: nvidia
image: compressa/compressa-layout-gpu:0.3.9
restart: always
shm_size: 32g
networks:
- ${NETWORK:-common_network}
...
Составим запрос на примере документа:
- Python (requests)
- cURL
# pip install requests, если у вас нет этой библиотеки
import requests
import os
# Скачиваем для примера PDF файл для сотрудников маркетплейса:
pdf_url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
pdf_response = requests.get(pdf_url)
# Сохраняем файл
with open("dummy.pdf", "wb") as file:
file.write(pdf_response.content)
# Отправляем файл для нарезки на чанки
compressa_url = "http://ваш_адрес:8080/v1/layout"
headers = {
"Authorization": "Ваш_API_ключ_Compressa",
"accept": "application/json",
}
# Указываем путь к нашему файлу
files = {"files": open("dummy.pdf", "rb")}
# Задаем параметры создания чанков
data = {
"output_format": "application/json",
"coordinates": "false",
"strategy": "fast",
"languages": ["rus", "eng"]
}
response = requests.post(
compressa_url,
headers=headers,
files=files,
data=data
)
# Выводим чанки документа в JSON формате
print(response.json())
curl -X POST "http://ваш_адрес:8080/v1/layout" \
-H "Authorization: Bearer Ваш_API_ключ_Compressa" \
-H "accept: application/json" \
-F "files=@path/to/file.pdf" \
-F "xml_keep_tags=false" \
-F "output_format=application/json" \
-F "coordinates=false" \
-F "strategy=auto" \
-F "languages[]=rus" \
-F "languages[]=eng"
Ниже мы разберем подробнее часть настроек, полная схема API доступна здесь.
Стратегия обработки документа (strategy)
fast: стратегия "rule-based" использует традиционные техники извлечения на основе NLP для быстрого извлечения всех текстовых элементов. Стратегия "fast" не рекомендуется для файлов, содержащих сложные макеты, изображения и другие элементы визуального стиля.
hi_res: стратегия "model-based" определяет макет документа. Преимущество стратегии "hi_res" заключается в том, что она использует макет документа для получения дополнительной информации о его элементах. Мы рекомендуем использовать эту стратегию, если ваш случай использования требует высокой точности классификации элементов документа.
auto: cтратегия "auto" автоматически выбирает метод разбиения документа в зависимости от его характеристик и других переданных параметров.
Параметры чанкинга (нарезки текста)
max_characters (по умолчанию = 500) — жёсткий предел размера для одного блока. Ни один блок не будет превышать указанного количества символов. Если элемент сам по себе превышает этот размер, он будет разделён на два или более блоков с использованием текстового разбиения.
new_after_n_chars (по умолчанию = max_characters) — "мягкий" предел размера блока. Блок, который уже достиг этого количества символов, не будет расширен, даже если следующий элемент поместится без превышения жёсткого предела. Этот параметр можно использовать вместе с max_characters, чтобы задать "предпочтительный" размер, например: "Предпочитаю блоки около 1000 символов, но лучше взять блок размером 1500 (max_characters), чем прибегать к разбиению текста". Это можно задать как (..., max_characters=1500, new_after_n_chars=1000).
overlap (по умолчанию = 0) — при использовании текстового разбиения для разделения слишком большого блока, включается указанное количество символов с конца предыдущего блока в качестве префикса для следующего. Это помогает смягчить эффект разрыва семантической единицы, представленной большим элементом.
overlap_all (по умолчанию = False) — также применяет overlap между "обычными" блоками, а не только при разбиении больших элементов. Так как обычные блоки формируются из целых элементов, каждый из которых имеет чёткую семантическую границу, эта опция может добавить шума в нормальные блоки. Нужно учитывать специфику вашего случая использования, чтобы решить, подходит ли вам этот параметр.
Пример UI ETL
