
Hyrje
Përshëndetje!
Në këtë artikull do të ndaj përvojën time në ndërtimin e një arkitekture mikroshërbimesh për një projekt që përdor rrjete nervore.
Do të flasim për kërkesat e arkitekturës, do të shohim diagrame të ndryshme strukturore, do të analizojmë secilin nga komponentët e arkitekturës së gatshme dhe do të vlerësojmë metrikat teknike të zgjidhjes.
Lexim të këndshëm!
Disa fjalë për detyrën dhe zgjidhjen e saj
Ideja kryesore – të ofrohet një vlerësim për tërheqjen e një personi në një shkallë nga 1 në 10 bazuar në fotografi.
Në këtë artikull do të shmangim përshkrimin e rrjeteve nervore të përdorura, si dhe procesin e përgatitjes së të dhënave dhe mësimit. Megjithatë, në një nga botimet e ardhshme, ne do të rikthehemi në analizën e pipeline-it të vlerësimit në një nivel më të thellë.
Aktualisht ne do të kalojmë nëpër pipeline-in e vlerësimit, duke u fokusuar në ndërveprimin e mikroshërbimeve në kontekstin e arkitekturës së përgjithshme të projektit.
Kur punonim mbi pipeline-in e vlerësimit të tërheqjes, detyra u dekompozua në komponentët e mëposhtëm:
- Identifikimi i fytyrave në foto
- Vlerësimi i çdo fytyre
- Renderimi i rezultatit
E para zgjidhet nga një model i trajnuar më parë . Për të dytën, një rrjet nervor konvolucional u trajnuar në PyTorch, si backbone u përdor – nga balanca "cilësi / shpejtësia e inferencës në CPU"

Diagrami funksional i pipeline-it të vlerësimit
Analiza e kërkesave për arkitekturën e projektit
Në ciklin e jetës etapat e punës mbi arkitekturën dhe automatizimin e shpërndarjes së modelit, shpeshherë janë disa nga ato më të kushtueshme në kohë dhe burime.

Cikli i jetës së projektit ML
Ky projekt nuk është përjashtim – u mor vendimi për të mbështjellë pipeline-in e vlerësimit në një shërbim online, për këtë ishte e nevojshme të thellohej në arkitekturë. U përcaktuan kërkesat bazë të mëposhtme:
- Një magazinë e vetme log-esh – të gjitha shërbimet duhet të shkruajnë log-ët në një vend, ato duhet të jenë lehtësisht të analizueshme
- Mundësia e shkallëzimit horizontal të shërbimit të vlerësimit — si Bottleneck më i mundshëm
- Për çdo imazh duhet të caktuar një sasi e barabartë burimesh të procesorit — për të shmangur devijimet në shpërndarjen e kohës për inferencë
- Ripërhapje e shpejtë (ri) e shërbimeve specifike, si dhe e stakës në tërësi
- Mundësia për të përdorur objekte të përbashkëta në shërbime të ndryshme, nëse është e nevojshme.
Arkitektura
Pas analizimit të kërkesave, u bë e qartë se arkitektura mikroshërbimore përshtatet pothuajse perfekt.
Për të shmangur dhimbjet e panevojshme, u zgjodh Telegram API si frontend.
Faza e parë është shqyrtimi i diagramës strukturore të arkitekturës përfundimtare, më pas do të kalojmë në përshkrimin e secilit komponent dhe do të formulojmë procesin e përpunimit të suksesshëm të imazheve.

