Уступленне
Прывітанне!
У дадзеным артыкуле я падзялюся вопытам пабудовы мікрасэрвіснай архітэктуры для праекта, які выкарыстоўвае нейронавыя сеткі.
Пагаворым аб патрабаваннях да архітэктуры, паглядзім на розныя структурныя дыяграмы, разбяром кожны з кампанентаў гатовай архітэктуры, а таксама ацэнім тэхнічныя метрыкі рашэння.
Прыемнага чытання!
Пару слоў аб задачы і яе рашэнні
Асноўная ідэя - на аснове фота даць ацэнку прывабнасці чалавека па дзесяцібальнай шкале.
У дадзеным артыкуле мы адыдзем ад апісання як выкарыстоўваных нейронавых сетак, так і працэсу падрыхтоўкі дадзеных, навучання. Аднак, у адной з наступных публікацый, мы абавязкова вернемся да разбору пайплайна адзнакі на паглыбленым узроўні.
Цяпер жа мы верхнеўзроўневай пройдземся па пайплайну адзнакі, а ўпор зробім на ўзаемадзеянне мікрасэрвісаў у кантэксце агульнай архітэктуры праекту.
Пры працы над пайплайнам адзнакі прывабнасці, задача была дэкампазыравана на наступныя складнікі:
- Вылучэнне асоб на фота
- Ацэнка кожнай з асоб
- Рэндэр выніку
Першае вырашаецца сіламі прадугледжанай
Функцыянальная дыяграма пайплайна ацэнкі
Аналіз патрабаванняў да архітэктуры праекта
У жыццёвым цыкле
Жыццёвы цыкл ML праекта
Дадзены праект не выключэнне - было прынята рашэнне абгарнуць пайплайн адзнакі ў анлайн-сэрвіс, для гэтага патрабавалася пагрузіцца ў архітэктуру. Былі абазначаны наступныя базавыя патрабаванні:
- Адзінае сховішча логаў - усе сэрвісы павінны пісаць логі ў адно месца, іх павінна быць зручна аналізаваць
- Магчымасць гарызантальнага маштабавання сэрвісу адзнакі — як найболей верагоднага Bottleneck
- На ацэнку кожнага малюнка павінна быць выдзелена аднолькавая колькасць рэсурсаў працэсара — каб пазбегнуць выкідаў у размеркаванні часу на інферэнс.
- Хуткае (пера)разгортванне як пэўных сэрвісаў, так і стэка ў цэлым
- Магчымасць, пры неабходнасці, выкарыстоўваць у розных сэрвісах агульныя аб'екты
Архітэктура
Пасля аналізу патрабаванняў стала відавочна, што мікрасэрвісная архітэктура ўпісваецца практычна ідэальна.
Для таго, каб пазбавіцца ад лішняга галаўнога болю, у якасці фронтэнда быў абраны Telegram API.
Для пачатку разгледзім структурную дыяграму гатовай архітэктуры, далей пяройдзем да апісання кожнага з кампанентаў, а таксама фармалізуем працэс паспяховай апрацоўкі малюнка.
Структурная дыяграма гатовай архітэктуры
Пагаворым падрабязней аб кожным з кампанентаў дыяграмы, абазначым іх Single Responsibility падчас ацэнкі малюнка.
Мікрасэрвіс «attrai-telegram-bot»
Дадзены мікрасэрвіс інкапсулюе ўсе ўзаемадзеянні з Telegram API. Можна вылучыць 2 асноўных сцэнара - праца з карыстацкай выявай і праца з вынікам пайплайна ацэнкі. Разбяром абодва сцэнарыя ў агульным выглядзе.
Пры атрыманні карыстацкага паведамлення з выявай:
- Вырабляецца фільтраванне, якая складаецца з наступных праверак:
- Наяўнасці аптымальнага памеру выявы
- Колькасці малюнкаў карыстальніка, якія ўжо знаходзяцца ў чарзе
- Пры праходжанні першаснага фільтравання выява захоўваецца ў docker volume
- У чаргу “to_estimate” прадусецца цяга, у якой, у тым ліку, фігуруе шлях да выявы, які ляжыць у нашым volume
- Калі вышэйпералічаныя этапы пройдзены паспяхова - карыстач атрымае паведамленне з прыкладным часам апрацоўкі малюнка, якое разлічваецца на аснове колькасці цягачаў у чарзе. У выпадку памылкі карыстач будзе відавочна аб гэтым абвешчаны - шляхам адпраўкі паведамлення з інфармацыяй аб тым, што магло пайсці не так.
Таксама, дадзены мікрасэрвіс, як celery worker, слухае чаргу «after_estimate», якая прызначаецца для цягоў, якія прайшлі праз пайплайн адзнакі.
Пры атрыманні новай цягі з "after_estimate":
- Калі выява апрацавана паспяхова - адпраўляем вынік карыстачу, калі не - апавяшчаем пра памылку
- Выдаляем малюнак, якое з'яўляецца вынікам пайплайна ацэнкі
Мікрасэрвіс ацэнкі «attrai-estimator»
Дадзены мікрасэрвіс з'яўляецца celery worker і інкапсулюе ў сабе ўсё, што звязана з пайплайнай ацэнкі малюнка. Алгарытм працы тут адзін - разбяром яго.
Пры атрыманні новай цягі з "to_estimate":
- Праганяем малюнак праз пайплайн адзнакі:
- Загружаем выяву ў памяць
- Прыводзім малюнак да патрэбнага памеру
- Знаходзім усе асобы (MTCNN)
- Ацэньваем усе асобы (азіраем знойдзеныя ў мінулым пункце асобы ў батч і інферэнсім ResNet34)
- Рэндэрым выніковае выявай
- Малюем bounding boxes
- Адмалёўваем адзнакі
- Выдаляем карыстацкі (зыходны) малюнак
- Захоўваем выхад з пайплайна ацэнкі
- Кладзём цягу ў чаргу “after_estimate”, якую слухае разабраны вышэй мікрасэрвіс “attrai-telegram-bot”
Graylog (+ mongoDB + Elasticsearch)
Выбар упаў менавіта на яго, а не на звыклы ўсім
Я, як чалавек, які да гэтага працаваў толькі з ELK стэкам, у цэлым, атрымаў пазітыўны досвед падчас працы з Graylog. Адзінае, што засмучае перавага па фічам Kibana над вэб-інтэрфейсам Graylog.
RabbitMQ
У дадзеным праекце ён выкарыстоўваўся як
Redis
Часам узнікае неабходнасць выкарыстоўваць у розных python-мікрасэрвісах агульныя аб'екты, якія рэалізуюць якія-небудзь структуры дадзеных.
Напрыклад, у Redis захоўваецца hashmap выгляду "telegram_user_id => колькасць актыўных тасак у чарзе", што дазваляе абмежаваць колькасць запытаў ад аднаго карыстача вызначаным значэннем і, тым самым, прадухіліць DoS-напады.
Фармалізуем працэс паспяховай апрацоўкі выявы
- Карыстальнік адпраўляе выява ў Telegram бота
- "attrai-telegram-bot" атрымлівае паведамленне ад Telegram API і разбірае яго
- Таск з выявай дадаецца ў асінхронную чаргу "to_estimate"
- Карыстальнік атрымлівае паведамленне з планаваным часам ацэнкі
- «attrai-estimator» бярэ таск з чаргі «to_estimate», праганяе праз пайплайн адзнакі і прад'юсіць таск у чаргу «after_estimate»
- "attrai-telegram-bot", які слухае чаргу "after_estimate", адпраўляе вынік карыстачу
DevOps
Нарэшце, пасля агляду архітэктуры, можна перайсці да не менш цікавай часткі - DevOps
Докерскі рой
Пры дапамозе "роя", усе ноды нашага кластара можна падзяліць на 2 тыпу - worker і manager. На машынах першага тыпу разгортваюцца групы кантэйнераў (стэкі), машыны другога тыпу адказваюць за скаляванне, балансаванне і
Кластар з адным leader manager і трыма worker
Мінімальна магчымы памер кластара - 1 нода, адзіная машына будзе адначасова выступаць як leader manager і worker. Зыходзячы з памеру праекта і мінімальных патрабаванняў да адмоваўстойлівасці, было прынята рашэнне выкарыстоўваць менавіта гэты падыход.
Забягаючы наперад, скажу, што з моманту першай production-пастаўкі, якая была ў сярэдзіне чэрвеня, праблем, злучаных з дадзенай арганізацыяй кластара, не было (але гэта не значыць, што падобная арганізацыя хоць колькі-небудзь дапушчальная ў любых сярэдне-буйных праектах, на якія накладваюцца патрабаванні па адмоваўстойлівасці).
Docker Stack
У рэжыме "роя" за разгортванне стэкаў (набораў docker services) адказвае
Ён падтрымлівае docker-compose канфігі, дазваляючы дадаткова выкарыстоўваць параметры deploy.
Напрыклад, пры дапамозе дадзеных параметраў былі абмежаваныя рэсурсы на кожны з інстансаў мікрасэрвісу адзнакі (вылучаем на N інстансаў N ядраў, у самім мікрасэрвісе абмяжоўваем кол-ць ядраў, выкарыстоўванае PyTorch`ем, адным)
attrai_estimator:
image: 'erqups/attrai_estimator:1.2'
deploy:
replicas: 4
resources:
limits:
cpus: '4'
restart_policy:
condition: on-failure
…
Важна адзначыць, што Redis, RabbitMQ і Graylog – stateful сэрвісы і маштабаваць іх гэтак жа проста, як «attrai-estimator», не атрымаецца
Прадказваючы пытанне - чаму не Kubernetes?
Здаецца, што выкарыстанне Kubernetes у праектах маленькага і сярэдняга памеру - оверхед, увесь неабходны функцыянал можна атрымаць ад Docker Swarm, які даволі user friendly для аркестратара кантэйнераў, а таксама мае нізкі парог уваходжання.
Інфраструктура
Разгортвалася гэта ўсё на VDS са наступнымі характарыстыкамі:
- CPU: 4 ядра Intel ® Xeon ® Gold 5120 CPU @ 2.20GHz
- Аператыўная памяць: 8 ГБ
- SSD: 160 ГБ
Пасля лакальнага нагрузачнага тэсціравання, здавалася, што пры сур'ёзным наплыве карыстальнікаў, дадзенай машынкі будзе хапаць упрытык.
Але, адразу пасля дэплою, я запосціў спасылку на адну з самых папулярных у СНД іміджборд (ага, тую самую), пасля чаго людзі зацікавіліся і за некалькі гадзін сэрвіс паспяхова апрацаваў дзясяткі тысяч малюнкаў. Пры гэтым у пікавыя моманты рэсурсы CPU і RAM не былі скарыстаны нават напалову.
Яшчэ крыху графікі
Колькасць унікальных карыстальнікаў і запытаў на адзнаку, з моманту дэплою, у залежнасці ад дня
Размеркаванне часу інферэнса пайплайна ацэнкі
Высновы
Рэзюмуючы, магу сказаць, што архітэктура і падыход да аркестрацыі кантэйнераў цалкам сябе апраўдалі - нават у пікавыя моманты не было падзенняў і прасяданняў па часе апрацоўкі.
Думаю, праекты маленькага і сярэдняга памераў, якія выкарыстоўваюць у сваім працэсе рэалтайм інферэнс нейронавых сетак на CPU, паспяхова могуць пераняць практыкі, апісаныя ў дадзеным артыкуле.
Дадам, што першапачаткова артыкул быў большы, але, каб не пасціць лонгрыд, вырашыў некаторыя моманты ў дадзеным артыкуле апусціць - вернемся да іх у наступных публікацыях.
Патыкаць робата можна ў Telegram – @ AttraiBot, працаваць будзе, як мінімум, да канца восені 2020 года. Нагадаю - ніякія карыстацкія дадзеныя не захоўваюцца - ні зыходныя малюнкі, ні вынікі пайплайна адзнакі - усё зносіцца пасля апрацоўкі.
Крыніца: habr.com