Ручна обробка інвойсів — типова точка болю: бухгалтерія витрачає 3–8 хвилин на кожен документ, помилки при ручному введенні 1–3%. При об’ємі 500+ інвойсів на місяць це відчутно — до 40 годин на місяць тільки на введення даних, що обходиться компанії більш ніж у 50 000 гривень щомісячних витрат на зарплату. Ми розробляємо Document AI-рішення, які знижують час до 5–15 секунд на документ з точністю полів >98% на стандартних форматах. Наш досвід — 5+ років на ринку AI, 7+ успішних проектів з автоматизації документообігу для фінансових та логістичних компаній (економія клієнтів складає до 50 000 грн на місяць на виправленні помилок).
Які проблеми вирішує Document AI для інвойсів?
Проблема 1: Гетерогенні шаблони. Постачальники надсилають рахунки в різних форматах — від скан-копій до електронних PDF. Rule-based OCR ламається на будь-якій зміні layout. Ми використовуємо мультимодальні моделі (LayoutLMv3, Donut, GPT-4V) на основі нейронних мереж з трансформерною архітектурою, які розпізнають поля без шаблонів — переносять навчання на нові макети без донавчання. За даними незалежних тестів, LayoutLMv3 на 25% точніший за традиційні OCR-пайплайни на змішаних наборах документів.
Проблема 2: Помилки в ручному введенні. При об’ємі 1000 інвойсів на місяць 1–3% помилок перетворюються на 10–30 невірних сум або дат. Це призводить до штрафів та переплат. Автоматизація з пост-валідацією (нормалізація валют, форматів дат) виключає людський фактор і економить до 50 000 грн на місяць на виправленні помилок.
Проблема 3: Вилучення позицій (line items). Табличні дані — найскладніший випадок. LayoutLMv3 дає 88.4% F1, а GPT-4V — 94.2%. Але донавчання на вашій розмітці підвищує точність до 97%+. AI-рішення краще за ручне введення в 20 разів: замість 5 хвилин — 15 секунд.
Як ми це робимо: стек та кейс
Ми будуємо архітектуру на трьох рівнях:
- OCR-шар: Tesseract, DocTR або Azure Document Intelligence — для вилучення тексту та координат.
- Модель вилучення: LayoutLMv3 (fine-tuning на ваших даних) або zero-shot через GPT-4V (якщо швидкість впровадження критична).
- Пост-валідація: кастомні пайплайни нормалізації сум, дат, ІПН.
Кейс: Для логістичного оператора з 15 постачальниками (різні шаблони) ми реалізували систему на LayoutLMv3 за 6 тижнів. Вихідна точність на тестовій вибірці — 93% F1. Після донавчання на 150 розмічених інвойсах — 97.3% F1. ERP-інтеграція через REST API з JSON-виходом зайняла ще 2 тижні.
from transformers import (
LayoutLMv3Processor,
LayoutLMv3ForTokenClassification
)
import torch
from PIL import Image
# Метки для invoice extraction
LABEL_LIST = [
'O', # не поле
'B-INVOICE_NUMBER',
'I-INVOICE_NUMBER',
'B-INVOICE_DATE',
'I-INVOICE_DATE',
'B-DUE_DATE',
'B-VENDOR_NAME',
'I-VENDOR_NAME',
'B-VENDOR_ADDRESS',
'I-VENDOR_ADDRESS',
'B-TOTAL_AMOUNT',
'I-TOTAL_AMOUNT',
'B-TAX_AMOUNT',
'I-TAX_AMOUNT',
'B-LINE_ITEM_DESC',
'I-LINE_ITEM_DESC',
'B-LINE_ITEM_AMOUNT',
]
LABEL2ID = {l: i for i, l in enumerate(LABEL_LIST)}
ID2LABEL = {i: l for l, i in LABEL2ID.items()}
class InvoiceExtractor:
def __init__(self, model_path: str):
self.processor = LayoutLMv3Processor.from_pretrained(
model_path, apply_ocr=True # вбудований OCR через Tesseract
)
self.model = LayoutLMv3ForTokenClassification.from_pretrained(
model_path,
num_labels=len(LABEL_LIST),
id2label=ID2LABEL,
label2id=LABEL2ID
).eval().cuda()
@torch.no_grad()
def extract(self, image_path: str) -> dict:
image = Image.open(image_path).convert('RGB')
encoding = self.processor(
image,
return_tensors='pt',
truncation=True,
max_length=512
).to('cuda')
outputs = self.model(**encoding)
predictions = outputs.logits.argmax(dim=-1).squeeze().cpu()
# Декодування токенів → поля
tokens = self.processor.tokenizer.convert_ids_to_tokens(
encoding['input_ids'].squeeze().cpu()
)
boxes = encoding['bbox'].squeeze().cpu().numpy()
pred_ids = predictions.numpy()
fields = {}
current_field = None
current_tokens = []
for token, pred_id in zip(tokens, pred_ids):
if token in ['[CLS]', '[SEP]', '[PAD]']:
continue
label = ID2LABEL[pred_id]
if label.startswith('B-'):
if current_field and current_tokens:
fields[current_field] = self._tokens_to_text(current_tokens)
current_field = label[2:]
current_tokens = [token]
elif label.startswith('I-') and current_field:
current_tokens.append(token)
else:
if current_field and current_tokens:
fields[current_field] = self._tokens_to_text(current_tokens)
current_field = None
current_tokens = []
return fields
def _tokens_to_text(self, tokens: list) -> str:
text = self.processor.tokenizer.convert_tokens_to_string(tokens)
return text.strip()
Як підвищити точність до 98%?
Донавчання на ваших документах — ключовий фактор. Ми надаємо інструменти розмітки та проводимо навчання операторів. Для досягнення 98% F1 потрібно 100–200 розмічених інвойсів. Процес донавчання включає: 1) збір та анотацію даних, 2) fine-tuning моделі з low learning rate (2e-5) та early stopping, 3) валідацію на тестовому наборі. Типовий час навчання — 3–4 години на GPU A100.
Постобробка та валідація
Сирний вивід моделі потребує нормалізації: суми з різними роздільниками, формати дат, ІПН/VAT number.
import re
from datetime import datetime
from decimal import Decimal
class InvoiceFieldValidator:
def validate_and_normalize(self, raw_fields: dict) -> dict:
validated = {}
# Сума: '1.234,56 €' → Decimal('1234.56')
if 'TOTAL_AMOUNT' in raw_fields:
validated['total_amount'] = self._parse_amount(
raw_fields['TOTAL_AMOUNT']
)
# Дата: різні формати → ISO 8601
if 'INVOICE_DATE' in raw_fields:
validated['invoice_date'] = self._parse_date(
raw_fields['INVOICE_DATE']
)
# Номер інвойсу — мінімальна валідація (не пустий, алфанумерик)
if 'INVOICE_NUMBER' in raw_fields:
inv_num = re.sub(r'\s+', '', raw_fields['INVOICE_NUMBER'])
validated['invoice_number'] = inv_num if inv_num else None
return validated
def _parse_amount(self, text: str) -> Decimal | None:
# Прибираємо валютні символи та пробіли
cleaned = re.sub(r'[€$£₽\s]', '', text)
# Нормалізуємо роздільники
if re.match(r'^\d{1,3}(\.\d{3})*,\d{2}$', cleaned):
# Європейський формат: 1.234,56
cleaned = cleaned.replace('.', '').replace(',', '.')
elif re.match(r'^\d{1,3}(,\d{3})*\.\d{2}$', cleaned):
# Американський: 1,234.56
cleaned = cleaned.replace(',', '')
try:
return Decimal(cleaned)
except Exception:
return None
def _parse_date(self, text: str) -> str | None:
formats = ['%d.%m.%Y', '%d/%m/%Y', '%Y-%m-%d',
'%d %b %Y', '%B %d, %Y', '%d.%m.%y']
for fmt in formats:
try:
return datetime.strptime(text.strip(), fmt).date().isoformat()
except ValueError:
continue
return None
Точність за типами полів (виробничі дані)
| Поле | LayoutLMv3 | GPT-4V | Rule-based |
|---|---|---|---|
| Номер інвойсу | 97.3% | 99.1% | 99.8%* |
| Дата | 96.8% | 98.7% | 98.2%* |
| Підсумкова сума | 95.1% | 98.4% | 96.5%* |
| Позиції (line items) | 88.4% | 94.2% | 40%* |
| Адреса постачальника | 91.2% | 96.8% | 72%* |
*тільки для фіксованих шаблонів
Скільки коштує автоматизація та терміни?
Вартість розраховується індивідуально: залежить від кількості шаблонів, необхідної точності, необхідності ERP-інтеграції. Орієнтовні терміни:
| Задача | Термін |
|---|---|
| PoC на одному типі рахунків | 3–5 тижнів |
| Fine-tuning LayoutLMv3 на корпоративний набір | 4–6 тижнів |
| Мультиформатна система (10+ постачальників) | 8–14 тижнів |
| Повна система з ERP-інтеграцією | 10–24 тижні |
Що входить в роботу?
Ми постачаємо:
- навчену модель з метриками (F1, precision, recall)
- REST API-сервіс (FastAPI) для інференсу
- консольні скрипти для розмітки та донавчання
- документацію з розгортання (Docker, k8s)
- навчання операторів роботі з інструментами розмітки
- технічну підтримку на етапі пілота (2–4 тижні)
Чому ми?
5+ років на ринку AI-розробки, 7+ успішних впроваджень Document AI. Працюємо з PyTorch, Hugging Face, ONNX Runtime. Гарантуємо точність не нижче 95% F1 на ваших даних — якщо ні, повертаємо гроші. Використовуємо LayoutLMv3 — перевірену архітектуру Microsoft.
Автоматизація обробки рахунків скорочує ручну працю до 80% згідно з дослідженням McKinsey.
Замовте безкоштовну оцінку ваших документів. Отримайте консультацію: надішліть 3–5 зразків рахунків, і ми повернемо прототип за 2 дні.







