WebGPU: Mở khoá quyền truy cập GPU hiện đại trong trình duyệt

Tìm hiểu cách WebGPU khai phá sức mạnh của GPU để mang lại hiệu suất học máy nhanh hơn và khả năng kết xuất đồ hoạ tốt hơn.

Corentin Wallez
Corentin Wallez
François Beaufort
François Beaufort

API WebGPU mới giúp tăng hiệu suất mạnh mẽ trong khối lượng công việc về đồ hoạ và máy học. Bài viết này khám phá cách WebGPU là một sự cải tiến so với giải pháp WebGL hiện tại, đồng thời có phần hé lộ về các phát triển trong tương lai. Nhưng trước tiên, hãy cùng cung cấp một vài thông tin về lý do WebGPU được phát triển.

Ngữ cảnh trên WebGPU

WebGL đã có mặt trên Chrome vào năm 2011. Bằng cách cho phép các ứng dụng web tận dụng GPU, WebGL mang lại những trải nghiệm tuyệt vời trên web – từ Google Earth, video nhạc tương tác đến hướng dẫn từng bước về bất động sản 3D và hơn thế nữa. WebGL dựa trên nhóm API OpenGL được phát triển lần đầu tiên vào năm 1992. Đã lâu rồi! Bạn có thể hình dung phần cứng GPU đã phát triển đáng kể kể từ thời điểm đó.

Để theo kịp sự phát triển này, một loại API mới đã được phát triển nhằm tương tác hiệu quả hơn với phần cứng GPU hiện đại. Các API như Direct3D 12, MetalVulkan. Những API mới này đã hỗ trợ những trường hợp sử dụng mới và đòi hỏi cao việc lập trình GPU, chẳng hạn như sự bùng nổ trong công nghệ học máy và những tiến bộ về thuật toán kết xuất hình ảnh. WebGPU là sự kế thừa của WebGL, mang những tiến bộ của loại API hiện đại mới này lên Web.

WebGPU mở ra rất nhiều khả năng lập trình GPU mới trong trình duyệt. Nó phản ánh rõ hơn cách hoạt động của phần cứng GPU hiện đại, đồng thời đặt nền móng cho các tính năng GPU nâng cao hơn trong tương lai. API này đã được tích hợp vào nhóm "GPU cho web" của W3C từ năm 2017 và là sự cộng tác giữa nhiều công ty như Apple, Google, Mozilla, Microsoft và Intel. Sau 6 năm làm việc, chúng tôi rất vui mừng được thông báo rằng cuối cùng thì một trong những tính năng bổ sung quan trọng nhất cho nền tảng web đã ra mắt!

WebGPU hiện đã có trong Chrome 113 trên ChromeOS, macOS và Windows, đồng thời sẽ sớm ra mắt cho các nền tảng khác. Xin chân thành cảm ơn những người đóng góp khác cho Chromium và đặc biệt là Intel đã giúp thực hiện điều này.

Bây giờ, hãy xem một số trường hợp sử dụng thú vị mà WebGPU cho phép.

Khai thác khối lượng công việc GPU mới để kết xuất

Các tính năng của WebGPU như trình đổ bóng tính toán cho phép chuyển các lớp thuật toán mới trên GPU. Ví dụ: các thuật toán có thể thêm thông tin chi tiết linh hoạt hơn vào cảnh, mô phỏng các hiện tượng thực tế và nhiều tính năng khác! Thậm chí có những khối lượng công việc trước đây chỉ có thể thực hiện trong JavaScript nhưng nay có thể được chuyển sang GPU.

Video sau đây cho thấy thuật toán khối hành trình được dùng để tam giác bề mặt của những siêu bóng này. Trong 20 giây đầu tiên của video, khi thuật toán chạy trong JavaScript, thuật toán sẽ cố gắng bắt kịp trang chỉ chạy ở tốc độ 8 khung hình/giây, khiến ảnh động bị giật. Để duy trì hiệu suất tốt trong JavaScript, chúng ta cần hạ thấp mức độ chi tiết đi rất nhiều.

