WebGPU: Desbloquea el acceso moderno a la GPU en el navegador

Descubre cómo WebGPU desbloquea la potencia de la GPU para un rendimiento más rápido del aprendizaje automático y una mejor renderización de gráficos.

La nueva API de WebGPU ofrece aumentos de rendimiento masivos en cargas de trabajo de gráficos y aprendizaje automático. En este artículo, se explora cómo WebGPU es una mejora en comparación con la solución actual de WebGL, con un adelanto de futuros desarrollos. Pero primero, proporcionemos un contexto de por qué se desarrolló WebGPU.

Contexto en WebGPU

WebGL llegó a Chrome en 2011. Ya que permite que las aplicaciones web aprovechen las GPU, WebGL ofrece experiencias increíbles en la Web, desde Google Earth hasta videos musicales interactivos, explicaciones en 3D de inmuebles y mucho más. WebGL se basa en la familia de APIs de OpenGL, desarrollada por primera vez en 1992. ¡Eso fue hace mucho tiempo! Puedes imaginar que el hardware de las GPU evolucionó de forma significativa desde ese momento.

Para seguir el ritmo de esta evolución, se desarrolló una nueva generación de APIs con el objetivo de interactuar de manera más eficiente con el hardware moderno de las GPU. APIs como Direct3D 12, Metal y Vulkan. Estas nuevas APIs admiten casos de uso nuevos y exigentes para la programación de GPU, como el auge del aprendizaje automático y los avances en los algoritmos de renderización. WebGPU es el sucesor de WebGL que trae los avances de esta nueva clase de APIs modernas a la Web.

WebGPU desbloquea muchas posibilidades de programación de GPU en el navegador. Refleja mejor cómo funciona el hardware moderno de GPU, a la vez que sienta las bases para capacidades de GPU más avanzadas en el futuro. La API se integra al grupo "GPU para la Web" de W3C desde 2017 y es una colaboración entre muchas empresas, como Apple, Google, Mozilla, Intel y Microsoft. Ahora, después de 6 años de trabajo, nos complace anunciar que una de las incorporaciones más importantes a la plataforma web finalmente está disponible.

WebGPU está disponible hoy en Chrome 113 en ChromeOS, macOS y Windows, y pronto se agregarán otras plataformas. Agradecemos a todos los demás colaboradores de Chromium y a Intel en particular que ayudaron a lograrlo.

Ahora, veamos algunos de los casos de uso emocionantes que habilita WebGPU.

Desbloquea nuevas cargas de trabajo de GPU para la renderización

Las funciones de WebGPU, como los sombreadores de cómputos, permiten la portabilidad de nuevas clases de algoritmos a la GPU. Por ejemplo, hay algoritmos que pueden agregar más detalles dinámicos a las escenas, simular fenómenos físicos y mucho más. Incluso hay cargas de trabajo que antes solo se podían realizar en JavaScript y que ahora se pueden mover a la GPU.

El siguiente video muestra cómo se utiliza el algoritmo de cubos de marcha para triangular la superficie de estas metabolas. En los primeros 20 segundos del video, el algoritmo, cuando se ejecuta en JavaScript, tiene dificultades para mantenerse al día con la página que solo se ejecuta a 8 FPS, lo que provoca bloqueos en la animación. Para mantener el rendimiento en JavaScript, tendríamos que reducir mucho el nivel de detalles.

Es una diferencia de día y noche cuando pasamos el mismo algoritmo a un sombreador de cómputos, que se ve en el video después de 20 segundos. El rendimiento mejora considerablemente cuando la página ahora se ejecuta a 60 FPS fluidas, y todavía hay mucho margen de rendimiento para otros efectos. Además, el bucle principal de JavaScript de la página se libera completamente para otras tareas, lo que garantiza que las interacciones con la página sean responsivas.

Demostración de las bolas de meta
.

WebGPU también habilita efectos visuales complejos que antes no eran prácticos. En el siguiente ejemplo, creado en la popular biblioteca Babylon.js, la superficie oceánica se simula por completo en la GPU. La dinámica realista se crea a partir de muchas ondas independientes que se agregan entre sí. Sin embargo, simular cada onda directamente sería demasiado costoso.

