|
| 1 | +# WebGPU Backend |
| 2 | + |
| 3 | +The ExecuTorch WebGPU backend runs delegated model graphs on GPUs through the |
| 4 | +[WebGPU API](https://www.w3.org/TR/webgpu/). It uses |
| 5 | +[Dawn](https://dawn.googlesource.com/dawn) and Tint for native execution and |
| 6 | +Emscripten's `emdawnwebgpu` port for browser builds. Operators are implemented |
| 7 | +as in-tree WGSL compute shaders. |
| 8 | + |
| 9 | +::::{note} |
| 10 | +The WebGPU backend is experimental and under active development. |
| 11 | +:::: |
| 12 | + |
| 13 | +## Features |
| 14 | + |
| 15 | +- Native GPU execution on macOS and Linux. |
| 16 | +- Browser execution through Emscripten and `emdawnwebgpu`. |
| 17 | +- Dynamic tensor shapes backed by maximum-size GPU buffer allocations. |
| 18 | +- FP32 execution and device-dependent FP16 paths. |
| 19 | +- Quantized linear, embedding, and convolution kernels, including 4-bit |
| 20 | + weight-only and dynamic 8-bit activation paths. |
| 21 | +- LLM-focused kernels for SDPA, KV-cache updates, rotary embeddings, and |
| 22 | + fused SwiGLU and QKV projections. |
| 23 | +- GPU timestamp-query profiling on devices that expose the feature. |
| 24 | + |
| 25 | +The backend contains more than 100 registered operators. |
| 26 | +See [Operator Support](webgpu-op-support.md) for details. |
| 27 | + |
| 28 | +## Architecture |
| 29 | + |
| 30 | +WebGPU currently reuses the Vulkan backend's export and serialization path: |
| 31 | + |
| 32 | +```text |
| 33 | +PyTorch model |
| 34 | + │ torch.export |
| 35 | + ▼ |
| 36 | +ExportedProgram |
| 37 | + │ WebGPUPartitioner (thin wrapper over VulkanPartitioner) |
| 38 | + ▼ |
| 39 | +Vulkan FlatBuffer delegate payload (VH00/VK00) inside a .pte file |
| 40 | + │ |
| 41 | + ├── Native: Dawn/Tint → Metal or Vulkan |
| 42 | + └── Browser: Emscripten + emdawnwebgpu → browser WebGPU implementation |
| 43 | +``` |
| 44 | + |
| 45 | +`WebGPUPartitioner` is a thin wrapper over `VulkanPartitioner`. It forwards |
| 46 | +partitioning unchanged and preserves Vulkan serialization and the |
| 47 | +`VulkanBackend` delegate identifier. It does not independently validate the |
| 48 | +narrower WebGPU runtime capability set. The runtime ignores Vulkan |
| 49 | +texture-storage annotations and executes the graph with WebGPU buffers and |
| 50 | +WGSL compute pipelines. |
| 51 | + |
| 52 | +::::{important} |
| 53 | +The WebGPU runtime currently registers with ExecuTorch as `VulkanBackend` so it |
| 54 | +can consume Vulkan delegate payloads. Do not link the Vulkan and WebGPU runtime |
| 55 | +backends into the same application. They provide the same backend identifier. |
| 56 | +:::: |
| 57 | + |
| 58 | +## Target Requirements |
| 59 | + |
| 60 | +| Target | Requirements | |
| 61 | +|---|---| |
| 62 | +| macOS native | A Metal-capable GPU and a Dawn installation built for macOS | |
| 63 | +| Linux native | A Vulkan-capable GPU and driver, plus Dawn | |
| 64 | +| Browser | A browser with WebGPU enabled and an Emscripten build using `emdawnwebgpu` | |
| 65 | + |
| 66 | +The exact shader features available, including FP16 and timestamp queries, |
| 67 | +depend on the selected WebGPU adapter. |
| 68 | + |
| 69 | +## Development Requirements |
| 70 | + |
| 71 | +- CMake 3.19 or later. |
| 72 | +- A Python environment with ExecuTorch installed for model export. |
| 73 | +- Dawn's CMake package for native builds. |
| 74 | +- Emscripten for browser builds. |
| 75 | + |
| 76 | +On Linux, the end-to-end validation script installs pinned Dawn and |
| 77 | +SwiftShader dependencies automatically: |
| 78 | + |
| 79 | +```bash |
| 80 | +bash backends/webgpu/test/test_build_webgpu.sh |
| 81 | +``` |
| 82 | + |
| 83 | +On macOS, provide a configured Dawn installation and set `Dawn_DIR` to its |
| 84 | +CMake package directory. |
| 85 | + |
| 86 | +## Exporting a Model |
| 87 | + |
| 88 | +Use `WebGPUPartitioner` to produce a `.pte` file that the WebGPU runtime can |
| 89 | +consume. This example delegates a supported `aten.add.Tensor` operation: |
| 90 | + |
| 91 | +```python |
| 92 | +import torch |
| 93 | + |
| 94 | +from executorch.backends.webgpu.partitioner import WebGPUPartitioner |
| 95 | +from executorch.exir import to_edge_transform_and_lower |
| 96 | + |
| 97 | + |
| 98 | +class AddOne(torch.nn.Module): |
| 99 | + def forward(self, x: torch.Tensor) -> torch.Tensor: |
| 100 | + return x + 1.0 |
| 101 | + |
| 102 | + |
| 103 | +example_inputs = (torch.randn(4, 4),) |
| 104 | +exported_program = torch.export.export(AddOne(), example_inputs) |
| 105 | + |
| 106 | +et_program = to_edge_transform_and_lower( |
| 107 | + exported_program, |
| 108 | + partitioner=[WebGPUPartitioner()], |
| 109 | +).to_executorch() |
| 110 | + |
| 111 | +with open("add_webgpu.pte", "wb") as file: |
| 112 | + file.write(et_program.buffer) |
| 113 | +``` |
| 114 | + |
| 115 | +Because `WebGPUPartitioner` delegates unchanged to `VulkanPartitioner`, it can |
| 116 | +select operators that do not yet have a WebGPU implementation. Validate the |
| 117 | +delegated graph against the WebGPU registry and operator tests. A |
| 118 | +Vulkan-supported but WebGPU-unsupported operator can fail when the WebGPU |
| 119 | +runtime builds the graph instead of falling back automatically. |
| 120 | + |
| 121 | +## Runtime Integration |
| 122 | + |
| 123 | +Configure a native source build with the WebGPU backend and Dawn: |
| 124 | + |
| 125 | +```bash |
| 126 | +# Dawn_DIR must point to Dawn's CMake package directory. |
| 127 | +cmake -B cmake-out-webgpu \ |
| 128 | + -DCMAKE_BUILD_TYPE=Release \ |
| 129 | + -DEXECUTORCH_BUILD_WEBGPU=ON \ |
| 130 | + -DDawn_DIR="${Dawn_DIR}" |
| 131 | +cmake --build cmake-out-webgpu --target webgpu_backend |
| 132 | +``` |
| 133 | + |
| 134 | +Link the `webgpu_backend` target into the application. The target exports the |
| 135 | +link options needed to retain its static backend and operator registrations. |
| 136 | +An exported Vulkan delegate payload will then be handled by WebGPU at runtime. |
| 137 | + |
| 138 | +When building with Emscripten, the backend automatically adds |
| 139 | +`--use-port=emdawnwebgpu` to its compile and link options instead of finding a |
| 140 | +native Dawn package. |
| 141 | + |
| 142 | +## Profiling |
| 143 | + |
| 144 | +Build with timestamp-query support and enable it at runtime: |
| 145 | + |
| 146 | +```bash |
| 147 | +# Dawn_DIR must point to Dawn's CMake package directory. |
| 148 | +cmake -B cmake-out-webgpu \ |
| 149 | + -DEXECUTORCH_BUILD_WEBGPU=ON \ |
| 150 | + -DEXECUTORCH_BUILD_WEBGPU_PROFILING=ON \ |
| 151 | + -DDawn_DIR="${Dawn_DIR}" |
| 152 | +cmake --build cmake-out-webgpu |
| 153 | + |
| 154 | +export WEBGPU_TIMESTAMP_QUERY=1 |
| 155 | +``` |
| 156 | + |
| 157 | +Run the WebGPU-enabled application normally after exporting the environment |
| 158 | +variable. Timestamp queries require adapter support and cannot be used with |
| 159 | +chunked execution. |
| 160 | + |
| 161 | +## Reference |
| 162 | + |
| 163 | +**→{doc}`/backends/webgpu/webgpu-op-support` — Operator coverage and limitations.** |
| 164 | + |
| 165 | +```{toctree} |
| 166 | +:maxdepth: 2 |
| 167 | +:hidden: |
| 168 | +:caption: WebGPU Backend |
| 169 | +
|
| 170 | +webgpu-op-support |
| 171 | +``` |
0 commit comments