Penyempurnaan WebAssembly dan WebGPU untuk Web AI yang lebih cepat, bagian 1

Pelajari cara peningkatan WebAssembly dan WebGPU meningkatkan performa machine learning di web.

Austin Eng
Austin Eng
Deepti Gandluri
Deepti Gandluri
François Beaufort
François Beaufort

Inferensi AI di web

Kita semua pernah mendengar cerita: AI mengubah dunia. Begitu juga dengan web.

Tahun ini, Chrome menambahkan fitur AI generatif, termasuk pembuatan tema kustom dan atau membantu Anda menulis draf teks pertama. Namun, AI lebih dari sekadar AI. AI dapat memperkaya aplikasi web itu sendiri.

Halaman web dapat menyematkan komponen cerdas untuk penglihatan, seperti memilih wajah atau mengenali gestur, untuk klasifikasi audio, atau untuk deteksi bahasa. Dalam setahun terakhir, kami telah melihat AI generatif berkembang pesat, termasuk beberapa demo model bahasa besar (LLM) yang sangat mengesankan di web. Pastikan Anda mempelajari AI praktis di perangkat untuk developer web.

Inferensi AI di web saat ini tersedia di sebagian besar perangkat, dan pemrosesan AI dapat terjadi di halaman web itu sendiri, dengan memanfaatkan hardware di perangkat pengguna.

Cara ini sangat efektif karena beberapa alasan:

  • Pengurangan biaya: Menjalankan inferensi pada klien browser secara signifikan mengurangi biaya server, dan ini bisa sangat berguna untuk kueri GenAI, yang bisa jadi jauh lebih mahal daripada kueri reguler.
  • Latensi: Untuk aplikasi yang sangat sensitif terhadap latensi, seperti aplikasi audio atau video, karena semua pemrosesan dilakukan di perangkat akan mengurangi latensi.
  • Privasi: Jika dijalankan di sisi klien, hal ini juga berpotensi membuka kelas aplikasi baru yang memerlukan peningkatan privasi, yang membuat data tidak dapat dikirim ke server.

Cara workload AI berjalan di web saat ini

Saat ini, developer aplikasi dan peneliti membuat model menggunakan framework, model dieksekusi di browser menggunakan runtime seperti Tensorflow.js atau ONNX Runtime Web, dan runtime memanfaatkan Web API untuk eksekusi.

Semua runtime tersebut pada akhirnya berjalan di CPU melalui JavaScript atau WebAssembly atau di GPU melalui WebGL atau WebGPU.

Diagram cara workload AI berjalan di web saat ini

Workload machine learning

Workload machine learning (ML) mendorong tensor melalui grafik node komputasi. Tensor adalah input dan output dari node ini yang melakukan komputasi dalam jumlah besar atas data.

Hal ini penting, karena:

  • Tensor adalah struktur data yang sangat besar, yang melakukan komputasi pada model yang dapat memiliki miliaran bobot
  • Penskalaan dan inferensi dapat menyebabkan paralelisme data. Artinya, operasi yang sama dilakukan pada semua elemen pada tensor.
  • ML tidak memerlukan presisi. Anda mungkin memerlukan bilangan floating point 64-bit untuk mendarat di bulan, tetapi Anda mungkin hanya memerlukan lautan angka 8-bit atau kurang untuk pengenalan wajah.

Untungnya, desainer chip telah menambahkan fitur agar model berjalan lebih cepat, lebih keren, dan bahkan memungkinkan untuk menjalankannya.

Sementara itu, di tim WebAssembly dan WebGPU, kami berupaya mengekspos kemampuan baru tersebut kepada developer web. Jika Anda seorang developer aplikasi web, Anda cenderung tidak sering menggunakan primitif tingkat rendah ini. Kami harap toolchain atau framework yang Anda gunakan akan mendukung fitur dan ekstensi baru, sehingga Anda bisa mendapatkan manfaat dengan perubahan minimal pada infrastruktur. Tetapi jika Anda ingin menyesuaikan aplikasi secara manual untuk meningkatkan kinerja, maka fitur ini relevan dengan pekerjaan Anda.

WebAssembly

WebAssembly (Wasm) adalah format kode byte yang ringkas dan efisien yang dapat dipahami dan dieksekusi oleh runtime. Layanan ini didesain untuk memanfaatkan kemampuan hardware pokok, sehingga bisa berjalan pada kecepatan yang mendekati native. Kode divalidasi dan dieksekusi di lingkungan dalam sandbox yang aman untuk memori.

Informasi modul Wasm direpresentasikan dengan encoding biner padat. Dibandingkan dengan format berbasis teks, yang berarti lebih cepat melakukan decoding, memuat lebih cepat, dan mengurangi penggunaan memori. Portabel dalam arti bahwa ia tidak membuat asumsi tentang arsitektur dasar yang belum umum untuk arsitektur modern.

