WebAssembly 和 WebGPU 強化技術,加快 Web AI 速度,第 1 部分

瞭解 WebAssembly 和 WebGPU 如何強化網頁機器學習效能。

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

網路上的 AI 推論

我們都聽過這故事:AI 改變了這個世界。網路也不例外。

今年 Chrome 新增了生成式 AI 功能,包括自訂主題,以及協助撰寫文字草稿。不過,AI 的發展不僅止於此,AI 可自行豐富網頁應用程式。

網頁可嵌入視覺輔助的智慧型元件,例如挑選臉孔或辨識手勢、音訊分類或語言偵測。過去一年來,我們看到生成式 AI 的進步,包括一些網路上大型語言模型的精彩範例。請務必查看網頁開發人員適用的實用裝置端 AI

現今大部分裝置都支援網路的 AI 推論功能,而且只要利用使用者裝置的硬體,就能在網頁本身中進行 AI 處理作業。

這項功能非常強大,原因如下:

  • 降低成本:在瀏覽器用戶端上執行推論會大幅減少伺服器成本,而且特別適合用於生成式 AI 查詢,後者的費用可能比一般查詢高。
  • 延遲時間:如果應用程式對於音訊或影片應用程式等延遲時間特別敏感,則所有處理作業都會在裝置上進行,因此可以縮短延遲時間。
  • 隱私性:在用戶端執行,同時有機會可解鎖需要加強隱私防護的全新應用程式類別,進而無法將資料傳送至伺服器。

AI 工作負載目前如何在網路上執行

現今的應用程式開發人員和研究人員使用架構建立模型、使用 Tensorflow.jsONNX Runtime Web 等執行階段在瀏覽器中執行模型,而執行階段則利用 Web API 執行。

這些執行階段最終會透過 JavaScript 或 WebAssembly,或在 GPU 透過 WebGL 或 WebGPU 在 GPU 上執行。

AI 工作負載目前在網路上執行方式的圖表

機器學習工作負載

機器學習 (ML) 工作負載會透過運算節點圖推送張量。張量是這些節點的輸入和輸出,需要對資料執行大量運算。

這很重要,因為:

  • Tensor 是非常龐大的資料結構,可在具有數十億權重的模型上執行運算
  • 資源調度和推論可能會導致資料平行處理。這意味著,張量中的所有元素都會執行相同的作業。
  • 機器學習不需要精確度。如果想飛向月球,您可能需要 64 位元浮點數,但是臉孔辨識時,只需要 8 位元數字的海面即可。

幸運的是,方塊設計師加入了新功能,讓模型執行速度更快、更冷,甚至完全能執行。

與此同時,我們也在 WebAssembly 和 WebGPU 團隊的職員,努力將這些新功能提供給網頁程式開發人員。如果您是網頁應用程式開發人員,不太可能經常使用這些低階基本功能。我們希望您使用的工具鍊或架構能夠支援新功能和擴充功能,因此您只要對基礎架構進行少許調整,即可獲益。不過,如果您有意手動調整應用程式來提高效能,這些功能就會與您的工作相關。

WebAssembly

WebAssembly (Wasm) 是一種精簡且高效率的位元組程式碼格式,可讓執行階段解讀及執行。而是利用基礎硬體功能,因此能以近乎原生速度的執行。系統會驗證程式碼,並在安全記憶體的沙箱環境中執行。

Wasm 模組資訊會以密集的二進位編碼表示。與文字格式相比,這種方式能夠加快解碼速度、加快載入速度,以及降低記憶體用量。這屬於可攜權,理論上不會假設現代架構不常見的基礎架構。

WebAssembly 規格是疊代的,在開放的 W3C 社群組織中工作。

二進位格式不會對主機環境做出任何假設,因此也能在非網頁嵌入作業中順利運作。

您的應用程式只需編譯一次,即可在任何位置執行,包括桌上型電腦、筆記型電腦、手機或任何具備瀏覽器的裝置。想瞭解更多資訊,請參閱「編寫一次,在任何最終能使用 WebAssembly 的情況下執行」。

插圖:筆記型電腦、平板電腦和手機

大多數在網路上執行 AI 推論的生產應用程式都會使用 WebAssembly (包括執行 CPU 運算,以及與特殊用途運算互動)。在原生應用程式中,您可以存取一般用途和特殊用途運算,因為應用程式可以存取裝置功能。

為確保網站的可攜性和安全性,我們會仔細評估已暴露在哪些基本物件。讓網路的無障礙與硬體提供的最佳效能之間取得平衡。

WebAssembly 是 CPU 的可攜式抽象化機制,因此所有 Wasm 推論作業都在 CPU 上執行。雖然這不是最有效的選擇,但 CPU 的可用性相當高,適用於大部分的工作負載,適用於大多數的裝置。

以小型工作負載 (例如文字或音訊工作負載) 來說,GPU 的價格高昂。以下列舉幾個近期的例子,協助您選擇 Wasm:

您可以在開放原始碼試用版中發掘更多相關資訊,例如:whisper-tinyllama.cppGemma2B 在瀏覽器中執行

將全面性的方法套用至應用程式

請依據特定機器學習模型、應用程式基礎架構,以及整體的使用者預期應用程式體驗來選擇基本功能

