Descubre cómo WebGPU aprovecha la potencia de la GPU para obtener un rendimiento de aprendizaje automático más rápido y una mejor renderización de gráficos.
La nueva API de WebGPU desbloquea grandes mejoras de rendimiento en las cargas de trabajo de gráficos y aprendizaje automático. En este artículo, se explora cómo WebGPU es una mejora con respecto a la solución actual de WebGL, con un adelanto de los desarrollos futuros. Pero primero, proporcionemos un poco de contexto sobre por qué se desarrolló WebGPU.
Contexto en WebGPU
WebGL llegó a Chrome en 2011. Dado que permite que las aplicaciones web aprovechen las GPUs, WebGL ofrece experiencias increíbles en la Web, desde Google Earth hasta videos musicales interactivos, recorridos de bienes raíces en 3D y mucho más. WebGL se basó en la familia de APIs de OpenGL, que se desarrolló por primera vez en 1992. ¡Eso fue hace mucho tiempo! Y puedes imaginar que el hardware de la GPU evolucionó significativamente desde ese momento.
Para seguir el ritmo de esta evolución, se desarrolló una nueva generación de APIs para interactuar de forma más eficiente con el hardware de GPU moderno. 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 abre muchas nuevas 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. Desde 2017, la API se integra al grupo "GPU para la Web" de W3C y es una colaboración entre muchas empresas, como Apple, Google, Mozilla, Intel y Microsoft. Y ahora, después de 6 años de trabajo, nos complace anunciar que una de las incorporaciones más importantes a la plataforma web ya está disponible.
WebGPU está disponible hoy en Chrome 113 en ChromeOS, macOS y Windows, y pronto se agregarán otras plataformas. Muchas gracias a los demás colaboradores de Chromium y, en particular, a Intel, que ayudaron a que esto sucediera.
Ahora, veamos algunos de los casos de uso interesantes que habilita WebGPU.
Desbloquea nuevas cargas de trabajo de GPU para la renderización
Las funciones de WebGPU, como los shaders de procesamiento, permiten que se porten nuevas clases de algoritmos en la GPU. Por ejemplo, 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 trasladar a la GPU.
En el siguiente video, se muestra el algoritmo de cubos en marcha que se usa para triangular la superficie de estas metabolas. En los primeros 20 segundos del video, el algoritmo, cuando se ejecuta en JavaScript, tiene dificultades para seguir el ritmo de la página, que solo se ejecuta a 8 FPS, lo que genera una animación con bloqueos. Para mantener el rendimiento en JavaScript, tendríamos que bajar mucho el nivel de detalles.
La diferencia es abismal cuando trasladamos el mismo algoritmo a un sombreador de cómputo, que se ve en el video después de 20 segundos. El rendimiento mejora de forma significativa, ya que la página ahora se ejecuta a 60 FPS fluidos y aún queda mucho margen de rendimiento para otros efectos. Además, el bucle principal de JavaScript de la página se libera por completo para otras tareas, lo que garantiza que las interacciones con la página sigan siendo responsivas.
WebGPU también permite efectos visuales complejos que antes no eran prácticos. En el siguiente ejemplo, creado en la popular biblioteca Babylon.js, la superficie del océano se simula por completo en la GPU. Las dinámicas realistas se crean a partir de muchas ondas independientes que se suman entre sí. Sin embargo, simular cada ola directamente sería demasiado costoso.
Por eso, la demostración usa un algoritmo avanzado llamado transformada rápida de Fourier. 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 fotograma usa la Transformada de Fourier para convertir los datos espectrales en datos posicionales que representan la altura de las olas.
Inferencia de AA más rápida
WebGPU también es útil para acelerar el aprendizaje automático, que se ha convertido en un uso importante de las GPUs en los últimos años.
Durante mucho tiempo, los desarrolladores creativos reutilizaron la API de renderización de WebGL para realizar operaciones que no son de renderización, como cálculos de aprendizaje automático. Sin embargo, esto requiere dibujar los píxeles de los triángulos como una forma de iniciar los cálculos y empaquetar y desempaquetar cuidadosamente los datos de tensores en la textura en lugar de accesos a memoria de uso general.
El uso de WebGL de esta manera requiere que los desarrolladores adapten su código de forma incómoda a las expectativas de una API diseñada solo para dibujar. Esto, junto con la falta de funciones básicas, como el acceso a la memoria compartida entre cálculos, genera trabajo duplicado y un rendimiento poco óptimo.
Los ComputeShaders son la principal función nueva de WebGPU y eliminan estos problemas. 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 limitado por la estructura estricta de las operaciones de renderización.
Los ComputeShaders ofrecen más oportunidades para compartir datos y resultados de procesamiento dentro de grupos de trabajo de ComputeShaders para mejorar la eficiencia. Esto puede generar ganancias significativas en comparación con los intentos anteriores de usar WebGL para el mismo propósito.
Como ejemplo de los aumentos de eficiencia que esto puede generar, un puerto inicial de un modelo de difusión de imágenes en TensorFlow.js muestra una mejora de rendimiento de 3 veces en una variedad de hardware cuando se pasa de WebGL a WebGPU. En algunos de los hardwares probados, la imagen se renderizó en menos de 10 segundos. Y como este fue un puerto inicial, creemos que es posible realizar aún más mejoras 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 la GPU a la Web.
Diseñado para JavaScript en primer lugar
Las funciones que habilitan estos casos de uso están disponibles para los desarrolladores de computadoras de escritorio y dispositivos móviles específicos de la plataforma desde hace tiempo, y nuestro desafío ha sido exponerlas de una manera que se sienta como 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 enfrentaron y los problemas que plantearon, y canalizamos todos esos comentarios en esta nueva API.
Vimos que el modelo de estado global de WebGL hacía que la creación de bibliotecas y aplicaciones componibles y sólidas fuera difícil y frágil. Por lo tanto, WebGPU reduce de forma significativa la cantidad de estado de la que los desarrolladores deben realizar un seguimiento mientras envían los comandos de la GPU.
Escuchamos que depurar aplicaciones de WebGL era un dolor de cabeza, por lo que WebGPU incluye mecanismos de manejo de errores más flexibles que no afectan tu rendimiento. Además, nos esforzamos por garantizar que cada mensaje que recibas de la API sea fácil de entender y que se pueda implementar.
También observamos que, con frecuencia, la sobrecarga de realizar demasiadas llamadas a JavaScript era un cuello de botella para las aplicaciones WebGL complejas. Como resultado, la API de WebGPU es menos conversacional, 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 Render Bundles, que te permiten grabar grandes cantidades de comandos de dibujo con anticipación y volver a reproducirlos con una sola llamada.
Para demostrar la gran diferencia que puede marcar una función como los paquetes de renderización, aquí tienes otra demostración de Babylon.js. Su renderizador WebGL 2 puede ejecutar todas las llamadas a JavaScript para renderizar esta escena de galería de arte alrededor de 500 veces por segundo. ¡Lo que es bastante bueno!
Sin embargo, su renderizador de WebGPU habilita una función que llaman 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 reducción significativa de la sobrecarga permite que WebGPU renderice escenas más complejas y, al mismo tiempo, permite que las aplicaciones hagan más con JavaScript en paralelo.
Las APIs de gráficos modernas tienen la reputación de ser complejas y de intercambiar la simplicidad por oportunidades de optimización extremas. WebGPU, por otro lado, se enfoca en la compatibilidad multiplataforma y controla automáticamente temas tradicionalmente difíciles, como la sincronización de recursos, 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 usa patrones de JavaScript conocidos, como las promesas, para las operaciones asíncronas. Esto ayuda a mantener la cantidad de código estándar necesaria en un 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 WebGPU ofrece a la plataforma web y esperamos ver todos los casos de uso nuevos y 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 populares de WebGL de JavaScript. En algunos casos, aprovechar los beneficios de WebGPU puede ser tan simple como cambiar una sola marca.
Y esta primera versión en Chrome 113 es solo el comienzo. Si bien nuestro lanzamiento 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. Las implementaciones también están en curso en Firefox y WebKit.
Además, en el W3C ya se están diseñando nuevas funciones 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 DP4a para obtener aún más mejoras en el rendimiento del aprendizaje automático.
WebGPU es una API extensa que ofrece 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 de GPU del Juego de la vida clásico 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. Varían desde el tradicional “triángulo hello” hasta canalizaciones de procesamiento y procesamiento más completas, lo que demuestra una variedad de técnicas. Por último, consulta nuestros otros recursos.