Использование Flask, Heroku и многопоточности

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

Вещи, о которых люди обычно не заботятся или о которых не думают, когда впервые экспериментируют с машинным обучением, - это размер ЦП, ОЗУ, взаимодействие с пользователем и время отклика, зависимость от внешних API и т. Д. Но они становятся очень важными, если наше приложение машинного обучения должно предоставлять какие-либо вроде реальная выгода.

В этой статье я учусь при развертывании моего недавнего приложения - SharedWatch - системы рекомендаций фильмов, основанной на текстовой аналитике и онлайн-кластеризации. Эта статья не об алгоритмах или подходах, используемых в основном приложении, а о проблемах / проблемах, возникающих при развертывании приложения.

Я расскажу одно за другим о каждом из препятствий, с которыми пришлось столкнуться, и о том, как они были устранены.

  1. RAM

Приложение должно было быть размещено на уровне Free, предлагаемом Heroku. Учитывая, что, поскольку он бесплатный, ему присущи ограничения. Ограничения по размеру приложения, количеству ядер и объему оперативной памяти.

Как вы можете видеть выше, уровень бесплатного пользования heroku предлагает только 512 МБ ОЗУ, что слишком ограничено для приложений машинного обучения.

Когда я впервые развернул приложение, я сразу же столкнулся с проблемой, когда приложение было принудительно остановлено Heroku, потому что оно превышало использование памяти почти на 200% !!

Это происходило из-за того, что за кулисами я использовал Spacy, и их простейшая полезная модель имеет размер 90 МБ на диске, а при загрузке в память увеличивается примерно до 200 МБ. Большая часть оперативной памяти съедалась просто за счет загрузки модели.

Теперь это кажется проблемой, которую сложно решить. Вам нужно либо искать более мелкие пригодные для использования модели, либо просто заплатить Heroku за обновление вашей машины. Как всегда, не имея финансирования, я остановил свой выбор на первом варианте. Но мне потребовалось некоторое время, прежде чем я наткнулся на PyMagnitude. Теперь эти ребята проделали огромную работу, взяв те же базовые модели, которые используются повсюду, от Spacy до NLTK, и преобразовали их во что-то, называемое форматом Magnitude, который занимает около 10 МБ ОЗУ !!! Значительное сокращение, очевидно, что стоимость - это время обработки, но тогда, по крайней мере, эта, казалось бы, неразрешимая проблема, имела путь вперед. Поэтому я заменил Spacy на PyMagnitude.

Урок. Прежде чем вы решите использовать больше оборудования, попробуйте оптимизировать свой код и поищите эффективные зависимости.

2 . ЦП и время отклика

Вторая проблема, которая была очень важна для приложения, - это время отклика. Поскольку за кулисами мы использовали онлайн-обработку и кластеризацию, мы должны были быть действительно эффективными, чтобы конечный пользователь приложения не испытывал значительного времени ожидания.

Еще одной причиной критики было жесткое ограничение, наложенное Heroku на веб-запросы. Время отклика должно быть менее 30 секунд (разумно высокий предел для веб-приложения, но для приложения машинного обучения?). Как только вы достигнете предела, Heroku убьет рабочего, и запрос умрет.

А. С точки зрения UX

Первое, что мы решили сделать, - это улучшить пользовательский опыт. В целом приложение выполняет две функции: позволяет пользователю исследовать темы в фильмах и находить похожие фильмы. Функция «Темы» вернет ответ в течение 3 секунд, а функция «Фильмы» займет вечность. Поэтому мы решили разместить пользователей на вкладке «Темы», которая позволила бы им немедленно начать изучение тем и фильмов по этим темам. Но мы оставили вкладку «Фильмы» отключенной и показывали символ загрузки, независимо от того, насколько быстрой она будет в будущем, мы ожидали, что она будет медленнее, чем тема, так что это вроде как имеет смысл.

Б. Делаем вещи быстрее - потоки

Еще один способ подавления нас - это сетевые вызовы. Мы делали много вызовов API (через кэш), которые в среднем занимали 1-2 секунды, и, поскольку мы делали их много, приложение просто взорвалось.

Естественный способ справиться с этой ситуацией - использовать параллельную обработку.

Теперь параллельная обработка может выполняться с помощью - MultiProcessing или MultiThreading. У обоих разные варианты использования.

Общее практическое правило

Если в вашем коде много операций ввода-вывода или использования сети:

  • Многопоточность - лучший выбор из-за низких накладных расходов.

Если у вас есть графический интерфейс

  • Многопоточность, чтобы поток пользовательского интерфейса не блокировался

Если ваш код ограничен ЦП:

  • Вам следует использовать многопроцессорность (если на вашем компьютере несколько ядер).

Поэтому, естественно, мы решили использовать Threading. Python предоставляет очень простой интерфейс для библиотеки потоковой передачи.

Цитируя официальную документацию, « multiprocessing.dummy копирует API multiprocessing, но является не более чем оболочкой для модуля threading ».

Теперь вместо использования последовательных циклов вы можете запускать вещи параллельно!

В приведенном выше фрагменте кода

[Строка 118] Сначала мы вызываем внешний API-интерфейс для получения фильмов, связанных с определенным ключевым словом, например «Романтика», «Драма» или «Дели», а затем [строка 120] параллельно извлекаем все ключевые слова для каждого фильма.

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

Это все для этой статьи, пожалуйста, оставьте комментарий, если что-то неясно или в случае каких-либо предложений.

Продолжение этой статьи или ее предшественник - Развертывание приложений на Heroku будет рассмотрено в другой статье.