WebGPU: Membuka akses GPU modern di browser

Pelajari cara WebGPU memanfaatkan kecanggihan GPU untuk performa machine learning yang lebih cepat dan rendering grafis yang lebih baik.

WebGPU API baru membuka peningkatan performa yang besar dalam beban kerja grafis dan machine learning. Artikel ini membahas bagaimana WebGPU merupakan peningkatan dari solusi WebGL saat ini, dengan cuplikan pengembangan mendatang. Namun, pertama-tama, mari kita berikan beberapa konteks tentang alasan WebGPU dikembangkan.

Konteks tentang WebGPU

WebGL hadir di Chrome pada tahun 2011. Dengan mengizinkan aplikasi web memanfaatkan GPU, WebGL memungkinkan pengalaman luar biasa di web—mulai dari Google Earth, video musik interaktif, hingga panduan real estate 3D dan lainnya. WebGL didasarkan pada API dari keluarga OpenGL yang pertama kali dikembangkan pada tahun 1992. Sudah lama sekali. Dan Anda dapat membayangkan bahwa hardware GPU telah berkembang secara signifikan sejak saat itu.

Untuk mengikuti perkembangan ini, jenis API baru dikembangkan agar dapat berinteraksi dengan hardware GPU modern secara lebih efisien. API seperti Direct3D 12, Metal, dan Vulkan. API baru ini telah mendukung kasus penggunaan baru dan yang menuntut untuk pemrograman GPU seperti ledakan machine learning dan kemajuan dalam algoritma rendering. WebGPU adalah penerus WebGL yang menghadirkan kemajuan class API modern baru ini ke Web.

WebGPU membuka banyak kemungkinan pemrograman GPU baru di browser. WebGPU lebih mencerminkan cara kerja hardware GPU modern, sekaligus meletakkan fondasi untuk kemampuan GPU yang lebih canggih di masa mendatang. API ini telah di-bake di grup "GPU for the Web" W3C sejak tahun 2017, dan merupakan kolaborasi antara banyak perusahaan seperti Apple, Google, Mozilla, Microsoft, dan Intel. Dan sekarang, setelah 6 tahun bekerja, dengan senang hati kami umumkan bahwa salah satu penambahan terbesar pada platform Web akhirnya tersedia.

WebGPU kini tersedia di Chrome 113 di ChromeOS, macOS, dan Windows, dengan platform lainnya akan segera hadir. Terima kasih banyak kepada kontributor Chromium lainnya dan Intel khususnya yang telah membantu mewujudkannya.

Sekarang, mari kita lihat beberapa kasus penggunaan menarik yang diaktifkan WebGPU.

Membuka kunci workload GPU baru untuk rendering

Fitur WebGPU seperti compute shader memungkinkan class algoritma baru ditransfer di GPU. Misalnya, algoritma yang dapat menambahkan detail yang lebih dinamis ke tampilan, menyimulasikan fenomena fisik, dan banyak lagi. Bahkan ada beban kerja yang sebelumnya hanya dapat dilakukan di JavaScript yang kini dapat dipindahkan ke GPU.

Video berikut menunjukkan algoritma marching cubes yang digunakan untuk me-triangulate permukaan metaball ini. Dalam 20 detik pertama video, algoritma, saat berjalan di JavaScript, kesulitan untuk mengimbangi halaman yang hanya berjalan pada 8 FPS sehingga menghasilkan animasi yang tersendat. Agar tetap berperforma baik di JavaScript, kita harus menurunkan tingkat detail secara signifikan.

Perbedaannya sangat signifikan saat kita memindahkan algoritma yang sama ke shader komputasi, yang terlihat dalam video setelah 20 detik. Performa meningkat secara dramatis dengan halaman yang kini berjalan pada 60 FPS yang lancar dan masih ada banyak headroom performa untuk efek lainnya. Selain itu, loop JavaScript utama halaman sepenuhnya dibebaskan untuk tugas lain, sehingga memastikan interaksi dengan halaman tetap responsif.

Demo metaball

WebGPU juga memungkinkan efek visual kompleks yang sebelumnya tidak praktis. Dalam contoh berikut, yang dibuat di library Babylon.js populer, permukaan samudra disimulasikan sepenuhnya di GPU. Dinamika yang realistis dibuat dari banyak gelombang independen yang ditambahkan satu sama lain. Namun, menyimulasikan setiap gelombang secara langsung akan terlalu mahal.

Demo samudra

