Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Eintrag

Hallo!

In diesem Artikel werde ich meine Erfahrungen beim Aufbau einer Microservice-Architektur für ein Projekt unter Verwendung neuronaler Netze teilen.

Lassen Sie uns über die Architekturanforderungen sprechen, verschiedene Strukturdiagramme betrachten, jede einzelne Komponente der fertigen Architektur analysieren und auch die technischen Metriken der Lösung bewerten.

Viel Spaß beim Lesen!

Ein paar Worte zum Problem und seiner Lösung

Die Grundidee besteht darin, die Attraktivität einer Person anhand eines Fotos auf einer zehnstufigen Skala zu bewerten.

In diesem Artikel werden wir uns von der Beschreibung sowohl der verwendeten neuronalen Netze als auch des Prozesses der Datenaufbereitung und des Trainings entfernen. In einer der folgenden Veröffentlichungen werden wir jedoch auf jeden Fall noch einmal auf die vertiefende Analyse der Bewertungspipeline zurückkommen.

Nun gehen wir die Evaluierungspipeline auf der obersten Ebene durch und konzentrieren uns auf das Zusammenspiel von Microservices im Kontext der gesamten Projektarchitektur. 

Bei der Arbeit an der Pipeline zur Attraktivitätsbewertung wurde die Aufgabe in die folgenden Komponenten zerlegt:

  1. Auswählen von Gesichtern in Fotos
  2. Bewertung jeder Person
  3. Rendern Sie das Ergebnis

Der erste wird durch die Kräfte des vorab trainierten gelöst MTCNN. Im zweiten Schritt wurde ein Faltungs-Neuronales Netzwerk auf PyTorch trainiert ResNet34 – aus der Balance „Qualität/Geschwindigkeit der Inferenz auf der CPU“

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Funktionsdiagramm der Evaluierungspipeline

Analyse der Anforderungen an die Projektarchitektur

Im Lebenszyklus ML Projektphasen der Arbeit an der Architektur und Automatisierung der Modellbereitstellung gehören oft zu den zeitaufwändigsten und ressourcenintensivsten.

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Lebenszyklus eines ML-Projekts

Dieses Projekt ist keine Ausnahme – die Entscheidung wurde getroffen, die Bewertungspipeline in einen Online-Dienst zu integrieren, was ein Eintauchen in die Architektur erforderte. Folgende Grundanforderungen wurden identifiziert:

  1. Einheitlicher Protokollspeicher – alle Dienste sollten Protokolle an einem Ort schreiben und bequem zu analysieren sein
  2. Möglichkeit einer horizontalen Skalierung des Bewertungsdienstes – als wahrscheinlichster Engpass
  3. Für die Auswertung jedes Bildes sollte die gleiche Menge an Prozessorressourcen zugewiesen werden, um Ausreißer in der Zeitverteilung für die Schlussfolgerung zu vermeiden
  4. Schnelle (Neu-)Bereitstellung sowohl spezifischer Dienste als auch des Stacks als Ganzes
  5. Die Möglichkeit, bei Bedarf gemeinsame Objekte in verschiedenen Diensten zu verwenden

Architektur

Nach der Analyse der Anforderungen wurde deutlich, dass die Microservice-Architektur nahezu perfekt passt.

Um unnötige Kopfschmerzen zu vermeiden, wurde die Telegram-API als Frontend ausgewählt.

Schauen wir uns zunächst das Strukturdiagramm der fertigen Architektur an, gehen dann zur Beschreibung der einzelnen Komponenten über und formalisieren den Prozess einer erfolgreichen Bildverarbeitung.

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Strukturdiagramm der fertigen Architektur

Lassen Sie uns detaillierter auf die einzelnen Komponenten des Diagramms eingehen und sie als Einzelverantwortung im Prozess der Bildauswertung bezeichnen.

Microservice „attrai-telegram-bot“

Dieser Microservice kapselt alle Interaktionen mit der Telegram-API. Es gibt zwei Hauptszenarien: Arbeiten mit einem benutzerdefinierten Bild und Arbeiten mit dem Ergebnis einer Bewertungspipeline. Schauen wir uns beide Szenarien allgemein an.

Wenn Sie eine benutzerdefinierte Nachricht mit einem Bild erhalten:

  1. Es wird eine Filtration durchgeführt, die aus folgenden Kontrollen besteht:
    • Verfügbarkeit der optimalen Bildgröße
    • Anzahl der Benutzerbilder, die sich bereits in der Warteschlange befinden
  2. Beim Bestehen der anfänglichen Filterung wird das Bild im Docker-Volume gespeichert
  3. In der Warteschlange „to_estimate“ wird eine Aufgabe erstellt, die unter anderem den Pfad zu dem Bild enthält, das sich in unserem Volume befindet
  4. Wenn die oben genannten Schritte erfolgreich abgeschlossen wurden, erhält der Benutzer eine Nachricht mit der ungefähren Bildverarbeitungszeit, die anhand der Anzahl der Aufgaben in der Warteschlange berechnet wird. Wenn ein Fehler auftritt, wird der Benutzer explizit benachrichtigt, indem eine Nachricht mit Informationen darüber gesendet wird, was möglicherweise schief gelaufen ist.

