Menu fechado

Revolução Zero Inference com WebGPU

WebGPU

🌐 Introdução ao WebGPU

O WebGPU é uma especificação da W3C que expõe uma interface de programação de baixo nível de GPU moderna através de navigator.gpu. Isso permite que os desenvolvedores executem workloads de aprendizado de máquina diretamente no navegador, sem a necessidade de servidores dedicados.

Com o WebGPU, os desenvolvedores podem reduzir significativamente os custos de inferência de AI em aplicações, pois os usuários podem executar modelos de aprendizado de máquina diretamente no seu próprio hardware, sem a necessidade de enviar dados para servidores remotos.

Isso não apenas melhora a eficiência e a escalabilidade, mas também permite que os desenvolvedores criem aplicações mais seguras e privadas, pois os dados não precisam ser enviados para servidores remotos.

Além disso, o WebGPU também oferece uma interface de programação de baixo nível, o que permite que os desenvolvedores tenham mais controle sobre a execução dos workloads de aprendizado de máquina.

Com o WebGPU, os desenvolvedores podem criar aplicações mais eficientes, escaláveis e seguras, o que é fundamental para o desenvolvimento de aplicações de aprendizado de máquina em larga escala.

WebGPU

É importante notar que o WebGPU ainda é uma tecnologia em desenvolvimento, e há muito o que aprender e explorar.

No entanto, com o WebGPU, os desenvolvedores podem criar aplicações mais eficientes, escaláveis e seguras, o que é fundamental para o desenvolvimento de aplicações de aprendizado de máquina em larga escala.


// Exemplo de uso do WebGPU
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const module = device.createShaderModule({
  code: `
    @group(0)
    @binding(0)
    var data: array;
    @compute
    @workgroup_size(64)
    fn main(@builtin(global_invocation_id) id: vec3u) {
      data[id.x] = data[id.x] * 2.0;
    }
  `,
});
const pipeline = device.createComputePipeline({
  layout: 'auto',
  compute: {
    module,
    entryPoint: 'main',
  },
});

🔍 Arquitetura e Funcionalidades do WebGPU

Interface de Programação de GPU Moderna e de Baixo Nível

O WebGPU é uma especificação do W3C que expõe uma interface de programação de GPU moderna e de baixo nível através de navigator.gpu. Isso significa que os desenvolvedores podem acessar recursos de GPU diretamente do JavaScript, sem a necessidade de compilação ou dependências nativas.

Pipelines de Computação

Uma das principais diferenças entre o WebGPU e o WebGL é a introdução de pipelines de computação. Isso permite que os desenvolvedores criem programas de computação que podem ser executados em paralelo, aumentando a eficiência e a velocidade do processamento.

Capacidade de Processamento Paralelo

O WebGPU também oferece uma capacidade de processamento paralelo mais avançada do que o WebGL. Isso permite que os desenvolvedores criem programas que podem ser executados em várias threads ao mesmo tempo, aumentando a velocidade do processamento e melhorando a escalabilidade.

Exemplo de Código


// Minimal WebGPU compute shader dispatch
// Note: a complete runnable example would also create the buffer and bind group (shown below).
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const module = device.createShaderModule({
  code: `
    @group(0)
    @binding(0)
    var data: array;
    @compute
    @workgroup_size(64)
    fn main(@builtin(global_invocation_id) id: vec3u) {
      data[id.x] = data[id.x] * 2.0;
    }
  `
});
const pipeline = device.createComputePipeline({
  layout: 'auto',
  compute: {
    module,
    entryPoint: 'main'
  }
});
// Create a buffer with some data (256 * 64 = 16384 elements)
const bufferSize = 256 * 64 * 4; // 16384 f32 values
const buffer = device.createBuffer({
  size: bufferSize,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
});
const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{
    binding: 0,
    resource: {
      buffer
    }
  }]
});
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(256); // 256 workgroups * 64 threads = 16384 invocations
pass.end();
device.queue.submit([encoder.finish()]);

Imagens e Ilustrações

Abaixo, você pode ver uma imagem que ilustra a arquitetura do WebGPU:

Essa imagem mostra a estrutura da interface de programação de GPU moderna e de baixo nível do WebGPU, incluindo os pipelines de computação e a capacidade de processamento paralelo.

O WebGPU é uma especificação do W3C que pode ser acessada através do seguinte link:

Especificação do WebGPU

Além disso, há várias ferramentas e bibliotecas que podem ser usadas para desenvolver aplicativos com o WebGPU, incluindo:




WebGPU
Transformers.js
ONNX Runtime Web

📊 Desempenho do WebGPU em Comparação com o WebGL

Arquitetura Comparativa

Comparando as capacidades de WebGL 2 e WebGPU, podemos observar as seguintes diferenças:

Capacidade WebGL 2 WebGPU
Tipo de shader Vertex + Fragment Vertex + Fragment + Compute
Armazenamento de dados para ML Texturas (hacky) Buffers de armazenamento (nativos)
Dispacho paralelo Trabalhos de fragmento de shader (workarounds) dispatchWorkgroups()
Half-precision (f16) Limitado/extensão-baseado Característica opcional, explicitamente solicitável via “shader-f16”
Compilação de pipeline assíncrona Não Sim
Batching de comandos Implicito Buffer de comandos explícito

Benchmark Breakdown