Demostración del océano
.

Es por eso que la demostración usa un algoritmo avanzado llamado Fast Fourier Transform. En lugar de representar todas las ondas como datos posicionales complejos, esto usa los datos espectrales, que son mucho más eficientes para realizar cálculos. Luego, cada marco usa la transformación de Fourier para convertir de datos espectrales a datos posicionales que representan la altura de las ondas.

Inferencia de AA más rápida

WebGPU también es útil para acelerar el aprendizaje automático, que se convirtió en un uso importante de las GPU en los últimos años.

Durante mucho tiempo, los desarrolladores de creatividades han reutilizado la API de renderización de WebGL para realizar operaciones sin renderización, como cálculos de aprendizaje automático. Sin embargo, esto requiere dibujar los píxeles de triángulos como una manera de iniciar los cálculos, y empaquetar y desempaquetar cuidadosamente los datos del tensor en textura en lugar de accesos a memoria de uso más general.

Ilustración de las ineficiencias en la ejecución de un solo operador de AA con WebGL, incluidas las cargas de memoria redundantes, los cálculos redundantes y los pocos valores escritos por subproceso.
Una sola ejecución de operador de AA con WebGL.

Para usar WebGL de esta forma, los desarrolladores deben ajustar su código de manera incómoda a las expectativas de una API diseñada solo para dibujar. Combinado con la falta de funciones básicas como el acceso a memoria compartida entre los cálculos, esto genera trabajo duplicado y un rendimiento subóptimo.

Los sombreadores de cómputos son la nueva función principal de WebGPU y quitan estas dificultades. Los sombreadores de cómputos ofrecen un modelo de programación más flexible que aprovecha la naturaleza masivamente paralela de la GPU sin estar limitados por la estructura estricta de las operaciones de renderización.

Las diversas mejoras de eficiencia de los sombreadores de cómputos WebGPU, incluidas las cargas de memoria compartida, los cálculos compartidos y las escrituras flexibles en la memoria.
Eficiencias del sombreador de cómputos de WebGPU

Los sombreadores de cómputos brindan más oportunidades para compartir datos y resultados de procesamiento dentro de grupos de trabajo de sombreadores para lograr una mejor eficiencia. Esto puede generar ganancias significativas en comparación con intentos anteriores de usar WebGL para el mismo propósito.

Como ejemplo de las mejoras en la eficiencia que esto puede aportar, un puerto inicial de un modelo de difusión de imágenes en TensorFlow.js muestra una mejora de rendimiento 3 veces mayor en una variedad de hardware cuando se traslada de WebGL a WebGPU. En parte del hardware probado, la imagen se renderizó en menos de 10 segundos. Y debido a que este fue un puerto inicial, creemos que hay aún más mejoras posibles en WebGPU y TensorFlow.js. Consulta What's new with Web ML in 2023? sesión de Google I/O.

Pero WebGPU no solo se trata de llevar las funciones de GPU a la Web.

Diseñado primero para JavaScript

Las funciones que posibilitan estos casos de uso han estado disponibles desde hace tiempo para desarrolladores de plataformas de escritorio y dispositivos móviles específicos, y ha sido nuestro desafío exponerlas de una manera que parezca una parte natural de la plataforma web.

WebGPU se desarrolló con el beneficio de la retrospectiva de más de una década de desarrolladores que hicieron un trabajo increíble con WebGL. Pudimos tomar los problemas que encontraron, los cuellos de botella que surgieron y los problemas que plantearon, y convirtieron todos esos comentarios en esta nueva API.

Vimos que el modelo de estado global de WebGL dificultaba y dificultó la creación de bibliotecas y aplicaciones sólidas y componibles. Por lo tanto, WebGPU reduce drásticamente la cantidad de estado que los desarrolladores deben controlar cuando envían los comandos de la GPU.

Sabemos que depurar aplicaciones de WebGL era una molestia, por lo que WebGPU incluye mecanismos de manejo de errores más flexibles que no reducen tu rendimiento. Además, nos esforzamos para asegurarnos de que todos los mensajes que recibes de la API sean fáciles de entender y prácticos.