Diagrami struktural i arkitekturës përfundimtare
Të flasim më në detaje mbi secilin nga komponentët e diagramës, duke ndarë përgjegjësinë e tyre të vetme në procesin e vlerësimit të imazhit.
Mikrosherbimi «attrai-telegram-bot»
Ky mikroshërbim inkapsulon të gjitha ndërveprimet me Telegram API. Mund të dallojmë dy skenarë kryesorë – punimi me imazhin e përdoruesit dhe punimi me rezultatin e procesit të vlerësimit. Do të shqyrtojmë të dyja skenarët në përmbledhje.
Kur merrni një mesazh të përdoruesit me një imazh:
- Kryhet filtrimi, i cili përfshin këto kontrollime:
- Prania e madhësisë optimale të imazhit
- Numri i imazheve të përdoruesit që tashmë janë në radhë
- Gjatë kalimit të filtër primar, imazhi ruhet në docker volume
- Në radhën “to_estimate” prodhohet një detyrë, ku, ndër të tjera, përfshihet rruga deri te imazhi, që ndodhet në volume tonë
- Nëse hapat e mësipërm përfundojnë me sukses - përdoruesi do të marrë një mesazh me kohën e përafërt të përpunimit të imazhit, e cila llogaritet në bazë të numrit të detyrave në radhë. Në rast gabimi, përdoruesi do të njoftohet qartë - duke dërguar një mesazh me informacionin se çfarë mund të ketë shkuar keq.
Gjithashtu, ky mikroshërbim, si punëtor celere, dëgjon radhën “after_estimate”, e cila është e destinuar për detyrat që kanë kaluar përmes pipeline-it të vlerësimit.
Kur marrim një detyrë të re nga “after_estimate”:
- Nëse imazhi është përpunuar me sukses - i dërgojmë rezultatin përdoruesit, në të kundërt - njoftojmë për gabimin
- Fshijmë imazhin, që është rezultati i pipeline-it të vlerësimit
Mikroshërbimi i vlerësimit “attrai-estimator”
Ky mikroshërbim është punëtor celere dhe inkapsulon gjithçka që lidhet me pipeline-in e vlerësimit të imazhit. Algoritmi i punës këtu është një - do ta shqyrtojmë atë.
Kur marrim një detyrë të re nga “to_estimate”:
- Kaluajmë imazhin përmes pipeline-it të vlerësimit:
- Ngarkohet imazhi në memorje
- Rregullojmë imazhin në madhësinë e duhur
- Gjejmë të gjitha fytyrat (MTCNN)
- Vlerësojmë të gjitha fytyrat (mbështjellim fytyrat e gjetura më parë në një grup dhe bëjmë inferencën me ResNet34)
- Renderojmë imazhin përfundimtar
- Vizatojmë kutitë ndihmëse
- Vizatojmë vlerësimet
- Fshijmë imazhin origjinal nga përdoruesi
- Ruajmë daljen nga pipeline-i i vlerësimit
- Vendosim detyrën në radhë "after_estimate", e cila dëgjohet nga mikroshërbisi i përmendur më sipër "attrai-telegram-bot"
Graylog (+ mongoDB + Elasticsearch)
është një zgjidhje për menaxhimin qendror të log-eve. Në këtë projekt, ai është përdorur sipas qëllimeve të tij të drejta.
Zgjedhja ra pikërisht mbi të, dhe jo mbi stakun e njohur për të gjithë për shkak të lehtësisë së punës me të nga Python. Gjithçka që duhet bërë për logimin në Graylog është të shtoni GELFTCPHandler nga paketa në handler-at tjerë root logger të mikroshërbisit tonë python.
Unë, si një person që më parë ka punuar vetëm me stakun ELK, në përgjithësi kam pasur një përvojë pozitive gjatë punës me Graylog. E vetmja gjë që më shqetëson është superioriteti i karakteristikave të Kibana-s ndaj ndërfaqes së web-it të Graylog.
RabbitMQ
— është një broker mesazhesh i bazuar në protokollin AMQP.
Në këtë projekt, ai u përdor si për Celery dhe punoi në modalitetin durable.
Redis
— është një DBMS NoSQL që punon me struktura të dhënash të tipit "çelës — vlerë".
Ndonjëherë lind nevoja për të përdorur objekte të zakonshme në mikroshërbime të ndryshme Python, të cilat implementojnë disa struktura të dhënash.
Për shembull, në Redis ruhet një hashmap i tipit "telegram_user_id => numri i task-eve aktive në radhë", çka lejon kufizimin e numrit të kërkesave nga një përdorues në një vlerë të caktuar dhe, në këtë mënyrë, parandalon sulmet DoS.
Formulojmë procesin e trajtimit të suksesshëm të imazhit
- Përdoruesi dërgon një imazh në botin Telegram
- "attrai-telegram-bot" merr mesazhin nga API i Telegram dhe e analizojnë atë
- Tasku me imazhin shtohet në radhën asinkrone "to_estimate"
- Përdoruesi merr një mesazh me kohën e parashikuar për vlerësim
- "attrai-estimator" merr taskun nga radhë "to_estimate", e kalon atë përmes tubit të vlerësimit dhe e prodhon taskun në radhën "after_estimate"
- "attrai-telegram-bot", që dëgjon radhën "after_estimate", i dërgon rezultatin përdoruesit
DevOps
Finally, after reviewing the architecture, we can move on to the no less interesting part — DevOps
Docker Swarm