Os resultados de benchmarking mostram que o WebGPU supera o WebGL em desempenho para modelos de linguagem, especialmente para operações de matriz e atenção. Os ganhos são dependentes do workload e do dispositivo:

  • Modelos de linguagem com operações de matriz intensivas e atenção beneficiam mais
  • Modelos de visão simples veem melhorias menores

Os speedups relatados em benchmarks da comunidade e na documentação de bibliotecas variam de aproximadamente 3x a 5x para modelos de linguagem, embora números exatos variem de acordo com o fabricante do GPU, a arquitetura do modelo e a versão do navegador.

Código de Exemplo


// Minimal WebGPU compute shader dispatch
// Nota: um exemplo completo executável também criaria o buffer e o grupo de vinculação (mostrado abaixo).
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const module = device.createShaderModule({
  code: ` @group(0) @binding(0) var data: array; @compute @workgroup_size(64) fn main(@builtin(global_invocation_id) id: vec3u) { data[id.x] = data[id.x] * 2.0; } `
});
const pipeline = device.createComputePipeline({
  layout: 'auto',
  compute: {
    module,
    entryPoint: 'main'
  }
});
// Crie um buffer com alguns dados (256 * 64 = 16384 elementos)
const bufferSize = 256 * 64 * 4; // 16384 f32 valores
const buffer = device.createBuffer({
  size: bufferSize,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
});
const bindGroup = device.createBindGroup({
  layout: pipeline.getBindGroupLayout(0),
  entries: [{
    binding: 0,
    resource: {
      buffer
    }
  }]
});
const encoder = device.createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipeline);
pass.setBindGroup(0, bindGroup);
pass.dispatchWorkgroups(256); // 256 workgroups * 64 threads = 16384 invocações
pass.end();
device.queue.submit([encoder.finish()]);

📚 Ecossistema JavaScript para WebGPU e Tutorial Prático

Transformers.js (Hugging Face)

Transformers.js é a biblioteca mais acessível para trabalhar com WebGPU. Ela fornece uma API de pipeline() que é idêntica à biblioteca Transformers em Python. A biblioteca suporta uma ampla gama de arquiteturas em diferentes tarefas: geração de texto, análise de sentimento, tradução, resumo, segmentação de imagem e geração de embeddings.


import { pipeline } from '@huggingface/transformers';
// Crie uma pipeline de análise de sentimento com o backend WebGPU
const classifier = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  { device: 'webgpu' }
);
// Execute a inferência
const result = await classifier('WebGPU faz o browser AI realmente rápido.');
console.log(result); // [{ label: 'POSITIVO', score: 0.9998 }]

ONNX Runtime Web

O ONNX Runtime Web é um runtime de código aberto que fornece uma execução de modelos ONNX em diferentes plataformas. A biblioteca suporta o backend WebGPU e permite que os desenvolvedores executem modelos ONNX em diferentes dispositivos.


import { ONNXRuntime } from 'onnxruntime-web';

// Crie um modelo ONNX
const model = await fetch('modelo.onnx');
const runtime = new ONNXRuntime(model);
// Execute a inferência
const result = await runtime.run('entrada', 'saida');
console.log(result); // Saída do modelo

Tutorial: Executar um Modelo de Linguagem no Navegador com WebGPU

Pré-requisitos e Configuração

Você precisa do Chrome ou Edge versão 113 ou posterior, e uma máquina com um GPU (discreto ou integrado). Comece com um projeto simples:


{
  "name": "webgpu-ai-demo",
  "type": "module",
  "dependencies": {
    "@huggingface/transformers": "^3.0.0"
  }
}

Instale com `npm install`, em seguida, scaffold com Vite ou use um setup de módulo ES vazio.

Carregar um Modelo com o Backend WebGPU

Vamos usar um modelo de análise de sentimento quantizado. A API de pipeline() cuida de baixar o modelo, armazená-lo em cache e configurar a inferência:


import { pipeline } from '@huggingface/transformers';

// Crie uma pipeline de análise de sentimento com o backend WebGPU
const classifier = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  { device: 'webgpu' }
);
// Execute a inferência
const result = await classifier('WebGPU faz o browser AI realmente rápido.');
console.log(result); // [{ label: 'POSITIVO', score: 0.9998 }]

Medir o Desempenho

Separe o tempo de carregamento do modelo do tempo de inferência para entender o comportamento real:


import { pipeline } from '@huggingface/transformers';

const t0 = performance.now();
const classifier = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  { device: 'webgpu' }
);
const loadTime = performance.now() - t0;
console.log(`Modelo carregado em ${loadTime.toFixed(0)}ms`);
const t1 = performance.now();
const result = await classifier('Isso é incrivelmente rápido.');
const inferTime = performance.now() - t1;
console.log(`Inferência concluída em ${inferTime.toFixed(0)}ms`);

Conectar ao UI

Vire a pipeline para um input de texto para um demo interativo. Se você estiver construindo uma interface responsiva para isso, [as unidades de viewport CSS](https://www.sitepoint.com/css-viewport-units-quick-start/) ajudam a garantir que a interface AI seja adaptável em diferentes tamanhos de tela.



Fonte de Referência: sitepoint.com.
Curadoria e Adaptação: Redação Yassutaro Developers.



Redação YTI&W-News

Redação Developers | Yassutaro TI & Web

Notícias do universo do Desenvolvimento Web, dicas e tutoriais para Webmasters.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Publicado em:Desenvolvimento Web
Fale Conosco
×

Inscreva-se em nossa Newsletter!


Receba nossos lançamentos e artigos em primera mão!