OCR Model Training (PaddleOCR, EasyOCR, TrOCR)

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
OCR Model Training (PaddleOCR, EasyOCR, TrOCR)
Medium
~5 business days
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822

Training OCR-моделей: PaddleOCR, TrOCR, EasyOCR

Общий OCR — задача решённая: Tesseract, Google Vision, Azure Read API хорошо справляются со стандартным печатным текстом. Кастомное обучение OCR нужно для: специфических шрифтов (рукопись, промышленная маркировка, нестандартные символы), редких языков, деградированных документов (факсы, старые архивы), специализированных форматов (матрицы, химические формулы).

PaddleOCR — архитектура и fine-tuning

PaddleOCR состоит из трёх независимых компонентов: detection (DBNet), direction classifier, recognition (SVTR/PP-OCR). Fine-tuning можно применять к каждому отдельно.

# Конфигурация fine-tuning recognition модели в PaddleOCR
# configs/rec/PP-OCRv4/en_PP-OCRv4_rec.yml (модифицированный)

Global:
  use_gpu: true
  epoch_num: 200
  log_smooth_window: 20
  print_batch_step: 10
  save_model_dir: ./output/rec_custom/
  save_epoch_step: 10
  eval_batch_step: [0, 2000]
  cal_metric_during_train: true
  pretrained_model: ./pretrain_models/en_PP-OCRv4_rec_train/best_accuracy
  checkpoints: null
  save_inference_dir: null

  character_dict_path: ./my_dict.txt    # кастомный символьный словарь
  max_text_length: 40
  infer_mode: false
  use_space_char: true

Train:
  dataset:
    name: SimpleDataSet
    data_dir: ./train_data/rec/
    label_file_list: ['./train_data/rec/train_labels.txt']
    transforms:
      - DecodeImage: {img_mode: BGR, channel_first: false}
      - RecAug:              # аугментации для recognition
          use_tia: true      # thin-plate spline деформация
      - CTCLabelEncode:
          max_text_length: 40
          character_dict_path: ./my_dict.txt
      - RecResizeImg:
          image_shape: [3, 48, 320]    # H=48 фиксированная
      - KeepKeys:
          keep_keys: ['image', 'label', 'length']
  loader:
    shuffle: true
    batch_size_per_card: 128
    drop_last: true
    num_workers: 8

Optimizer:
  name: Adam
  beta1: 0.9
  beta2: 0.999
  lr:
    name: Piecewise
    decay_epochs: [100, 150]
    values: [0.001, 0.0001, 0.00001]

TrOCR — трансформерный OCR для сложных случаев

TrOCR (Microsoft) — encoder-decoder архитектура на базе ViT + RoBERTa. Превосходит PaddleOCR на рукописном тексте и низком качестве изображений:

from transformers import (
    TrOCRProcessor,
    VisionEncoderDecoderModel,
    Seq2SeqTrainer,
    Seq2SeqTrainingArguments
)
from torch.utils.data import Dataset
from PIL import Image
import torch

class OCRDataset(Dataset):
    def __init__(self, image_paths: list, labels: list,
                 processor: TrOCRProcessor):
        self.image_paths = image_paths
        self.labels = labels
        self.processor = processor

    def __len__(self): return len(self.image_paths)

    def __getitem__(self, idx):
        image = Image.open(self.image_paths[idx]).convert('RGB')
        pixel_values = self.processor(
            image, return_tensors='pt'
        ).pixel_values.squeeze()

        # Токенизация текстовой метки
        with self.processor.tokenizer.as_target_tokenizer():
            labels = self.processor.tokenizer(
                self.labels[idx],
                padding='max_length',
                max_length=64,
                truncation=True,
                return_tensors='pt'
            ).input_ids.squeeze()

        labels[labels == self.processor.tokenizer.pad_token_id] = -100
        return {'pixel_values': pixel_values, 'labels': labels}

def finetune_trocr(
    train_paths: list, train_labels: list,
    val_paths: list, val_labels: list,
    base_model: str = 'microsoft/trocr-base-handwritten',
    output_dir: str = './trocr_custom'
) -> VisionEncoderDecoderModel:

    processor = TrOCRProcessor.from_pretrained(base_model)
    model = VisionEncoderDecoderModel.from_pretrained(base_model)

    # Конфигурация decoder
    model.config.decoder_start_token_id = processor.tokenizer.cls_token_id
    model.config.pad_token_id = processor.tokenizer.pad_token_id
    model.config.vocab_size = model.config.decoder.vocab_size
    model.config.eos_token_id = processor.tokenizer.sep_token_id
    model.config.max_length = 64
    model.config.early_stopping = True
    model.config.no_repeat_ngram_size = 3
    model.config.length_penalty = 2.0
    model.config.num_beams = 4

    train_dataset = OCRDataset(train_paths, train_labels, processor)
    val_dataset   = OCRDataset(val_paths, val_labels, processor)

    training_args = Seq2SeqTrainingArguments(
        output_dir=output_dir,
        per_device_train_batch_size=8,
        per_device_eval_batch_size=8,
        num_train_epochs=50,
        learning_rate=4e-5,
        warmup_steps=500,
        weight_decay=0.01,
        fp16=True,
        predict_with_generate=True,
        evaluation_strategy='epoch',
        save_strategy='epoch',
        load_best_model_at_end=True,
        metric_for_best_model='cer'  # Character Error Rate
    )

    trainer = Seq2SeqTrainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=val_dataset
    )
    trainer.train()
    return model

Metrics OCR

CER (Character Error Rate) — основная метрика. Levenshtein distance / длина референсного текста. WER (Word Error Rate) — для задач, где важна точность слов.

Применение Приемлемый CER Инструмент
Цифровые документы (invoice, ID) < 0.5% PaddleOCR PP-OCRv4
Рукописный текст < 3% TrOCR-large
Промышленная маркировка < 1% PaddleOCR fine-tuned
Исторические документы < 5% TrOCR + domain adapt.
Номерные знаки < 0.3% ALPR специализированный

Типичные проблемы

  • Распознавание нулей и букв O — критично для серийных номеров. Решение: расширенный словарь с контекстными правилами (only digits для серийных полей)
  • Сложная фоновая текстура — накладывается на символы. Решение: STN (Spatial Transformer Network) перед recognition для выравнивания
  • Вертикальный текст — PaddleOCR плохо работает без direction classifier. Нужен отдельный классификатор ориентации

Сроки

Задача Срок
Fine-tuning PaddleOCR на кастомный шрифт/язык 2–3 недели
TrOCR для рукописи с нуля 4–6 недель
Полный OCR-pipeline с preprocessing 6–10 недель