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 kisahnya: AI mengubah dunia kita. Begitu pula dengan web.

Tahun ini, Chrome menambahkan fitur AI generatif, termasuk pembuatan tema kustom dan/atau membantu Anda menulis draf teks pertama. Namun, AI tidak hanya itu; AI dapat memperkaya aplikasi webnya sendiri.

Halaman web dapat menyematkan komponen cerdas untuk penglihatan, seperti memilih wajah atau mengenali gestur, untuk klasifikasi audio, atau untuk deteksi bahasa. Pada tahun lalu, kami melihat AI generatif berkembang pesat, termasuk beberapa demo model bahasa besar yang sangat mengesankan di web. Pastikan untuk melihat AI praktis di perangkat untuk developer web.

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

Hal ini sangat kuat karena beberapa alasan:

  • Mengurangi biaya: Menjalankan inferensi di klien browser mengurangi biaya server secara signifikan, dan hal ini dapat sangat berguna untuk kueri AI Generatif, yang mungkin menjadi urutan yang lebih mahal daripada kueri reguler.
  • Latensi: Untuk aplikasi yang sangat sensitif terhadap latensi, seperti aplikasi audio atau video - membuat semua pemrosesan terjadi di perangkat akan mengurangi latensi.
  • Privasi: Berjalan di sisi klien, juga berpotensi membuka kelas aplikasi baru yang memerlukan peningkatan privasi, yang mana data tidak dapat dikirim ke server.

Cara workload AI berjalan di web saat ini

Saat ini, developer dan peneliti aplikasi membangun model menggunakan framework, model yang dieksekusi di browser menggunakan runtime seperti Tensorflow.js atau Web Runtime ONNX, dan runtime menggunakan API Web 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 node ini yang melakukan komputasi dalam jumlah besar pada data.

Hal ini penting, karena:

  • Tensor adalah struktur data yang sangat besar, 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, para perancang {i>chip<i} telah menambahkan fitur agar model berjalan lebih cepat, lebih keren, dan bahkan memungkinkan untuk dijalankan sama sekali.

Sementara itu, dari tim WebAssembly dan WebGPU, kami berupaya untuk menunjukkan kemampuan baru tersebut kepada para developer web. Jika Anda seorang developer aplikasi web, Anda jarang menggunakan primitif tingkat rendah ini. Kami harap toolchain atau framework yang Anda gunakan akan mendukung fitur dan ekstensi baru, sehingga Anda dapat memperoleh manfaat dengan sedikit perubahan pada infrastruktur. Namun, jika Anda ingin menyesuaikan performa aplikasi secara manual, fitur ini relevan dengan pekerjaan Anda.

WebAssembly

WebAssembly (Wasm) adalah format kode byte yang ringkas dan efisien yang dapat dipahami dan dieksekusi oleh runtime. Ini dirancang untuk memanfaatkan kemampuan perangkat keras yang mendasarinya, sehingga dapat mengeksekusi pada kecepatan yang mendekati bawaan. Kode ini divalidasi dan dieksekusi di lingkungan dalam sandbox yang aman untuk memori.

Informasi modul Wasm direpresentasikan dengan encoding biner padat. Dibandingkan dengan format berbasis teks, itu berarti decoding lebih cepat, pemuatan lebih cepat, dan penggunaan memori berkurang. Ia portabel dalam arti tidak membuat asumsi tentang arsitektur dasar yang belum umum bagi arsitektur modern.

Spesifikasi WebAssembly bersifat iteratif dan dikerjakan di grup komunitas W3C terbuka.

Format biner tidak membuat asumsi tentang lingkungan host, sehingga format ini juga dirancang agar berfungsi 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 Write 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 memanfaatkan WebAssembly, baik untuk komputasi CPU maupun interaksi 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, untuk portabilitas dan keamanan, kami mengevaluasi dengan cermat kumpulan primitif apa yang terekspos. Hal ini menyeimbangkan aksesibilitas web dengan performa maksimal yang disediakan oleh hardware.

