Saiba como a WebGPU libera o poder da GPU para desempenho de aprendizado de máquina mais rápido e melhor renderização gráfica.
A nova API WebGPU oferece ganhos de performance enormes em cargas de trabalho de gráficos e aprendizado de máquina. Este artigo explica como a WebGPU é uma melhoria em relação à solução atual do WebGL, com uma prévia dos desenvolvimentos futuros. Mas, primeiro, vamos explicar por que a WebGPU foi desenvolvida.
Contexto na WebGPU
O WebGL chegou ao Chrome em 2011. Ao permitir que os aplicativos da Web aproveitem as GPUs, o WebGL oferece experiências incríveis na Web, como o Google Earth, videoclipes interativos, tours 3D de imóveis e muito mais. O WebGL foi baseado na família de APIs OpenGL (link em inglês), desenvolvida pela primeira vez em 1992. Faz muito tempo! E você pode imaginar que o hardware de GPU evoluiu significativamente desde então.
Para acompanhar essa evolução, uma nova geração de APIs foi desenvolvida para interagir de maneira mais eficiente com o hardware de GPU moderno. APIs como Direct3D 12, Metal e Vulkan. Essas novas APIs oferecem suporte a casos de uso novos e exigentes para programação de GPU, como a explosão no aprendizado de máquina e os avanços nos algoritmos de renderização. A WebGPU é a sucessora da WebGL, levando os avanços dessa nova classe de APIs modernas para a Web.
A WebGPU libera muitas novas possibilidades de programação de GPU no navegador. Ela reflete melhor como o hardware moderno da GPU funciona e serve de base para recursos mais avançados da GPU no futuro. A API está no grupo "GPU for the Web" do W3C desde 2017 e é uma colaboração entre muitas empresas, como Apple, Google, Mozilla, Microsoft e Intel. Depois de seis anos de trabalho, temos o prazer de anunciar que uma das maiores adições à plataforma da Web finalmente está disponível.
A WebGPU já está disponível no Chrome 113 para ChromeOS, macOS e Windows. Outras plataformas serão lançadas em breve. Agradecemos muito aos outros colaboradores do Chromium e à Intel, em particular, por ajudar a fazer isso acontecer.
Agora vamos conferir alguns dos casos de uso incríveis que a WebGPU possibilita.
Desbloqueie novas cargas de trabalho da GPU para renderização
Recursos da WebGPU, como sombreadores de computação, permitem a portabilidade de novas classes de algoritmos na GPU. Por exemplo, algoritmos que podem adicionar mais detalhes dinâmicos às cenas, simular fenômenos físicos e muito mais. Até mesmo cargas de trabalho que antes só podiam ser feitas em JavaScript, agora podem ser movidas para a GPU.
O vídeo a seguir mostra o algoritmo de cubos de marcha sendo usado para triangular a superfície dessas metaesferas. Nos primeiros 20 segundos do vídeo, o algoritmo, quando executado em JavaScript, tem dificuldade para acompanhar a página que está sendo executada a apenas 8 QPS, resultando em uma animação instável. Para manter o bom desempenho em JavaScript, precisaríamos diminuir bastante o nível de detalhes.
Quando mudamos o mesmo algoritmo para um sombreador de computação, ocorre uma diferença noturna, o que é mostrado no vídeo após 20 segundos. A performance melhora drasticamente, com a página funcionando a 60 QPS, e ainda há muito espaço para outros efeitos. Além disso, o loop JavaScript principal da página fica totalmente liberado para outras tarefas, garantindo que as interações com a página permaneçam responsivas.
A WebGPU também permite efeitos visuais complexos que não eram práticos antes. No exemplo a seguir, criado na popular biblioteca Babylon.js, a superfície do oceano é simulada inteiramente na GPU. A dinâmica realista é criada a partir de muitas ondas independentes que são adicionadas umas às outras. Mas simular cada onda diretamente seria muito caro.
É por isso que a demonstração usa um algoritmo avançado chamado Transformada rápida de Fourier. Em vez de representar todas as ondas como dados posicionais complexos, ele usa os dados espectrais, que são muito mais eficientes para realizar cálculos. Em seguida, cada frame usa a transformação de Fourier para converter dados espectrais em dados posicionais que representam a altura das ondas.
Inferência de ML mais rápida
A WebGPU também é útil para acelerar o aprendizado de máquina, que se tornou um uso importante das GPUs nos últimos anos.
Por muito tempo, os desenvolvedores criativos reutilizaram a API de renderização do WebGL para realizar operações que não são de renderização, como cálculos de aprendizado de máquina. No entanto, isso exige o desenho dos pixels de triângulos como uma forma de iniciar as computações e empacotar e desempacotar dados de tensor na textura com cuidado, em vez de acessos de memória de uso geral.
Dessa forma, o uso do WebGL exige que os desenvolvedores adaptem o código de maneira estranha às expectativas de uma API projetada apenas para exibição. Isso, combinado com a falta de recursos básicos, como o acesso à memória compartilhada entre as computações, leva a trabalhos duplicados e a um desempenho subótimo.
Os sombreadores de computação são o novo recurso principal da WebGPU e removem esses pontos problemáticos. Os sombreadores de computação oferecem um modelo de programação mais flexível que aproveita a natureza extremamente paralela da GPU, sem serem limitados pela estrutura rígida das operações de renderização.
Os shaders de computação oferecem mais oportunidades de compartilhamento de dados e resultados de computação em grupos de trabalho de shaders para maior eficiência. Isso pode gerar ganhos significativos em relação às tentativas anteriores de usar o WebGL com o mesmo propósito.
Como exemplo dos ganhos de eficiência que isso pode trazer, uma porta inicial de um modelo de difusão de imagens no TensorFlow.js mostra um ganho de desempenho três vezes maior em vários hardwares quando movidos do WebGL para o WebGPU. Em alguns dos hardwares testados, a imagem foi renderizada em menos de 10 segundos. Como esse foi um port inicial, acreditamos que há ainda mais melhorias possíveis na WebGPU e no TensorFlow.js. Confira O que há de novo no Web ML em 2023? sessão do Google I/O.
Mas a WebGPU não se trata apenas de trazer recursos de GPU para a Web.
Projetado para JavaScript
Os recursos que permitem esses casos de uso já estão disponíveis para desenvolvedores de desktop e dispositivos móveis específicos da plataforma há algum tempo. O desafio é apresentá-los de uma forma que pareça uma parte natural da plataforma da Web.
A WebGPU foi desenvolvida com o benefício da visão retrospectiva de mais de uma década de desenvolvedores fazendo um trabalho incrível com o WebGL. Conseguimos analisar os problemas enfrentados, os gargalos encontrados e os problemas levantados, e afunilamos todo esse feedback para essa nova API.
Vimos que o modelo de estado global do WebGL tornou difícil e frágil a criação de bibliotecas e aplicativos combináveis robustos. Portanto, a WebGPU reduz drasticamente a quantidade de estado que os desenvolvedores precisam acompanhar ao enviar os comandos da GPU.
Sabemos que depurar aplicativos WebGL é uma dor de cabeça. Por isso, a WebGPU inclui mecanismos de manipulação de erros mais flexíveis que não prejudicam o desempenho. E nos esforçamos para garantir que todas as mensagens que você recebe da API sejam fáceis de entender e úteis.
Também observamos que, com frequência, o overhead de fazer muitas chamadas de JavaScript era um gargalo para aplicativos WebGL complexos. Como resultado, a API WebGPU é menos chata, então você pode fazer mais com menos chamadas de função. Focamos em realizar a validação pesada antecipadamente, mantendo o loop de renderização crítico o mais enxuto possível. Também oferecemos novas APIs, como os pacotes de renderização, que permitem gravar um grande número de comandos de exibição com antecedência e reproduzi-los com uma única chamada.
Para demonstrar a grande diferença que um recurso como pacotes de renderização pode fazer, veja aqui outra demonstração da Babylon.js. O renderizador WebGL 2 pode executar todas as chamadas de JavaScript para renderizar essa cena de galeria de arte cerca de 500 vezes por segundo. O que é muito bom!
No entanto, o renderizador da WebGPU ativa um recurso chamado "Rendering Snapshot". Criado sobre pacotes de renderização de WebGPUs, esse recurso permite que a mesma cena seja enviada mais de 10 vezes mais rápido. Essa sobrecarga significativamente reduzida permite que a WebGPU renderize cenas mais complexas, ao mesmo tempo que permite que os aplicativos façam mais com o JavaScript em paralelo.
As APIs gráficas modernas são conhecidas pela complexidade, trocando a simplicidade por oportunidades extremas de otimização. O WebGPU, por outro lado, se concentra na compatibilidade entre plataformas, processando de forma automática temas tradicionalmente difíceis, como a sincronização de recursos, na maioria dos casos.
Isso tem o efeito colateral positivo de que a WebGPU é fácil de aprender e usar. Ela conta com recursos existentes da plataforma da Web para coisas como carregamento de imagens e vídeos e se alinha a padrões JavaScript conhecidos, como promessas para operações assíncronas. Isso ajuda a manter a quantidade de código clichê necessária no mínimo. Você pode exibir seu primeiro triângulo na tela em menos de 50 linhas 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>
Conclusão
É empolgante ver todas as novas possibilidades que a WebGPU traz para a plataforma da Web e estamos ansiosos para ver todos os novos casos de uso interessantes que você encontrará para a WebGPU.
Um ecossistema vibrante de bibliotecas e frameworks foi criado em torno da WebGL, e esse mesmo ecossistema está ansioso para adotar a WebGPU. O suporte à WebGPU está em andamento ou já foi concluído em muitas bibliotecas populares do Javascript WebGL. Em alguns casos, aproveitar os benefícios da WebGPU pode ser tão simples quanto mudar uma única flag.
E essa primeira versão do Chrome 113 é apenas o começo. Embora a versão inicial seja para Windows, ChromeOS e MacOS, planejamos trazer a WebGPU para as plataformas restantes, como Android e Linux, em breve.
E não é apenas a equipe do Chrome que está trabalhando no lançamento da WebGPU. Implementações também estão em andamento no Firefox e no WebKit.
Além disso, novos recursos já estão sendo projetados no W3C e podem ser expostos quando estiverem disponíveis no hardware. Por exemplo, no Chrome, planejamos ativar o suporte a números de ponto flutuante de 16 bits em shaders e a classe de instruções DP4a em breve para melhorar ainda mais o desempenho do aprendizado de máquina.
A WebGPU é uma API extensa que oferece um desempenho incrível se você investir nela. Hoje, só podemos abordar os benefícios de forma geral, mas, se você quiser começar a usar a WebGPU, confira nosso codelab introdutório, Seu primeiro app WebGPU. Nele, você vai criar uma versão de GPU do clássico Game of Life da Conway. Este codelab explica o processo passo a passo para que você possa testá-lo, mesmo que seja sua primeira vez fazendo desenvolvimento de GPU.
Os exemplos da WebGPU também são um bom lugar para conhecer a API. Elas variam do tradicional "hello triangle" até pipelines de renderização e computação mais completos, demonstrando uma variedade de técnicas. Por fim, confira nossos outros recursos.