WebGPU 的新变化 (Chrome 120)

François Beaufort
François Beaufort

在 WGSL 中支持 16 位浮点值

在 WGSL 中,f16 类型是 IEEE-754 binary16(半精度)格式的 16 位浮点值集合。这意味着它使用 16 位来表示浮点数,而传统的单精度浮点数 (f32) 使用 32 位。这种较小的体积可以显著提升性能,尤其是在处理大量数据时。

相比之下,在 Apple M1 Pro 设备上,WebLLM 聊天演示中使用的 Llama2 7B 模型f16 实现速度明显快于 f32 实现,预填充速度提高 28%,解码速度提高 41%,如以下屏幕截图所示。

使用 f32 和 f16 Llama2 7B 模型的 WebLLM 聊天演示的屏幕截图。
使用 f32(左)和 f16(右)Llama2 7B 模型的 WebLLM 聊天演示。

并非所有 GPU 都支持 16 位浮点值。当 GPUAdapter 中提供 "shader-f16" 功能时,您现在可以请求具有此功能的 GPUDevice,并创建利用半精度浮点类型 f16 的 WGSL 着色器模块。仅当您使用 enable f16; 启用 f16 WGSL 扩展时,此类型才能在 WGSL 着色器模块中使用。否则,createShaderModule() 会生成验证错误。请参阅以下最小示例和问题 dawn:1510

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("shader-f16")) {
  throw new Error("16-bit floating-point value support is not available");
}
// Explicitly request 16-bit floating-point value support.
const device = await adapter.requestDevice({
  requiredFeatures: ["shader-f16"],
});

const code = `
  enable f16;

  @compute @workgroup_size(1)
  fn main() {
    const c : vec3h = vec3<f16>(1.0h, 2.0h, 3.0h);
  }
`;

const shaderModule = device.createShaderModule({ code });
// Create a compute pipeline with this shader module
// and run the shader on the GPU...

可以使用 alias 在 WGSL 着色器模块代码中同时支持 f16f32 类型,具体取决于 "shader-f16" 功能支持,如以下代码段所示。

const adapter = await navigator.gpu.requestAdapter();
const hasShaderF16 = adapter.features.has("shader-f16");

const device = await adapter.requestDevice({
  requiredFeatures: hasShaderF16 ? ["shader-f16"] : [],
});

const header = hasShaderF16
  ? `enable f16;
     alias min16float = f16;`
  : `alias min16float = f32;`;

const code = `
  ${header}

  @compute @workgroup_size(1)
  fn main() {
    const c = vec3<min16float>(1.0, 2.0, 3.0);
  }
`;

挑战极限

默认情况下,容纳所有颜色附件的一个渲染管道输出数据样本(像素或子像素)所需的最大字节数为 32 字节。现在,使用 maxColorAttachmentBytesPerSample 这一限制,最多可以请求 64 个会话。请参阅以下示例并问题 dawn:2036

const adapter = await navigator.gpu.requestAdapter();

if (adapter.limits.maxColorAttachmentBytesPerSample < 64) {
  // When the desired limit isn't supported, take action to either fall back to
  // a code path that does not require the higher limit or notify the user that
  // their device does not meet minimum requirements.
}

// Request highest limit of max color attachments bytes per sample.
const device = await adapter.requestDevice({
  requiredLimits: { maxColorAttachmentBytesPerSample: 64 },
});

已放宽所有平台上用于阶段间通信的 maxInterStageShaderVariablesmaxInterStageShaderComponents 限制。如需了解详情,请参阅问题 dawn:1448

对于每个着色器阶段,流水线布局中作为存储缓冲区的绑定组布局条目的数量上限默认为 8。现在,使用 maxStorageBuffersPerShaderStage 限制可以请求最多 10 个请求。请参阅问题 dawn:2159

已添加新的maxBindGroupsPlusVertexBuffers限额。它包含同时使用的绑定组和顶点缓冲区槽位的最大值,包括低于最高索引的所有空槽位。其默认值为 24。请参阅问题 dawn:1849

深度模板状态更改

为了改善开发者体验,我们不再总是要求使用深度模板状态 depthWriteEnableddepthCompare 属性:只有具有深度的格式才需要 depthWriteEnabled,而对于具有深度的格式,则不需要 depthCompare。请参阅问题 dawn:2132

适配器信息更新

如果用户在 chrome://flags/#enable-webgpu-developer-features 处启用了“WebGPU 开发者功能”标记,那么调用 requestAdapterInfo() 后,现在可以使用非标准 typebackend 适配器信息属性。type 可以是“独立 GPU”“集成 GPU”“CPU”或“未知”。backend 是“WebGPU”“D3D11”“D3D12”“metal”“vulkan”“openGL”“openGLES”或“null”。请参阅问题 dawn:2112问题 dawn:2107

https://webgpureport.org 的屏幕截图,其中显示了后端和输入适配器信息。
https://webgpureport.org 上显示的适配器信息后端和类型。

移除了 requestAdapterInfo() 中的可选 unmaskHints 列表参数。请参阅问题 dawn:1427

时间戳查询量化

时间戳查询可让应用以纳秒级精度测量 GPU 命令的执行时间。但是,出于时间攻击方面的考虑,WebGPU 规范将时间戳查询设为可选查询。Chrome 团队认为,量化时间戳查询可将分辨率降低至 100 微秒,从而在精确度和安全性之间取得较好的折衷。请参阅问题 dawn:1800

在 Chrome 中,用户可以通过在 chrome://flags/#enable-webgpu-developer-features 处启用“WebGPU 开发者功能”标记来停用时间戳量化。请注意,如果只使用此标志,则无法启用 "timestamp-query" 功能。其实现仍处于实验阶段,因此需要在 chrome://flags/#enable-unsafe-webgpu 位置添加“Unsafe WebGPU Support”标志。

Dawn 中新增了一个名为“timestamp_quantization”的设备切换开关,它默认处于启用状态。以下代码段展示了如何在请求设备时允许不带时间戳量化的实验性“时间戳查询”功能。

wgpu::DawnTogglesDescriptor deviceTogglesDesc = {};

const char* allowUnsafeApisToggle = "allow_unsafe_apis";
deviceTogglesDesc.enabledToggles = &allowUnsafeApisToggle;
deviceTogglesDesc.enabledToggleCount = 1;

const char* timestampQuantizationToggle = "timestamp_quantization";
deviceTogglesDesc.disabledToggles = &timestampQuantizationToggle;
deviceTogglesDesc.disabledToggleCount = 1;

wgpu::DeviceDescriptor desc = {.nextInChain = &deviceTogglesDesc};

// Request a device with no timestamp quantization.
myAdapter.RequestDevice(&desc, myCallback, myUserData);

弹簧清洁功能

实验性功能“timestamp-query-inside-passes”已重命名为“chromium-experimental-timestamp-query-inside-passes”,以向开发者明确表明此功能处于实验阶段,目前仅适用于基于 Chromium 的浏览器。请参阅问题 dawn:1193

仅部分实施的实验性“pipeline-statistics-query”功能已被移除,因为它已不再开发。请参阅问题 chromium:1177506

这仅涵盖了部分重要的亮点。查看详尽的提交内容列表

WebGPU 的新变化

WebGPU 的新变化系列中涵盖的所有内容的列表。

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113