Außerdem lauscht dieser Microservice wie ein Sellerie-Worker auf die „after_estimate“-Warteschlange, die für Aufgaben gedacht ist, die die Evaluierungspipeline durchlaufen haben.

Wenn Sie eine neue Aufgabe von „after_estimate“ erhalten:

  1. Wenn das Bild erfolgreich verarbeitet wurde, senden wir das Ergebnis an den Benutzer. Wenn nicht, benachrichtigen wir über einen Fehler.
  2. Entfernen des Bildes, das das Ergebnis der Evaluierungspipeline ist

Evaluierungs-Microservice „attrai-estimator“

Dieser Microservice ist ein Sellerie-Worker und kapselt alles, was mit der Bildauswertungspipeline zu tun hat. Hier gibt es nur einen funktionierenden Algorithmus – analysieren wir ihn.

Beim Empfang einer neuen Aufgabe von „to_estimate“:

  1. Lassen Sie uns das Bild durch die Auswertungspipeline laufen lassen:
    1. Laden des Bildes in den Speicher
    2. Wir bringen das Bild auf die gewünschte Größe
    3. Alle Gesichter finden (MTCNN)
    4. Wir werten alle Gesichter aus (wir verpacken die im letzten Schritt gefundenen Gesichter in einen Stapel und schließen daraus ResNet34)
    5. Rendern Sie das endgültige Bild
      1. Zeichnen wir die Begrenzungsrahmen
      2. Ziehung der Bewertungen
  2. Löschen eines benutzerdefinierten (Original-)Bildes
  3. Speichern der Ausgabe der Evaluierungspipeline
  4. Wir stellen die Aufgabe in die Warteschlange „after_estimate“, die vom oben besprochenen Mikrodienst „attrai-telegram-bot“ abgehört wird.

Graylog (+ mongoDB + Elasticsearch)

Graylog ist eine Lösung für die zentrale Protokollverwaltung. In diesem Projekt wurde es bestimmungsgemäß verwendet.

Die Wahl fiel auf ihn und nicht auf die übliche ELCH Stack, da es praktisch ist, von Python aus damit zu arbeiten. Um sich bei Graylog anzumelden, müssen Sie lediglich den GELFTCPHandler aus dem Paket hinzufügen grau an den Rest der Root-Logger-Handler unseres Python-Microservices.

Als jemand, der bisher nur mit dem ELK-Stack gearbeitet hatte, hatte ich insgesamt eine positive Erfahrung bei der Arbeit mit Graylog. Das Einzige, was deprimierend ist, ist die Überlegenheit der Kibana-Funktionen gegenüber der Graylog-Weboberfläche.

RabbitMQ

RabbitMQ ist ein Nachrichtenbroker, der auf dem AMQP-Protokoll basiert.

In diesem Projekt wurde es als verwendet das stabilste und bewährteste Makler für Sellerie und arbeitete im dauerhaften Modus.

Redis

Redis ist ein NoSQL-DBMS, das mit Schlüsselwert-Datenstrukturen arbeitet

Manchmal besteht die Notwendigkeit, gemeinsame Objekte zu verwenden, die bestimmte Datenstrukturen in verschiedenen Python-Mikrodiensten implementieren.

Redis speichert beispielsweise eine Hashmap der Form „telegram_user_id => Anzahl aktiver Aufgaben in der Warteschlange“, mit der Sie die Anzahl der Anfragen eines Benutzers auf einen bestimmten Wert begrenzen und so DoS-Angriffe verhindern können.

Lassen Sie uns den Prozess einer erfolgreichen Bildverarbeitung formalisieren

  1. Der Benutzer sendet ein Bild an den Telegram-Bot
  2. „attrai-telegram-bot“ empfängt eine Nachricht von der Telegram-API und analysiert sie
  3. Die Aufgabe mit dem Bild wird zur asynchronen Warteschlange „to_estimate“ hinzugefügt.
  4. Der Benutzer erhält eine Nachricht mit dem geplanten Beurteilungszeitpunkt
  5. „attrai-estimator“ nimmt eine Aufgabe aus der „to_estimate“-Warteschlange, führt die Schätzungen durch die Pipeline und stellt die Aufgabe in die „after_estimate“-Warteschlange
  6. „attrai-telegram-bot“ lauscht der Warteschlange „after_estimate“ und sendet das Ergebnis an den Benutzer

DevOps

Nachdem Sie sich die Architektur angesehen haben, können Sie schließlich mit dem ebenso interessanten Teil fortfahren – DevOps

Hafenschwarm

 

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Hafenschwarm  – ein Clustering-System, dessen Funktionalität in der Docker Engine implementiert ist und sofort verfügbar ist.