Spesifikasi WebAssembly bersifat iteratif dan dikerjakan dalam kelompok komunitas W3C terbuka.

Format biner tidak membuat asumsi tentang lingkungan host, sehingga format ini juga dirancang untuk bekerja dengan baik dalam embedding non-web.

Aplikasi Anda dapat dikompilasi sekali, dan dijalankan di mana saja: desktop, laptop, ponsel, atau perangkat lainnya dengan browser. Lihat Tulis sekali, jalankan di mana saja yang akhirnya terwujud dengan WebAssembly untuk mempelajari lebih lanjut tentang hal ini.

Ilustrasi laptop, tablet, dan ponsel

Sebagian besar aplikasi produksi yang menjalankan inferensi AI di web menggunakan WebAssembly, baik untuk komputasi CPU maupun antarmuka dengan komputasi tujuan khusus. Pada aplikasi native, Anda dapat mengakses komputasi tujuan umum dan tujuan khusus, karena aplikasi tersebut dapat mengakses kemampuan perangkat.

Di web, demi portabilitas dan keamanan, kami dengan cermat mengevaluasi kumpulan elemen primitif yang diekspos. Hal ini menyeimbangkan aksesibilitas web dengan performa maksimal yang diberikan oleh hardware.

WebAssembly adalah abstraksi CPU portabel, sehingga semua inferensi Wasm dijalankan pada CPU. Meskipun ini bukanlah pilihan berperforma terbaik, CPU tersedia secara luas dan berfungsi di sebagian besar beban kerja, pada sebagian besar perangkat.

Untuk beban kerja yang lebih kecil, seperti beban kerja teks atau audio, GPU akan menjadi mahal. Ada sejumlah contoh terbaru penggunaan Wasm sebagai pilihan yang tepat:

Anda dapat menemukan lebih banyak lagi di demo open source, seperti: whisper-small, llama.cpp, dan Gemma2B yang berjalan di browser.

Lakukan pendekatan menyeluruh pada aplikasi Anda

Anda harus memilih primitif berdasarkan model ML tertentu, infrastruktur aplikasi, dan pengalaman aplikasi yang diinginkan secara keseluruhan untuk pengguna

Misalnya, dalam deteksi penanda wajah MediaPipe, inferensi CPU dan inferensi GPU sebanding (berjalan di perangkat Apple M1), tetapi ada model yang variannya dapat secara signifikan lebih tinggi.

Dalam hal beban kerja ML, kami mempertimbangkan tampilan aplikasi yang menyeluruh, sambil mendengarkan penulis framework dan partner aplikasi, untuk mengembangkan dan mengirimkan peningkatan yang paling banyak diminta. Secara garis besar, penerapan hak cipta dapat dikelompokkan ke dalam tiga kategori:

  • Mengekspos ekstensi CPU yang penting bagi performa
  • Memungkinkan pengoperasian model yang lebih besar
  • Mengaktifkan interop yang lancar dengan API Web lainnya

Komputasi yang lebih cepat

Seperti sekarang, spesifikasi WebAssembly hanya menyertakan serangkaian petunjuk tertentu yang kami ekspos ke web. Namun, hardware terus menambahkan instruksi baru yang meningkatkan kesenjangan antara performa native dan WebAssembly.

Ingat, model ML tidak selalu memerlukan tingkat presisi yang tinggi. SIMD santai adalah proposal yang mengurangi beberapa persyaratan non-determinisme yang ketat, sehingga menghasilkan codegen yang lebih cepat untuk beberapa operasi vektor yang merupakan hot spot untuk performa. Selanjutnya, Casual SIMD memperkenalkan produk dot baru dan instruksi FMA yang mempercepat beban kerja yang ada sebanyak 1,5 - 3 kali lipat. Fitur ini dikirimkan pada Chrome 114.

Format floating point presisi setengah menggunakan 16 bit untuk IEEE FP16, bukan 32 bit yang digunakan untuk nilai presisi tunggal. Dibandingkan dengan nilai presisi tunggal, ada beberapa keuntungan dalam menggunakan nilai presisi setengah, persyaratan memori yang lebih sedikit, yang memungkinkan pelatihan dan deployment jaringan neural yang lebih besar, dan mengurangi bandwidth memori. Presisi yang berkurang mempercepat transfer data dan operasi matematika.

Model yang lebih besar

Pointer ke memori linear Wasm direpresentasikan sebagai bilangan bulat 32-bit. Ini memiliki dua konsekuensi: ukuran heap dibatasi hingga 4 GB (ketika komputer memiliki RAM fisik yang jauh lebih banyak dari itu), dan kode aplikasi yang menargetkan Wasm harus kompatibel dengan ukuran pointer 32-bit (yang).

