Co nowego w WebGPU (Chrome 120)

François Beaufort
François Beaufort

Obsługa 16-bitowych wartości zmiennoprzecinkowych w WGSL

W WGSL typ f16 to zbiór 16-bitowych wartości zmiennoprzecinkowych w formacie IEEE-754 binary16 (półprecyzyjnym). Oznacza to, że do reprezentowania liczby zmiennoprzecinkowej używa 16 bitów, a nie 32 bitów, jak w przypadku konwencjonalnej liczby zmiennoprzecinkowej pojedynczej precyzji (f32). Mniejszy rozmiar może prowadzić do znacznej poprawy wydajności, zwłaszcza podczas przetwarzania dużych ilości danych.

Dla porównania na urządzeniu Apple M1 Pro implementacja f16 modeli Llama2 7B używanych w demonstracji czatu WebLLM jest znacznie szybsza niż implementacja f32. Jak pokazują poniższe zrzuty ekranu, szybkość wstępnego wypełniania jest o 28% większa, a szybkość dekodowania o 41% większa.

Zrzut ekranu z demonstracji czatu WebLLM z modelami Llama2 7B w formatach f32 i f16.
Dema czatu WebLLM z modelami Llama2 7B f32 (po lewej) i f16 (po prawej).

Nie wszystkie procesory graficzne obsługują 16-bitowe wartości zmiennoprzecinkowe. Gdy funkcja "shader-f16" jest dostępna w GPUAdapter, możesz poprosić o GPUDevice z tą funkcją i utworzyć moduł cieniowania WGSL, który korzysta z typu zmiennoprzecinkowego o połowie precyzji f16. Ten typ można stosować w module cieniowania WGSL tylko wtedy, gdy włączysz f16rozszerzenie WGSLenable f16;. W przeciwnym razie funkcja createShaderModule() wygeneruje błąd weryfikacji. Zapoznaj się z tym krótkim przykładem i problemem 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...

W kodzie modułu cieniowania WGSL można obsługiwać typy f16f32 za pomocą alias w zależności od obsługi funkcji "shader-f16", jak pokazano w tym fragmencie kodu.

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);
  }
`;

Przekraczaj granice

Maksymalna liczba bajtów potrzebna do przechowywania jednej próbki (piksela lub subpiksela) danych wyjściowych potoku renderowania we wszystkich załącznikach kolorów wynosi domyślnie 32 bajty. Możesz teraz poprosić o maksymalnie 64 adresy, korzystając z limitu maxColorAttachmentBytesPerSample. Zapoznaj się z tym przykładem i problemem 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 },
});

Limity maxInterStageShaderVariablesmaxInterStageShaderComponents używane do komunikacji między etapami zostały zwiększone na wszystkich platformach. Więcej informacji znajdziesz w tym zgłoszeniu: dawn:1448.

W przypadku każdego etapu shadera maksymalna liczba wpisów układu grupy powiązań w układzie potoku, które są buforami pamięci, wynosi domyślnie 8. Możesz teraz poprosić o maksymalnie 10 takich kont, korzystając z limitu maxStorageBuffersPerShaderStage. Zobacz problem dawn:2159.

Dodaliśmy nowy limit maxBindGroupsPlusVertexBuffers. Składa się z maksymalnej liczby gniazd grupy wiązań i bufora wierzchołków używanych jednocześnie, wliczając puste gniazda poniżej najwyższego indeksu. Wartość domyślna to 24. Zobacz problem dawn:1849.

Zmiany stanu bufora głębi i szablonu

Aby ułatwić pracę deweloperom, atrybuty stanu bufora głębi i szablonu depthWriteEnableddepthCompare nie są już zawsze wymagane: atrybut depthWriteEnabled jest wymagany tylko w przypadku formatów z głębią, a atrybut depthCompare nie jest wymagany w przypadku formatów z głębią, jeśli nie jest w ogóle używany. Zobacz problem dawn:2132.

Aktualizacje informacji o adapterze

Niestandardowe atrybuty informacji o adapterze typebackend są teraz dostępne po wywołaniu funkcji requestAdapterInfo(), gdy użytkownik włączy flagę „Funkcje deweloperskie WebGPU” w chrome://flags/#enable-webgpu-developer-features. Wartość type może być „discrete GPU”, „integrated GPU”, „CPU” lub „unknown”. Wartość backend to „WebGPU”, „D3D11”, „D3D12”, „metal”, „vulkan”, „openGL”, „openGLES” lub „null”. Zobacz issue dawn:2112 i issue dawn:2107.

Zrzut ekranu ze strony https://webgpureport.org, na którym w informacjach o karcie widać backend i typ.
Informacje o adapterze i jego typ wyświetlane na stronie https://webgpureport.org.

Usunięto opcjonalny parametr listy unmaskHints w metodzie requestAdapterInfo(). Zobacz problem dawn:1427.

Kwantyzacja zapytań dotyczących sygnatur czasowych

Zapytania o sygnatury czasowe umożliwiają aplikacjom pomiar czasu wykonywania poleceń GPU z dokładnością do nanosekundy. Specyfikacja WebGPU sprawia jednak, że zapytania o sygnatury czasowe są opcjonalne ze względu na obawy związane z atakami czasowymi. Zespół Chrome uważa, że kwantyzacja zapytań o sygnatury czasowe stanowi dobry kompromis między precyzją a bezpieczeństwem, ponieważ zmniejsza rozdzielczość do 100 mikrosekund. Zobacz issue dawn:1800.

W Chrome użytkownicy mogą wyłączyć kwantyzację sygnatur czasowych, włączając flagę „Funkcje deweloperskie WebGPU” na stronie chrome://flags/#enable-webgpu-developer-features. Pamiętaj, że ten flag nie włącza samodzielnie funkcji "timestamp-query". Jego wdrożenie jest nadal eksperymentalne, dlatego wymaga flagi „Unsafe WebGPU Support” (Niebezpieczna obsługa WebGPU) na stronie chrome://flags/#enable-unsafe-webgpu.

W Dawn dodaliśmy nowy przełącznik urządzenia o nazwie „timestamp_quantization”, który jest domyślnie włączony. Poniższy fragment kodu pokazuje, jak zezwolić na eksperymentalną funkcję „timestamp-query” bez kwantyzacji sygnatury czasowej podczas wysyłania prośby o urządzenie.

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

Funkcje wiosennych porządków

Eksperymentalna funkcja „timestamp-query-inside-passes” została zmieniona na „chromium-experimental-timestamp-query-inside-passes”, aby deweloperzy wiedzieli, że jest to funkcja eksperymentalna i obecnie dostępna tylko w przeglądarkach opartych na Chromium. Zobacz problem dawn:1193.

Funkcja eksperymentalna „pipeline-statistics-query”, która została wdrożona tylko częściowo, została usunięta, ponieważ nie jest już rozwijana. Zobacz issue chromium:1177506.

Obejmuje to tylko niektóre z najważniejszych informacji. Zapoznaj się z pełną listą zatwierdzeń.

Nowości w WebGPU

Lista wszystkich tematów omówionych w serii Co nowego w WebGPU.

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