Как стать автором
Обновить
117.86
Smart Engines
Обработка изображений, распознавание в видеопотоке

Распознавание документов в браузере вашего устройства

Время на прочтение6 мин
Количество просмотров2.9K

Привет Хабр! Те из вас, кто следит за нашими публикациями про мобильное распознавание документов, знает, что мы придерживаемся принципа распознавания документов только на самом устройстве. Модуль, который отвечает за распознавание и ввод данных, не должен быть уязвимее того, что он в моменте заменяет (а именно, клавиатуру). Наши технологии легко встраиваются в мобильные приложения, но что делать, когда необходимо реализовать веб-приложение с возможностями ИИ? Уступать принципам не приходится - на помощь приходит WebAssembly (или Wasm). Под катом мы расскажем, как мы портировали наши решения по распознаванию документов, банковских карт, баркодов, и всего остального, для использования в Wasm. Уверены, что вам будет интересно.

WebAssembly - формат бинарного кода для виртуальной машины, в который можно компилировать программы на C, C++, C#, Rust или Go и который браузеры могут транслировать в нативный бинарный код для той машины, на котором запущены. WebAssembly разрабатывается с 2015-го года и в данный момент развивается такими компаниями, как Mozilla, Microsoft, Google, Apple, Intel, Red Hat и пр. В настоящее время Wasm уже поддерживают (с разными ограничениями, но об этом позже) наиболее популярные браузеры: Firefox, Chrome, Microsoft Edge, Safari и другие.

Наш основной интерес к технологии Wasm связан с возможностью обработки чувствительной информации в браузере без участия сервера. Обработка цифровых изображений, извлечение текстовых данных из документов, бланков, банковских карт, чтение баркодов происходят только в памяти браузера локальной машины без необходимости пересылки данных по сети, минимизируя риски утечек персональных, биометрических, и всяких других данных. 

Благодаря Wasm, многие тяжелые или платформозависимые приложения теперь можно моментально разворачивать на любом устройстве с выходом в интернет и современным браузером: вместо скачивания и установки приложения пользователю теперь нужен только один клик по ссылке, чтобы получить готовую систему по оптическому извлечению данных с веб-камеры или сканера. 

Более того, даже если целевой кейс - облачные вычисления, но предоставить такую возможность всем клиентам не представляется возможным (проблемы с горизонтальным масштабированием, поддержкой или арендой инфраструктуры и т.п.) Wasm выступает практически безальтернативной технологией. Ему удалось, по крайней мере в области намерений, найти баланс между удобством интеграции, производительностью и безопасностью, путь к которому прослеживается с java-апплетов, Flash, Silverlight, ActiveX и прочего.

Одна из идей Wasm состояла (и состоит) в том, чтобы выполнять браузером вычисления со скоростью, максимально приближенной к нативному приложению. Хотя Wasm - технология достаточно молодая, современная реализация уже позволяет производить сложные вычисления, даже такие, как обработка изображений и распознавание, с достаточно высокой производительностью. В нашем случае, используя все оптимизации, модуль распознавания уже обрабатывает документы за время, немногим уступающее решению, скомпилированным под нативную платформу, как мы и продемонстрируем в конце статьи.

Всякое ли технологическое решение, реализованное в виде той или иной нативной библиотеки, может быть портировано на Wasm так, чтобы все вычисления выполнялись кроссплатформенно, прямо в браузере? Вынося за скобки ряд деталей можно сказать, что да, если все компоненты решения имеются на уровне исходного кода. Нам это сделать удалось – т.к. наша библиотека не имеет никаких внешних зависимостей, весь код системы, алгоритмы обработки изображений, исполнение нейросетей и т.п. – все написано нами, а значит мы можем легко собрать все из исходников и модифицировать при необходимости.

Обертки интерфейсов и модули для встраивания мы создаем всегда на основе С++ интерфейса нашей главной библиотеки. Это позволяет легко интегрироваться в системы, написанные на разных языках программирования и практически на любых платформах, сохраняя логику, заложенную в интерфейс.

Существует множество инструментов для портирования существующей кодовой базы в Wasm модуль. Для языка С++  существует проект Emscripten, который включает в себя инструмент EmBind. Он позволяет максимально простым способом обернуть классы, их поля и методы в объекты, видимые из js. В принципе, это уже позволяет создать минимальное рабочее приложение или библиотеку, однако Wasm постепенно обрастает поддержкой разного рода оптимизаций, которые хотелось бы использовать по-максимуму. 

Для Wasm существует список фич, которые поддерживаются лишь частью существующих браузеров. В их числе как раз используемые нами многопоточность и SIMD-инструкции.

