OCRmyPDF: считаем стоимость одной распознанной страницы
«OCRmyPDF бесплатен, Tesseract бесплатен, а сервер за пару долларов в месяц — вообще не деньги» — с этой мысли обычно начинается решение поднять своё распознавание текста вместо оплаты облачного OCR-API постранично. Проблема в том, что «бесплатно» тут — про лицензию, а не про итоговую стоимость. Сервер, CPU-время на каждую страницу и ваше время на то, чтобы пайплайн не падал по ночам — это реальные расходы, просто не в виде счёта за подписку. Разберём честно, как посчитать стоимость одной распознанной страницы при self-hosted OCR и при каком объёме это решение реально выгоднее платного API, а при каком — нет.
Содержание
- Что такое OCRmyPDF и почему сравнение не сводится к «Tesseract бесплатный»
- Из чего складывается стоимость self-hosted распознавания
- Время администратора: установка — это только начало
- Скрытые издержки, которые расчёт «сервер плюс apt-get» не видит
- Облачные OCR-API: как считается цена за страницу
- Точка перелома: при каком объёме self-host выгоднее
Что такое OCRmyPDF и почему сравнение не сводится к «Tesseract бесплатный»
OCRmyPDF — не альтернатива Tesseract, а обвязка над ним. Сам Tesseract умеет распознавать текст на изображении и отдать его строкой или в каком-то структурированном формате, но не умеет работать с PDF как с документом: добавить невидимый текстовый слой поверх исходного скана так, чтобы документ выглядел как обычный скан, но при этом находился полнотекстовым поиском и копировался как текст. Именно эту работу делает OCRmyPDF, дополнительно оборачивая пайплайн предобработки: выравнивание страниц (--deskew), очистку шума перед распознаванием (--clean), поворот страниц по ориентации текста (--rotate-pages) и постобработку через Ghostscript для сжатия итогового PDF (--optimize).
Базовый вызов выглядит просто:
ocrmypdf --language rus+eng input.pdf output.pdf
Установка — тоже одна команда на большинстве дистрибутивов:
apt-get install ocrmypdf tesseract-ocr-rus tesseract-ocr-eng
или через Docker-образ, если не хочется тянуть Ghostscript, qpdf и зависимости Python в систему напрямую. На этом «бесплатность» решения заканчивается и начинается реальная эксплуатация: сколько CPU-времени съедает каждая страница, сколько стоит сервер, на котором это крутится, и сколько времени вы тратите на то, чтобы пайплайн не разваливался на первом же битом файле. Дальше — по порядку.
Из чего складывается стоимость self-hosted распознавания
Три составляющие, и наивный расчёт обычно видит только первую.
Аренда сервера. OCRmyPDF не требует GPU и не требует много памяти на одну страницу — типичная нагрузка упирается в CPU, а не в RAM или диск. Но CPU нужен настоящий: распознавание — процесс, который на время обработки партии документов может занять все выделенные ядра. Если сервер используется ещё и под что-то другое (сайт, база данных), крупная партия OCR-задач заметно просядёт по отзывчивости остальных сервисов, если не ограничить ресурсы явно.
CPU-время на страницу. Это переменная, а не константа, и зависит от нескольких факторов сразу:
- разрешение скана (DPI) — чем выше, тем дольше распознавание и тем точнее результат, компромисс не обходится ни в одну сторону бесплатно;
- какой набор данных Tesseract используется —
tessdata_fastбыстрее и грубее,tessdata_bestточнее и медленнее, выбор — явная настройка, а не то, что подставляется по умолчанию правильно для всех случаев; - включённые опции предобработки —
--deskewи--cleanдобавляют шаги перед распознаванием, а не ускоряют его; - сложность layout — колонки, таблицы, смешанный язык на странице обрабатываются дольше однородного текста.
Точное число секунд на страницу у вас будет своё — зависит от конкретного CPU, сканов и флагов, и любая цифра «из интернета» тут скорее вводит в заблуждение. Прежде чем считать TCO, прогоните ocrmypdf на выборке из 30–50 своих документов с теми флагами, которые пойдут в прод, и замерьте время сами — это единственный источник цифр, которому стоит доверять в расчёте.
Параллелизация. Флаг --jobs N заставляет OCRmyPDF обрабатывать несколько страниц одного документа параллельными процессами, что почти линейно снижает время на многоядерном сервере — до предела, за которым процессы начинают конкурировать за память быстрее, чем прирастает скорость. При батче из многих документов параллелизация имеет смысл на уровне очереди задач, а не только --jobs внутри одного вызова — иначе легко упереться в память, запустив десяток тяжёлых процессов Ghostscript одновременно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPS для распознавания текстаВремя администратора: установка — это только начало
Установить OCRmyPDF — вечер работы в лучшем случае. Дальше начинается то, что расчёт «поставил и работает» обычно не видит:
- языковые пакеты подбираются под содержимое архива, а не ставятся один раз наугад — документ на языке, для которого пакет не установлен, распознаётся мусором без явной ошибки, если не указать язык явно;
- PriorOcrFoundError — частая ошибка новичков: OCRmyPDF по умолчанию отказывается обрабатывать PDF, где уже есть текстовый слой, и требует явного флага
--skip-text(пропустить уже распознанные страницы) или--force-ocr(растрировать заново и распознать поверх, теряя исходный текст, если он был); - память на тяжёлых документах. Многостраничный PDF с изображениями высокого разрешения, обрабатываемый через Ghostscript на этапе
--optimize, может съесть заметно больше памяти, чем ожидалось из размера файла на диске; - битый файл в батче — не мелочь. Если скрипт перебирает директорию из тысячи PDF в цикле и на файле номер 340 падает без обработки ошибки, вы теряете весь батч или, что хуже, не замечаете этого до утра — код возврата процесса нужно проверять явно;
- обновления Tesseract и языковых моделей со временем меняют качество распознавания — иногда в лучшую сторону, иногда ломают воспроизводимость без тестирования на контрольной выборке.
Регулярная эксплуатация обычно решается через очередь задач и запуск по расписанию, а не ручной прогон команды каждый раз — базовые принципы настройки такого расписания разобраны в статье про настройку cron-задач с примерами, сама специфика OCR добавляется поверх: нужен явный лог результата каждой задачи (успех/ошибка/сколько страниц), а не просто факт, что cron отработал по расписанию.
Скрытые издержки, которые расчёт «сервер плюс apt-get» не видит
Помимо CPU-времени и разбора ошибок, есть статьи расходов, которые проявляются не на старте, а через месяц-два эксплуатации:
- качество исходных сканов определяет качество результата сильнее любых настроек OCRmyPDF. Кривой скан, тень от переплёта, низкий DPI — распознавание либо не сработает, либо даст текст с числом ошибок, делающим полнотекстовый поиск бесполезным. Стандарт сканирования стоит зафиксировать до массовой загрузки архива, а не чинить постфактум;
- повторный прогон архива при смене флагов или языковых пакетов — если конфигурация исправлена после того, как через пайплайн уже прошли десятки тысяч страниц, пересчёт всего архива — то же CPU-время, потраченное один раз впустую;
- хранилище растёт быстрее, чем кажется.
--optimizeумеет пережимать изображения внутри PDF, но исходное качество скана в файле по умолчанию сохраняется — архив распознанных сканов ощутимо тяжелее того же архива в виде обычного текста; - мониторинг пайплайна — если очередь задач встала (закончилась память, упал воркер, диск заполнился), новые документы продолжают поступать, но не распознаются, и без явного алерта это может остаться незамеченным неделями;
- бэкап результата, а не только исходников. Если распознанный PDF потерян из-за отсутствия бэкапа, восстановление — это не копирование файла, а повторный прогон через весь пайплайн с нуля.
Облачные OCR-API: как считается цена за страницу
У платного облачного OCR принципиально другая модель стоимости — не «сервер плюс время», а прямая оплата за факт обработки. Провайдеры обычно выставляют цену за страницу или за пакет из тысячи страниц, часто с бесплатной квотой на небольшой объём в месяц и снижением цены за страницу на больших объёмах — точный прайс и структура тарифов у каждого провайдера свои и меняются со временем, поэтому перед расчётом стоит свериться с актуальным прайс-листом конкретного сервиса, а не опираться на цифры из старой статьи или чужого опыта годичной давности.
Что вы реально покупаете в этой цене, помимо самого распознавания:
- инфраструктуру и её масштабирование — пиковая нагрузка в тысячу страниц за час не требует от вас держать сервер под такой пик постоянно, провайдер решает это на своей стороне;
- обновления моделей распознавания без вашего участия — иногда это плюс (точность растёт бесплатно для вас), иногда риск (поведение модели меняется без предупреждения, и то, что стабильно распознавалось вчера, завтра может дать другой результат);
- отсутствие затрат времени администратора на установку, языковые пакеты, разбор ошибок пайплайна — вы платите за то, чтобы про это не думать вообще;
- иногда более широкое покрытие языков и почерков — сложное рукописное распознавание, редкие языки — там, где self-hosted Tesseract объективно слабее коммерческих моделей.
Обратная сторона — данные уходят за пределы вашей инфраструктуры. Для части документов (медицинские данные, персональные данные клиентов, юридически чувствительные документы) это не вопрос цены, а вопрос принципиальной допустимости — здесь self-hosted решение может быть обязательным требованием, даже если по чистой экономике облачный API выходит дешевле.
Точка перелома: при каком объёме self-host выгоднее
Формула сравнения та же логика, что применима к любому решению «делать самому или платить за managed-услугу»: считаете стоимость каждого варианта в пересчёте на месяц и сравниваете.
TCO self-host (в месяц) =
аренда сервера
+ (CPU-время на страницу × число страниц в месяц × стоимость CPU-часа)
+ время администратора на пайплайн в месяц × себестоимость часа
TCO облачный API (в месяц) =
цена за страницу × число страниц в месяц
Ключевое наблюдение из этой формулы: у self-host есть постоянная часть (аренда сервера, минимальное время администратора на поддержание пайплайна), которая не зависит от объёма, а у облачного API стоимость растёт линейно с нуля без фиксированной части. Это значит, что при малом объёме страниц в месяц облачный API почти всегда выгоднее — вы платите только за то, что реально обработали, а постоянная часть self-host размазывается на маленький объём и делает цену страницы аномально высокой. При росте объёма страниц в месяц постоянная часть self-host размазывается на всё больший объём, и в какой-то точке переменная стоимость (CPU-время на страницу) плюс амортизированная постоянная часть становится дешевле, чем построничная цена API.
Иллюстративный пример хода расчёта (цифры условные, ваши нужно подставить свои — из замера на своей выборке документов и актуального прайса конкретного провайдера):
- аренда сервера под пайплайн OCR — фиксированная сумма в месяц;
- время администратора на поддержание пайплайна в рабочем состоянии — несколько часов в месяц в устоявшемся режиме (не считая первичной настройки), умноженное на вашу себестоимость часа (см. отдельный разбор расчёта стоимости часа администратора — там же разобрана общая формула «сам или доплатить», применимая не только к OCR);
- CPU-время на страницу, замеренное на своей выборке, переводится в стоимость через цену CPU-часа вашего сервера;
- сумма этих трёх слагаемых делится на число страниц в месяц — получаете свою реальную стоимость страницы self-host;
- сравниваете с ценой страницы у конкретного облачного провайдера на нужный вам объём (тариф может отличаться по мере роста объёма — сверяйтесь с актуальным прайсом).
При объёме в сотни страниц в месяц self-host почти всегда проигрывает по чистой экономике — постоянная часть (сервер, время админа) не успевает размазаться. При объёме в десятки и сотни тысяч страниц в месяц картина обычно меняется на противоположную — переменная стоимость CPU-времени на self-host, как правило, ощутимо ниже построничной цены большинства коммерческих API, и постоянная часть на таком объёме становится почти незаметной добавкой к цене страницы. Точное число страниц, на котором происходит перелом, — не универсальная константа, а результат вашего собственного расчёта по формуле выше: у кого-то это тысяча страниц в месяц, у кого-то — на порядок больше, в зависимости от цены сервера, скорости распознавания на вашем CPU и тарифа конкретного облачного API.
Отдельно стоит учитывать, что если у вас уже есть сервер под другие задачи с запасом CPU, предельная стоимость добавления OCR к нему может оказаться намного ниже, чем аренда отдельного сервера только под распознавание — тогда точка перелома сдвигается в пользу self-host при заметно меньшем объёме страниц. Общая логика такого честного счёта разобрана в статье про TCO выделенного сервера и то, что не входит в аренду — те же принципы применимы и к отдельному сервису на существующем сервере.
Если помимо OCR вам нужны и другие операции с PDF — слияние, разбивка, конвертация форматов, — есть смысл смотреть не только на OCRmyPDF, а на связку с более широким инструментом вроде Stirling PDF, разобранным в статье про установку Stirling PDF на VPS: один сервер может закрыть весь набор задач с документами, и тогда постоянная часть TCO делится не на одну функцию, а на несколько сразу.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPS для распознавания текстаНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли запустить OCRmyPDF без Docker, прямо на системе?
Да, через пакетный менеджер дистрибутива или через pip install ocrmypdf с отдельной установкой Tesseract, Ghostscript и qpdf как системных зависимостей. Docker удобнее там, где нужна изоляция версий или воспроизводимое окружение между несколькими серверами, но не является обязательным требованием для работы инструмента.
Что делать, если один битый файл в батче ломает весь скрипт обработки?
Оборачивайте вызов ocrmypdf для каждого файла в обработку кода возврата и логирование, а не в цикл без проверки ошибок — так один сбойный PDF не остановит обработку остальных файлов в очереди, и вы сразу увидите, какой именно файл требует ручного разбора.
Нужен ли GPU для ускорения OCRmyPDF?
Нет, стандартный пайплайн Tesseract, на котором построен OCRmyPDF, рассчитан на CPU и не использует GPU-ускорение из коробки. Для больших объёмов важнее число ядер CPU и параллелизация через --jobs и очередь задач, а не наличие видеокарты.
Как оценить CPU-время на своих документах, не дожидаясь конца месяца эксплуатации?
Прогоните ocrmypdf с теми флагами, которые планируете использовать в проде, на выборке из 30–50 реальных документов разного типа (текст, таблицы, разное качество скана) и замерьте суммарное время выполнения — это даст рабочую оценку CPU-времени на страницу для вашей формулы TCO точнее, чем любая цифра из чужой статьи.
Что если документы нельзя отправлять в облако вообще, независимо от цены?
Тогда сравнение TCO становится вторичным вопросом — self-hosted распознавание оказывается не «более выгодным вариантом», а единственным допустимым по требованиям конфиденциальности или закона, и расчёт стоимости страницы нужен уже не для выбора между вариантами, а для планирования бюджета под единственно возможное решение.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →