WebGPU: Moderne GPU-Zugriffe im Browser

Hier erfahren Sie, wie WebGPU die Leistung der GPU für höhere Leistung beim maschinellen Lernen und ein besseres Grafik-Rendering freischaltet.

Corentin Wallez
Corentin Wallez
François Beaufort
François Beaufort

Die neue WebGPU API bietet erhebliche Leistungssteigerungen bei Grafik- und ML-Arbeitslasten. In diesem Artikel wird erläutert, inwiefern WebGPU eine Verbesserung gegenüber der aktuellen WebGL-Lösung darstellt. Außerdem erhalten Sie einen kleinen Vorgeschmack auf zukünftige Entwicklungen. Zunächst möchten wir Ihnen aber erklären, warum WebGPU entwickelt wurde.

Kontext auf WebGPU

WebGL ist seit 2011 in Chrome verfügbar. WebGL bietet die Möglichkeit, GPUs zu nutzen, und ermöglicht so beeindruckende Erlebnisse im Web – von Google Earth über interaktive Musikvideos bis hin zu 3D-Immobilientouren und mehr. WebGL basierte auf der OpenGL-API-Familie, die 1992 entwickelt wurde. Das ist lange her! Die GPU-Hardware hat sich seitdem enorm weiterentwickelt.

Um mit dieser Entwicklung Schritt zu halten, wurden neue APIs entwickelt, die eine effizientere Interaktion mit moderner GPU-Hardware ermöglichen. APIs wie Direct3D 12, Metal und Vulkan Diese neuen APIs haben neue und anspruchsvolle Anwendungsfälle für die GPU-Programmierung unterstützt, wie die explosionsartige Zunahme von maschinellem Lernen und Fortschritten bei den Rendering-Algorithmen. WebGPU ist der Nachfolger von WebGL und bringt die Fortschritte dieser neuen Klasse moderner APIs ins Web.

WebGPU eröffnet viele neue Möglichkeiten zur GPU-Programmierung im Browser. Sie spiegelt die Funktionsweise moderner GPU-Hardware besser wider und bildet gleichzeitig die Grundlage für erweiterte GPU-Funktionen in Zukunft. Die API ist seit 2017 Bestandteil der W3C-Gruppe „GPU für das Web“ und ist ein Gemeinschaftsprojekt vieler Unternehmen wie Apple, Google, Mozilla, Microsoft und Intel. Nach 6 Jahren Arbeit freuen wir uns, Ihnen mitteilen zu können, dass eine der größten Neuzugänge zur Webplattform endlich verfügbar ist!

WebGPU ist aktuell in Chrome 113 für ChromeOS, macOS und Windows verfügbar. Weitere Plattformen folgen demnächst. Vielen Dank an andere Chromium-Beitragende und insbesondere an Intel, die dazu beigetragen haben.

Werfen wir nun einen Blick auf einige der spannenden Anwendungsfälle, die WebGPU ermöglicht.

Neue GPU-Arbeitslasten für das Rendering freischalten

WebGPU-Funktionen wie Compute-Shader ermöglichen die Portierung neuer Algorithmenklassen auf der GPU. Dazu gehören zum Beispiel Algorithmen, die Szenen mehr dynamische Details hinzufügen, physische Phänomene simulieren und vieles mehr! Es gibt sogar Arbeitslasten, die zuvor nur in JavaScript ausgeführt werden konnten und jetzt in die GPU verschoben werden können.

Das folgende Video zeigt, wie der Algorithmus der Marschwürfel die Oberfläche dieser Metakugeln trianguliert. In den ersten 20 Sekunden des Videos hat der Algorithmus bei der Ausführung in JavaScript Schwierigkeiten, mit der aktuellen Seite mit nur 8 fps Schritt zu halten. Dies führt zu einer verzögerten Animation. Um die Leistung in JavaScript aufrechtzuerhalten, müssten wir die Detailebene stark verringern.

Wenn wir denselben Algorithmus in einen Compute-Shader verschieben, der nach 20 Sekunden im Video sichtbar ist, macht es einen Unterschied zwischen Tag und Nacht. Da die Seite nun mit 60 fps ausgeführt wird, lässt sich die Leistung erheblich verbessern. Außerdem ist noch viel Spielraum für andere Effekte vorhanden. Außerdem wird die Haupt-JavaScript-Schleife der Seite vollständig für andere Aufgaben freigegeben, sodass die Interaktionen mit der Seite weiterhin responsiv bleiben.

Die Metaball-Demo

WebGPU ermöglicht auch komplexe visuelle Effekte, die zuvor nicht praktikabel waren. Im folgenden Beispiel, das in der beliebten Bibliothek Babylon.js erstellt wurde, wird die Meeresoberfläche vollständig auf der GPU simuliert. Die realistische Dynamik entsteht durch viele unabhängige Wellen, die sich gegenseitig ergänzen. Aber jede einzelne Welle direkt zu simulieren, wäre zu teuer.

The Ocean Demo

Deshalb wird in der Demo ein erweiterter Algorithmus namens Fast Fourier Transform verwendet. Statt alle Wellen als komplexe Positionsdaten darzustellen, werden hier die spektralen Daten verwendet, was für Berechnungen wesentlich effizienter ist. Dann verwendet jeder Frame die Fourier-Transformation, um von Spektraldaten in Positionsdaten umzuwandeln, die die Höhe der Wellen darstellen.

Schnellere ML-Inferenz

WebGPU ist auch nützlich, um das maschinelle Lernen zu beschleunigen, das in den letzten Jahren zu einer wichtigen Verwendung von GPUs geworden ist.

Seit Langem nutzen Creative-Entwickler die Rendering API von WebGL, um Nicht-Rendering-Vorgänge wie Berechnungen für maschinelles Lernen auszuführen. Dies erfordert jedoch das Zeichnen der Pixel von Dreiecken, um die Berechnungen zu initiieren, und das sorgfältige Packen und Entpacken der Tensordaten in der Textur anstelle von allgemeinen Speicherzugriffen.

Darstellung der Ineffizienzen bei der Ausführung eines einzelnen ML-Operators mit WebGL, darunter redundante Speicherlasten, redundante Berechnungen und wenige Werte pro Thread.
Ausführung eines einzelnen ML-Operators mit WebGL.

Bei der Verwendung von WebGL auf diese Weise müssen Entwickler ihren Code umständlich an die Erwartungen einer API anpassen, die nur zum Zeichnen entwickelt wurde. Zusammen mit dem Mangel an grundlegenden Funktionen wie dem Zugriff auf gemeinsam genutzten Speicher zwischen Berechnungen führt dies zu doppelter Arbeit und suboptimaler Leistung.

Compute-Shader sind die wichtigste neue Funktion von WebGPU und beseitigen diese Probleme. Compute-Shader bieten ein flexibleres Programmiermodell, das die massive Parallelität der GPU ausnutzt, ohne durch die strenge Struktur der Rendering-Vorgänge eingeschränkt zu werden.

Die verschiedenen Effizienzvorteile von WebGPU-Computing-Shadern, einschließlich gemeinsamer Speicherlasten, gemeinsam genutzter Berechnungen und flexibler Schreibvorgänge in den Speicher.
Effizienz des WebGPU-Rechen-Shaders.

Compute-Shader bieten mehr Möglichkeiten für die Freigabe von Daten und Berechnungsergebnissen innerhalb von Shader-Arbeitsgruppen, um die Effizienz zu verbessern. Dies kann im Vergleich zu früheren Versuchen, WebGL für denselben Zweck zu nutzen, zu erheblichen Vorteilen führen.

