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

Франсуа Бофор
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 с моделями f32 и f16 Llama2 7B.
Демонстрации чата WebLLM с моделями Llama2 7B f32 (слева) и f16 (справа).

Не все графические процессоры поддерживают 16-битные значения с плавающей запятой. Когда функция "shader-f16" доступна в GPUAdapter , вы можете запросить 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 . См. issue dawn:2159 .

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

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

Для удобства разработчиков атрибуты depthWriteEnabled и depthCompare для состояния трафарета глубины теперь не всегда требуются: depthWriteEnabled требуется только для форматов с глубиной, а depthCompare не требуется для форматов с глубиной, если не используется вообще. См. issue 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() был удалён. См. issue 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. См. issue dawn:1193 .

Экспериментальная функция «pipeline-statistics-query», которая была реализована лишь частично, была удалена, поскольку её разработка прекращена. См. issue chromium:1177506 .

Здесь рассматриваются лишь некоторые из ключевых моментов. Ознакомьтесь с полным списком коммитов .

Что нового в WebGPU

Список всего, что было рассмотрено в серии « Что нового в WebGPU» .

Хром 140

Хром 139

Хром 138

Хром 137

Хром 136

Хром 135

Хром 134

Хром 133

Хром 132

Хром 131

Хром 130

Хром 129

Хром 128

Хром 127

Хром 126

Хром 125

Хром 124

Хром 123

Хром 122

Хром 121

Хром 120

Хром 119

Хром 118

Хром 117

Хром 116

Хром 115

Хром 114

Хром 113