มีอะไรใหม่ใน WebGPU (Chrome 120)

François Beaufort
François Beaufort

การรองรับค่าทศนิยม 16 บิตใน WGSL

ใน WGSL ประเภท f16 คือชุดของค่าทศนิยม 16 บิตในรูปแบบไบนารี 16 (ความแม่นยำครึ่งหนึ่ง) ของ IEEE-754 หมายความว่า ระบบจะใช้ 16 บิตเพื่อแสดงจำนวนจุดลอยตัว แทนที่จะเป็น 32 บิตสำหรับจุดลอยตัวค่าความแม่นยําเดียวปกติ (f32) ขนาดเล็กลงนี้สามารถทําการปรับปรุงประสิทธิภาพได้อย่างมาก โดยเฉพาะอย่างยิ่งเมื่อประมวลผลข้อมูลจํานวนมาก

เมื่อเปรียบเทียบกันแล้ว ในอุปกรณ์ Apple M1 Pro การใช้ f16 รุ่น Llama2 7B ที่ใช้ในการสาธิตการแชท WebLLM จะเร็วกว่าการใช้งาน f32 อย่างมาก โดยมีการกรอกข้อมูลล่วงหน้าเร็วกว่า 28% และความเร็วในการถอดรหัสเพิ่มขึ้น 41% ดังที่แสดงในภาพหน้าจอต่อไปนี้

วันที่ ภาพหน้าจอของการสาธิตการแชท WebLLM ที่มีโมเดล f32 และ f16 Llama2 7B
การสาธิตการแชท WebLLM ที่มีโมเดล f32 (ซ้าย) และ f16 (ขวา) Llama2 7B

GPU บางรุ่นไม่รองรับค่าจุดลอยตัว 16 บิต เมื่อฟีเจอร์ "shader-f16" พร้อมใช้งานใน GPUAdapter ตอนนี้คุณสามารถขอ GPUDevice ด้วยฟีเจอร์นี้และสร้างโมดูลตัวปรับแสงเงา WGSL ที่ใช้ประโยชน์จากประเภทจุดลอยตัวครึ่งความแม่นยํา f16 ได้แล้ว ประเภทนี้ใช้ได้ในโมดูลตัวปรับแสงเงา WGSL เฉพาะเมื่อคุณเปิดใช้ส่วนขยาย f16 WGSL ด้วย 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...

คุณสามารถรองรับทั้งประเภท f16 และ f32 ในโค้ดโมดูลตัวปรับแสงเงา WGSL ด้วย 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);
  }
`;

ก้าวข้ามขีดจำกัด

โดยค่าเริ่มต้น จำนวนไบต์สูงสุดที่จำเป็นในการเก็บตัวอย่าง 1 รายการ (พิกเซลหรือพิกเซลย่อย) ของข้อมูลเอาต์พุตของไปป์ไลน์ในไฟล์แนบทุกสีคือ 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 สำหรับการสื่อสารระหว่างระยะมากขึ้นในทุกแพลตฟอร์ม ดูรายละเอียดได้ที่ issue dawn:1448

สำหรับแต่ละขั้นของตัวปรับเฉดสี จำนวนสูงสุดของรายการเลย์เอาต์กลุ่มการเชื่อมโยงในเลย์เอาต์ไปป์ไลน์ซึ่งเป็นบัฟเฟอร์พื้นที่เก็บข้อมูลคือ 8 โดยค่าเริ่มต้น ตอนนี้คุณจะส่งคำขอได้สูงสุด 10 รายการโดยใช้ขีดจำกัด maxStorageBuffersPerShaderStage ดูปัญหา dawn:2159

เพิ่มขีดจำกัด maxBindGroupsPlusVertexBuffers ใหม่แล้ว ซึ่งประกอบด้วยจำนวนสูงสุดของ Bind Group และช่องบัฟเฟอร์ Vertex ที่ใช้พร้อมกัน โดยนับช่องที่ว่างที่ต่ำกว่าดัชนีสูงสุด ซึ่งค่าเริ่มต้นคือ 24 ดูปัญหา dawn:1849

การเปลี่ยนแปลงสถานะความลึกของลายฉลุ

เพื่อปรับปรุงประสบการณ์ของนักพัฒนาแอป คุณไม่จำเป็นต้องระบุแอตทริบิวต์สถานะ Deep-Stencil depthWriteEnabled และ depthCompare อีกต่อไป เนื่องจากต้องระบุ depthWriteEnabled สำหรับรูปแบบที่มีความลึกเท่านั้น และไม่จำเป็นต้องใช้ depthCompare สำหรับรูปแบบที่มีความลึกหากไม่ได้ใช้เลย ดูปัญหา dawn:2132

การอัปเดตข้อมูลอะแดปเตอร์

ขณะนี้แอตทริบิวต์ข้อมูลอะแดปเตอร์ type และ backend ที่ไม่ใช่แบบมาตรฐานพร้อมให้บริการเมื่อเรียกใช้ requestAdapterInfo() เมื่อผู้ใช้เปิดใช้ "ฟีเจอร์สำหรับนักพัฒนาซอฟต์แวร์ WebGPU" การแจ้งที่ chrome://flags/#enable-webgpu-developer-features type อาจเป็น "GPU แบบแยกต่างหาก", "GPU แบบรวม", "CPU" หรือ "ไม่รู้จัก" 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

การวัดปริมาณการค้นหาการประทับเวลา

การค้นหาการประทับเวลาช่วยให้แอปพลิเคชันวัดเวลาประมวลผลของคำสั่ง 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_quantityization" มีการเพิ่มและเปิดใช้โดยค่าเริ่มต้น ข้อมูลโค้ดต่อไปนี้แสดงวิธีอนุญาตให้ใช้ "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

รายการทั้งหมดที่กล่าวถึงในซีรีส์ What's New in WebGPU

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