Web-KI-Modelltests mit WebGPU, WebGL und Headless Chrome vorantreiben

François Beaufort
François Beaufort

Gute Neuigkeiten: Sie haben eine coole Web-KI-Anwendung entwickelt, die Modelle für maschinelles Lernen direkt auf dem Gerät eines Nutzers ausführt. Sie wird vollständig im clientseitigen Webbrowser ausgeführt, ohne dass die Cloud benötigt wird. Dieses On-Device-Design verbessert den Datenschutz für Nutzer, steigert die Leistung und reduziert die Kosten erheblich.

Es gibt jedoch ein Problem. Ihr TensorFlow.js-Modell kann sowohl auf CPUs (WebAssembly) als auch auf leistungsstärkeren GPUs (über WebGL und WebGPU) ausgeführt werden. Die Frage lautet: Wie können Sie Browsertests mit der ausgewählten Hardware konsistent automatisieren?

Die Consistency ist entscheidend, um die Leistung von Modellen für maschinelles Lernen im Zeitverlauf zu vergleichen, während Sie sie iterieren und verbessern, bevor sie für echte Nutzer auf ihren Geräten bereitgestellt werden.

Das Einrichten einer einheitlichen Testumgebung mit GPUs kann schwieriger sein als erwartet. In diesem Blogpost beschreiben wir die Probleme, die wir hatten, und wie wir sie gelöst haben, damit Sie die Leistung Ihrer Anwendung verbessern können.

Das ist nicht nur für Web-KI-Entwickler interessant. Auch wenn Sie an Webspielen oder Grafiken arbeiten, ist dieser Beitrag für Sie interessant.

Was ist in unserem Automatisierungs-Tool enthalten?

Wir verwenden Folgendes:

  • Umgebung: Ein Linux-basiertes Google Colab-Notebook, das mit einer NVIDIA T4- oder V100-GPU verbunden ist. Sie können auch andere Cloud-Plattformen wie Google Cloud (GCP) verwenden.
  • Browser: Chrome unterstützt WebGPU, einen leistungsstarken Nachfolger von WebGL, der die Vorteile moderner GPU-APIs ins Web bringt.
  • Automatisierung: Puppeteer ist eine Node.js-Bibliothek, mit der Sie Browser programmatisch mit JavaScript steuern können. Mit Puppeteer können wir Chrome im headless-Modus automatisieren, d. h., der Browser wird ohne sichtbare Benutzeroberfläche auf einem Server ausgeführt. Wir verwenden den verbesserten neuen headless-Modus, nicht das alte Formular.

Umgebung prüfen

Die beste Möglichkeit, die Hardwarebeschleunigung in Chrome zu prüfen, ist das Eingeben von chrome://gpu in die Adressleiste. Mit console.log können Sie das Äquivalent mit Puppeteer programmatisch ausführen oder den vollständigen Bericht als PDF speichern, um ihn manuell zu prüfen:

/* Incomplete example.js */
import puppeteer from 'puppeteer';

// Configure launch parameters: Expands later
const browser = await puppeteer.launch({
  headless: 'new',
  args:  ['--no-sandbox']
});

const page = await browser.newPage();
await page.goto('chrome://gpu');

// Verify: log the WebGPU status or save the GPU report as PDF
const txt = await page.waitForSelector('text/WebGPU');
const status = await txt.evaluate(g => g.parentElement.textContent);
console.log(status);
await page.pdf({ path: './gpu.pdf' });

await browser.close();

Öffnen Sie chrome://gpu. Sie sollten die folgenden Ergebnisse sehen:

Status der Grafikfunktion
OpenGL: Deaktiviert
Vulkan: Deaktiviert
WebGL: Nur Software, Hardwarebeschleunigung nicht verfügbar.
WebGL2: Nur Software, Hardwarebeschleunigung nicht verfügbar.
WebGPU: Deaktiviert

Probleme erkannt
: WebGPU wurde über die Blockliste oder die Befehlszeile deaktiviert.

Kein guter Anfang. Es ist ziemlich klar, dass die Hardwareerkennung fehlgeschlagen ist. WebGL, WebGL2 und WebGPU sind im Wesentlichen deaktiviert oder nur als Software verfügbar. Wir sind nicht allein mit diesem Problem. Es gibt zahlreiche Onlinediskussionen von Nutzern in einer ähnlichen Situation, auch in den offiziellen Chrome-Supportkanälen (1, 2).

WebGPU- und WebGL-Unterstützung aktivieren