— a clustering system whose functionality is implemented within the Docker Engine and available out of the box.
Using the ‘swarm’, all nodes in our cluster can be divided into 2 types – worker and manager. Containers (stacks) are deployed on machines of the first type, while machines of the second type are responsible for scaling, balancing, and . Managers are, by default, also workers.

A cluster with one leader manager and three workers
The minimum possible size of a cluster is 1 node, with a single machine acting as both the leader manager and worker. Based on the project size and minimal fault tolerance requirements, it was decided to use this approach.
To get ahead of myself, I’ll say that since the first production deployment in mid-June, there have been no issues related to this cluster organization (but this doesn’t mean that such an organization is acceptable in any medium-large projects that have reliability requirements).
Docker Stack
Në modin «swarm», për shpërndarjen e stekëve (grupeve të shërbimeve docker) është përgjegjës
Ai mbështet konfigurimet docker-compose, duke lejuar përdorimin e parametrave të shpërndarjes.
Për shembull, me këta parametra janë kufizuar burimet për çdo instancë të mikroshërbimit të vlerësimit (i alokoni N instancave N bërthama, në mikroshërbim kufizojmë numrin e bërthamave, që përdoret nga PyTorch, në një)
attrai_estimator:
image: 'erqups/attrai_estimator:1.2'
deploy:
replicas: 4
resources:
limits:
cpus: '4'
restart_policy:
condition: on-failure
…Është e rëndësishme të theksohet se Redis, RabbitMQ dhe Graylog janë shërbime stateful dhe nuk është kaq e lehtë t’i shkallëzosh si «attrai-estimator»
Për të parashikuar pyetjen - pse jo Kubernetes?
Duket se përdorimi i Kubernetes në projekte të vogla dhe mesme është një overhead, të gjithë funksionalitetin e nevojshëm mund ta merrni nga Docker Swarm, i cili është mjaft miqësor për përdoruesit në menaxhimin e kontejnerëve, si dhe ka një prag të ulët hyrjeje.
Infrastruktura
Kjo e gjithë është vendosur në VDS me këto karakteristika:
- CPU: 4 bërthama Intel® Xeon® Gold 5120 CPU @ 2.20GHz
- RAM: 8 GB
- SSD: 160 GB
Pas testimit local të ngarkesës, dukej se nëse ka një fluks të konsiderueshëm përdoruesish, kjo makinë do të ishte e mjaftueshme.
Por, menjëherë pas deploy-it, postova një lidhje në një nga bordet më të njohura të imazheve në CE (po, atë vetë), dhe pas kësaj njerëzit u interesuan dhe brenda disa orësh, shërbimi përfundoi me sukses përpunimin e dhjetëra mijëra imazheve. Në momentet kulmore, burimet e CPU dhe RAM nuk u përdorën as gjysmë.


Pak më shumë grafikë
Numri i përdoruesve unik dhe kërkesat për vlerësim, nga momenti i deploy-it, në varësi të ditës

Shpërndarja e kohës së inferencës së rafteve të vlerësimit

Përfundimet
Përmbledhësisht, mund të them se arkitektura dhe qasja për orkestrimin e kontejnerëve u vërtetuan plotësisht – edhe në momentet kulmore nuk kishte rënie apo ngadalësim në kohën e përpunimit.
Mendoj se projektet e vogla dhe të mesme, që përdorin inferencë në kohë reale me rrjete neuronale në CPU, mund të adoptojnë me sukses praktikat e përshkruara në këtë artikull.
Do të shtoj se fillimisht artikulli ishte më i gjatë, por që të mos postoj një tekst të gjatë, vendosa të shkep disa pika në këtë artikull — do t'i kthehemi në publikimet e ardhshme.
Mund ta provosh botin në Telegram — @AttraiBot, do të funksionojë së paku deri në fund të vjeshtës 2020. Kujtojmë — nuk ruhen të dhëna të përdoruesve — as imazhet origjinale, as rezultatet e procesit të vlerësimit — gjithçka zhduket pas përpunimit.
Burimi: habr.com
