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 个字符。请参阅以下示例和issue 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

适配器信息更新

现在,如果用户启用了“WebGPU 开发者功能”,在调用 requestAdapterInfo() 时,就可以使用非标准的 typebackend 适配器信息属性。标记chrome://flags/#enable-webgpu-developer-featurestype 可以是“独立 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 中,用户可以通过启用“WebGPU 开发者功能”来停用时间戳量化flag(位于 chrome://flags/#enable-webgpu-developer-features 处)。请注意,单独使用此标志并不能启用 "timestamp-query" 功能。其实现仍处在实验阶段,因此需要“不安全的 WebGPU 支持”(位于 chrome://flags/#enable-unsafe-webgpu 处)。

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 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