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 在 CPU 上執行。

AI 工作負載目前如何在網路上運作的圖表

機器學習工作負載

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

這很重要,因為:

  • 張量是非常大型的資料結構,可針對可能擁有數十億權重的模型執行運算作業
  • 資源調度和推論可能會導致資料平行處理。這意味著,系統會對張量中的所有元素執行相同的作業。
  • 機器學習不需要精確度您可能需要一個 64 位元的浮點數才能登陸月球,不過在臉部辨識的情況下,您可能只需要用到 8 位元數字的海洋即可。

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

與此同時,WebAssembly 和 WebGPU 團隊的成員,也持續努力向網頁開發人員提供這些新功能。如果您是網頁應用程式開發人員,應該不會經常使用這些低階基本功能。我們預期您使用的工具鍊或架構支援新的功能和擴充功能,因此您可以盡量減少對基礎架構進行的變更,從中獲益。但如果您希望手動調整應用程式來提高效能,則這些功能會與您的工作相關。

WebAssembly

WebAssembly (Wasm) 是一種精簡且高效率的位元組程式碼格式,可供執行階段瞭解及執行。這項功能可善用基礎硬體功能,因此能以近乎原生的速度執行。程式碼會經過驗證,並在安全的沙箱環境中執行。

Wasm 模組資訊會以稠密的二進位編碼表示。相較於文字格式,這意味著解碼速度更快、載入速度更快,記憶體用量也更少。因此可攜性,也就是不假設現代架構尚未常見的基礎架構。

WebAssembly 規格目前仍在開放的 W3C 社群群組中經過疊代處理。

二進位格式不會假設主機環境,因此在設計上也能在非網頁嵌入中順利運作。

應用程式只要編譯一次,就能在電腦、筆電、手機或任何具備瀏覽器的裝置等各種裝置執行。如要進一步瞭解相關資訊,請參閱 Write 一次,隨時隨地透過 WebAssembly 實現的構想

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

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

從網路可攜性和安全性而言,我們會仔細評估要揭露哪些基本功能。這在維持網路存取便利性與硬體所提供的最大效能之間取得平衡。

WebAssembly 是 CPU 的可攜式抽象機制,因此所有 Wasm 推論作業都會在 CPU 上執行。雖然這不是最有效的選擇,但 CPU 可以廣泛使用,適用於大多數工作負載,在大多數裝置上運作。

以文字或音訊工作負載等較小型的工作負載來說,GPU 費用昂貴。以下列舉幾個建議採用 Wasm 的例子:

此外,您還可以在開放原始碼示範中探索更多內容,例如:whisper-tinyllama.cpp 以及 Gemma2B run in the Browser

以獨具一格的做法,處理應用程式

您應該根據特定機器學習模型、應用程式基礎架構,以及使用者的整體應用程式體驗來選擇基本版本

舉例來說,在 MediaPipe 的臉部地標偵測功能中,CPU 推論和 GPU 推論雖然在 Apple M1 裝置上可相輔相成,但有些模型的變異數可能會特別高。

處理機器學習工作負載時,我們會考慮截然不同的應用程式觀點,同時傾聽架構作者與應用程式合作夥伴的意見,開發並推出最受人要求的強化功能。這些可大致分為三類:

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

加快運算速度

如您所知,WebAssembly 規格僅包含我們公開在網路上的一組指示。但硬體持續增加新的操作說明,提高原生和 WebAssembly 效能之間的差距。

請記住,機器學習模型不一定每次都需要高精確度。放鬆 SIMD 這項提案減少了部分嚴格的非確定性要求,有助於加快程式碼生成速度,處理某些對於效能特別高的向量作業。此外,寬鬆的 SIMD 導入了新的圓點產品和 FMA 指示,可加快現有工作負載的 1.5 至 3 倍速度。這是於 Chrome 114 版出貨。

半精度浮點格式採用 IEEE FP16 的 16 位元格式,而非用於單精度值的 32 位元。與單精度值相比,使用半精度值、降低記憶體需求可帶來一些優勢。這類網路可以訓練及部署更大型的類神經網路,進而降低記憶體頻寬。降低精確度可加快資料移轉和數學作業的速度。

大型模型

進入 Wasm 線性記憶體的指標會以 32 位元整數表示。這會產生兩個結果:堆積大小限制為 4 GB (電腦的實體 RAM 多於 4 GB),而指定 Wasm 的應用程式程式碼必須與 32 位元指標大小相容 (這)。

將這類模型載入 WebAssembly 時,往往會受到限制。Memory64 提案移除了這些對於大小超過 4GB 且符合原生平台位址空間的線性記憶體限制。

我們已在 Chrome 中實作了完整的實作方式,預計今年稍晚就會推出。現階段,您可以使用旗標 chrome://flags/#enable-experimental-webassembly-features 進行實驗,並提供意見回饋

改善網路互通性

WebAssembly 可能是網路特殊用途的進入點。

WebAssembly 可用於將 GPU 應用程式帶到網路上。換言之,可在裝置上執行的相同 C++ 應用程式,只要稍微修改即可在網路上執行。

Wasm 編譯器工具鍊 Emscripten 已有 WebGPU 的繫結。這是 AI 網路推論的進入點,因此 Wasm 必須能與網路平台的其他部分順暢互通。我們正在針對這個領域設計幾項不同的提案。

JavaScript 承諾整合 (JSPI)

一般的 C 和 C++ (以及許多其他語言) 應用程式通常是針對同步 API 編寫。這表示應用程式會停止執行作業,直到作業完成為止。相較於具備非同步感知的應用程式,這類封鎖應用程式一般在編寫上較為直覺。

如果耗用資源較多的作業封鎖主執行緒,則可封鎖 I/O,並向使用者顯示卡頓。原生應用程式的同步程式設計模型與網頁非同步模型之間存在差異。這對舊版應用程式而言更是如此,因為攜碼轉移會耗用大量資源。Emscripten 可透過 Asyncify 達到這個目標,但這不是最好的選擇,因為程式碼更大,效率也較低。

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

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 (Chrome 的 JavaScript 引擎) 中設計了原型,以做為此標準的演進。

決定合適的後端

雖然 CPU 無所不在,但不一定是最佳選擇。GPU 或加速器上的特殊用途運算可以提供規模較高的效能,特別是在大型型號和高階裝置上。對原生應用程式和網頁應用程式來說都是如此。

您選擇的後端取決於應用程式、架構或工具鍊,以及影響效能的其他因素。不過,我們持續投入心力,讓核心 Wasm 能與網路平台的其他平台順利搭配使用,更具體地與 WebGPU 搭配運作。

繼續閱讀第 2 部分