Mithilfe eines „Schwarms“ können alle Knoten in unserem Cluster in zwei Typen unterteilt werden – Arbeiter und Manager. Auf Maschinen des ersten Typs werden Gruppen von Behältern (Stapel) eingesetzt, Maschinen des zweiten Typs sind für die Skalierung, den Ausgleich usw. verantwortlich andere coole Features. Manager sind grundsätzlich auch Arbeiter.

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Cluster mit einem leitenden Manager und drei Arbeitern

Die minimal mögliche Clustergröße beträgt 1 Knoten; eine einzelne Maschine fungiert gleichzeitig als Leiter, Manager und Arbeiter. Aufgrund der Größe des Projekts und der Mindestanforderungen an die Fehlertoleranz wurde beschlossen, diesen Ansatz zu verwenden.

Mit Blick auf die Zukunft kann ich sagen, dass es seit der ersten Produktionsauslieferung Mitte Juni keine Probleme im Zusammenhang mit dieser Clusterorganisation gegeben hat (was jedoch nicht bedeutet, dass eine solche Organisation in einem mittelgroßen bis großen Unternehmen in irgendeiner Weise akzeptabel ist). Projekte, die Fehlertoleranzanforderungen unterliegen).

Docker-Stack

Im Schwarmmodus ist er für die Bereitstellung von Stacks (Sätze von Docker-Diensten) verantwortlich. Docker-Stack

Es unterstützt Docker-Compose-Konfigurationen, sodass Sie zusätzlich Bereitstellungsoptionen verwenden können.  

Durch die Verwendung dieser Parameter wurden beispielsweise die Ressourcen für jede der Evaluierungs-Microservice-Instanzen begrenzt (wir weisen N Kernen für N Instanzen zu, im Microservice selbst begrenzen wir die Anzahl der von PyTorch verwendeten Kerne auf einen).

attrai_estimator:
  image: 'erqups/attrai_estimator:1.2'
  deploy:
    replicas: 4
    resources:
      limits:
        cpus: '4'
    restart_policy:
      condition: on-failure
      …

Es ist wichtig zu beachten, dass Redis, RabbitMQ und Graylog zustandsbehaftete Dienste sind und nicht so einfach skaliert werden können wie „attrai-estimator“.

Die Frage lässt ahnen: Warum nicht Kubernetes?

Es scheint, dass der Einsatz von Kubernetes in kleinen und mittelgroßen Projekten ein Overhead ist; alle notwendigen Funktionen können von Docker Swarm bezogen werden, was für einen Container-Orchestrator recht benutzerfreundlich ist und zudem eine niedrige Eintrittsbarriere aufweist.

Infrastruktur

All dies wurde auf VDS mit den folgenden Merkmalen bereitgestellt:

  • CPU: 4-Kern-Intel® Xeon® Gold 5120-CPU mit 2.20 GHz
  • RAM: 8 GB
  • SSD: 160 GB

Nach lokalen Belastungstests schien es, dass diese Maschine bei einem großen Zustrom von Benutzern ausreichen würde.

Aber unmittelbar nach der Bereitstellung habe ich einen Link zu einem der beliebtesten Imageboards in der GUS gepostet (ja, dasselbe), woraufhin das Interesse der Leute geweckt wurde und der Dienst innerhalb weniger Stunden erfolgreich Zehntausende Bilder verarbeitete. Gleichzeitig wurden in Spitzenzeiten die CPU- und RAM-Ressourcen nicht einmal zur Hälfte genutzt.

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen
Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Noch ein paar Grafiken

Anzahl der eindeutigen Benutzer und Bewertungsanfragen seit der Bereitstellung, abhängig vom Tag

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Zeitverteilung der Evaluierungspipeline-Inferenz

Allgemeiner Überblick über die Servicearchitektur zur Beurteilung des Erscheinungsbilds basierend auf neuronalen Netzen

Befund

Zusammenfassend kann ich sagen, dass sich die Architektur und der Ansatz zur Orchestrierung von Containern voll und ganz bewährt haben – selbst in Spitzenzeiten gab es keine Einbrüche oder Einbrüche in der Verarbeitungszeit. 

Ich denke, dass kleine und mittlere Projekte, die in ihrem Prozess die Echtzeitinferenz neuronaler Netze auf der CPU nutzen, die in diesem Artikel beschriebenen Praktiken erfolgreich übernehmen können.

Ich füge hinzu, dass der Artikel anfangs länger war, aber um keinen Longread zu veröffentlichen, habe ich beschlossen, einige Punkte in diesem Artikel wegzulassen – wir werden in zukünftigen Veröffentlichungen darauf zurückkommen.

Sie können den Bot auf Telegram anstupsen – @AttraiBot, er wird mindestens bis Ende Herbst 2020 funktionieren. Ich möchte Sie daran erinnern, dass keine Benutzerdaten gespeichert werden – weder die Originalbilder noch die Ergebnisse der Auswertungspipeline – alles wird nach der Verarbeitung zerstört.

Source: habr.com

Kommentar hinzufügen