Ручная обработка инвойсов — типичная точка боли: бухгалтерия тратит 3–8 минут на каждый документ, ошибки при ручном вводе 1–3%. При объёме 500+ инвойсов в месяц это ощутимо — до 40 часов в месяц только на ввод данных, что обходится компании более чем в $450–650 ежемесячных затрат на зарплату. Мы разрабатываем Document AI-решения, которые снижают время до 5–15 секунд на документ с точностью полей >98% на стандартных форматах. Наш опыт — 7+ проектов по автоматизации документооборота для финансовых и логистических компаний.
Какие проблемы решает Document AI для инвойсов?
Проблема 1: Гетерогенные шаблоны. Поставщики присылают счета в разном формате — от сканов до электронных PDF. Rule-based OCR ломается на любом изменении layout. Мы используем мультимодальные модели (LayoutLMv3, Donut, GPT-4V), которые распознают поля без шаблонов — переносят обучение на новые макеты без дообучения. По данным независимых тестов, LayoutLMv3 на 25% точнее традиционных OCR-пайплайнов на смешанных наборах документов.
Проблема 2: Ошибки в ручном вводе. При объёме 1000 инвойсов в месяц 1–3% ошибок переводятся в 10–30 неверных сумм или дат. Это приводит к штрафам и переплатам. Автоматизация с пост-валидацией (нормализация валют, форматов дат) исключает человеческий фактор и экономит до $450–650. в месяц на исправлении ошибок.
Проблема 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 размеченных инвойсов. Подробнее о процессе дообучения
Мы используем стратегию transfer learning: берём предобученную модель LayoutLMv3 и дообучаем её на вашем корпусе с low learning rate (2e-5) и early stopping. Типичное время обучения — 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.
Automation of invoice processing reduces manual effort by up to 80% according to a McKinsey study. -- McKinsey & Company
Закажите бесплатную оценку ваших документов. Получите консультацию: пришлите 3–5 образцов счетов, и мы вернём прототип за 2 дня.