Itulah sebabnya demo menggunakan algoritma lanjutan yang disebut Fast Fourier Transform. Sebagai gantinya, semua gelombang direpresentasikan sebagai data posisi yang kompleks, yang menggunakan data spektral yang jauh lebih efisien untuk melakukan komputasi. Kemudian, setiap frame menggunakan Transformasi Fourier untuk mengonversi dari data spektral menjadi data posisional yang mewakili tinggi gelombang.

Inferensi ML yang lebih cepat

WebGPU juga berguna untuk mempercepat machine learning, yang telah menjadi penggunaan utama GPU dalam beberapa tahun terakhir.

Selama ini, developer materi iklan telah menggunakan kembali API rendering WebGL untuk melakukan operasi non-rendering seperti komputasi machine learning. Namun, hal ini memerlukan gambar piksel segitiga sebagai cara untuk memulai komputasi, serta mengemas dan mengekstrak data tensor dengan cermat dalam tekstur, bukan akses memori tujuan umum lainnya.

Ilustrasi inefisiensi dalam satu eksekusi operator ML dengan WebGL, termasuk pemuatan memori redundan, komputasi redundan, dan sedikit nilai yang ditulis per thread.
Satu eksekusi operator ML dengan WebGL.

Menggunakan WebGL dengan cara ini mengharuskan developer menyesuaikan kode mereka dengan harapan API yang hanya dirancang untuk menggambar. Ditambah dengan kurangnya fitur dasar seperti akses memori bersama di antara komputasi, hal ini menyebabkan pekerjaan duplikat dan performa yang kurang optimal.

Compute shader adalah fitur baru utama WebGPU dan menghilangkan poin masalah ini. Shader komputasi menawarkan model pemrograman yang lebih fleksibel yang memanfaatkan sifat paralel GPU secara massal tanpa dibatasi oleh struktur operasi rendering yang ketat.

Berbagai peningkatan efisiensi dalam shader komputasi WebGPU, termasuk pemuatan memori bersama, komputasi bersama, dan penulisan fleksibel ke memori.
Efektivitas shader komputasi WebGPU.

Shader komputasi memberikan lebih banyak peluang untuk berbagi data dan hasil komputasi dalam grup tugas shader untuk efisiensi yang lebih baik. Hal ini dapat menghasilkan peningkatan yang signifikan dibandingkan upaya sebelumnya untuk menggunakan WebGL untuk tujuan yang sama.

Sebagai contoh peningkatan efisiensi yang dapat dihasilkan, port awal model difusi gambar di TensorFlow.js menunjukkan peningkatan performa 3x lipat pada berbagai hardware saat dipindahkan dari WebGL ke WebGPU. Pada beberapa hardware yang diuji, gambar dirender dalam waktu kurang dari 10 detik. Dan karena ini adalah port awal, kami yakin ada lebih banyak peningkatan yang mungkin dilakukan di WebGPU dan TensorFlow.js. Lihat Apa yang baru di ML Web pada tahun 2023? Sesi Google I/O.

Namun, WebGPU tidak hanya menghadirkan fitur GPU ke web.

Didesain untuk JavaScript terlebih dahulu

Fitur yang memungkinkan kasus penggunaan ini telah tersedia untuk developer desktop dan seluler khusus platform selama beberapa waktu, dan kami menghadapi tantangan untuk mengeksposnya dengan cara yang terasa seperti bagian alami dari platform web.

WebGPU dikembangkan dengan manfaat dari pengalaman lebih dari satu dekade developer yang melakukan pekerjaan luar biasa dengan WebGL. Kami dapat mengatasi masalah yang mereka alami, bottleneck yang mereka hadapi, dan masalah yang mereka ajukan, lalu menyalurkan semua masukan tersebut ke API baru ini.

Kita melihat bahwa model status global WebGL membuat pembuatan library dan aplikasi composable yang andal menjadi sulit dan rapuh. Jadi, WebGPU secara drastis mengurangi jumlah status yang perlu dilacak developer saat mengirim perintah GPU.

Kami mendengar bahwa proses debug aplikasi WebGL sangat merepotkan, sehingga WebGPU menyertakan mekanisme penanganan error yang lebih fleksibel dan tidak menurunkan performa Anda. Selain itu, kami telah berupaya keras untuk memastikan bahwa setiap pesan yang Anda terima dari API mudah dipahami dan dapat ditindaklanjuti.