舉例來說,在 MediaPipe 的臉部地標偵測中,CPU 推論和 GPU 推論是相當的結果 (在 Apple M1 裝置上執行),但某些型號的變異數可能相當高。

就機器學習工作負載而言,我們不僅是採用全方位的應用程式觀點,也會傾聽架構作者和應用程式合作夥伴的需求,開發與推送最要求的強化功能。這些類別大致可分為三類:

  • 公開對效能至關重要的 CPU 擴充功能
  • 啟用執行大型模型
  • 實現與其他 Web API 的無縫互通性

加快運算速度

如圖所述,WebAssembly 規格僅包含一組我們提供給網路的特定指示。但硬體會繼續新增操作說明,以增加原生和 WebAssembly 效能之間的差距。

別忘了,機器學習模型不一定需要高精確度。放鬆 SIM 卡是一種提案,可以減少一些嚴格、非確定性的要求,針對某些最熱門的向量運算方式,加快程式碼產生速度。此外,放鬆的 SIMD 也導入了新的圓點產品和 FMA 操作說明,將現有工作負載從 1.5 增加至 3 倍。這項功能是在 Chrome 114 版中出貨。

半精度浮點格式會在 IEEE FP16 中使用 16 位元,而非用於單精度值的 32 位元。與單精度值相比,使用半精度值和記憶體需求降低的優點,可讓訓練及部署較大型的類神經網路,進而降低記憶體頻寬。降低精確度能加快資料移轉和數學運算速度。

大型模型

指向 Wasm 線性記憶體的指標是以 32 位元整數表示。這有兩個結果:堆積大小限制為 4 GB (當電腦的實體 RAM 遠超過此上限時),以 Wasm 為目標的應用程式程式碼必須與 32 位元指標大小 (這點) 相容。

將這些模型載入 WebAssembly 會受到限制,特別是在目前我們擁有的大型模型。Memory64 提案會將這些限制從線性記憶體中移除,使其大於 4 GB,且符合原生平台的位址空間。

我們目前已在 Chrome 中導入完善的架構,預計今年稍晚出貨。目前,您可以使用旗標 chrome://flags/#enable-experimental-webassembly-features 進行實驗,並傳送意見回饋給我們。

改善網路互通性

WebAssembly 可能是用於網路上特殊運算的進入點。

WebAssembly 可用於將 GPU 應用程式帶到網路。這表示,在裝置上執行的同一 C++ 應用程式只要稍微修改,也能在網路上執行。

Emscripten 是 Wasm 編譯器工具鍊,已有 WebGPU 繫結。這是網路 AI 推論的進入點,因此請務必讓 Wasm 能與網站平台的其他部分完美互通。我們正在這個領域研究幾個不同的提案

JavaScript 承諾整合 (JSPI)

一般 C 和 C++ (以及許多其他語言) 應用程式通常是針對同步 API 編寫。這表示應用程式會停止執行,直到作業完成為止。與具非同步感知特性的應用程式相比,這類封鎖的應用程式通常更容易進行寫入。

當高成本作業封鎖主執行緒時,他們可以封鎖 I/O,向使用者顯示卡頓。原生應用程式的同步程式設計模型與網路非同步模型之間的差異並不相符。這對於舊版應用程式特別有問題,通訊埠則十分昂貴。Emscripten 可讓您透過 Asyncify 執行這項操作,但這不一定是最佳選項:程式碼大小較大,效率也不佳。

以下範例是使用 JavaScript 的承諾來計算 fibonacci。

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

在這個例子中,請注意下列事項:

  • EM_ASYNC_JS 巨集會產生所有必要的黏著程式碼,以便我們使用 JSPI 存取承諾結果,就像處理一般函式一樣。
  • 特殊的指令列選項 -s ASYNCIFY=2。這會叫用產生使用 JSPI 時,用於產生傳回承諾的 JavaScript 匯入程式碼的選項。

如要進一步瞭解 JSPI、使用方式和優點,請參閱「在 8.dev 版上推出 WebAssembly JavaScript Promise Integration API」。進一步瞭解目前的來源試用

記憶體控制

開發人員對 Wasm 記憶體的控制權幾乎沒有部分限制,模組則擁有自己的記憶體。任何需要存取這個記憶體的 API 都必須複製或複製,並實際增加這些用量。舉例來說,圖形應用程式可能需要複製並複製每個影格。

記憶體控制提案的用意是讓您更精細地控管 Wasm 線性記憶體,並減少整個應用程式管道的複製數量。本提案邁入第 1 階段,也就是在 Chrome 的 JavaScript 引擎 V8 中設計這個原型,以為標準演進。

找出合適的後端

雖然 CPU 技術無所不在,但不一定是最佳選擇。特殊用途的 GPU 或加速器運算效能,也能提供比數量級更高的效能,特別是大型模型和高階裝置。原生應用程式和網頁應用程式也是如此。

要選擇哪種後端,取決於應用程式、架構或工具鍊,以及其他會影響效能的因素。話雖如此,我們仍持續投資開發提案,讓核心 Wasm 的和其他網路平台平台都能順利運作,而更著重於 WebGPU 。

繼續閱讀第 2 部分