Sự chênh lệch về đêm và ngày khi chúng ta di chuyển cùng một thuật toán sang chương trình đổ bóng điện toán xuất hiện trong video sau 20 giây. Hiệu suất được cải thiện đáng kể khi trang hiện chạy ở tốc độ 60 khung hình/giây mượt mà và vẫn còn nhiều khoảng trống hiệu suất cho các hiệu ứng khác. Ngoài ra, vòng lặp JavaScript chính của trang được giải phóng hoàn toàn cho các tác vụ khác, đảm bảo rằng các hoạt động tương tác với trang luôn phản hồi.

Bản minh hoạ metaballs

WebGPU cũng kích hoạt các hiệu ứng hình ảnh phức tạp mà trước đây không thiết thực. Trong ví dụ sau, được tạo trong thư viện Babylon.js phổ biến, bề mặt đại dương đang được mô phỏng hoàn toàn trên GPU. Các động lực thực tế được tạo ra từ nhiều sóng độc lập được thêm vào nhau. Tuy nhiên, việc mô phỏng trực tiếp từng sóng sẽ quá tốn kém.

Bản minh hoạ về đại dương

Đó là lý do tại sao bản minh hoạ sử dụng thuật toán nâng cao có tên là Chuyển đổi Fourier nhanh. Thay vì biểu diễn tất cả các sóng dưới dạng dữ liệu vị trí phức tạp, phương pháp này sử dụng dữ liệu quang phổ hiệu quả hơn nhiều để thực hiện các phép tính. Sau đó, mỗi khung sử dụng Biến đổi Fourier để chuyển đổi từ dữ liệu quang phổ sang dữ liệu vị trí biểu thị độ cao của sóng.

Suy luận học máy nhanh hơn

WebGPU cũng hữu ích trong việc tăng tốc công nghệ học máy, vốn đã trở thành một ứng dụng chính của GPU trong những năm gần đây.

Trong một thời gian dài, các nhà phát triển mẫu quảng cáo đã sử dụng lại API kết xuất của WebGL để thực hiện những thao tác không kết xuất như các phép tính học máy. Tuy nhiên, việc này đòi hỏi việc vẽ các pixel của tam giác như một cách để bắt đầu các phép tính cũng như đóng gói và giải nén dữ liệu tensor ở dạng kết cấu một cách cẩn thận thay vì dùng các phương thức truy cập bộ nhớ cho mục đích chung.

Hình minh hoạ những điểm không hiệu quả trong một quá trình thực thi toán tử ML bằng WebGL, bao gồm tải bộ nhớ thừa, tính toán dự phòng và một vài giá trị được ghi trên mỗi luồng.
Thực thi toán tử ML duy nhất với WebGL.

Việc sử dụng WebGL theo cách này yêu cầu nhà phát triển phải thay đổi mã của họ sao cho phù hợp với kỳ vọng của một API chỉ dùng để vẽ. Cùng với việc thiếu các tính năng cơ bản như quyền truy cập vào bộ nhớ dùng chung giữa các lần tính toán, điều này dẫn đến công việc trùng lặp và hiệu suất dưới mức tối ưu.

Chương trình đổ bóng điện toán là tính năng mới chính của WebGPU và loại bỏ những vấn đề này. Chương trình đổ bóng điện toán cung cấp một mô hình lập trình linh hoạt hơn, tận dụng tính chất song song của GPU mà không bị hạn chế bởi cấu trúc nghiêm ngặt của các hoạt động kết xuất.

Mức tăng hiệu suất khác nhau trong chương trình đổ bóng điện toán WebGPU, bao gồm tải bộ nhớ dùng chung, tính toán dùng chung và ghi linh hoạt vào bộ nhớ.
Hiệu quả của chương trình đổ bóng điện toán WebGPU.

Chương trình đổ bóng điện toán mang lại nhiều cơ hội hơn để chia sẻ dữ liệu và kết quả tính toán trong các nhóm chương trình đổ bóng hoạt động để mang lại hiệu quả tốt hơn. Điều này có thể mang lại những lợi ích đáng kể so với những lần sử dụng WebGL trước đó.