In Headless Chrome ist die GPU standardmäßig deaktiviert. Wenn Sie die Funktion unter Linux aktivieren möchten, müssen Sie beim Starten von Chrome ohne Benutzeroberfläche alle folgenden Flags anwenden:

  • Mit dem Flag --no-sandbox wird die Sicherheits-Sandbox von Chrome deaktiviert, wodurch der Browserprozess vom Rest des Systems isoliert wird. Das Ausführen von Chrome als Root ohne diese Sandbox wird nicht unterstützt.
  • Mit dem Flag --headless=new wird Chrome im neuen und verbesserten Headless-Modus ohne sichtbare Benutzeroberfläche ausgeführt.
  • Das Flag --use-angle=vulkan weist Chrome an, das Vulkan-Backend für ANGLE zu verwenden, das OpenGL ES 2/3-Aufrufe in Vulkan API-Aufrufe umwandelt.
  • Mit dem Flag --enable-features=Vulkan wird das Vulkan-Grafik-Backend für das Compositing und die Rasterung in Chrome aktiviert.
  • Mit dem Flag --disable-vulkan-surface wird die VK_KHR_surface-Vulkan-Instanzerweiterung deaktiviert. Anstelle eines Swapchains wird für das Renderergebnis auf dem Bildschirm Bit Blit verwendet.
  • Mit dem Flag --enable-unsafe-webgpu wird die experimentelle WebGPU API in Chrome unter Linux aktiviert und die Blockliste der Adapter deaktiviert.

Jetzt kombinieren wir alle bisher vorgenommenen Änderungen. Hier ist das vollständige Script.

/* Complete example.js */
import puppeteer from 'puppeteer';

// Configure launch parameters
const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--no-sandbox',
    '--headless=new',
    '--use-angle=vulkan',
    '--enable-features=Vulkan',
    '--disable-vulkan-surface',
    '--enable-unsafe-webgpu',
  ]
});

const page = await browser.newPage();
await page.goto('chrome://gpu');

// Verify: log the WebGPU status or save the GPU report as PDF
const txt = await page.waitForSelector('text/WebGPU');
const status = await txt.evaluate(g => g.parentElement.textContent);
console.log(status);
await page.pdf({path: './gpu.pdf'});

await browser.close();

Führen Sie das Script noch einmal aus. Es werden keine WebGPU-Probleme erkannt und der Wert ändert sich von „deaktiviert“ zu „nur Software“.

Status der Grafikfunktion
OpenGL: Deaktiviert
Vulkan: Deaktiviert
WebGL: Nur Software, Hardwarebeschleunigung nicht verfügbar.
WebGL2: Nur Software, Hardwarebeschleunigung nicht verfügbar.
WebGPU: Nur Software, Hardwarebeschleunigung nicht verfügbar.

Die Hardwarebeschleunigung ist jedoch weiterhin nicht verfügbar, da die NVIDIA T4-GPU nicht erkannt wird.

Die richtigen GPU-Treiber installieren

Wir haben die Ausgabe von chrome://gpu gemeinsam mit einigen GPU-Experten aus dem Chrome-Team genauer untersucht. Wir haben Probleme mit den Standardtreibern gefunden, die auf der Linux Colab-Instanz installiert sind. Diese haben zu Problemen mit Vulkan geführt, sodass Chrome die NVIDIA T4-GPU auf GL_RENDERER-Ebene nicht erkennen konnte, wie in der folgenden Ausgabe zu sehen ist. Das führt zu Problemen mit Headless Chrome.

Die Standardausgabe erkennt die NVIDIA T4-GPU nicht.
Informationen zum Fahrer
GL_RENDERER ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver-5.0.0)

Durch die Installation der richtigen kompatiblen Treiber wird das Problem behoben.

Aktualisierte Ausgabe nach der Installation der Treiber
Informationen zum Fahrer
GL_RENDERER ANGLE (NVIDIA Corporation, Tesla T4/PCIe/SSE2, OpenGL ES 3.2 NVIDIA 525.105.17)

Führen Sie während der Einrichtung die folgenden Befehle aus, um die richtigen Treiber zu installieren. Mit den letzten beiden Zeilen können Sie die von NVIDIA-Treibern und vulkaninfo erkannten Ausgaben protokollieren.

apt-get install -y vulkan-tools libnvidia-gl-525

// Verify the NVIDIA drivers detects along with vulkaninfo
nvidia-smi
vulkaninfo --summary

Führen Sie das Script noch einmal aus. Das Ergebnis sieht dann so aus: 🎉

Status der Grafikfunktion
OpenGL: Aktiviert
Vulkan: Aktiviert
WebGL: Hardwarebeschleunigt, aber mit reduzierter Leistung.
WebGL2: Hardwarebeschleunigt, aber mit reduzierter Leistung.
WebGPU: Hardwarebeschleunigt, aber mit reduzierter Leistung.

Durch die Verwendung der richtigen Treiber und Flags beim Ausführen von Chrome haben wir jetzt WebGPU- und WebGL-Unterstützung mit dem neuen Headless-Modus.

Hinter den Kulissen: Die Untersuchung unseres Teams