Kami juga melihat bahwa overhead yang sering kali terjadi karena terlalu banyak panggilan JavaScript menjadi bottleneck untuk aplikasi WebGL yang kompleks. Akibatnya, WebGPU API tidak terlalu banyak berkomunikasi, sehingga Anda dapat melakukan lebih banyak hal dengan lebih sedikit panggilan fungsi. Kami berfokus pada melakukan validasi berat di awal, sehingga loop gambar penting tetap ramping. Selain itu, kami menawarkan API baru seperti Render Bundle, yang memungkinkan Anda merekam perintah gambar dalam jumlah besar terlebih dahulu dan memutarnya kembali dengan satu panggilan.

Untuk menunjukkan perbedaan yang signifikan yang dapat dihasilkan oleh fitur seperti paket render, berikut demo lain dari Babylon.js. Perender WebGL 2 mereka dapat mengeksekusi semua panggilan JavaScript untuk merender tampilan galeri seni ini sekitar 500 kali per detik. Hasilnya cukup bagus.

Galeri seni

Namun, perender WebGPU mereka mengaktifkan fitur yang mereka sebut Rendering Snapshot. Dibuat berdasarkan paket render WebGPU, fitur ini memungkinkan tampilan yang sama dikirimkan lebih dari 10x lebih cepat. Pengurangan overhead yang signifikan ini memungkinkan WebGPU merender tampilan yang lebih kompleks, sekaligus memungkinkan aplikasi melakukan lebih banyak hal dengan JavaScript secara paralel.

API grafis modern memiliki reputasi yang kompleks, yang mengorbankan kesederhanaan untuk mendapatkan peluang pengoptimalan ekstrem. Di sisi lain, WebGPU berfokus pada kompatibilitas lintas platform, yang menangani topik yang biasanya sulit seperti sinkronisasi resource secara otomatis dalam sebagian besar kasus.

Hal ini memiliki efek samping yang menyenangkan, yaitu WebGPU mudah dipelajari dan digunakan. API ini mengandalkan fitur platform web yang ada untuk hal-hal seperti pemuatan gambar dan video, serta mengandalkan pola JavaScript yang terkenal seperti Promise untuk operasi asinkron. Hal ini membantu menjaga jumlah kode boilerplate yang diperlukan seminimal mungkin. Anda dapat menampilkan segitiga pertama di layar dalam waktu kurang dari 50 baris kode.

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

Kesimpulan

Sangat menarik untuk melihat semua kemungkinan baru yang dibawa WebGPU ke platform web dan kami menantikan semua kasus penggunaan baru yang keren yang akan Anda temukan untuk WebGPU.

Ekosistem library dan framework yang dinamis telah dibuat di sekitar WebGL, dan ekosistem yang sama tersebut ingin mengadopsi WebGPU. Dukungan untuk WebGPU sedang dalam proses atau sudah selesai di banyak library WebGL JavaScript populer, dan dalam beberapa kasus, memanfaatkan manfaat WebGPU mungkin semudah mengubah satu flag.

Babylon.js, Construct 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js, dan Unity.
Framework, aplikasi, dan library dengan port WebGPU yang sudah selesai atau sedang berlangsung.

Dan rilis pertama di Chrome 113 ini hanyalah permulaan. Meskipun rilis awal kami ditujukan untuk Windows, ChromeOS, dan MacOS, kami berencana untuk menghadirkan WebGPU ke platform lainnya seperti Android dan Linux dalam waktu dekat.

Selain tim Chrome, ada tim lain yang telah berupaya meluncurkan WebGPU. Implementasi juga sedang berlangsung di Firefox dan WebKit.

Selain itu, fitur baru sudah didesain di W3C yang dapat diekspos saat tersedia di hardware. Misalnya: Di Chrome, kami berencana untuk segera mengaktifkan dukungan untuk angka floating point 16 bit di shader dan class petunjuk DP4a untuk meningkatkan performa machine learning lebih lanjut.

WebGPU adalah API yang luas yang membuka performa luar biasa jika Anda berinvestasi di dalamnya. Hari ini kita hanya dapat membahas manfaatnya secara umum, tetapi jika Anda ingin memulai WebGPU, lihat Codelab pengantar kami, Aplikasi WebGPU pertama Anda. Dalam codelab ini, Anda akan mem-build Game of Life Conway klasik versi GPU. Codelab ini memandu Anda menjalani prosesnya langkah demi langkah, sehingga Anda dapat mencobanya meskipun ini adalah pertama kalinya Anda melakukan pengembangan GPU.

Contoh WebGPU juga merupakan tempat yang tepat untuk merasakan API. Contoh ini berkisar dari "hello triangle" tradisional hingga pipeline rendering dan komputasi yang lebih lengkap, yang menunjukkan berbagai teknik. Terakhir, lihat referensi kami yang lain.