Ví dụ về lợi ích hiệu quả mà việc này có thể mang lại, cổng ban đầu của mô hình khuếch tán hình ảnh trong TensorFlow.js cho thấy hiệu suất tăng gấp 3 lần trên nhiều phần cứng khi chuyển từ WebGL sang WebGPU. Trên một số thiết bị được kiểm thử, hình ảnh kết xuất được trong chưa đầy 10 giây. Vì đây là một cảng sớm, nên chúng tôi tin rằng cả WebGPU và TensorFlow.js còn có thể cải tiến nhiều hơn nữa! Xem bài viết Công nghệ học máy web có gì mới trong năm 2023? Phiên Google I/O.

Tuy nhiên, WebGPU không chỉ mang các tính năng GPU lên web.

Được thiết kế cho JavaScript trước tiên

Các tính năng hỗ trợ những trường hợp sử dụng này đã được cung cấp cho các nhà phát triển máy tính và thiết bị di động dành riêng cho nền tảng được một thời gian. Tuy nhiên, chúng tôi gặp khó khăn trong việc cung cấp các tính năng này theo cách tự nhiên trên nền tảng web.

WebGPU được phát triển với lợi ích của cái nhìn sâu sắc từ hơn một thập kỷ của các nhà phát triển đã làm những công việc tuyệt vời với WebGL. Chúng tôi có thể xử lý những vấn đề họ gặp phải, điểm tắc nghẽn họ gặp phải cũng như những vấn đề họ đã nêu ra và chuyển tất cả những phản hồi đó vào API mới này.

Chúng tôi nhận thấy rằng mô hình trạng thái toàn cầu của WebGL khiến việc tạo thư viện và ứng dụng mạnh mẽ, có khả năng kết hợp trở nên khó khăn và dễ vỡ. Vì vậy, WebGPU giảm đáng kể lượng trạng thái mà nhà phát triển cần theo dõi trong khi gửi các lệnh GPU.

Chúng tôi nghe nói rằng việc gỡ lỗi ứng dụng WebGL là một vấn đề, vì vậy WebGPU bao gồm cơ chế xử lý lỗi linh hoạt hơn mà không làm tăng hiệu suất của bạn. Chúng tôi cũng nỗ lực hết mình để đảm bảo rằng mọi thông báo bạn nhận được từ API này đều dễ hiểu và dễ xử lý.

Chúng tôi cũng nhận thấy rằng việc thường xuyên thực hiện quá nhiều lệnh gọi JavaScript sẽ gây trở ngại cho các ứng dụng WebGL phức tạp. Do đó, WebGPU API ít trò chuyện hơn, vì vậy bạn có thể hoàn thành nhiều việc hơn với ít lệnh gọi hàm hơn. Chúng tôi tập trung vào việc thực hiện trước việc xác thực các phần tử nặng, giữ cho vòng lặp vẽ quan trọng tinh gọn nhất có thể. Ngoài ra, chúng tôi còn cung cấp các API mới như Gói kết xuất, cho phép bạn ghi lại trước số lượng lớn các lệnh vẽ và phát lại các lệnh đó chỉ bằng một lệnh gọi.

Để minh hoạ sự khác biệt đáng kể mà một tính năng như gói kết xuất có thể tạo ra, dưới đây là một bản minh hoạ khác từ Babylon.js. Trình kết xuất WebGL 2 của họ có thể thực thi tất cả các lệnh gọi JavaScript để kết xuất cảnh phòng trưng bày nghệ thuật này khoảng 500 lần một giây. Tốt lắm!

Phòng tranh

Tuy nhiên, trình kết xuất WebGPU của họ bật một tính năng mà họ gọi là Kết xuất ảnh chụp nhanh. Được xây dựng dựa trên các gói kết xuất WebGPU, tính năng này cho phép gửi cùng một cảnh nhanh hơn 10 lần. Mức hao tổn giảm đáng kể này cho phép WebGPU kết xuất các cảnh phức tạp hơn, trong khi vẫn cho phép các ứng dụng làm được nhiều việc hơn với JavaScript song song.

API đồ hoạ hiện đại nổi tiếng về sự phức tạp, tính đơn giản trong giao dịch mang đến các cơ hội tối ưu hoá cực kỳ lớn. Mặt khác, WebGPU tập trung vào khả năng tương thích giữa nhiều nền tảng, tự động xử lý các chủ đề khó khăn theo truyền thống như đồng bộ hoá tài nguyên trong hầu hết các trường hợp.