También vimos que, con frecuencia, la sobrecarga de realizar demasiadas llamadas a JavaScript era un cuello de botella para las aplicaciones de WebGL complejas. Como resultado, la API de WebGPU es menos frecuente, por lo que puedes lograr más con menos llamadas a funciones. Nos enfocamos en realizar validaciones pesadas desde el principio, manteniendo el bucle de dibujo crítico lo más simple posible. Además, ofrecemos nuevas APIs, como los paquetes de renderización, que te permiten grabar grandes cantidades de comandos de dibujo por adelantado y volver a reproducirlos con una sola llamada.

Para demostrar la gran diferencia que puede hacer una función como los paquetes de renderización, aquí hay otra demostración de Babylon.js. El procesador de WebGL 2 puede ejecutar todas las llamadas de JavaScript para renderizar esta escena de una galería de arte unas 500 veces por segundo. ¡Lo que es bastante bueno!

La galería de arte
.

Sin embargo, su procesador de WebGPU habilita una función que llama “Renderización de instantáneas”. Esta función, que se basa en los paquetes de renderización de WebGPU, permite enviar la misma escena más de 10 veces más rápido. Esta sobrecarga significativa permite que WebGPU renderice escenas más complejas, a la vez que permite que las aplicaciones hagan más tareas con JavaScript en paralelo.

Las APIs de gráficos modernas tienen reputación de complejidad, sacrifican sencillez por oportunidades de optimización extremas. WebGPU, por otro lado, se enfoca en la compatibilidad multiplataforma y maneja temas que suelen ser difíciles, como la sincronización de recursos automáticamente en la mayoría de los casos.

Esto tiene el efecto secundario feliz de que WebGPU es fácil de aprender y usar. Se basa en funciones existentes de la plataforma web para tareas como la carga de imágenes y videos y utiliza patrones de JavaScript conocidos, como las promesas, para las operaciones asíncronas. Esto ayuda a mantener la cantidad de código estándar necesaria al mínimo. Puedes ver tu primer triángulo en pantalla en menos de 50 líneas de código.

<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>

Conclusión

Es emocionante ver todas las nuevas posibilidades que ofrece WebGPU a la plataforma web y esperamos ver todos los nuevos casos de uso geniales que encontrarás para WebGPU.

Se construyó un dinámico ecosistema de bibliotecas y frameworks en torno a WebGL, y ese mismo ecosistema está ansioso por adoptar WebGPU. La compatibilidad con WebGPU está en curso o ya está completa en muchas bibliotecas de WebGL populares de JavaScript y, en algunos casos, aprovechar los beneficios de WebGPU puede ser tan simple como cambiar una sola marca.

Babylon.js, Construct 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js y Unity
Frameworks, aplicaciones y bibliotecas con puertos WebGPU terminados o en curso.

Y esta primera versión en Chrome 113 es solo el comienzo. Si bien nuestra versión inicial es para Windows, ChromeOS y macOS, planeamos llevar WebGPU a las plataformas restantes, como Android y Linux, en un futuro cercano.

Y no solo el equipo de Chrome ha estado trabajando en el lanzamiento de WebGPU. También hay implementaciones en curso en Firefox y WebKit.

Además, ya se están diseñando nuevas funciones en W3C que se pueden exponer cuando estén disponibles en el hardware. Por ejemplo, en Chrome planeamos habilitar pronto la compatibilidad con números de punto flotante de 16 bits en sombreadores y la clase de instrucciones de DP4a para lograr aún más mejoras en el rendimiento del aprendizaje automático.

WebGPU es una API extensa que desbloquea un rendimiento increíble si inviertes en ella. Hoy, solo podríamos cubrir sus beneficios en términos generales, pero si quieres comenzar a usar WebGPU, consulta nuestro codelab introductorio, Tu primera app de WebGPU. En este codelab, compilarás una versión en GPU del clásico Juego de la vida de Conway. En este codelab, se explica el proceso paso a paso, para que puedas probarlo incluso si es la primera vez que desarrollas una GPU.

Las muestras de WebGPU también son un buen lugar para conocer la API. Van desde la frase tradicional “hola triángulo” hasta canalizaciones de procesamiento y renderización más completas, lo que demuestra una variedad de técnicas. Por último, consulta nuestros otros recursos.