WebAssembly adalah abstraksi portabel dari CPU, sehingga semua inferensi Wasm dijalankan pada CPU. Meskipun ini bukan pilihan yang paling berperforma tinggi, 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 di mana Wasm adalah pilihan yang tepat:

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

Ambil pendekatan menyeluruh untuk aplikasi Anda

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

Misalnya, dalam deteksi tanda wajah MediaPipe, inferensi CPU dan inferensi GPU setara (berjalan di perangkat Apple M1), tetapi ada model dengan varian yang dapat jauh lebih tinggi.

Dalam hal beban kerja ML, kami mempertimbangkan tampilan aplikasi menyeluruh, sambil mendengarkan penulis framework dan partner aplikasi, untuk mengembangkan dan mengirimkan peningkatan yang paling banyak diminta. Secara umum, hal-hal tersebut terbagi dalam tiga kategori:

  • Mengekspos ekstensi CPU yang penting untuk performa
  • Mungkinkan model yang lebih besar berjalan
  • Mengaktifkan interop lancar dengan API Web lain

Komputasi yang lebih cepat

Seperti yang telah diketahui, spesifikasi WebAssembly hanya menyertakan serangkaian petunjuk tertentu yang ditampilkan di 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 area penting untuk performa. Selanjutnya, Santai SIMD memperkenalkan produk titik baru dan petunjuk FMA yang mempercepat beban kerja yang ada dari 1,5 - 3 kali. Ini diluncurkan di 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, terdapat beberapa keuntungan dalam menggunakan nilai presisi setengah, persyaratan memori yang lebih rendah, yang memungkinkan pelatihan dan deployment jaringan neural yang lebih besar, serta mengurangi bandwidth memori. Pengurangan presisi 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 terbatas hingga 4GB (ketika komputer memiliki lebih banyak RAM fisik dari itu), dan kode aplikasi yang menargetkan Wasm harus kompatibel dengan ukuran pointer 32-bit (yang).

Terutama dengan model besar seperti yang kita miliki sekarang, pemuatan model ini ke WebAssembly dapat menjadi batasan. Proposal Memory64 menghapus batasan ini oleh memori linear agar lebih besar dari 4 GB dan mencocokkan ruang alamat platform native.

Kami memiliki implementasi yang berfungsi penuh di Chrome 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.

Interoperabilitas 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. Machine learning merupakan titik entri untuk inferensi AI di web, sehingga Wasm dapat berinteraksi secara lancar dengan platform web lainnya. Kami sedang mengerjakan beberapa proposal berbeda di bidang ini.

Integrasi promise JavaScript (JSPI)

Aplikasi C dan C++ standar (serta banyak bahasa lainnya) umumnya ditulis menggunakan API sinkron. Ini berarti aplikasi akan menghentikan eksekusi hingga operasi selesai. Aplikasi pemblokiran semacam itu biasanya lebih intuitif untuk ditulis daripada aplikasi yang peka terhadap asinkron.

Jika 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 memerlukan banyak biaya untuk porting. Emscripten menyediakan cara untuk melakukan ini dengan Asyncify, tetapi ini tidak selalu merupakan pilihan 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 menghasilkan kode yang menggunakan JSPI untuk berinteraksi dengan impor JavaScript yang menampilkan promise.

Untuk mengetahui 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 sedikit kontrol atas memori Wasm; maka modul memiliki memorinya sendiri. Setiap API yang perlu mengakses memori ini harus menyalin atau menyalin, dan penggunaan ini benar-benar dapat bertambah. Misalnya, aplikasi grafis mungkin perlu menyalin dan menyalin untuk setiap {i>frame<i}.

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

Tentukan backend yang tepat untuk Anda

Meskipun CPU ada di mana-mana, itu bukan selalu menjadi pilihan terbaik. Komputasi tujuan khusus pada GPU atau akselerator dapat menawarkan performa yang jauh lebih tinggi, terutama untuk model yang lebih besar dan pada 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. Meskipun demikian, kami terus berinvestasi dalam proposal yang memungkinkan Wasm inti untuk bekerja baik dengan seluruh platform web, dan lebih khusus lagi dengan WebGPU.

Lanjutkan membaca Bagian 2