Điều này có một ưu điểm phụ là WebGPU dễ tìm hiểu và dễ sử dụng. AI của Google dựa vào các tính năng hiện có của nền tảng web cho những hoạt động như tải hình ảnh và video, đồng thời dựa vào các mẫu JavaScript phổ biến như Promises cho các hoạt động không đồng bộ. Điều này giúp giảm thiểu số lượng mã nguyên mẫu cần thiết. Bạn có thể tạo hình tam giác đầu tiên trên màn hình trong chưa đầy 50 dòng mã.

<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const context = canvas.getContext("webgpu");
  const format = navigator.gpu.getPreferredCanvasFormat();
  context.configure({ device, format });

  const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
  const shaderModule = device.createShaderModule({ code });
  const pipeline = device.createRenderPipeline({
    layout: "auto",
    vertex: {
      module: shaderModule,
      entryPoint: "vertexMain",
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [{ format }],
    },
  });
  const commandEncoder = device.createCommandEncoder();
  const colorAttachments = [
    {
      view: context.getCurrentTexture().createView(),
      loadOp: "clear",
      storeOp: "store",
    },
  ];
  const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
</script>

Kết luận

Tôi rất vui mừng khi chứng kiến tất cả những khả năng mới mà WebGPU mang lại cho nền tảng web và chúng tôi rất mong được thấy tất cả các trường hợp sử dụng mới, thú vị mà bạn sẽ thấy cho WebGPU!

Hệ sinh thái thư viện và khung sinh động đã được xây dựng dựa trên WebGL và cùng hệ sinh thái đó cũng háo hức muốn sử dụng WebGPU. Hỗ trợ cho WebGPU đang được tiến hành hoặc đã hoàn tất trong nhiều thư viện WebGL phổ biến và trong một số trường hợp việc tận dụng các lợi ích của WebGPU có thể chỉ đơn giản như thay đổi một cờ duy nhất!

Babylon.js, Xây dựng 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js và Unity.
Khung, ứng dụng và thư viện có các cổng WebGPU đã hoàn tất hoặc đang hoạt động.

bản phát hành đầu tiên trong Chrome 113 này chỉ là một khởi đầu. Mặc dù bản phát hành ban đầu của chúng tôi dành cho Windows, ChromeOS và MacOS, nhưng chúng tôi dự định sẽ cung cấp WebGPU cho các nền tảng còn lại như Android và Linux trong thời gian sắp tới.

Và không chỉ nhóm Chrome đang nỗ lực phát hành WebGPU. Việc triển khai cũng đang được tiến hành trên Firefox và WebKit.

Ngoài ra, các tính năng mới đã được thiết kế tại W3C có thể được bộc lộ khi có sẵn trong phần cứng. Ví dụ: Trong Chrome, chúng tôi dự định sẽ sớm hỗ trợ các số có dấu phẩy động 16 bit trong chương trình đổ bónglớp hướng dẫn DP4a để cải thiện hiệu suất của công nghệ học máy hơn nữa.

WebGPU là một API mở rộng giúp bạn đạt được hiệu suất đáng kinh ngạc nếu bạn đầu tư vào đó. Hôm nay, chúng ta chỉ có thể đề cập đến những lợi ích của WebGPU ở mức độ cao, nhưng nếu bạn muốn bắt đầu với WebGPU, hãy xem Lớp học lập trình giới thiệu của chúng tôi, Ứng dụng WebGPU đầu tiên của bạn. Trong lớp học lập trình này, bạn sẽ xây dựng một phiên bản GPU của Game of Life cổ điển của Conway. Lớp học lập trình này sẽ hướng dẫn từng bước về quy trình này, vì vậy, bạn có thể dùng thử ngay cả khi đây là lần đầu tiên bạn phát triển GPU.

Các mẫu WebGPU cũng là nơi lý tưởng để tìm hiểu về API. Chúng có phạm vi từ "hình tam giác xin chào" truyền thống cho đến các quy trình kết xuất và tính toán hoàn chỉnh hơn, thể hiện nhiều kỹ thuật. Cuối cùng, hãy tham khảo các tài nguyên khác của chúng tôi.