Ein Beispiel für die damit einhergehenden Effizienzsteigerungen ist, dass ein erster Port eines Bilddiffusionsmodells in TensorFlow.js beim Wechsel von WebGL zu WebGPU auf einer Vielzahl von Hardware eine dreifache Leistungssteigerung zeigt. Auf einigen Hardwarekomponenten wurde das Bild in weniger als 10 Sekunden gerendert. Und da dies ein früher Port war, glauben wir, dass sowohl WebGPU als auch TensorFlow.js noch mehr Verbesserungen möglich sind! Weitere Informationen finden Sie unter What’s new with Web ML in 2023? Google I/O-Session

Mit WebGPU können Sie jedoch nicht nur GPU-Funktionen ins Web bringen.

Speziell für JavaScript entwickelt

Die Funktionen, die diese Anwendungsfälle ermöglichen, stehen plattformspezifischen Desktop- und mobilen Entwicklern schon eine Weile zur Verfügung und es war unsere Herausforderung, sie auf eine Weise zu präsentieren, die sich wie ein natürlicher Teil der Webplattform anfühlt.

WebGPU wurde im Nachhinein von über zehn Jahren Entwickler entwickelt, die hervorragende Arbeit mit WebGL leisten. Wir konnten die aufgetretenen Probleme, die aufgetretenen Engpässe und die aufgetretenen Probleme in die neue API übertragen.

Wir haben festgestellt, dass das globale Zustandsmodell von WebGL die Erstellung robuster, zusammensetzbarer Bibliotheken und Anwendungen schwierig und fragil machte. Mit WebGPU wird der Umfang des Status, den Entwickler beim Senden der GPU-Befehle im Auge behalten müssen, erheblich reduziert.

Wir haben gehört, dass das Debugging von WebGL-Anwendungen mühsam war. Deshalb beinhaltet die WebGPU flexiblere Fehlerbehandlungsmechanismen, die die Leistung nicht beeinträchtigen. Außerdem haben wir alles daran gesetzt, dass jede Nachricht, die Sie von der API erhalten, leicht verständlich und leicht verständlich ist.

Außerdem stellten wir fest, dass der Aufwand für zu viele JavaScript-Aufrufe häufig ein Engpass für komplexe WebGL-Anwendungen darstellte. Dadurch verursacht die WebGPU API weniger Chatfunktionen, sodass Sie mit weniger Funktionsaufrufen mehr erreichen können. Wir konzentrieren uns darauf, eine umfangreiche Validierung im Vorfeld durchzuführen und die kritische Zeichenschleife so schlank wie möglich zu halten. Außerdem bieten wir neue APIs wie Render Bundles an, mit denen ihr eine große Anzahl von Zeichenbefehlen im Voraus aufzeichnen und mit einem einzigen Aufruf wiedergeben könnt.

Hier ist eine weitere Demo von Babylon.js, die zeigt, welchen entscheidenden Unterschied eine Funktion wie Rendering-Bundles machen kann. Ihr WebGL 2-Renderer kann alle JavaScript-Aufrufe ausführen, um diese Kunstgalerie-Szene etwa 500 Mal pro Sekunde zu rendern. Das ist ziemlich gut!

Kunstgalerie

Ihr WebGPU-Renderer aktiviert jedoch eine Funktion, die sie Snapshot-Rendering aufruft. Diese Funktion basiert auf Rendering-Bundles für Web-GPUs und kann dieselbe Szene mehr als zehnmal schneller einreichen. Dieser deutlich reduzierte Overhead ermöglicht es WebGPU, komplexere Szenen zu rendern, während Anwendungen gleichzeitig mehr mit JavaScript erledigen können.

Moderne Grafik-APIs sind für ihre Komplexität bekannt, wobei Einfachheit gegen extreme Optimierungsmöglichkeiten steht. WebGPU hingegen konzentriert sich auf die plattformübergreifende Kompatibilität und bearbeitet traditionelle schwierige Themen wie die Ressourcensynchronisierung in den meisten Fällen automatisch.

