Что нового в WebGPU (Chrome 120)

François Beaufort
François Beaufort

Поддержка 16-битных значений с плавающей запятой в WGSL

В WGSL тип f16 представляет собой набор 16-битных значений с плавающей запятой в формате IEEE-754 binary16 (половинная точность). Это означает, что для представления числа с плавающей запятой используется 16 бит, а не 32, как в случае с обычной точностью (f32). Меньший размер может значительно повысить производительность, особенно при обработке больших объемов данных.

Для сравнения: на устройстве Apple M1 Pro реализация f16 моделей Llama2 7B, используемых в демоверсии чата WebLLM, работает значительно быстрее, чем реализация f32. Как показано на скриншотах ниже, скорость предварительного заполнения увеличилась на 28 %, а скорость декодирования – на 41 %.

Скриншот демонстрации чата WebLLM с моделями Llama2 7B f32 и f16.
Демоверсии чата WebLLM с моделями Llama2 7B f32 (слева) и f16 (справа).

Не все графические процессоры поддерживают 16-битные значения с плавающей запятой. Если в GPUAdapter доступна функция "shader-f16", вы можете запросить GPUDevice с этой функцией и создать модуль шейдера WGSL, в котором используется тип с плавающей запятой половинной точности f16. Этот тип можно использовать в модуле шейдера WGSL, только если вы включили расширение WGSL f16 с помощью enable f16;. В противном случае функция 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...

В коде модуля шейдера WGSL можно поддерживать типы f16 и f32 с помощью alias в зависимости от поддержки функции "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 байта. Теперь можно запросить до 64, используя ограничение maxColorAttachmentBytesPerSample. Ознакомьтесь с примером ниже и проблемой 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 },
});

На всех платформах увеличены лимиты на количество символов maxInterStageShaderVariables и maxInterStageShaderComponents, используемые для межэтапного общения. Подробную информацию можно найти в задаче dawn:1448.

Для каждого этапа шейдера максимальное количество записей макета группы привязки в макете конвейера, которые являются буферами хранения, по умолчанию равно 8. Теперь можно запросить до 10, используя лимит maxStorageBuffersPerShaderStage. См. ошибку dawn:2159.

Добавлен новый лимит maxBindGroupsPlusVertexBuffers. Она состоит из максимального количества слотов группы привязки и буфера вершин, используемых одновременно, включая все пустые слоты ниже самого высокого индекса. Значение по умолчанию – 24. Подробнее о проблеме dawn:1849…

Изменения состояния буфера глубины и трафарета

Чтобы упростить работу разработчиков, атрибуты состояния буфера глубины и трафарета depthWriteEnabled и depthCompare теперь не всегда обязательны. Атрибут depthWriteEnabled требуется только для форматов с глубиной, а depthCompare не нужен для форматов с глубиной, если он не используется. Подробнее о проблеме dawn:2132…

Обновление информации об адаптере

Нестандартные атрибуты информации об адаптере type и backend теперь доступны при вызове requestAdapterInfo(), если пользователь включил флаг "Функции разработчика WebGPU" на странице chrome://flags/#enable-webgpu-developer-features. Значение type может быть "дискретный графический процессор", "встроенный графический процессор", "центральный процессор" или "неизвестно". В поле backend может быть указано "WebGPU", "D3D11", "D3D12", "metal", "vulkan", "openGL", "openGLES" или "null". См. issue dawn:2112 и issue dawn:2107.

Скриншот сайта https://webgpureport.org с информацией о серверной части и типе в адаптере.
Информация о внутреннем и внешнем адаптере, которая показывается на странице https://webgpureport.org.

Удален необязательный параметр списка unmaskHints в requestAdapterInfo(). Подробнее о проблеме dawn:1427…

Квантование запросов временных меток

Запросы временных меток позволяют приложениям измерять время выполнения команд графического процессора с точностью до наносекунды. Однако в спецификации WebGPU запросы временных меток являются необязательными из-за опасений по поводу атак по времени. Команда Chrome считает, что квантование запросов временных меток обеспечивает оптимальный баланс между точностью и безопасностью, поскольку разрешение снижается до 100 микросекунд. См. issue dawn:1800.

В Chrome пользователи могут отключить квантование временных меток, включив флаг "Функции разработчика WebGPU" на странице 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 155–156

Chrome 153–154

Chrome 151–152

Chrome 149–150

Chrome 147–148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

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