Grundlagen der Web Worker-Bildverarbeitung
Ein Web Worker ist ein separater JavaScript-Ausführungskontext, der aufwendige Berechnungen durchführen kann, ohne dass der Hauptthread des Editors die ganze Arbeit erledigen muss. Für die Browser-Bildverarbeitung bedeutet das, dass die Modelleinrichtung und -inferenz von dem Thread abhängen kann, der für Schaltflächen, Fortschrittsmeldungen, Pinseleingaben und Bildschirmaktualisierungen verantwortlich ist.
Das Ergebnis ist keine „freie Hintergrundverarbeitung“. Dasselbe Gerät führt weiterhin die Berechnung durch und verwendet Speicher. Der architektonische Vorteil liegt in der Trennung: Bei einem umfangreichen Modellvorgang ist es weniger wahrscheinlich, dass er jede Schnittstellenantwort während der Ausführung blockiert.
Der Hauptthread hat einen Benutzeroberflächenjob
Eine Browserseite führt normalerweise JavaScript in einem Hauptthread aus. Dieser Thread koordiniert auch Layout, Malerei und Eingabe. Wenn eine lange Berechnung die Seite belegt, kann es sein, dass sich Klicks verzögert anfühlen, die Animation stoppt und der Browser warnt möglicherweise, dass die Seite nicht reagiert.
Ein Bildbearbeiter hat viele Haupt-Thread-Aufgaben, bevor die Inferenz überhaupt beginnt:
- eine Dateiauswahl, das Einfügen oder Ablegen erhalten;
- ein Bild dekodieren und anzeigen;
- Fortschritts- und Fehlerstatus aktualisieren;
- Zeichnen Sie die Vorschau-Leinwand;
- Behandeln Sie die Pinselbewegung „Hinzufügen“ und „Löschen“;
- Download- oder Zwischenablage-Aktionen vorbereiten.
Würde man die numerische Arbeit eines Segmentierungsmodells auf denselben Thread verteilen, würden diese Aufgaben direkt miteinander konkurrieren. Ein Arbeiter schafft eine klarere Grenze.
Die nachrichtenbasierte Grenze
Der Editor und der Worker nutzen keine gewöhnlichen Variablen gemeinsam. Sie kommunizieren, indem sie Nachrichten senden. Ein vereinfachter Ablauf sieht so aus:
- Der Editor erstellt einen Worker oder verwendet ihn wieder.
- Der Worker wird aufgefordert, die Inferenzlaufzeit und das Inferenzmodell zu initialisieren.
- Es bereitet Bilddaten vor und sendet eine Inferenzanfrage.
- Der Worker wandelt die Daten in die erwartete Eingabe des Modells um.
- Der Worker führt das Modell aus und erzeugt Maskenwerte.
- Es sendet die Masken- oder Ergebnisdaten zurück.
- Der Editor stellt die Vorschau zusammen und ermöglicht die Verfeinerung oder den Export.
Nachrichten sollten genügend Kontext enthalten, um eine Antwort auf die richtige Anfrage zuzuordnen. Dies ist wichtig, wenn ein Benutzer ein anderes Bild auswählt, bevor der vorherige Auftrag abgeschlossen ist. Die Schnittstelle muss vermeiden, dass ein altes Ergebnis über einer neuen Quelle angezeigt wird.
Bilddaten kopieren und übertragen
Das Versenden einer kleinen Textnachricht ist günstig. Das Senden von Millionen Pixelwerten kann teuer sein, wenn der Browser den gesamten Puffer kopieren muss. Web-APIs können stattdessen den Besitz bestimmter Binärpuffer übertragen. Ein übertragener Puffer steht dem Empfänger zur Verfügung, ohne dass auf der Senderseite ein verwendbares Duplikat zurückgehalten wird.
Diese Optimierung bringt eine Designbeschränkung mit sich: Nach der Übertragung kann der Absender nicht weiterhin denselben Puffer verwenden, als ob er immer noch Eigentümer der Daten wäre. Ein Editor kann eine separate Anzeigedarstellung beibehalten, einen dedizierten Inferenzpuffer erstellen oder später rekonstruieren, was er benötigt.
Nicht jede Implementierung verwendet die Übertragung an genau denselben Stellen. Die allgemeine Lehre ist, dass die Thread-Trennung nicht dazu führt, dass die Datenbewegung verschwindet. Bildabmessungen, Puffergröße und die Anzahl der Konvertierungen wirken sich weiterhin auf Latenz und Speicher aus.
Was Easy Background Remover in den Arbeiter einfügt
Easy Background Remover verwendet einen Web Worker mit einer Browser-Inferenzlaufzeit für die Segmentierung auf dem Gerät. Der schwere automatische Ausschnittschritt erzeugt eine Maske. Der Editor zeigt dann das zusammengesetzte Ergebnis an und unterstützt die Pinselverfeinerung auf der CPU-Leinwand.
Durch diese Trennung erhalten Fehler eine sinnvollere Grenze. Wenn der Worker nicht initialisiert werden kann oder während der Inferenz abstürzt, kann die Schnittstelle einen Worker-bezogenen Fehler melden, anstatt sich auf einen dauerhaft eingefrorenen Tab als einziges Signal zu verlassen.
Dadurch bleibt auch der Anspruch auf lokale Verarbeitung verständlich. Das Senden von Pixeln von einer Erweiterungsseite an ihren eigenen Worker ist eine Kommunikation innerhalb der Browserumgebung und kein Upload auf eine Remote-Ausschnitt-API. Die erste Sitzung kann das wiederverwendbare Modell-Asset separat herunterladen; siehe Warum beim ersten Lauf ein Modell heruntergeladen wird.
Ein Arbeiter führt die Berechnung nicht sofort durch
Mitarbeiter verbessern die Reaktionsfähigkeit, nicht die reine Gerätefähigkeit. Das Modell verbraucht weiterhin CPU-, GPU- oder andere Laufzeitressourcen, je nachdem, was der Browser bereitstellen kann. Eine große Eingabe kann dennoch länger dauern und mehr Speicher erfordern als eine kleine.
Es bleiben mehrere Grenzen bestehen:
- Die Modellinitialisierung ist mit echten Kosten verbunden.
- Pixelpuffer belegen beim Kopieren Speicher auf beiden Seiten;
- Größenänderung und Formatkonvertierung brauchen Zeit;
- Geräte mit wenig Speicher können mit großen Bildern Probleme haben;
- Mehr Arbeitnehmer können den Konflikt verschärfen, anstatt ihn zu verringern.
- Export- und Canvas-Updates können weiterhin den Hauptthread betreffen.
Das Starten von fünf Inferenzarbeitern für fünf Bilder ist nicht automatisch fünfmal schneller. Die Arbeiter teilen sich die gleiche Maschine. Parallele Jobs können um Speicherbandbreite und Ausführungsressourcen konkurrieren, während jede Modellinstanz ihre eigenen Speicherkosten verursachen kann.
Fortschrittsberichte sind kooperativ
Ein Mitarbeiter kann Statusmeldungen senden, er weiß jedoch nicht automatisch, welcher Fortschrittsprozentsatz sich als richtig anfühlt. Modelldownload, Laufzeitinitialisierung, Eingabevorbereitung, Inferenz, Maskenkonvertierung und Vorschau-Rendering sind separate Phasen mit unterschiedlichem Timing.
Einige Phasen haben messbare Bytezahlen. Eine einzelne Modellausführung darf nur „gestartet“ und „abgeschlossen“ offenlegen. Ein gleichmäßiger, gleichmäßiger Anstieg des Prozentsatzes kann daher eher kosmetischer Natur als eine präzise Messung sein.
Die nützliche Fortschritts-Benutzeroberfläche benennt die Phase, wenn möglich: Vorbereiten des Modells, Verarbeiten des Bildes oder Erstellen des Ergebnisses. Es behandelt auch Fehler und Abbrüche, anstatt einen Spinner ohne Erklärung zu hinterlassen.
Stornierung ist mehr als nur das Verstecken eines Spinners
Wenn der Benutzer ein Bild schließt oder von vorne beginnt, kann die Schnittstelle die eventuelle Antwort der veralteten Anfrage ignorieren. Das sofortige Anhalten der zugrunde liegenden Berechnung erfordert möglicherweise zusätzliche Unterstützung durch die Laufzeit oder das Beenden und Neuerstellen des Workers.
Das Beenden eines Workers ist entscheidend, verwirft jedoch seinen initialisierten Zustand. Beim nächsten Job muss das Modell möglicherweise erneut geladen und initialisiert werden. Bei einer kurzen Operation kann es günstiger sein, das Ergebnis als veraltet zu markieren, als alles abzureißen.
Die richtige Wahl hängt von der Speicherauslastung, der Betriebsdauer und den Laufzeitfunktionen ab. Aus Sicht des Benutzers ist die wichtige Regel, dass veraltete Arbeiten die aktuelle Bearbeitung nicht überschreiben dürfen.
Auch Fehler müssen Grenzen überschreiten
Eine Ausnahme innerhalb eines Workers wird nicht zu einer normalen Haupt-Thread-Ausnahme. Der Worker muss verwertbare Fehler melden und der Editor sollte auf Fehler auf Worker-Ebene achten.
Eine gute Fehlerbehandlung zeichnet mindestens aus:
- Modell-Asset nicht verfügbar;
- Modellinitialisierung fehlgeschlagen;
- Bilddekodierung oder Eingabevorbereitung fehlgeschlagen;
- Schlussfolgerung fehlgeschlagen;
- Arbeiter blieb unerwartet stehen;
- Ergebnis gehört nicht mehr zur aktuellen Anfrage.
Dies ist umsetzbarer als die allgemeine Aussage „Etwas ist schief gelaufen“, insbesondere wenn die Ersteinrichtung und die normale Bildverarbeitung unterschiedliche Abhilfemaßnahmen bieten.
Worker-Ausgabe ist immer noch nur eine erste Maske
Die Thread-Architektur verbessert nicht allein eine mehrdeutige Kante. Der Arbeiter kann eine technisch gültige Maske zurückgeben, der noch Fell, transparentes Material, schmale Träger oder ein gewünschter Schatten fehlen. Das sind Segmentierungs- und Absichtsfragen.
Die Arbeit des Editors wird nach der Inferenz fortgesetzt: Skalieren Sie die Maske in das Arbeitskoordinatensystem, erstellen Sie eine Vorschau, lassen Sie sie vom Benutzer verfeinern und exportieren Sie den aktuellen Status. Maskenauflösung vs. Vorschaugröße erklärt, warum diese Koordinatensysteme nicht verwechselt werden sollten.
Ein prägnantes mentales Modell
Stellen Sie sich den Arbeiter als einen lokalen Spezialisten hinter einem Nachrichtenfenster vor:
- Der Herausgeber ist Eigentümer der Interaktion. – Der Arbeiter ist für die schwere Inferenzaufgabe zuständig. – binäre Bilddaten überschreiten eine definierte Grenze;
- Der Arbeiter gibt eine Maske zurück, nicht ein fertiges Urteil über jede Kante;
- Der Herausgeber bleibt für den aktuellen Stand, die Überprüfung, die Verfeinerung und den Export verantwortlich.
Für die Sicht des Modells auf die Pixel selbst fahren Sie mit Was ein Ausschnittmodell auf dem Gerät sieht fort. Eine umfassende praktische Übersicht finden Sie unter Funktionsweise der lokalen Hintergrundentfernung.