Dies hat den positiven Nebeneffekt, dass WebGPU leicht zu erlernen und zu verwenden ist. Sie stützt sich auf bestehende Funktionen der Webplattform, um Bilder und Videos zu laden, und stützt sich auf bekannte JavaScript-Muster wie Promises für asynchrone Vorgänge. Dies trägt dazu bei, die Menge an erforderlichen Boilerplate-Code auf ein Minimum zu reduzieren. Das erste Dreieck kann mit weniger als 50 Codezeilen auf dem Bildschirm angezeigt werden.

<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const context = canvas.getContext("webgpu");
  const format = navigator.gpu.getPreferredCanvasFormat();
  context.configure({ device, format });

  const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
  const shaderModule = device.createShaderModule({ code });
  const pipeline = device.createRenderPipeline({
    layout: "auto",
    vertex: {
      module: shaderModule,
      entryPoint: "vertexMain",
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [{ format }],
    },
  });
  const commandEncoder = device.createCommandEncoder();
  const colorAttachments = [
    {
      view: context.getCurrentTexture().createView(),
      loadOp: "clear",
      storeOp: "store",
    },
  ];
  const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
</script>

Fazit

Es ist spannend, all die neuen Möglichkeiten zu sehen, die WebGPU der Web-Plattform bietet, und wir freuen uns schon auf all die coolen neuen Anwendungsfälle, die Sie für WebGPU finden werden!

Rund um WebGL wurde eine lebendige Umgebung von Bibliotheken und Frameworks aufgebaut, die auch WebGPU gern unterstützt. Die Unterstützung für WebGPU wird derzeit entwickelt oder ist in vielen gängigen JavaScript-WebGL-Bibliotheken bereits abgeschlossen. In einigen Fällen kann die Nutzung der Vorteile von WebGPU schon durch das Ändern eines einzelnen Flags erreicht werden.

Babylon.js, Konstrukt 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js und Unity.
Frameworks, Anwendungen und Bibliotheken mit fertigen oder laufenden WebGPU-Ports.

Und diese erste Version in Chrome 113 ist nur der Anfang. Unsere erste Version ist für Windows, ChromeOS und macOS verfügbar. Wir planen jedoch, die WebGPU in naher Zukunft auch auf anderen Plattformen wie Android und Linux verfügbar zu machen.

Und nicht nur das Chrome-Team arbeitet an der Einführung von WebGPU. Auch in Firefox und WebKit laufen Implementierungen.

Darüber hinaus werden beim W3C bereits neue Funktionen entwickelt, die präsentiert werden können, wenn sie in der Hardware verfügbar sind. Beispiel: In Chrome planen wir, die Unterstützung für 16-Bit-Gleitkommazahlen in Shadern und die Anweisungen der DP4a-Klasse bald zu aktivieren, um noch mehr Leistungsverbesserungen beim maschinellen Lernen zu erzielen.

WebGPU ist eine umfassende API, die erstaunliche Leistung bietet, wenn Sie in sie investieren. Heute können wir nur einen allgemeinen Überblick über die Vorteile von WebGPU machen. Wenn Sie jedoch mit WebGPU beginnen möchten, schauen Sie sich unser einführendes Codelab an: Ihre erste WebGPU-App. In diesem Codelab erstellen Sie eine GPU-Version von Conways Game of Life. In diesem Codelab werden Sie Schritt für Schritt durch den Prozess geführt, damit Sie es selbst dann ausprobieren können, wenn Sie die GPU-Entwicklung zum ersten Mal durchführen.

Die WebGPU-Beispiele eignen sich ebenfalls gut, um ein Gefühl für die API zu bekommen. Sie reichen vom traditionellen „Hallo Dreieck“ bis hin zu umfassenderen Rendering- und Computing-Pipelines, die eine Vielzahl von Techniken demonstrieren. Wirf auch einen Blick auf unsere anderen Ressourcen.