Terutama untuk model besar seperti yang kita miliki saat ini, memuat model ini ke WebAssembly dapat bersifat ketat. Proposal Memory64 menghapus batasan ini berdasarkan memori linear agar lebih besar dari 4 GB dan mencocokkan ruang alamat platform native.

Kami telah menerapkan Chrome sepenuhnya dan diperkirakan akan diluncurkan dalam tahun ini. Untuk saat ini, Anda dapat menjalankan eksperimen dengan flag chrome://flags/#enable-experimental-webassembly-features, dan mengirimkan masukan kepada kami.

Interop web yang lebih baik

WebAssembly dapat menjadi titik entri untuk komputasi tujuan khusus di web.

WebAssembly dapat digunakan untuk menghadirkan aplikasi GPU ke web. Artinya, aplikasi C++ yang sama yang dapat berjalan di perangkat juga dapat berjalan di web, dengan sedikit modifikasi.

Emscripten, toolchain compiler Wasm, sudah memiliki binding untuk WebGPU. Ini adalah titik entri untuk inferensi AI di web, sehingga sangat penting bagi Wasm untuk dapat beroperasi secara lancar dengan platform web lainnya. Kami sedang mengerjakan beberapa proposal berbeda di ruang ini.

Integrasi promise JavaScript (JSPI)

Aplikasi C dan C++ (serta banyak bahasa lainnya) umumnya ditulis terhadap API sinkron. Artinya, aplikasi akan menghentikan eksekusi hingga operasi selesai. Aplikasi pemblokir tersebut biasanya lebih intuitif untuk ditulis daripada aplikasi yang peka asinkron.

Ketika operasi yang mahal memblokir thread utama, operasi tersebut dapat memblokir I/O dan jank akan terlihat oleh pengguna. Ada ketidakcocokan antara model pemrograman sinkron aplikasi native dan model web asinkron. Hal ini terutama bermasalah untuk aplikasi lama, yang akan mahal untuk melakukan porting. Emscripten menyediakan cara untuk melakukan ini dengan Asyncify, tetapi ini tidak selalu merupakan opsi terbaik - ukuran kode yang lebih besar dan tidak efisien.

Contoh berikut adalah menghitung fibonacci, menggunakan promise JavaScript untuk penambahan.

long promiseFib(long x) {
 if (x == 0)
   return 0;
 if (x == 1)
   return 1;
 return promiseAdd(promiseFib(x - 1), promiseFib(x - 2));
}
// promise an addition
EM_ASYNC_JS(long, promiseAdd, (long x, long y), {
  return Promise.resolve(x+y);
});
emcc -O3 fib.c -o b.html -s ASYNCIFY=2

Dalam contoh ini, perhatikan hal berikut:

  • Makro EM_ASYNC_JS menghasilkan semua kode glue yang diperlukan sehingga kita dapat menggunakan JSPI untuk mengakses hasil promise, seperti yang dilakukan untuk fungsi normal.
  • Opsi command line khusus, -s ASYNCIFY=2. Tindakan ini akan memanggil opsi untuk membuat kode yang menggunakan JSPI untuk berinteraksi dengan impor JavaScript yang menampilkan promise.

Untuk informasi selengkapnya tentang JSPI, cara menggunakannya, dan manfaatnya, baca Memperkenalkan WebAssembly JavaScript Promise Integration API di v8.dev. Pelajari uji coba origin saat ini.

Kontrol memori

Developer memiliki sangat sedikit kontrol atas memori Wasm; modul memiliki memori sendiri. API apa pun yang perlu mengakses memori ini harus disalin atau disalin, dan penggunaan ini benar-benar dapat bertambah. Misalnya, aplikasi grafis mungkin perlu menyalin dan menyalin untuk setiap bingkai.

Proposal Kontrol memori bertujuan untuk memberikan kontrol yang lebih terperinci atas memori linear Wasm dan mengurangi jumlah salinan di seluruh pipeline aplikasi. Proposal ini masih dalam Tahap 1. Kami membuat prototipenya di V8, mesin JavaScript Chrome, untuk menginformasikan evolusi standar ini.

Tentukan backend yang tepat untuk Anda

Meskipun CPU ada di mana-mana, itu tidak selalu menjadi opsi terbaik. Komputasi tujuan khusus di GPU atau akselerator dapat menawarkan performa yang jauh lebih tinggi, terutama untuk model yang lebih besar dan di perangkat kelas atas. Hal ini berlaku untuk aplikasi native dan aplikasi web.

Backend yang Anda pilih bergantung pada aplikasi, framework, atau toolchain, serta faktor lain yang memengaruhi performa. Oleh karena itu, kami terus berinvestasi dalam proposal yang memungkinkan Wasm inti berfungsi baik dengan platform web lainnya, dan lebih khusus lagi dengan WebGPU.

Lanjutkan membaca Bagian 2