Nach langem Suchen konnten wir keine funktionierenden Methoden für die Umgebung finden, die wir in Google Colab ausführen mussten. Es gab jedoch einige vielversprechende Beiträge, die in anderen Umgebungen funktionierten. Letztendlich konnten wir diesen Erfolg nicht in der Colab-Umgebung mit NVIDIA T4 wiederholen, da wir zwei Hauptprobleme hatten:

  1. Einige Kombinationen von Flags ermöglichen die Erkennung der GPU, aber nicht die tatsächliche Nutzung.
  2. Beispiele für funktionierende Lösungen von Drittanbietern verwendeten die alte headless-Version von Chrome, die irgendwann eingestellt und durch die neue Version ersetzt wird. Wir brauchten eine Lösung, die mit dem neuen Headless Chrome funktionierte, um zukunftssicherer zu sein.

Wir haben die geringe Auslastung der GPU bestätigt, indem wir eine Beispiel-TensorFlow.js-Webseite für die Bilderkennung ausgeführt haben. Dabei haben wir ein Modell trainiert, um Kleidungsmuster zu erkennen (eine Art „Hallo Welt“ des maschinellen Lernens).

Auf einem normalen Computer sollten 50 Trainingszyklen (sogenannte Epochen) jeweils in weniger als einer Sekunde ausgeführt werden. Wenn wir Headless Chrome im Standardzustand aufrufen, können wir die JavaScript-Konsolenausgabe in der serverseitigen Node.js-Befehlszeile protokollieren, um zu sehen, wie schnell diese Trainingszyklen tatsächlich ablaufen.

Wie erwartet dauerte jede Trainingsepoche viel länger als erwartet (mehrere Sekunden). Das deutet darauf hin, dass Chrome auf die einfache JS-CPU-Ausführung zurückgegriffen hat, anstatt die GPU zu verwenden:

Die Trainingsepochen verlaufen mit einer langsameren Taktfrequenz.
Abbildung 1: Echtzeitaufzeichnung, die zeigt, wie lange die Ausführung jeder Trainingsepoche gedauert hat (in Sekunden).

Nachdem die Treiber korrigiert und die richtige Kombination von Flags für Headless Chrome verwendet wurde, führt das erneute Ausführen des TensorFlow.js-Trainingsbeispiels zu viel schnelleren Trainingsepochen.

Die Geschwindigkeit für Epochen wird erhöht.
Abbildung 2: Echtzeitaufzeichnung, die die Beschleunigung der Epochen zeigt

Zusammenfassung

Web-KI hat sich seit ihrer Einführung im Jahr 2017 exponentiell weiterentwickelt. Mit Browsertechnologien wie WebGPU, WebGL und WebAssembly können die mathematischen Vorgänge eines Modells für maschinelles Lernen auf der Clientseite weiter beschleunigt werden.

Im Jahr 2023 haben TensorFlow.js und MediaPipe Web über eine Milliarde Downloads von Modellen und Bibliotheken erreicht – ein historischer Meilenstein und ein Zeichen dafür, wie Webentwickler und ‑ingenieure KI in ihren Web-Apps der nächsten Generation einsetzen, um wirklich unglaubliche Lösungen zu entwickeln.

Ein großer Erfolg bei der Nutzung birgt gleichzeitig eine große Verantwortung. Bei dieser Nutzung in Produktionssystemen besteht die Notwendigkeit, clientseitige, browserbasierte KI-Modelle in einer echten Browserumgebung zu testen, die gleichzeitig skalierbar, automatisierbar und in einer bekannten standardisierten Hardwarekonfiguration ist.

Mit der kombinierten Leistung der neuen Headless Chrome-Version und Puppeteer können Sie solche Arbeitslasten in einer standardisierten und reproduzierbaren Umgebung testen und so für konsistente und zuverlässige Ergebnisse sorgen.

Zusammenfassung

In unserer Dokumentation finden Sie eine Schritt-für-Schritt-Anleitung, mit der Sie die gesamte Einrichtung selbst ausprobieren können.

Wenn Ihnen dieser Artikel gefallen hat, teilen Sie ihn gern auf LinkedIn, X (früher Twitter) oder in einem anderen sozialen Netzwerk mit dem Hashtag #WebAI. Wir würden uns über Feedback freuen, damit wir in Zukunft mehr solche Artikel schreiben können.

Füge dem GitHub-Repository einen Stern hinzu, um zukünftige Updates zu erhalten.

Danksagungen

Ein großes Dankeschön an alle im Chrome-Team, die uns bei der Fehlerbehebung bei den Treiber- und WebGPU-Problemen unterstützt haben, die bei dieser Lösung aufgetreten sind. Ein besonderer Dank geht an Jecelyn Yeen und Alexandra White, die mir bei der Formulierung dieses Blogposts geholfen haben. Vielen Dank an Yuly Novikov, Andrey Kosyakov und Alex Rudenko, die maßgeblich zur Entwicklung der endgültigen, funktionierenden Lösung beigetragen haben.