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() 将生成验证错误。请参阅以下最小示例和 issue 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...

您可以在 WGSL 着色器模块代码中使用 alias 同时支持 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。请参阅 issue dawn:1849

深度模板状态的更改

为了改进开发者体验,深度-模板缓冲区状态 depthWriteEnableddepthCompare 属性不再是必需的:depthWriteEnabled 仅适用于具有深度的格式,如果不使用深度,则无需 depthCompare。请参阅问题 dawn:2132

适配器信息更新

现在,当用户在 chrome://flags/#enable-webgpu-developer-features 中启用“WebGPU 开发者功能”标志时,调用 requestAdapterInfo() 时会提供非标准 typebackend 适配器信息属性。type 可以是“独立显卡”“集成显卡”“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”的设备切换开关,默认处于启用状态。以下代码段展示了如何在请求设备时允许不进行时间戳量化的实验性“timestamp-query”功能。

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 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

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