Конечно, не всe заработало сразу - процесс разработки быстро превратился в путь, полный чудес и новых открытий. Первым делом разбирались с дебагом и эксепшнами - exception’ы в васме реализованы через лютый костыль:  программе дают “упасть”, но не удаляют из памяти. Это позволяет взять адрес последнего возвращенного объекта и через cast представить как объект типа exception, после чего из него можно достать exception message и вернуть в консоль браузера. Пришлось заводить специальную функцию в модуле под это дело. В будущем обещают нормальную поддержку exception.

Больше всего времени мы потратили на имплементацию многопоточности. Многопоточность в js эмулируется с помощью воркеров. На этапе инициализации создается пул воркеров, в которых и происходит параллельное выполнение разных частей кода. Методом проб и ошибок выяснилось эмпирическое правило: количество одновременно выполняемых тредов внутри системы не может превышать количество созданных воркеров. Другими словами, создать сотню тредов, открепить их и дождаться результатов выполнения, вы не сможете. Для себя мы решили эту проблему, приравняв количество создаваемых для задачи воркеров и количество одновременно выполняющихся внутри библиотеки тредов, к количеству потоков, доступных системе. Для этого пришлось переделать весь механизм обеспечения многопоточности и внедрить очередь из задач, ожидающих выполнения на доступных системе потоках.

Неполная поддержка SIMD-инструкций, проблемы с i64 пойнтерами на старых архитектурах, слабая документация - но мы в итоге победили.

Для того, чтобы сделать наше распознавание доступным для максимального количества браузеров, в принципе поддерживающих Wasm, мы готовим сразу четыре варианта сборки: 

  • simd.threads (симды и многопоточность);

  • simd.nothreads (симды без многопоточности);

  • nosimd.threads (многопоточность без симдов);

  • nosimd.nothreads (ну сами понимаете).

Для определения поддерживаемых браузером фич и, соответственно, загрузки с сервера только нужной версии модуля распознавания, существуют две маленькие опенсорсные библиотеки:

  1. https://github.com/GoogleChromeLabs/wasm-feature-detect (Apache 2).

  2. https://github.com/MaxGraey/wasm-check (MIT).

Для загрузки подходящей сборки мы рекомендуем использовать importScripts(), поскольку новые динамические импорты (ESM) не работают в воркерах в Firefox без полифила.

Тестим!

Вот как это выглядит на iPhone 8 и на OnePlus 8T:

Основные выводы, конечно, же не могут обойтись без бенчмарка. Измерим производительность модуля распознавания на различных платформах с разными оптимизациями (в таблицах указаны средние значения).

simd.threads

Устройство

barcode

card

mrz

Chrome 100 on
OnePlus 8T (Qualcomm 865 Octa-core)

0.30с

0.30 с

0.70с

Chrome 100 on
Ryzen 7 3700X 8-Core

0.20с

0.25с

0.30с

Chrome 100 on
microsoft surface (Pentium 4415Y dual-core)

0.50с

0.90с

2.00с

nosimd.nothreads:

Устройство

barcode

card

mrz

Chrome 100 on OnePlus 8T (Qualcomm 865 Octa-core)

0.55с

0.35с

1.70с

Chrome 100 on
Ryzen 7 3700X 8-Core

0.60с

0.30с

0.90с

Safari 14 on Apple iPhone 8

0.25с

0.45с

1.65с

Chrome 100 on Microsoft Surface (Pentium 4415Y dual-core)

0.40с

1.30с

4.50с

В таблицах выше мы представили результаты замеров двух крайних случаев: работу с оптимизациями (SIMD, многопоточность) и без, на самых разных машинах. 

Планшет и мобильные телефоны работали со штатной камерой, компьютер же был в связке с Microsoft LifeCam Studio. Изображение ограничено 640х480 (размер canvas, на который мы выводили видеопоток). 

iPhone представлен только в колонке без оптимизаций - работу с SIMD-инструкциями на айфоны еще не подвезли, многопоточность присутствует только на старших моделях, да и то работает с ограничениями. 

Surface - машинка с посредственной камерой и довольно средним железом выступает довольно типичным примером кейса работы на тонком клиенте (кассы или рабочие места банковских служащих).

Заключение

В целом, Wasm показал себя прекрасным решением для безопасного кроссплатформенного распознавания. Производительность его уже сегодня вполне достаточна для выполнения даже вычислительно сложных задач, таких, как распознавание документов. Таким образом, у всех наших организаций теперь имеется хороший инструмент сделать удобные веб-приложения, обладающие привычными функционалом на базе ИИ, без привязки к магазинам приложений (App Store, Google Play и т.д.).

Теги:
Хабы:
+6
Комментарии1

Публикации

Информация

Сайт
smartengines.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия